/************************************************************************ * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC * Copyright(c) 2002-2010 Exar Corp. * * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by reference. * Drivers based on or derived from this code fall under the GPL and must * retain the authorship, copyright and license notice. This file is not * a complete program and may only be used when the entire operating * system is licensed under the GPL. * See the file COPYING in this distribution for more information. * * Credits: * Jeff Garzik : For pointing out the improper error condition * check in the s2io_xmit routine and also some * issues in the Tx watch dog function. Also for * patiently answering all those innumerable * questions regaring the 2.6 porting issues. * Stephen Hemminger : Providing proper 2.6 porting mechanism for some * macros available only in 2.6 Kernel. * Francois Romieu : For pointing out all code part that were * deprecated and also styling related comments. * Grant Grundler : For helping me get rid of some Architecture * dependent code. * Christopher Hellwig : Some more 2.6 specific issues in the driver. * * The module loadable parameters that are supported by the driver and a brief * explanation of all the variables. * * rx_ring_num : This can be used to program the number of receive rings used * in the driver. * rx_ring_sz: This defines the number of receive blocks each ring can have. * This is also an array of size 8. * rx_ring_mode: This defines the operation mode of all 8 rings. The valid * values are 1, 2. * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. * tx_fifo_len: This too is an array of 8. Each element defines the number of * Tx descriptors that can be associated with each corresponding FIFO. * intr_type: This defines the type of interrupt. The values can be 0(INTA), * 2(MSI_X). Default value is '2(MSI_X)' * lro_max_pkts: This parameter defines maximum number of packets can be * aggregated as a single large packet * napi: This parameter used to enable/disable NAPI (polling Rx) * Possible values '1' for enable and '0' for disable. Default is '1' * vlan_tag_strip: This can be used to enable or disable vlan stripping. * Possible values '1' for enable , '0' for disable. * Default is '2' - which means disable in promisc mode * and enable in non-promiscuous mode. * multiq: This parameter used to enable/disable MULTIQUEUE support. * Possible values '1' for enable and '0' for disable. Default is '0' ************************************************************************/ #define pr_fmt(fmt) … #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/ioport.h> #include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/kernel.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/mdio.h> #include <linux/skbuff.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/stddef.h> #include <linux/ioctl.h> #include <linux/timex.h> #include <linux/ethtool.h> #include <linux/workqueue.h> #include <linux/if_vlan.h> #include <linux/ip.h> #include <linux/tcp.h> #include <linux/uaccess.h> #include <linux/io.h> #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/slab.h> #include <linux/prefetch.h> #include <net/tcp.h> #include <net/checksum.h> #include <asm/div64.h> #include <asm/irq.h> /* local include */ #include "s2io.h" #include "s2io-regs.h" #define DRV_VERSION … /* S2io Driver name & version. */ static const char s2io_driver_name[] = …; static const char s2io_driver_version[] = …; static const int rxd_size[2] = …; static const int rxd_count[2] = …; static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) { … } /* * Cards with following subsystem_id have a link state indication * problem, 600B, 600C, 600D, 640B, 640C and 640D. * macro below identifies these cards given the subsystem_id. */ #define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) … #define LINK_IS_UP(val64) … static inline int is_s2io_card_up(const struct s2io_nic *sp) { … } /* Ethtool related variables and Macros. */ static const char s2io_gstrings[][ETH_GSTRING_LEN] = …; static const char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = …; static const char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = …; static const char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = …; #define S2IO_XENA_STAT_LEN … #define S2IO_ENHANCED_STAT_LEN … #define S2IO_DRIVER_STAT_LEN … #define XFRAME_I_STAT_LEN … #define XFRAME_II_STAT_LEN … #define XFRAME_I_STAT_STRINGS_LEN … #define XFRAME_II_STAT_STRINGS_LEN … #define S2IO_TEST_LEN … #define S2IO_STRINGS_LEN … /* copy mac addr to def_mac_addr array */ static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr) { … } /* * Constants to be programmed into the Xena's registers, to configure * the XAUI. */ #define END_SIGN … static const u64 herc_act_dtx_cfg[] = …; static const u64 xena_dtx_cfg[] = …; /* * Constants for Fixing the MacAddress problem seen mostly on * Alpha machines. */ static const u64 fix_mac[] = …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; MODULE_VERSION(…); /* Module Loadable parameters. */ S2IO_PARM_INT(tx_fifo_num, FIFO_DEFAULT_NUM); S2IO_PARM_INT(rx_ring_num, 1); S2IO_PARM_INT(multiq, 0); S2IO_PARM_INT(rx_ring_mode, 1); S2IO_PARM_INT(use_continuous_tx_intrs, 1); S2IO_PARM_INT(rmac_pause_time, 0x100); S2IO_PARM_INT(mc_pause_threshold_q0q3, 187); S2IO_PARM_INT(mc_pause_threshold_q4q7, 187); S2IO_PARM_INT(shared_splits, 0); S2IO_PARM_INT(tmac_util_period, 5); S2IO_PARM_INT(rmac_util_period, 5); S2IO_PARM_INT(l3l4hdr_size, 128); /* 0 is no steering, 1 is Priority steering, 2 is Default steering */ S2IO_PARM_INT(tx_steering_type, TX_DEFAULT_STEERING); /* Frequency of Rx desc syncs expressed as power of 2 */ S2IO_PARM_INT(rxsync_frequency, 3); /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ S2IO_PARM_INT(intr_type, 2); /* Large receive offload feature */ /* Max pkts to be aggregated by LRO at one time. If not specified, * aggregation happens until we hit max IP pkt size(64K) */ S2IO_PARM_INT(lro_max_pkts, 0xFFFF); S2IO_PARM_INT(indicate_max_pkts, 0); S2IO_PARM_INT(napi, 1); S2IO_PARM_INT(vlan_tag_strip, NO_STRIP_IN_PROMISC); static unsigned int tx_fifo_len[MAX_TX_FIFOS] = …; static unsigned int rx_ring_sz[MAX_RX_RINGS] = …; static unsigned int rts_frm_len[MAX_RX_RINGS] = …; module_param_array(…); module_param_array(…); module_param_array(…); /* * S2IO device table. * This table lists all the devices that this driver supports. */ static const struct pci_device_id s2io_tbl[] = …; MODULE_DEVICE_TABLE(pci, s2io_tbl); static const struct pci_error_handlers s2io_err_handler = …; static struct pci_driver s2io_driver = …; /* A simplifier macro used both by init and free shared_mem Fns(). */ #define TXD_MEM_PAGE_CNT(len, per_each) … /* netqueue manipulation helper functions */ static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp) { … } static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no) { … } static inline void s2io_start_all_tx_queue(struct s2io_nic *sp) { … } static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp) { … } static inline void s2io_wake_tx_queue( struct fifo_info *fifo, int cnt, u8 multiq) { … } /** * init_shared_mem - Allocation and Initialization of Memory * @nic: Device private variable. * Description: The function allocates all the memory areas shared * between the NIC and the driver. This includes Tx descriptors, * Rx descriptors and the statistics block. */ static int init_shared_mem(struct s2io_nic *nic) { … } /** * free_shared_mem - Free the allocated Memory * @nic: Device private variable. * Description: This function is to free all memory locations allocated by * the init_shared_mem() function and return it to the kernel. */ static void free_shared_mem(struct s2io_nic *nic) { … } /* * s2io_verify_pci_mode - */ static int s2io_verify_pci_mode(struct s2io_nic *nic) { … } #define NEC_VENID … #define NEC_DEVID … static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) { … } static int bus_speed[8] = …; /* * s2io_print_pci_mode - */ static int s2io_print_pci_mode(struct s2io_nic *nic) { … } /** * init_tti - Initialization transmit traffic interrupt scheme * @nic: device private variable * @link: link status (UP/DOWN) used to enable/disable continuous * transmit interrupts * @may_sleep: parameter indicates if sleeping when waiting for * command complete * Description: The function configures transmit traffic interrupts * Return Value: SUCCESS on success and * '-1' on failure */ static int init_tti(struct s2io_nic *nic, int link, bool may_sleep) { … } /** * init_nic - Initialization of hardware * @nic: device private variable * Description: The function sequentially configures every block * of the H/W from their reset values. * Return Value: SUCCESS on success and * '-1' on failure (endian settings incorrect). */ static int init_nic(struct s2io_nic *nic) { … } #define LINK_UP_DOWN_INTERRUPT … #define MAC_RMAC_ERR_TIMER … static int s2io_link_fault_indication(struct s2io_nic *nic) { … } /** * do_s2io_write_bits - update alarm bits in alarm register * @value: alarm bits * @flag: interrupt status * @addr: address value * Description: update alarm bits in alarm register * Return Value: * NONE. */ static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr) { … } static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag) { … } /** * en_dis_able_nic_intrs - Enable or Disable the interrupts * @nic: device private variable, * @mask: A mask indicating which Intr block must be modified and, * @flag: A flag indicating whether to enable or disable the Intrs. * Description: This function will either disable or enable the interrupts * depending on the flag argument. The mask argument can be used to * enable/disable any Intr block. * Return Value: NONE. */ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) { … } /** * verify_pcc_quiescent- Checks for PCC quiescent state * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * @flag: boolean controlling function path * Return: 1 If PCC is quiescence * 0 If PCC is not quiescence */ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) { … } /** * verify_xena_quiescence - Checks whether the H/W is ready * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * Description: Returns whether the H/W is ready to go or not. Depending * on whether adapter enable bit was written or not the comparison * differs and the calling function passes the input argument flag to * indicate this. * Return: 1 If xena is quiescence * 0 If Xena is not quiescence */ static int verify_xena_quiescence(struct s2io_nic *sp) { … } /** * fix_mac_address - Fix for Mac addr problem on Alpha platforms * @sp: Pointer to device specifc structure * Description : * New procedure to clear mac address reading problems on Alpha platforms * */ static void fix_mac_address(struct s2io_nic *sp) { … } /** * start_nic - Turns the device on * @nic : device private variable. * Description: * This function actually turns the device on. Before this function is * called,all Registers are configured from their reset states * and shared memory is allocated but the NIC is still quiescent. On * calling this function, the device interrupts are cleared and the NIC is * literally switched on by writing into the adapter control register. * Return Value: * SUCCESS on success and -1 on failure. */ static int start_nic(struct s2io_nic *nic) { … } /** * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb * @fifo_data: fifo data pointer * @txdlp: descriptor * @get_off: unused */ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct TxD *txdlp, int get_off) { … } /** * free_tx_buffers - Free all queued Tx buffers * @nic : device private variable. * Description: * Free all queued Tx buffers. * Return Value: void */ static void free_tx_buffers(struct s2io_nic *nic) { … } /** * stop_nic - To stop the nic * @nic : device private variable. * Description: * This function does exactly the opposite of what the start_nic() * function does. This function is called to stop the device. * Return Value: * void. */ static void stop_nic(struct s2io_nic *nic) { … } /** * fill_rx_buffers - Allocates the Rx side skbs * @nic : device private variable. * @ring: per ring structure * @from_card_up: If this is true, we will map the buffer to get * the dma address for buf0 and buf1 to give it to the card. * Else we will sync the already mapped buffer to give it to the card. * Description: * The function allocates Rx side skbs and puts the physical * address of these buffers into the RxD buffer pointers, so that the NIC * can DMA the received frame into these locations. * The NIC supports 3 receive modes, viz * 1. single buffer, * 2. three buffer and * 3. Five buffer modes. * Each mode defines how many fragments the received frame will be split * up into by the NIC. The frame is split into L3 header, L4 Header, * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself * is split into 3 fragments. As of now only single buffer mode is * supported. * Return Value: * SUCCESS on success or an appropriate -ve value on failure. */ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, int from_card_up) { … } static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) { … } /** * free_rx_buffers - Frees all Rx buffers * @sp: device private variable. * Description: * This function will free all Rx buffers allocated by host. * Return Value: * NONE. */ static void free_rx_buffers(struct s2io_nic *sp) { … } static int s2io_chk_rx_buffers(struct s2io_nic *nic, struct ring_info *ring) { … } /** * s2io_poll_msix - Rx interrupt handler for NAPI support * @napi : pointer to the napi structure. * @budget : The number of packets that were budgeted to be processed * during one pass through the 'Poll" function. * Description: * Comes into picture only if NAPI support has been incorporated. It does * the same thing that rx_intr_handler does, but not in a interrupt context * also It will process only a given number of packets. * Return value: * 0 on success and 1 if there are No Rx packets to be processed. */ static int s2io_poll_msix(struct napi_struct *napi, int budget) { … } static int s2io_poll_inta(struct napi_struct *napi, int budget) { … } #ifdef CONFIG_NET_POLL_CONTROLLER /** * s2io_netpoll - netpoll event handler entry point * @dev : pointer to the device structure. * Description: * This function will be called by upper layer to check for events on the * interface in situations where interrupts are disabled. It is used for * specific in-kernel networking tasks, such as remote consoles and kernel * debugging over the network (example netdump in RedHat). */ static void s2io_netpoll(struct net_device *dev) { … } #endif /** * rx_intr_handler - Rx interrupt handler * @ring_data: per ring structure. * @budget: budget for napi processing. * Description: * If the interrupt is because of a received frame or if the * receive ring contains fresh as yet un-processed frames,this function is * called. It picks out the RxD at which place the last Rx processing had * stopped and sends the skb to the OSM's Rx handler and then increments * the offset. * Return Value: * No. of napi packets processed. */ static int rx_intr_handler(struct ring_info *ring_data, int budget) { … } /** * tx_intr_handler - Transmit interrupt handler * @fifo_data : fifo data pointer * Description: * If an interrupt was raised to indicate DMA complete of the * Tx packet, this function is called. It identifies the last TxD * whose buffer was freed and frees all skbs whose data have already * DMA'ed into the NICs internal memory. * Return Value: * NONE */ static void tx_intr_handler(struct fifo_info *fifo_data) { … } /** * s2io_mdio_write - Function to write in to MDIO registers * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS) * @addr : address value * @value : data value * @dev : pointer to net_device structure * Description: * This function is used to write values to the MDIO registers * NONE */ static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device *dev) { … } /** * s2io_mdio_read - Function to write in to MDIO registers * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS) * @addr : address value * @dev : pointer to net_device structure * Description: * This function is used to read values to the MDIO registers * NONE */ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev) { … } /** * s2io_chk_xpak_counter - Function to check the status of the xpak counters * @counter : counter value to be updated * @regs_stat : registers status * @index : index * @flag : flag to indicate the status * @type : counter type * Description: * This function is to check the status of the xpak counters value * NONE */ static void s2io_chk_xpak_counter(u64 *counter, u64 * regs_stat, u32 index, u16 flag, u16 type) { … } /** * s2io_updt_xpak_counter - Function to update the xpak counters * @dev : pointer to net_device struct * Description: * This function is to upate the status of the xpak counters value * NONE */ static void s2io_updt_xpak_counter(struct net_device *dev) { … } /** * wait_for_cmd_complete - waits for a command to complete. * @addr: address * @busy_bit: bit to check for busy * @bit_state: state to check * @may_sleep: parameter indicates if sleeping when waiting for * command complete * Description: Function that waits for a command to Write into RMAC * ADDR DATA registers to be completed and returns either success or * error depending on whether the command was complete or not. * Return value: * SUCCESS on success and FAILURE on failure. */ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit, int bit_state, bool may_sleep) { … } /** * check_pci_device_id - Checks if the device id is supported * @id : device id * Description: Function to check if the pci device id is supported by driver. * Return value: Actual device id if supported else PCI_ANY_ID */ static u16 check_pci_device_id(u16 id) { … } /** * s2io_reset - Resets the card. * @sp : private member of the device structure. * Description: Function to Reset the card. This function then also * restores the previously saved PCI configuration space registers as * the card reset also resets the configuration space. * Return value: * void. */ static void s2io_reset(struct s2io_nic *sp) { … } /** * s2io_set_swapper - to set the swapper controle on the card * @sp : private member of the device structure, * pointer to the s2io_nic structure. * Description: Function to set the swapper control on the card * correctly depending on the 'endianness' of the system. * Return value: * SUCCESS on success and FAILURE on failure. */ static int s2io_set_swapper(struct s2io_nic *sp) { … } static int wait_for_msix_trans(struct s2io_nic *nic, int i) { … } static void restore_xmsi_data(struct s2io_nic *nic) { … } static void store_xmsi_data(struct s2io_nic *nic) { … } static int s2io_enable_msi_x(struct s2io_nic *nic) { … } /* Handle software interrupt used during MSI(X) test */ static irqreturn_t s2io_test_intr(int irq, void *dev_id) { … } /* Test interrupt path by forcing a software IRQ */ static int s2io_test_msi(struct s2io_nic *sp) { … } static void remove_msix_isr(struct s2io_nic *sp) { … } static void remove_inta_isr(struct s2io_nic *sp) { … } /* ********************************************************* * * Functions defined below concern the OS part of the driver * * ********************************************************* */ /** * s2io_open - open entry point of the driver * @dev : pointer to the device structure. * Description: * This function is the open entry point of the driver. It mainly calls a * function to allocate Rx buffers and inserts them into the buffer * descriptors and then enables the Rx part of the NIC. * Return value: * 0 on success and an appropriate (-)ve integer as defined in errno.h * file on failure. */ static int s2io_open(struct net_device *dev) { … } /** * s2io_close -close entry point of the driver * @dev : device pointer. * Description: * This is the stop entry point of the driver. It needs to undo exactly * whatever was done by the open entry point,thus it's usually referred to * as the close function.Among other things this function mainly stops the * Rx side of the NIC and frees all the Rx buffers in the Rx rings. * Return value: * 0 on success and an appropriate (-)ve integer as defined in errno.h * file on failure. */ static int s2io_close(struct net_device *dev) { … } /** * s2io_xmit - Tx entry point of te driver * @skb : the socket buffer containing the Tx data. * @dev : device pointer. * Description : * This function is the Tx entry point of the driver. S2IO NIC supports * certain protocol assist features on Tx side, namely CSO, S/G, LSO. * NOTE: when device can't queue the pkt,just the trans_start variable will * not be upadted. * Return value: * 0 on success & 1 on failure. */ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) { … } static void s2io_alarm_handle(struct timer_list *t) { … } static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) { … } static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) { … } static void s2io_txpic_intr_handle(struct s2io_nic *sp) { … } /** * do_s2io_chk_alarm_bit - Check for alarm and incrment the counter * @value: alarm bits * @addr: address value * @cnt: counter variable * Description: Check for alarm and increment the counter * Return Value: * 1 - if alarm bit set * 0 - if alarm bit is not set */ static int do_s2io_chk_alarm_bit(u64 value, void __iomem *addr, unsigned long long *cnt) { … } /** * s2io_handle_errors - Xframe error indication handler * @dev_id: opaque handle to dev * Description: Handle alarms such as loss of link, single or * double ECC errors, critical and serious errors. * Return Value: * NONE */ static void s2io_handle_errors(void *dev_id) { … } /** * s2io_isr - ISR handler of the device . * @irq: the irq of the device. * @dev_id: a void pointer to the dev structure of the NIC. * Description: This function is the ISR handler of the device. It * identifies the reason for the interrupt and calls the relevant * service routines. As a contongency measure, this ISR allocates the * recv buffers, if their numbers are below the panic value which is * presently set to 25% of the original number of rcv buffers allocated. * Return value: * IRQ_HANDLED: will be returned if IRQ was handled by this routine * IRQ_NONE: will be returned if interrupt is not from our device */ static irqreturn_t s2io_isr(int irq, void *dev_id) { … } /* * s2io_updt_stats - */ static void s2io_updt_stats(struct s2io_nic *sp) { … } /** * s2io_get_stats - Updates the device statistics structure. * @dev : pointer to the device structure. * Description: * This function updates the device statistics structure in the s2io_nic * structure and returns a pointer to the same. * Return value: * pointer to the updated net_device_stats structure. */ static struct net_device_stats *s2io_get_stats(struct net_device *dev) { … } /** * s2io_set_multicast - entry point for multicast address enable/disable. * @dev : pointer to the device structure * @may_sleep: parameter indicates if sleeping when waiting for command * complete * Description: * This function is a driver entry point which gets called by the kernel * whenever multicast addresses must be enabled/disabled. This also gets * called to set/reset promiscuous mode. Depending on the deivce flag, we * determine, if multicast address must be enabled or if promiscuous mode * is to be disabled etc. * Return value: * void. */ static void s2io_set_multicast(struct net_device *dev, bool may_sleep) { … } /* NDO wrapper for s2io_set_multicast */ static void s2io_ndo_set_multicast(struct net_device *dev) { … } /* read from CAM unicast & multicast addresses and store it in * def_mac_addr structure */ static void do_s2io_store_unicast_mc(struct s2io_nic *sp) { … } /* restore unicast & multicast MAC to CAM from def_mac_addr structure */ static void do_s2io_restore_unicast_mc(struct s2io_nic *sp) { … } /* add a multicast MAC address to CAM */ static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr) { … } /* add MAC address to CAM */ static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off) { … } /* deletes a specified unicast/multicast mac entry from CAM */ static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr) { … } /* read mac entries from CAM */ static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset) { … } /* * s2io_set_mac_addr - driver entry point */ static int s2io_set_mac_addr(struct net_device *dev, void *p) { … } /** * do_s2io_prog_unicast - Programs the Xframe mac address * @dev : pointer to the device structure. * @addr: a uchar pointer to the new mac address which is to be set. * Description : This procedure will program the Xframe to receive * frames with new Mac Address * Return value: SUCCESS on success and an appropriate (-)ve integer * as defined in errno.h file on failure. */ static int do_s2io_prog_unicast(struct net_device *dev, const u8 *addr) { … } /** * s2io_ethtool_set_link_ksettings - Sets different link parameters. * @dev : pointer to netdev * @cmd: pointer to the structure with parameters given by ethtool to set * link information. * Description: * The function sets different link parameters provided by the user onto * the NIC. * Return value: * 0 on success. */ static int s2io_ethtool_set_link_ksettings(struct net_device *dev, const struct ethtool_link_ksettings *cmd) { … } /** * s2io_ethtool_get_link_ksettings - Return link specific information. * @dev: pointer to netdev * @cmd : pointer to the structure with parameters given by ethtool * to return link information. * Description: * Returns link specific information like speed, duplex etc.. to ethtool. * Return value : * return 0 on success. */ static int s2io_ethtool_get_link_ksettings(struct net_device *dev, struct ethtool_link_ksettings *cmd) { … } /** * s2io_ethtool_gdrvinfo - Returns driver specific information. * @dev: pointer to netdev * @info : pointer to the structure with parameters given by ethtool to * return driver information. * Description: * Returns driver specefic information like name, version etc.. to ethtool. * Return value: * void */ static void s2io_ethtool_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { … } /** * s2io_ethtool_gregs - dumps the entire space of Xfame into the buffer. * @dev: pointer to netdev * @regs : pointer to the structure with parameters given by ethtool for * dumping the registers. * @space: The input argument into which all the registers are dumped. * Description: * Dumps the entire register space of xFrame NIC into the user given * buffer area. * Return value : * void . */ static void s2io_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *space) { … } /* * s2io_set_led - control NIC led */ static void s2io_set_led(struct s2io_nic *sp, bool on) { … } /** * s2io_ethtool_set_led - To physically identify the nic on the system. * @dev : network device * @state: led setting * * Description: Used to physically identify the NIC on the system. * The Link LED will blink for a time specified by the user for * identification. * NOTE: The Link has to be Up to be able to blink the LED. Hence * identification is possible only if it's link is up. */ static int s2io_ethtool_set_led(struct net_device *dev, enum ethtool_phys_id_state state) { … } static void s2io_ethtool_gringparam(struct net_device *dev, struct ethtool_ringparam *ering, struct kernel_ethtool_ringparam *kernel_ering, struct netlink_ext_ack *extack) { … } /** * s2io_ethtool_getpause_data -Pause frame generation and reception. * @dev: pointer to netdev * @ep : pointer to the structure with pause parameters given by ethtool. * Description: * Returns the Pause frame generation and reception capability of the NIC. * Return value: * void */ static void s2io_ethtool_getpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { … } /** * s2io_ethtool_setpause_data - set/reset pause frame generation. * @dev: pointer to netdev * @ep : pointer to the structure with pause parameters given by ethtool. * Description: * It can be used to set or reset Pause frame generation or reception * support of the NIC. * Return value: * int, returns 0 on Success */ static int s2io_ethtool_setpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { … } #define S2IO_DEV_ID … /** * read_eeprom - reads 4 bytes of data from user given offset. * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * @off : offset at which the data must be written * @data : Its an output parameter where the data read at the given * offset is stored. * Description: * Will read 4 bytes of data from the user given offset and return the * read data. * NOTE: Will allow to read only part of the EEPROM visible through the * I2C bus. * Return value: * -1 on failure and 0 on success. */ static int read_eeprom(struct s2io_nic *sp, int off, u64 *data) { … } /** * write_eeprom - actually writes the relevant part of the data value. * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * @off : offset at which the data must be written * @data : The data that is to be written * @cnt : Number of bytes of the data that are actually to be written into * the Eeprom. (max of 3) * Description: * Actually writes the relevant part of the data value into the Eeprom * through the I2C bus. * Return value: * 0 on success, -1 on failure. */ static int write_eeprom(struct s2io_nic *sp, int off, u64 data, int cnt) { … } static void s2io_vpd_read(struct s2io_nic *nic) { … } /** * s2io_ethtool_geeprom - reads the value stored in the Eeprom. * @dev: pointer to netdev * @eeprom : pointer to the user level structure provided by ethtool, * containing all relevant information. * @data_buf : user defined value to be written into Eeprom. * Description: Reads the values stored in the Eeprom at given offset * for a given length. Stores these values int the input argument data * buffer 'data_buf' and returns these to the caller (ethtool.) * Return value: * int 0 on success */ static int s2io_ethtool_geeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * data_buf) { … } /** * s2io_ethtool_seeprom - tries to write the user provided value in Eeprom * @dev: pointer to netdev * @eeprom : pointer to the user level structure provided by ethtool, * containing all relevant information. * @data_buf : user defined value to be written into Eeprom. * Description: * Tries to write the user provided value in the Eeprom, at the offset * given by the user. * Return value: * 0 on success, -EFAULT on failure. */ static int s2io_ethtool_seeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data_buf) { … } /** * s2io_register_test - reads and writes into all clock domains. * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * @data : variable that returns the result of each of the test conducted b * by the driver. * Description: * Read and write into all clock domains. The NIC has 3 clock domains, * see that registers in all the three regions are accessible. * Return value: * 0 on success. */ static int s2io_register_test(struct s2io_nic *sp, uint64_t *data) { … } /** * s2io_eeprom_test - to verify that EEprom in the xena can be programmed. * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * @data:variable that returns the result of each of the test conducted by * the driver. * Description: * Verify that EEPROM in the xena can be programmed using I2C_CONTROL * register. * Return value: * 0 on success. */ static int s2io_eeprom_test(struct s2io_nic *sp, uint64_t *data) { … } /** * s2io_bist_test - invokes the MemBist test of the card . * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * @data:variable that returns the result of each of the test conducted by * the driver. * Description: * This invokes the MemBist test of the card. We give around * 2 secs time for the Test to complete. If it's still not complete * within this peiod, we consider that the test failed. * Return value: * 0 on success and -1 on failure. */ static int s2io_bist_test(struct s2io_nic *sp, uint64_t *data) { … } /** * s2io_link_test - verifies the link state of the nic * @sp: private member of the device structure, which is a pointer to the * s2io_nic structure. * @data: variable that returns the result of each of the test conducted by * the driver. * Description: * The function verifies the link state of the NIC and updates the input * argument 'data' appropriately. * Return value: * 0 on success. */ static int s2io_link_test(struct s2io_nic *sp, uint64_t *data) { … } /** * s2io_rldram_test - offline test for access to the RldRam chip on the NIC * @sp: private member of the device structure, which is a pointer to the * s2io_nic structure. * @data: variable that returns the result of each of the test * conducted by the driver. * Description: * This is one of the offline test that tests the read and write * access to the RldRam chip on the NIC. * Return value: * 0 on success. */ static int s2io_rldram_test(struct s2io_nic *sp, uint64_t *data) { … } /** * s2io_ethtool_test - conducts 6 tsets to determine the health of card. * @dev: pointer to netdev * @ethtest : pointer to a ethtool command specific structure that will be * returned to the user. * @data : variable that returns the result of each of the test * conducted by the driver. * Description: * This function conducts 6 tests ( 4 offline and 2 online) to determine * the health of the card. * Return value: * void */ static void s2io_ethtool_test(struct net_device *dev, struct ethtool_test *ethtest, uint64_t *data) { … } static void s2io_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *tmp_stats) { … } static int s2io_ethtool_get_regs_len(struct net_device *dev) { … } static int s2io_get_eeprom_len(struct net_device *dev) { … } static int s2io_get_sset_count(struct net_device *dev, int sset) { … } static void s2io_ethtool_get_strings(struct net_device *dev, u32 stringset, u8 *data) { … } static int s2io_set_features(struct net_device *dev, netdev_features_t features) { … } static const struct ethtool_ops netdev_ethtool_ops = …; /** * s2io_ioctl - Entry point for the Ioctl * @dev : Device pointer. * @rq : An IOCTL specefic structure, that can contain a pointer to * a proprietary structure used to pass information to the driver. * @cmd : This is used to distinguish between the different commands that * can be passed to the IOCTL functions. * Description: * Currently there are no special functionality supported in IOCTL, hence * function always return EOPNOTSUPPORTED */ static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { … } /** * s2io_change_mtu - entry point to change MTU size for the device. * @dev : device pointer. * @new_mtu : the new MTU size for the device. * Description: A driver entry point to change MTU size for the device. * Before changing the MTU the device must be stopped. * Return value: * 0 on success and an appropriate (-)ve integer as defined in errno.h * file on failure. */ static int s2io_change_mtu(struct net_device *dev, int new_mtu) { … } /** * s2io_set_link - Set the LInk status * @work: work struct containing a pointer to device private structure * Description: Sets the link status for the adapter */ static void s2io_set_link(struct work_struct *work) { … } static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, struct buffAdd *ba, struct sk_buff **skb, u64 *temp0, u64 *temp1, u64 *temp2, int size) { … } static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, int size) { … } static int rxd_owner_bit_reset(struct s2io_nic *sp) { … } static int s2io_add_isr(struct s2io_nic *sp) { … } static void s2io_rem_isr(struct s2io_nic *sp) { … } static void do_s2io_card_down(struct s2io_nic *sp, int do_io) { … } static void s2io_card_down(struct s2io_nic *sp) { … } static int s2io_card_up(struct s2io_nic *sp) { … } /** * s2io_restart_nic - Resets the NIC. * @work : work struct containing a pointer to the device private structure * Description: * This function is scheduled to be run by the s2io_tx_watchdog * function after 0.5 secs to reset the NIC. The idea is to reduce * the run time of the watch dog routine which is run holding a * spin lock. */ static void s2io_restart_nic(struct work_struct *work) { … } /** * s2io_tx_watchdog - Watchdog for transmit side. * @dev : Pointer to net device structure * @txqueue: index of the hanging queue * Description: * This function is triggered if the Tx Queue is stopped * for a pre-defined amount of time when the Interface is still up. * If the Interface is jammed in such a situation, the hardware is * reset (by s2io_close) and restarted again (by s2io_open) to * overcome any problem that might have been caused in the hardware. * Return value: * void */ static void s2io_tx_watchdog(struct net_device *dev, unsigned int txqueue) { … } /** * rx_osm_handler - To perform some OS related operations on SKB. * @ring_data : the ring from which this RxD was extracted. * @rxdp: descriptor * Description: * This function is called by the Rx interrupt serivce routine to perform * some OS related operations on the SKB before passing it to the upper * layers. It mainly checks if the checksum is OK, if so adds it to the * SKBs cksum variable, increments the Rx packet count and passes the SKB * to the upper layer. If the checksum is wrong, it increments the Rx * packet error count, frees the SKB and returns error. * Return value: * SUCCESS on success and -1 on failure. */ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) { … } /** * s2io_link - stops/starts the Tx queue. * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * @link : inidicates whether link is UP/DOWN. * Description: * This function stops/starts the Tx queue depending on whether the link * status of the NIC is down or up. This is called by the Alarm * interrupt handler whenever a link change interrupt comes up. * Return value: * void. */ static void s2io_link(struct s2io_nic *sp, int link) { … } /** * s2io_init_pci -Initialization of PCI and PCI-X configuration registers . * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. * Description: * This function initializes a few of the PCI and PCI-X configuration registers * with recommended values. * Return value: * void */ static void s2io_init_pci(struct s2io_nic *sp) { … } static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, u8 *dev_multiq) { … } /** * rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS or Traffic class respectively. * @nic: device private variable * @ds_codepoint: data * @ring: ring index * Description: The function configures the receive steering to * desired receive ring. * Return Value: SUCCESS on success and * '-1' on failure (endian settings incorrect). */ static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring) { … } static const struct net_device_ops s2io_netdev_ops = …; /** * s2io_init_nic - Initialization of the adapter . * @pdev : structure containing the PCI related information of the device. * @pre: List of PCI devices supported by the driver listed in s2io_tbl. * Description: * The function initializes an adapter identified by the pci_dec structure. * All OS related initialization including memory and device structure and * initlaization of the device private variable is done. Also the swapper * control register is initialized to enable read and write into the I/O * registers of the device. * Return value: * returns 0 on success and negative on failure. */ static int s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) { … } /** * s2io_rem_nic - Free the PCI device * @pdev: structure containing the PCI related information of the device. * Description: This function is called by the Pci subsystem to release a * PCI device and free up all resource held up by the device. This could * be in response to a Hot plug event or when the driver is to be removed * from memory. */ static void s2io_rem_nic(struct pci_dev *pdev) { … } module_pci_driver(…) …; static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, struct tcphdr **tcp, struct RxD_t *rxdp, struct s2io_nic *sp) { … } static int check_for_socket_match(struct lro *lro, struct iphdr *ip, struct tcphdr *tcp) { … } static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp) { … } static void initiate_new_session(struct lro *lro, u8 *l2h, struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag) { … } static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) { … } static void aggregate_new_rx(struct lro *lro, struct iphdr *ip, struct tcphdr *tcp, u32 l4_pyld) { … } static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) { … } static int s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, struct RxD_t *rxdp, struct s2io_nic *sp) { … } static void clear_lro_session(struct lro *lro) { … } static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag) { … } static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, struct sk_buff *skb, u32 tcp_len) { … } /** * s2io_io_error_detected - called when PCI error is detected * @pdev: Pointer to PCI device * @state: The current pci connection state * * This function is called after a PCI bus error affecting * this device has been detected. */ static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { … } /** * s2io_io_slot_reset - called after the pci bus has been reset. * @pdev: Pointer to PCI device * * Restart the card from scratch, as if from a cold-boot. * At this point, the card has exprienced a hard reset, * followed by fixups by BIOS, and has its config space * set up identically to what it was at cold boot. */ static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev) { … } /** * s2io_io_resume - called when traffic can start flowing again. * @pdev: Pointer to PCI device * * This callback is called when the error recovery driver tells * us that its OK to resume normal operation. */ static void s2io_io_resume(struct pci_dev *pdev) { … }