From: Andy Gospodarek <gospo@redhat.com> Subject: [RHEL5.1 PATCH] s2io: update to driver version 2.0.25.1 Date: Mon, 13 Aug 2007 15:10:50 -0400 Bugzilla: 223033 Message-Id: <20070813191049.GE19875@gospo.rdu.redhat.com> Changelog: [net] s2io: update to driver version 2.0.25.1 This is an update to the s2io driver as requested by Neterion. Apparently this is needed by some vendors who will be shipping Neterion Xframe-II cards. This will resolve BZ 223033. --- s2io-regs.h | 19 s2io.c | 2439 ++++++++++++++++++++++++++++++++---------------------------- s2io.h | 612 +++++++-------- 3 files changed, 1662 insertions(+), 1408 deletions(-) --- linux-2.6.18.i386/drivers/net/s2io.c.orig +++ linux-2.6.18.i386/drivers/net/s2io.c @@ -1,6 +1,6 @@ /************************************************************************ * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC - * Copyright(c) 2002-2005 Neterion Inc. + * Copyright(c) 2002-2007 Neterion Inc. * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by reference. @@ -32,16 +32,24 @@ * 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 and 3. + * 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), - * 1(MSI), 2(MSI_X). Default value is '0(INTA)' + * 2(MSI_X). Default value is '0(INTA)' * lro: Specifies whether to enable Large Receive Offload (LRO) or not. * Possible values '1' for enable '0' for disable. Default is '0' * 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' + * ufo: This parameter used to enable/disable UDP Fragmentation Offload(UFO) + * Possible values '1' for enable and '0' for disable. Default is '0' + * 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. ************************************************************************/ #include <linux/module.h> @@ -59,7 +67,6 @@ #include <linux/stddef.h> #include <linux/ioctl.h> #include <linux/timex.h> -#include <linux/sched.h> #include <linux/ethtool.h> #include <linux/workqueue.h> #include <linux/if_vlan.h> @@ -77,16 +84,19 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.15.2" +#define DRV_VERSION "2.0.25.1" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; static char s2io_driver_version[] = DRV_VERSION; -static int rxd_size[4] = {32,48,48,64}; -static int rxd_count[4] = {127,85,85,63}; +static int rxd_size[2] = {32,48}; +static int rxd_count[2] = {127,85}; -static inline int RXD_IS_UP2DT(RxD_t *rxdp) +/* RHEL5 compat */ +typedef __u16 __bitwise __sum16; + +static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) { int ret; @@ -111,9 +121,9 @@ static inline int RXD_IS_UP2DT(RxD_t *rx #define TASKLET_IN_USE test_and_set_bit(0, (&sp->tasklet_status)) #define PANIC 1 #define LOW 2 -static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) +static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring) { - mac_info_t *mac_control; + struct mac_info *mac_control; mac_control = &sp->mac_control; if (rxb_size <= rxd_count[sp->rxd_mode]) @@ -132,7 +142,7 @@ static char s2io_gstrings[][ETH_GSTRING_ "BIST Test\t(offline)" }; -static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { +static char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = { {"tmac_frms"}, {"tmac_data_octets"}, {"tmac_drop_frms"}, @@ -226,7 +236,10 @@ static char ethtool_stats_keys[][ETH_GST {"rxd_rd_cnt"}, {"rxd_wr_cnt"}, {"txf_rd_cnt"}, - {"rxf_wr_cnt"}, + {"rxf_wr_cnt"} +}; + +static char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = { {"rmac_ttl_1519_4095_frms"}, {"rmac_ttl_4096_8191_frms"}, {"rmac_ttl_8192_max_frms"}, @@ -242,7 +255,10 @@ static char ethtool_stats_keys[][ETH_GST {"rmac_red_discard"}, {"rmac_rts_discard"}, {"rmac_ingm_full_discard"}, - {"link_fault_cnt"}, + {"link_fault_cnt"} +}; + +static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { {"\n DRIVER STATISTICS"}, {"single_bit_ecc_errs"}, {"double_bit_ecc_errs"}, @@ -268,10 +284,41 @@ static char ethtool_stats_keys[][ETH_GST ("lro_out_of_sequence_pkts"), ("lro_flush_due_to_max_pkts"), ("lro_avg_aggr_pkts"), + ("mem_alloc_fail_cnt"), + ("pci_map_fail_cnt"), + ("watchdog_timer_cnt"), + ("mem_allocated"), + ("mem_freed"), + ("link_up_cnt"), + ("link_down_cnt"), + ("link_up_time"), + ("link_down_time"), + ("tx_tcode_buf_abort_cnt"), + ("tx_tcode_desc_abort_cnt"), + ("tx_tcode_parity_err_cnt"), + ("tx_tcode_link_loss_cnt"), + ("tx_tcode_list_proc_err_cnt"), + ("rx_tcode_parity_err_cnt"), + ("rx_tcode_abort_cnt"), + ("rx_tcode_parity_abort_cnt"), + ("rx_tcode_rda_fail_cnt"), + ("rx_tcode_unkn_prot_cnt"), + ("rx_tcode_fcs_err_cnt"), + ("rx_tcode_buf_size_err_cnt"), + ("rx_tcode_rxd_corrupt_cnt"), + ("rx_tcode_unkn_err_cnt") }; -#define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN -#define S2IO_STAT_STRINGS_LEN S2IO_STAT_LEN * ETH_GSTRING_LEN +#define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN +#define S2IO_ENHANCED_STAT_LEN sizeof(ethtool_enhanced_stats_keys)/ \ + ETH_GSTRING_LEN +#define S2IO_DRIVER_STAT_LEN sizeof(ethtool_driver_stats_keys)/ ETH_GSTRING_LEN + +#define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN ) +#define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN ) + +#define XFRAME_I_STAT_STRINGS_LEN ( XFRAME_I_STAT_LEN * ETH_GSTRING_LEN ) +#define XFRAME_II_STAT_STRINGS_LEN ( XFRAME_II_STAT_LEN * ETH_GSTRING_LEN ) #define S2IO_TEST_LEN sizeof(s2io_gstrings) / ETH_GSTRING_LEN #define S2IO_STRINGS_LEN S2IO_TEST_LEN * ETH_GSTRING_LEN @@ -286,7 +333,7 @@ static char ethtool_stats_keys[][ETH_GST static void s2io_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) { - nic_t *nic = dev->priv; + struct s2io_nic *nic = dev->priv; unsigned long flags; spin_lock_irqsave(&nic->tx_lock, flags); @@ -294,17 +341,8 @@ static void s2io_vlan_rx_register(struct spin_unlock_irqrestore(&nic->tx_lock, flags); } -/* Unregister the vlan */ -static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) -{ - nic_t *nic = dev->priv; - unsigned long flags; - - spin_lock_irqsave(&nic->tx_lock, flags); - if (nic->vlgrp) - nic->vlgrp->vlan_devices[vid] = NULL; - spin_unlock_irqrestore(&nic->tx_lock, flags); -} +/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ +int vlan_strip_flag; /* * Constants to be programmed into the Xena's registers, to configure @@ -371,7 +409,6 @@ static const u64 fix_mac[] = { END_SIGN }; -MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); @@ -393,7 +430,7 @@ S2IO_PARM_INT(bimodal, 0); S2IO_PARM_INT(l3l4hdr_size, 128); /* Frequency of Rx desc syncs expressed as power of 2 */ S2IO_PARM_INT(rxsync_frequency, 3); -/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ +/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ S2IO_PARM_INT(intr_type, 0); /* Large receive offload feature */ S2IO_PARM_INT(lro, 0); @@ -401,9 +438,11 @@ S2IO_PARM_INT(lro, 0); * aggregation happens until we hit max IP pkt size(64K) */ S2IO_PARM_INT(lro_max_pkts, 0xFFFF); -#ifndef CONFIG_S2IO_NAPI S2IO_PARM_INT(indicate_max_pkts, 0); -#endif + +S2IO_PARM_INT(napi, 1); +S2IO_PARM_INT(ufo, 0); +S2IO_PARM_INT(vlan_tag_strip, NO_STRIP_IN_PROMISC); static unsigned int tx_fifo_len[MAX_TX_FIFOS] = {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; @@ -464,15 +503,16 @@ static int init_shared_mem(struct s2io_n u32 size; void *tmp_v_addr, *tmp_v_addr_next; dma_addr_t tmp_p_addr, tmp_p_addr_next; - RxD_block_t *pre_rxd_blk = NULL; - int i, j, blk_cnt, rx_sz, tx_sz; + struct RxD_block *pre_rxd_blk = NULL; + int i, j, blk_cnt; int lst_size, lst_per_page; struct net_device *dev = nic->dev; unsigned long tmp; - buffAdd_t *ba; + struct buffAdd *ba; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; + unsigned long long mem_allocated = 0; mac_control = &nic->mac_control; config = &nic->config; @@ -489,20 +529,20 @@ static int init_shared_mem(struct s2io_n return -EINVAL; } - lst_size = (sizeof(TxD_t) * config->max_txds); - tx_sz = lst_size * size; + lst_size = (sizeof(struct TxD) * config->max_txds); lst_per_page = PAGE_SIZE / lst_size; for (i = 0; i < config->tx_fifo_num; i++) { int fifo_len = config->tx_cfg[i].fifo_len; - int list_holder_size = fifo_len * sizeof(list_info_hold_t); + int list_holder_size = fifo_len * sizeof(struct list_info_hold); mac_control->fifos[i].list_info = kmalloc(list_holder_size, GFP_KERNEL); if (!mac_control->fifos[i].list_info) { - DBG_PRINT(ERR_DBG, + DBG_PRINT(INFO_DBG, "Malloc failed for list_info\n"); return -ENOMEM; } + mem_allocated += list_holder_size; memset(mac_control->fifos[i].list_info, 0, list_holder_size); } for (i = 0; i < config->tx_fifo_num; i++) { @@ -525,9 +565,9 @@ static int init_shared_mem(struct s2io_n tmp_v = pci_alloc_consistent(nic->pdev, PAGE_SIZE, &tmp_p); if (!tmp_v) { - DBG_PRINT(ERR_DBG, + DBG_PRINT(INFO_DBG, "pci_alloc_consistent "); - DBG_PRINT(ERR_DBG, "failed for TxDL\n"); + DBG_PRINT(INFO_DBG, "failed for TxDL\n"); return -ENOMEM; } /* If we got a zero DMA address(can happen on @@ -537,18 +577,19 @@ static int init_shared_mem(struct s2io_n */ if (!tmp_p) { mac_control->zerodma_virt_addr = tmp_v; - DBG_PRINT(INIT_DBG, + DBG_PRINT(INIT_DBG, "%s: Zero DMA address for TxDL. ", dev->name); - DBG_PRINT(INIT_DBG, + DBG_PRINT(INIT_DBG, "Virtual address %p\n", tmp_v); tmp_v = pci_alloc_consistent(nic->pdev, PAGE_SIZE, &tmp_p); if (!tmp_v) { - DBG_PRINT(ERR_DBG, + DBG_PRINT(INFO_DBG, "pci_alloc_consistent "); - DBG_PRINT(ERR_DBG, "failed for TxDL\n"); + DBG_PRINT(INFO_DBG, "failed for TxDL\n"); return -ENOMEM; } + mem_allocated += PAGE_SIZE; } while (k < lst_per_page) { int l = (j * lst_per_page) + k; @@ -563,10 +604,10 @@ static int init_shared_mem(struct s2io_n } } - nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); + nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL); if (!nic->ufo_in_band_v) return -ENOMEM; - memset(nic->ufo_in_band_v, 0, size); + mem_allocated += (size * sizeof(u64)); /* Allocation and initialization of RXDs in Rings */ size = 0; @@ -587,10 +628,9 @@ static int init_shared_mem(struct s2io_n mac_control->rings[i].block_count; } if (nic->rxd_mode == RXD_MODE_1) - size = (size * (sizeof(RxD1_t))); + size = (size * (sizeof(struct RxD1))); else - size = (size * (sizeof(RxD3_t))); - rx_sz = size; + size = (size * (sizeof(struct RxD3))); for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].rx_curr_get_info.block_index = 0; @@ -608,7 +648,7 @@ static int init_shared_mem(struct s2io_n (rxd_count[nic->rxd_mode] + 1); /* Allocating all the Rx blocks */ for (j = 0; j < blk_cnt; j++) { - rx_block_info_t *rx_blocks; + struct rx_block_info *rx_blocks; int l; rx_blocks = &mac_control->rings[i].rx_blocks[j]; @@ -625,12 +665,17 @@ static int init_shared_mem(struct s2io_n rx_blocks->block_virt_addr = tmp_v_addr; return -ENOMEM; } + mem_allocated += size; memset(tmp_v_addr, 0, size); rx_blocks->block_virt_addr = tmp_v_addr; rx_blocks->block_dma_addr = tmp_p_addr; - rx_blocks->rxds = kmalloc(sizeof(rxd_info_t)* + rx_blocks->rxds = kmalloc(sizeof(struct rxd_info)* rxd_count[nic->rxd_mode], GFP_KERNEL); + if (!rx_blocks->rxds) + return -ENOMEM; + mem_allocated += + (sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]); for (l=0; l<rxd_count[nic->rxd_mode];l++) { rx_blocks->rxds[l].virt_addr = rx_blocks->block_virt_addr + @@ -653,14 +698,14 @@ static int init_shared_mem(struct s2io_n mac_control->rings[i].rx_blocks[(j + 1) % blk_cnt].block_dma_addr; - pre_rxd_blk = (RxD_block_t *) tmp_v_addr; + pre_rxd_blk = (struct RxD_block *) tmp_v_addr; pre_rxd_blk->reserved_2_pNext_RxD_block = (unsigned long) tmp_v_addr_next; pre_rxd_blk->pNext_RxD_Blk_physical = (u64) tmp_p_addr_next; } } - if (nic->rxd_mode >= RXD_MODE_3A) { + if (nic->rxd_mode == RXD_MODE_3B) { /* * Allocation of Storages for buffer addresses in 2BUFF mode * and the buffers as well. @@ -669,18 +714,21 @@ static int init_shared_mem(struct s2io_n blk_cnt = config->rx_cfg[i].num_rxd / (rxd_count[nic->rxd_mode]+ 1); mac_control->rings[i].ba = - kmalloc((sizeof(buffAdd_t *) * blk_cnt), + kmalloc((sizeof(struct buffAdd *) * blk_cnt), GFP_KERNEL); if (!mac_control->rings[i].ba) return -ENOMEM; + mem_allocated +=(sizeof(struct buffAdd *) * blk_cnt); for (j = 0; j < blk_cnt; j++) { int k = 0; mac_control->rings[i].ba[j] = - kmalloc((sizeof(buffAdd_t) * + kmalloc((sizeof(struct buffAdd) * (rxd_count[nic->rxd_mode] + 1)), GFP_KERNEL); if (!mac_control->rings[i].ba[j]) return -ENOMEM; + mem_allocated += (sizeof(struct buffAdd) * \ + (rxd_count[nic->rxd_mode] + 1)); while (k != rxd_count[nic->rxd_mode]) { ba = &mac_control->rings[i].ba[j][k]; @@ -688,6 +736,8 @@ static int init_shared_mem(struct s2io_n (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); if (!ba->ba_0_org) return -ENOMEM; + mem_allocated += + (BUF0_LEN + ALIGN_SIZE); tmp = (unsigned long)ba->ba_0_org; tmp += ALIGN_SIZE; tmp &= ~((unsigned long) ALIGN_SIZE); @@ -697,6 +747,8 @@ static int init_shared_mem(struct s2io_n (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); if (!ba->ba_1_org) return -ENOMEM; + mem_allocated + += (BUF1_LEN + ALIGN_SIZE); tmp = (unsigned long) ba->ba_1_org; tmp += ALIGN_SIZE; tmp &= ~((unsigned long) ALIGN_SIZE); @@ -708,7 +760,7 @@ static int init_shared_mem(struct s2io_n } /* Allocation and initialization of Statistics block */ - size = sizeof(StatInfo_t); + size = sizeof(struct stat_block); mac_control->stats_mem = pci_alloc_consistent (nic->pdev, size, &mac_control->stats_mem_phy); @@ -720,14 +772,15 @@ static int init_shared_mem(struct s2io_n */ return -ENOMEM; } + mem_allocated += size; mac_control->stats_mem_sz = size; tmp_v_addr = mac_control->stats_mem; - mac_control->stats_info = (StatInfo_t *) tmp_v_addr; + mac_control->stats_info = (struct stat_block *) tmp_v_addr; memset(tmp_v_addr, 0, size); DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name, (unsigned long long) tmp_p_addr); - + mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; return SUCCESS; } @@ -741,29 +794,34 @@ static int init_shared_mem(struct s2io_n static void free_shared_mem(struct s2io_nic *nic) { int i, j, blk_cnt, size; + u32 ufo_size = 0; void *tmp_v_addr; dma_addr_t tmp_p_addr; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; int lst_size, lst_per_page; - struct net_device *dev = nic->dev; + struct net_device *dev; + int page_num = 0; if (!nic) return; + dev = nic->dev; + mac_control = &nic->mac_control; config = &nic->config; - lst_size = (sizeof(TxD_t) * config->max_txds); + lst_size = (sizeof(struct TxD) * config->max_txds); lst_per_page = PAGE_SIZE / lst_size; for (i = 0; i < config->tx_fifo_num; i++) { - int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, - lst_per_page); + ufo_size += config->tx_cfg[i].fifo_len; + page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, + lst_per_page); for (j = 0; j < page_num; j++) { int mem_blks = (j * lst_per_page); if (!mac_control->fifos[i].list_info) - return; + return; if (!mac_control->fifos[i].list_info[mem_blks]. list_virt_addr) break; @@ -774,6 +832,8 @@ static void free_shared_mem(struct s2io_ mac_control->fifos[i]. list_info[mem_blks]. list_phy_addr); + nic->mac_control.stats_info->sw_stat.mem_freed + += PAGE_SIZE; } /* If we got a zero DMA address during allocation, * free the page now @@ -782,13 +842,17 @@ static void free_shared_mem(struct s2io_ pci_free_consistent(nic->pdev, PAGE_SIZE, mac_control->zerodma_virt_addr, (dma_addr_t)0); - DBG_PRINT(INIT_DBG, + DBG_PRINT(INIT_DBG, "%s: Freeing TxDL with zero DMA addr. ", dev->name); DBG_PRINT(INIT_DBG, "Virtual address %p\n", mac_control->zerodma_virt_addr); + nic->mac_control.stats_info->sw_stat.mem_freed + += PAGE_SIZE; } kfree(mac_control->fifos[i].list_info); + nic->mac_control.stats_info->sw_stat.mem_freed += + (nic->config.tx_cfg[i].fifo_len *sizeof(struct list_info_hold)); } size = SIZE_OF_BLOCK; @@ -803,11 +867,14 @@ static void free_shared_mem(struct s2io_ break; pci_free_consistent(nic->pdev, size, tmp_v_addr, tmp_p_addr); + nic->mac_control.stats_info->sw_stat.mem_freed += size; kfree(mac_control->rings[i].rx_blocks[j].rxds); + nic->mac_control.stats_info->sw_stat.mem_freed += + ( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]); } } - if (nic->rxd_mode >= RXD_MODE_3A) { + if (nic->rxd_mode == RXD_MODE_3B) { /* Freeing buffer storage addresses in 2BUFF mode. */ for (i = 0; i < config->rx_ring_num; i++) { blk_cnt = config->rx_cfg[i].num_rxd / @@ -817,15 +884,23 @@ static void free_shared_mem(struct s2io_ if (!mac_control->rings[i].ba[j]) continue; while (k != rxd_count[nic->rxd_mode]) { - buffAdd_t *ba = + struct buffAdd *ba = &mac_control->rings[i].ba[j][k]; kfree(ba->ba_0_org); + nic->mac_control.stats_info->sw_stat.\ + mem_freed += (BUF0_LEN + ALIGN_SIZE); kfree(ba->ba_1_org); + nic->mac_control.stats_info->sw_stat.\ + mem_freed += (BUF1_LEN + ALIGN_SIZE); k++; } kfree(mac_control->rings[i].ba[j]); + nic->mac_control.stats_info->sw_stat.mem_freed += (sizeof(struct buffAdd) * + (rxd_count[nic->rxd_mode] + 1)); } kfree(mac_control->rings[i].ba); + nic->mac_control.stats_info->sw_stat.mem_freed += + (sizeof(struct buffAdd *) * blk_cnt); } } @@ -834,18 +909,23 @@ static void free_shared_mem(struct s2io_ mac_control->stats_mem_sz, mac_control->stats_mem, mac_control->stats_mem_phy); + nic->mac_control.stats_info->sw_stat.mem_freed += + mac_control->stats_mem_sz; } - if (nic->ufo_in_band_v) + if (nic->ufo_in_band_v) { kfree(nic->ufo_in_band_v); + nic->mac_control.stats_info->sw_stat.mem_freed + += (ufo_size * sizeof(u64)); + } } /** * s2io_verify_pci_mode - */ -static int s2io_verify_pci_mode(nic_t *nic) +static int s2io_verify_pci_mode(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64 = 0; int mode; @@ -862,9 +942,10 @@ static int s2io_verify_pci_mode(nic_t *n static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) { struct pci_dev *tdev = NULL; - while ((tdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { - if ((tdev->vendor == NEC_VENID) && (tdev->device == NEC_DEVID)){ + while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { + if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { if (tdev->bus == s2io_pdev->bus->parent) + pci_dev_put(tdev); return 1; } } @@ -875,9 +956,9 @@ static int bus_speed[8] = {33, 133, 133, /** * s2io_print_pci_mode - */ -static int s2io_print_pci_mode(nic_t *nic) +static int s2io_print_pci_mode(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64 = 0; int mode; struct config_param *config = &nic->config; @@ -945,13 +1026,13 @@ static int s2io_print_pci_mode(nic_t *ni static int init_nic(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; struct net_device *dev = nic->dev; register u64 val64 = 0; void __iomem *add; u32 time; int i, j; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; int dtx_cnt = 0; unsigned long long mem_share; @@ -1283,7 +1364,7 @@ static int init_nic(struct s2io_nic *nic writeq(val64, &bar0->rx_w_round_robin_1); val64 = 0x0200010000010203ULL; writeq(val64, &bar0->rx_w_round_robin_2); - val64 = 0x0001020001000001ULL; + val64 = 0x0001020001000001ULL; writeq(val64, &bar0->rx_w_round_robin_3); val64 = 0x0203000100000000ULL; writeq(val64, &bar0->rx_w_round_robin_4); @@ -1378,6 +1459,16 @@ static int init_nic(struct s2io_nic *nic &bar0->rts_frm_len_n[i]); } } + + /* Disable differentiated services steering logic */ + for (i = 0; i < 64; i++) { + if (rts_ds_steer(nic, i, 0) == FAILURE) { + DBG_PRINT(ERR_DBG, "%s: failed rts ds steering", + dev->name); + DBG_PRINT(ERR_DBG, "set on codepoint %d\n", i); + return FAILURE; + } + } /* Program statistics memory */ writeq(mac_control->stats_mem_phy, &bar0->stat_addr); @@ -1421,7 +1512,7 @@ static int init_nic(struct s2io_nic *nic val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | TTI_DATA2_MEM_TX_UFC_B(0x20) | - TTI_DATA2_MEM_TX_UFC_C(0x70) | TTI_DATA2_MEM_TX_UFC_D(0x80); + TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80); writeq(val64, &bar0->tti_data2_mem); val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; @@ -1617,7 +1708,8 @@ static int init_nic(struct s2io_nic *nic * that does not start on an ADB to reduce disconnects. */ if (nic->device_type == XFRAME_II_DEVICE) { - val64 = EXT_REQ_EN | MISC_LINK_STABILITY_PRD(3); + val64 = FAULT_BEHAVIOUR | EXT_REQ_EN | + MISC_LINK_STABILITY_PRD(3); writeq(val64, &bar0->misc_control); val64 = readq(&bar0->pic_control2); val64 &= ~(BIT(13)|BIT(14)|BIT(15)); @@ -1633,7 +1725,7 @@ static int init_nic(struct s2io_nic *nic #define LINK_UP_DOWN_INTERRUPT 1 #define MAC_RMAC_ERR_TIMER 2 -static int s2io_link_fault_indication(nic_t *nic) +static int s2io_link_fault_indication(struct s2io_nic *nic) { if (nic->intr_type != INTA) return MAC_RMAC_ERR_TIMER; @@ -1656,14 +1748,14 @@ static int s2io_link_fault_indication(ni static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64 = 0, temp64 = 0; /* Top level interrupt classification */ /* PIC Interrupts */ if ((mask & (TX_PIC_INTR | RX_PIC_INTR))) { /* Enable PIC Intrs in the general intr mask register */ - val64 = TXPIC_INT_M | PIC_RX_INT_M; + val64 = TXPIC_INT_M; if (flag == ENABLE_INTRS) { temp64 = readq(&bar0->general_int_mask); temp64 &= ~((u64) val64); @@ -1701,70 +1793,6 @@ static void en_dis_able_nic_intrs(struct } } - /* DMA Interrupts */ - /* Enabling/Disabling Tx DMA interrupts */ - if (mask & TX_DMA_INTR) { - /* Enable TxDMA Intrs in the general intr mask register */ - val64 = TXDMA_INT_M; - if (flag == ENABLE_INTRS) { - temp64 = readq(&bar0->general_int_mask); - temp64 &= ~((u64) val64); - writeq(temp64, &bar0->general_int_mask); - /* - * Keep all interrupts other than PFC interrupt - * and PCC interrupt disabled in DMA level. - */ - val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M | - TXDMA_PCC_INT_M); - writeq(val64, &bar0->txdma_int_mask); - /* - * Enable only the MISC error 1 interrupt in PFC block - */ - val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1); - writeq(val64, &bar0->pfc_err_mask); - /* - * Enable only the FB_ECC error interrupt in PCC block - */ - val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR); - writeq(val64, &bar0->pcc_err_mask); - } else if (flag == DISABLE_INTRS) { - /* - * Disable TxDMA Intrs in the general intr mask - * register - */ - writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask); - writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask); - temp64 = readq(&bar0->general_int_mask); - val64 |= temp64; - writeq(val64, &bar0->general_int_mask); - } - } - - /* Enabling/Disabling Rx DMA interrupts */ - if (mask & RX_DMA_INTR) { - /* Enable RxDMA Intrs in the general intr mask register */ - val64 = RXDMA_INT_M; - if (flag == ENABLE_INTRS) { - temp64 = readq(&bar0->general_int_mask); - temp64 &= ~((u64) val64); - writeq(temp64, &bar0->general_int_mask); - /* - * All RxDMA block interrupts are disabled for now - * TODO - */ - writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); - } else if (flag == DISABLE_INTRS) { - /* - * Disable RxDMA Intrs in the general intr mask - * register - */ - writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); - temp64 = readq(&bar0->general_int_mask); - val64 |= temp64; - writeq(val64, &bar0->general_int_mask); - } - } - /* MAC Interrupts */ /* Enabling/Disabling MAC interrupts */ if (mask & (TX_MAC_INTR | RX_MAC_INTR)) { @@ -1791,53 +1819,6 @@ static void en_dis_able_nic_intrs(struct } } - /* XGXS Interrupts */ - if (mask & (TX_XGXS_INTR | RX_XGXS_INTR)) { - val64 = TXXGXS_INT_M | RXXGXS_INT_M; - if (flag == ENABLE_INTRS) { - temp64 = readq(&bar0->general_int_mask); - temp64 &= ~((u64) val64); - writeq(temp64, &bar0->general_int_mask); - /* - * All XGXS block error interrupts are disabled for now - * TODO - */ - writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); - } else if (flag == DISABLE_INTRS) { - /* - * Disable MC Intrs in the general intr mask register - */ - writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); - temp64 = readq(&bar0->general_int_mask); - val64 |= temp64; - writeq(val64, &bar0->general_int_mask); - } - } - - /* Memory Controller(MC) interrupts */ - if (mask & MC_INTR) { - val64 = MC_INT_M; - if (flag == ENABLE_INTRS) { - temp64 = readq(&bar0->general_int_mask); - temp64 &= ~((u64) val64); - writeq(temp64, &bar0->general_int_mask); - /* - * Enable all MC Intrs. - */ - writeq(0x0, &bar0->mc_int_mask); - writeq(0x0, &bar0->mc_err_mask); - } else if (flag == DISABLE_INTRS) { - /* - * Disable MC Intrs in the general intr mask register - */ - writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask); - temp64 = readq(&bar0->general_int_mask); - val64 |= temp64; - writeq(val64, &bar0->general_int_mask); - } - } - - /* Tx traffic interrupts */ if (mask & TX_TRAFFIC_INTR) { val64 = TXTRAFFIC_INT_M; @@ -1884,41 +1865,36 @@ static void en_dis_able_nic_intrs(struct } } -static int check_prc_pcc_state(u64 val64, int flag, int rev_id, int herc) +/** + * verify_pcc_quiescent- Checks for PCC quiescent state + * Return: 1 If PCC is quiescence + * 0 If PCC is not quiescence + */ +static int verify_pcc_quiescent(struct s2io_nic *sp, int flag) { - int ret = 0; + int ret = 0, herc; + struct XENA_dev_config __iomem *bar0 = sp->bar0; + u64 val64 = readq(&bar0->adapter_status); + + herc = (sp->device_type == XFRAME_II_DEVICE); if (flag == FALSE) { - if ((!herc && (rev_id >= 4)) || herc) { - if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) && - ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == - ADAPTER_STATUS_RC_PRC_QUIESCENT)) { + if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) { + if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE)) ret = 1; - } - }else { - if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && - ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == - ADAPTER_STATUS_RC_PRC_QUIESCENT)) { + } else { + if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE)) ret = 1; - } } } else { - if ((!herc && (rev_id >= 4)) || herc) { + if ((!herc && (get_xena_rev_id(sp->pdev) >= 4)) || herc) { if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) == - ADAPTER_STATUS_RMAC_PCC_IDLE) && - (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || - ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == - ADAPTER_STATUS_RC_PRC_QUIESCENT))) { + ADAPTER_STATUS_RMAC_PCC_IDLE)) ret = 1; - } } else { if (((val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) == - ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && - (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || - ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == - ADAPTER_STATUS_RC_PRC_QUIESCENT))) { + ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE)) ret = 1; - } } } @@ -1926,9 +1902,6 @@ static int check_prc_pcc_state(u64 val64 } /** * verify_xena_quiescence - Checks whether the H/W is ready - * @val64 : Value read from adapter status register. - * @flag : indicates if the adapter enable bit was ever written once - * before. * 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 @@ -1937,24 +1910,63 @@ static int check_prc_pcc_state(u64 val64 * 0 If Xena is not quiescence */ -static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag) +static int verify_xena_quiescence(struct s2io_nic *sp) { - int ret = 0, herc; - u64 tmp64 = ~((u64) val64); - int rev_id = get_xena_rev_id(sp->pdev); + int mode; + struct XENA_dev_config __iomem *bar0 = sp->bar0; + u64 val64 = readq(&bar0->adapter_status); + mode = s2io_verify_pci_mode(sp); - herc = (sp->device_type == XFRAME_II_DEVICE); - if (! - (tmp64 & - (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY | - ADAPTER_STATUS_PFC_READY | ADAPTER_STATUS_TMAC_BUF_EMPTY | - ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY | - ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK | - ADAPTER_STATUS_P_PLL_LOCK))) { - ret = check_prc_pcc_state(val64, flag, rev_id, herc); + if (!(val64 & ADAPTER_STATUS_TDMA_READY)) { + DBG_PRINT(ERR_DBG, "%s", "TDMA is not ready!"); + return 0; + } + if (!(val64 & ADAPTER_STATUS_RDMA_READY)) { + DBG_PRINT(ERR_DBG, "%s", "RDMA is not ready!"); + return 0; + } + if (!(val64 & ADAPTER_STATUS_PFC_READY)) { + DBG_PRINT(ERR_DBG, "%s", "PFC is not ready!"); + return 0; + } + if (!(val64 & ADAPTER_STATUS_TMAC_BUF_EMPTY)) { + DBG_PRINT(ERR_DBG, "%s", "TMAC BUF is not empty!"); + return 0; + } + if (!(val64 & ADAPTER_STATUS_PIC_QUIESCENT)) { + DBG_PRINT(ERR_DBG, "%s", "PIC is not QUIESCENT!"); + return 0; + } + if (!(val64 & ADAPTER_STATUS_MC_DRAM_READY)) { + DBG_PRINT(ERR_DBG, "%s", "MC_DRAM is not ready!"); + return 0; + } + if (!(val64 & ADAPTER_STATUS_MC_QUEUES_READY)) { + DBG_PRINT(ERR_DBG, "%s", "MC_QUEUES is not ready!"); + return 0; + } + if (!(val64 & ADAPTER_STATUS_M_PLL_LOCK)) { + DBG_PRINT(ERR_DBG, "%s", "M_PLL is not locked!"); + return 0; } - return ret; + /* + * In PCI 33 mode, the P_PLL is not used, and therefore, + * the the P_PLL_LOCK bit in the adapter_status register will + * not be asserted. + */ + if (!(val64 & ADAPTER_STATUS_P_PLL_LOCK) && + sp->device_type == XFRAME_II_DEVICE && mode != + PCI_MODE_PCI_33) { + DBG_PRINT(ERR_DBG, "%s", "P_PLL is not locked!"); + return 0; + } + if (!((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == + ADAPTER_STATUS_RC_PRC_QUIESCENT)) { + DBG_PRINT(ERR_DBG, "%s", "RC_PRC is not QUIESCENT!"); + return 0; + } + return 1; } /** @@ -1965,9 +1977,9 @@ static int verify_xena_quiescence(nic_t * */ -static void fix_mac_address(nic_t * sp) +static void fix_mac_address(struct s2io_nic * sp) { - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64; int i = 0; @@ -1993,11 +2005,11 @@ static void fix_mac_address(nic_t * sp) static int start_nic(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; struct net_device *dev = nic->dev; register u64 val64 = 0; u16 subid, i; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; mac_control = &nic->mac_control; @@ -2029,6 +2041,13 @@ static int start_nic(struct s2io_nic *ni writeq(val64, &bar0->rx_pa_cfg); } + if (vlan_tag_strip == 0) { + val64 = readq(&bar0->rx_pa_cfg); + val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG; + writeq(val64, &bar0->rx_pa_cfg); + vlan_strip_flag = 0; + } + /* * Enabling MC-RLDRAM. After enabling the device, we timeout * for around 100ms, which is approximately the time required @@ -2059,7 +2078,7 @@ static int start_nic(struct s2io_nic *ni * it. */ val64 = readq(&bar0->adapter_status); - if (!verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { + if (!verify_xena_quiescence(nic)) { DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name); DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n", (unsigned long long) val64); @@ -2102,11 +2121,12 @@ static int start_nic(struct s2io_nic *ni /** * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb */ -static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, int get_off) +static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \ + TxD *txdlp, int get_off) { - nic_t *nic = fifo_data->nic; + struct s2io_nic *nic = fifo_data->nic; struct sk_buff *skb; - TxD_t *txds; + struct TxD *txds; u16 j, frg_cnt; txds = txdlp; @@ -2120,7 +2140,7 @@ static struct sk_buff *s2io_txdl_getskb( skb = (struct sk_buff *) ((unsigned long) txds->Host_Control); if (!skb) { - memset(txdlp, 0, (sizeof(TxD_t) * fifo_data->max_txds)); + memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds)); return NULL; } pci_unmap_single(nic->pdev, (dma_addr_t) @@ -2134,12 +2154,12 @@ static struct sk_buff *s2io_txdl_getskb( skb_frag_t *frag = &skb_shinfo(skb)->frags[j]; if (!txds->Buffer_Pointer) break; - pci_unmap_page(nic->pdev, (dma_addr_t) + pci_unmap_page(nic->pdev, (dma_addr_t) txds->Buffer_Pointer, frag->size, PCI_DMA_TODEVICE); } } - memset(txdlp,0, (sizeof(TxD_t) * fifo_data->max_txds)); + memset(txdlp,0, (sizeof(struct TxD) * fifo_data->max_txds)); return(skb); } @@ -2155,9 +2175,9 @@ static void free_tx_buffers(struct s2io_ { struct net_device *dev = nic->dev; struct sk_buff *skb; - TxD_t *txdp; + struct TxD *txdp; int i, j; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; int cnt = 0; @@ -2166,10 +2186,12 @@ static void free_tx_buffers(struct s2io_ for (i = 0; i < config->tx_fifo_num; i++) { for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { - txdp = (TxD_t *) mac_control->fifos[i].list_info[j]. - list_virt_addr; + txdp = (struct TxD *) \ + mac_control->fifos[i].list_info[j].list_virt_addr; skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); if (skb) { + nic->mac_control.stats_info->sw_stat.mem_freed + += skb->truesize; dev_kfree_skb(skb); cnt++; } @@ -2194,10 +2216,10 @@ static void free_tx_buffers(struct s2io_ static void stop_nic(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64 = 0; u16 interruptible; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; mac_control = &nic->mac_control; @@ -2215,39 +2237,6 @@ static void stop_nic(struct s2io_nic *ni writeq(val64, &bar0->adapter_control); } -static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) -{ - struct net_device *dev = nic->dev; - struct sk_buff *frag_list; - void *tmp; - - /* Buffer-1 receives L3/L4 headers */ - ((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single - (nic->pdev, skb->data, l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); - - /* skb_shinfo(skb)->frag_list will have L4 data payload */ - skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE); - if (skb_shinfo(skb)->frag_list == NULL) { - DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n ", dev->name); - return -ENOMEM ; - } - frag_list = skb_shinfo(skb)->frag_list; - frag_list->next = NULL; - tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1); - frag_list->data = tmp; - frag_list->tail = tmp; - - /* Buffer-2 receives L4 data payload */ - ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev, - frag_list->data, dev->mtu, - PCI_DMA_FROMDEVICE); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); - - return SUCCESS; -} - /** * fill_rx_buffers - Allocates the Rx side skbs * @nic: device private variable @@ -2273,18 +2262,20 @@ static int fill_rx_buffers(struct s2io_n { struct net_device *dev = nic->dev; struct sk_buff *skb; - RxD_t *rxdp; + struct RxD_t *rxdp; int off, off1, size, block_no, block_no1; u32 alloc_tab = 0; u32 alloc_cnt; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; u64 tmp; - buffAdd_t *ba; -#ifndef CONFIG_S2IO_NAPI + struct buffAdd *ba; unsigned long flags; -#endif - RxD_t *first_rxdp = NULL; + struct RxD_t *first_rxdp = NULL; + u64 Buffer0_ptr = 0, Buffer1_ptr = 0; + struct RxD1 *rxdp1; + struct RxD3 *rxdp3; + struct swStat *stats = &nic->mac_control.stats_info->sw_stat; mac_control = &nic->mac_control; config = &nic->config; @@ -2327,14 +2318,17 @@ static int fill_rx_buffers(struct s2io_n DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", dev->name, rxdp); } -#ifndef CONFIG_S2IO_NAPI - spin_lock_irqsave(&nic->put_lock, flags); - mac_control->rings[ring_no].put_pos = - (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; - spin_unlock_irqrestore(&nic->put_lock, flags); -#endif + if(!napi) { + spin_lock_irqsave(&nic->put_lock, flags); + mac_control->rings[ring_no].put_pos = + (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; + spin_unlock_irqrestore(&nic->put_lock, flags); + } else { + mac_control->rings[ring_no].put_pos = + (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; + } if ((rxdp->Control_1 & RXD_OWN_XENA) && - ((nic->rxd_mode >= RXD_MODE_3A) && + ((nic->rxd_mode == RXD_MODE_3B) && (rxdp->Control_2 & BIT(0)))) { mac_control->rings[ring_no].rx_curr_put_info. offset = off; @@ -2345,44 +2339,56 @@ static int fill_rx_buffers(struct s2io_n HEADER_802_2_SIZE + HEADER_SNAP_SIZE; if (nic->rxd_mode == RXD_MODE_1) size += NET_IP_ALIGN; - else if (nic->rxd_mode == RXD_MODE_3B) - size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; else - size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; + size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; /* allocate skb */ skb = dev_alloc_skb(size); if(!skb) { - DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); - DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); + DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); + DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n"); if (first_rxdp) { wmb(); first_rxdp->Control_1 |= RXD_OWN_XENA; } + nic->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; return -ENOMEM ; } + nic->mac_control.stats_info->sw_stat.mem_allocated + += skb->truesize; if (nic->rxd_mode == RXD_MODE_1) { /* 1 buffer mode - normal operation mode */ - memset(rxdp, 0, sizeof(RxD1_t)); + rxdp1 = (struct RxD1*)rxdp; + memset(rxdp, 0, sizeof(struct RxD1)); skb_reserve(skb, NET_IP_ALIGN); - ((RxD1_t*)rxdp)->Buffer0_ptr = pci_map_single + rxdp1->Buffer0_ptr = pci_map_single (nic->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == + DMA_ERROR_CODE)) + goto pci_map_failed; - } else if (nic->rxd_mode >= RXD_MODE_3A) { + rxdp->Control_2 = + SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); + + } else if (nic->rxd_mode == RXD_MODE_3B) { /* - * 2 or 3 buffer mode - - * Both 2 buffer mode and 3 buffer mode provides 128 + * 2 buffer mode - + * 2 buffer mode provides 128 * byte aligned receive buffers. - * - * 3 buffer mode provides header separation where in - * skb->data will have L3/L4 headers where as - * skb_shinfo(skb)->frag_list will have the L4 data - * payload */ - memset(rxdp, 0, sizeof(RxD3_t)); + rxdp3 = (struct RxD3*)rxdp; + /* save buffer pointers to avoid frequent dma mapping */ + Buffer0_ptr = rxdp3->Buffer0_ptr; + Buffer1_ptr = rxdp3->Buffer1_ptr; + memset(rxdp, 0, sizeof(struct RxD3)); + /* restore the buffer pointers for dma sync*/ + rxdp3->Buffer0_ptr = Buffer0_ptr; + rxdp3->Buffer1_ptr = Buffer1_ptr; + ba = &mac_control->rings[ring_no].ba[block_no][off]; skb_reserve(skb, BUF0_LEN); tmp = (u64)(unsigned long) skb->data; @@ -2391,47 +2397,50 @@ static int fill_rx_buffers(struct s2io_n skb->data = (void *) (unsigned long)tmp; skb->tail = (void *) (unsigned long)tmp; - if (!(((RxD3_t*)rxdp)->Buffer0_ptr)) - ((RxD3_t*)rxdp)->Buffer0_ptr = + if (!(rxdp3->Buffer0_ptr)) + rxdp3->Buffer0_ptr = pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); else pci_dma_sync_single_for_device(nic->pdev, - (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, + (dma_addr_t) rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) + goto pci_map_failed; + rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (nic->rxd_mode == RXD_MODE_3B) { /* Two buffer mode */ /* - * Buffer2 will have L3/L4 header plus + * Buffer2 will have L3/L4 header plus * L4 payload */ - ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single + rxdp3->Buffer2_ptr = pci_map_single (nic->pdev, skb->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - /* Buffer-1 will be dummy buffer. Not used */ - if (!(((RxD3_t*)rxdp)->Buffer1_ptr)) { - ((RxD3_t*)rxdp)->Buffer1_ptr = - pci_map_single(nic->pdev, + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) + goto pci_map_failed; + + rxdp3->Buffer1_ptr = + pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { + pci_unmap_single + (nic->pdev, + (dma_addr_t)rxdp3->Buffer2_ptr, + dev->mtu + 4, + PCI_DMA_FROMDEVICE); + goto pci_map_failed; } rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3 (dev->mtu + 4); - } else { - /* 3 buffer mode */ - if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) { - dev_kfree_skb_irq(skb); - if (first_rxdp) { - wmb(); - first_rxdp->Control_1 |= - RXD_OWN_XENA; - } - return -ENOMEM ; - } } rxdp->Control_2 |= BIT(0); } @@ -2466,6 +2475,11 @@ static int fill_rx_buffers(struct s2io_n } return SUCCESS; +pci_map_failed: + stats->pci_map_fail_cnt++; + stats->mem_freed += skb->truesize; + dev_kfree_skb_irq(skb); + return -ENOMEM; } static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) @@ -2473,9 +2487,11 @@ static void free_rxd_blk(struct s2io_nic struct net_device *dev = sp->dev; int j; struct sk_buff *skb; - RxD_t *rxdp; - mac_info_t *mac_control; - buffAdd_t *ba; + struct RxD_t *rxdp; + struct mac_info *mac_control; + struct buffAdd *ba; + struct RxD1 *rxdp1; + struct RxD3 *rxdp3; mac_control = &sp->mac_control; for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) { @@ -2487,43 +2503,34 @@ static void free_rxd_blk(struct s2io_nic continue; } if (sp->rxd_mode == RXD_MODE_1) { + rxdp1 = (struct RxD1*)rxdp; pci_unmap_single(sp->pdev, (dma_addr_t) - ((RxD1_t*)rxdp)->Buffer0_ptr, - dev->mtu + - HEADER_ETHERNET_II_802_3_SIZE - + HEADER_802_2_SIZE + - HEADER_SNAP_SIZE, - PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(RxD1_t)); + rxdp1->Buffer0_ptr, + dev->mtu + + HEADER_ETHERNET_II_802_3_SIZE + + HEADER_802_2_SIZE + + HEADER_SNAP_SIZE, + PCI_DMA_FROMDEVICE); + memset(rxdp, 0, sizeof(struct RxD1)); } else if(sp->rxd_mode == RXD_MODE_3B) { + rxdp3 = (struct RxD3*)rxdp; ba = &mac_control->rings[ring_no]. ba[blk][j]; pci_unmap_single(sp->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer0_ptr, - BUF0_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(sp->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer1_ptr, - BUF1_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(sp->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer2_ptr, - dev->mtu + 4, - PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(RxD3_t)); - } else { - pci_unmap_single(sp->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, + rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer1_ptr, - l3l4hdr_size + 4, + rxdp3->Buffer1_ptr, + BUF1_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(sp->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu, + rxdp3->Buffer2_ptr, + dev->mtu + 4, PCI_DMA_FROMDEVICE); - memset(rxdp, 0, sizeof(RxD3_t)); + memset(rxdp, 0, sizeof(struct RxD3)); } + sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; dev_kfree_skb(skb); atomic_dec(&sp->rx_bufs_left[ring_no]); } @@ -2542,7 +2549,7 @@ static void free_rx_buffers(struct s2io_ { struct net_device *dev = sp->dev; int i, blk = 0, buf_cnt = 0; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; mac_control = &sp->mac_control; @@ -2575,15 +2582,13 @@ static void free_rx_buffers(struct s2io_ * 0 on success and 1 if there are No Rx packets to be processed. */ -#if defined(CONFIG_S2IO_NAPI) static int s2io_poll(struct net_device *dev, int *budget) { - nic_t *nic = dev->priv; + struct s2io_nic *nic = dev->priv; int pkt_cnt = 0, org_pkts_to_process; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; - XENA_dev_config_t __iomem *bar0 = nic->bar0; - u64 val64 = 0xFFFFFFFFFFFFFFFFULL; + struct XENA_dev_config __iomem *bar0 = nic->bar0; int i; atomic_inc(&nic->isr_cnt); @@ -2595,8 +2600,8 @@ static int s2io_poll(struct net_device * nic->pkts_to_process = dev->quota; org_pkts_to_process = nic->pkts_to_process; - writeq(val64, &bar0->rx_traffic_int); - val64 = readl(&bar0->rx_traffic_int); + writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); + readl(&bar0->rx_traffic_int); for (i = 0; i < config->rx_ring_num; i++) { rx_intr_handler(&mac_control->rings[i]); @@ -2615,14 +2620,14 @@ static int s2io_poll(struct net_device * for (i = 0; i < config->rx_ring_num; i++) { if (fill_rx_buffers(nic, i) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); - DBG_PRINT(ERR_DBG, " in Rx Poll!!\n"); + DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); break; } } /* Re enable the Rx interrupts. */ writeq(0x0, &bar0->rx_traffic_mask); - val64 = readl(&bar0->rx_traffic_mask); + readl(&bar0->rx_traffic_mask); atomic_dec(&nic->isr_cnt); return 0; @@ -2632,15 +2637,14 @@ no_rx: for (i = 0; i < config->rx_ring_num; i++) { if (fill_rx_buffers(nic, i) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); - DBG_PRINT(ERR_DBG, " in Rx Poll!!\n"); + DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); break; } } atomic_dec(&nic->isr_cnt); return 1; } -#endif #ifdef CONFIG_NET_POLL_CONTROLLER /** @@ -2654,13 +2658,16 @@ no_rx: */ static void s2io_netpoll(struct net_device *dev) { - nic_t *nic = dev->priv; - mac_info_t *mac_control; + struct s2io_nic *nic = dev->priv; + struct mac_info *mac_control; struct config_param *config; - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; u64 val64 = 0xFFFFFFFFFFFFFFFFULL; int i; + if (nic->pdev->error_state != pci_channel_io_normal) + return; + disable_irq(dev->irq); atomic_inc(&nic->isr_cnt); @@ -2670,7 +2677,7 @@ static void s2io_netpoll(struct net_devi writeq(val64, &bar0->rx_traffic_int); writeq(val64, &bar0->tx_traffic_int); - /* we need to free up the transmitted skbufs or else netpoll will + /* we need to free up the transmitted skbufs or else netpoll will * run out of skbs and will fail and eventually netpoll application such * as netdump will fail. */ @@ -2683,8 +2690,8 @@ static void s2io_netpoll(struct net_devi for (i = 0; i < config->rx_ring_num; i++) { if (fill_rx_buffers(nic, i) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); - DBG_PRINT(ERR_DBG, " in Rx Netpoll!!\n"); + DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; } } @@ -2706,18 +2713,18 @@ static void s2io_netpoll(struct net_devi * Return Value: * NONE. */ -static void rx_intr_handler(ring_info_t *ring_data) +static void rx_intr_handler(struct ring_info *ring_data) { - nic_t *nic = ring_data->nic; + struct s2io_nic *nic = ring_data->nic; struct net_device *dev = (struct net_device *) nic->dev; int get_block, put_block, put_offset; - rx_curr_get_info_t get_info, put_info; - RxD_t *rxdp; + struct rx_curr_get_info get_info, put_info; + struct RxD_t *rxdp; struct sk_buff *skb; -#ifndef CONFIG_S2IO_NAPI int pkt_cnt = 0; -#endif int i; + struct RxD1* rxdp1; + struct RxD3* rxdp3; spin_lock(&nic->rx_lock); if (atomic_read(&nic->card_state) == CARD_DOWN) { @@ -2729,19 +2736,21 @@ static void rx_intr_handler(ring_info_t get_info = ring_data->rx_curr_get_info; get_block = get_info.block_index; - put_info = ring_data->rx_curr_put_info; + memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info)); put_block = put_info.block_index; rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr; -#ifndef CONFIG_S2IO_NAPI - spin_lock(&nic->put_lock); - put_offset = ring_data->put_pos; - spin_unlock(&nic->put_lock); -#else - put_offset = (put_block * (rxd_count[nic->rxd_mode] + 1)) + - put_info.offset; -#endif + if (!napi) { + spin_lock(&nic->put_lock); + put_offset = ring_data->put_pos; + spin_unlock(&nic->put_lock); + } else + put_offset = ring_data->put_pos; + while (RXD_IS_UP2DT(rxdp)) { - /* If your are next to put index then it's FIFO full condition */ + /* + * If your are next to put index then it's + * FIFO full condition + */ if ((get_block == put_block) && (get_info.offset + 1) == put_info.offset) { DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name); @@ -2756,32 +2765,23 @@ static void rx_intr_handler(ring_info_t return; } if (nic->rxd_mode == RXD_MODE_1) { + rxdp1 = (struct RxD1*)rxdp; pci_unmap_single(nic->pdev, (dma_addr_t) - ((RxD1_t*)rxdp)->Buffer0_ptr, - dev->mtu + - HEADER_ETHERNET_II_802_3_SIZE + - HEADER_802_2_SIZE + - HEADER_SNAP_SIZE, - PCI_DMA_FROMDEVICE); + rxdp1->Buffer0_ptr, + dev->mtu + + HEADER_ETHERNET_II_802_3_SIZE + + HEADER_802_2_SIZE + + HEADER_SNAP_SIZE, + PCI_DMA_FROMDEVICE); } else if (nic->rxd_mode == RXD_MODE_3B) { + rxdp3 = (struct RxD3*)rxdp; pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer0_ptr, - BUF0_LEN, PCI_DMA_FROMDEVICE); - pci_unmap_single(nic->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer2_ptr, - dev->mtu + 4, - PCI_DMA_FROMDEVICE); - } else { - pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, - PCI_DMA_FROMDEVICE); - pci_unmap_single(nic->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer1_ptr, - l3l4hdr_size + 4, - PCI_DMA_FROMDEVICE); + rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) - ((RxD3_t*)rxdp)->Buffer2_ptr, - dev->mtu, PCI_DMA_FROMDEVICE); + rxdp3->Buffer2_ptr, + dev->mtu + 4, + PCI_DMA_FROMDEVICE); } prefetch(skb->data); rx_osm_handler(ring_data, rxdp); @@ -2799,20 +2799,17 @@ static void rx_intr_handler(ring_info_t rxdp = ring_data->rx_blocks[get_block].block_virt_addr; } -#ifdef CONFIG_S2IO_NAPI nic->pkts_to_process -= 1; - if (!nic->pkts_to_process) + if ((napi) && (!nic->pkts_to_process)) break; -#else pkt_cnt++; if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) break; -#endif } if (nic->lro) { /* Clear all LRO sessions before exiting */ for (i=0; i<MAX_LRO_SESSIONS; i++) { - lro_t *lro = &nic->lro0_n[i]; + struct lro *lro = &nic->lro0_n[i]; if (lro->in_use) { update_L3L4_header(nic, lro); queue_rx_frame(lro->parent); @@ -2836,17 +2833,18 @@ static void rx_intr_handler(ring_info_t * NONE */ -static void tx_intr_handler(fifo_info_t *fifo_data) +static void tx_intr_handler(struct fifo_info *fifo_data) { - nic_t *nic = fifo_data->nic; + struct s2io_nic *nic = fifo_data->nic; struct net_device *dev = (struct net_device *) nic->dev; - tx_curr_get_info_t get_info, put_info; + struct tx_curr_get_info get_info, put_info; struct sk_buff *skb; - TxD_t *txdlp; + struct TxD *txdlp; + u8 err_mask; get_info = fifo_data->tx_curr_get_info; - put_info = fifo_data->tx_curr_put_info; - txdlp = (TxD_t *) fifo_data->list_info[get_info.offset]. + memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info)); + txdlp = (struct TxD *) fifo_data->list_info[get_info.offset]. list_virt_addr; while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && (get_info.offset != put_info.offset) && @@ -2859,14 +2857,35 @@ static void tx_intr_handler(fifo_info_t nic->mac_control.stats_info->sw_stat. parity_err_cnt++; } - if ((err >> 48) == 0xA) { - DBG_PRINT(TX_DBG, "TxD returned due \ -to loss of link\n"); - } - else { - DBG_PRINT(ERR_DBG, "***TxD error \ -%llx\n", err); - } + + /* update t_code statistics */ + err_mask = err >> 48; + switch(err_mask) { + case 2: + nic->mac_control.stats_info->sw_stat. + tx_buf_abort_cnt++; + break; + + case 3: + nic->mac_control.stats_info->sw_stat. + tx_desc_abort_cnt++; + break; + + case 7: + nic->mac_control.stats_info->sw_stat. + tx_parity_err_cnt++; + break; + + case 10: + nic->mac_control.stats_info->sw_stat. + tx_link_loss_cnt++; + break; + + case 15: + nic->mac_control.stats_info->sw_stat. + tx_list_proc_err_cnt++; + break; + } } skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset); @@ -2879,12 +2898,13 @@ to loss of link\n"); /* Updating the statistics block */ nic->stats.tx_bytes += skb->len; + nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; dev_kfree_skb_irq(skb); get_info.offset++; if (get_info.offset == get_info.fifo_len + 1) get_info.offset = 0; - txdlp = (TxD_t *) fifo_data->list_info + txdlp = (struct TxD *) fifo_data->list_info [get_info.offset].list_virt_addr; fifo_data->tx_curr_get_info.offset = get_info.offset; @@ -2909,8 +2929,8 @@ to loss of link\n"); static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device *dev) { u64 val64 = 0x0; - nic_t *sp = dev->priv; - XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; //address transaction val64 = val64 | MDIO_MMD_INDX_ADDR(addr) @@ -2958,8 +2978,8 @@ static u64 s2io_mdio_read(u32 mmd_type, { u64 val64 = 0x0; u64 rval64 = 0x0; - nic_t *sp = dev->priv; - XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; /* address transaction */ val64 = val64 | MDIO_MMD_INDX_ADDR(addr) @@ -3062,8 +3082,8 @@ static void s2io_updt_xpak_counter(struc u64 val64 = 0x0; u64 addr = 0x0; - nic_t *sp = dev->priv; - StatInfo_t *stat_info = sp->mac_control.stats_info; + struct s2io_nic *sp = dev->priv; + struct stat_block *stat_info = sp->mac_control.stats_info; /* Check the communication with the MDIO slave */ addr = 0x0000; @@ -3161,15 +3181,14 @@ static void s2io_updt_xpak_counter(struc static void alarm_intr_handler(struct s2io_nic *nic) { struct net_device *dev = (struct net_device *) nic->dev; - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64 = 0, err_reg = 0; u64 cnt; int i; - - if ((nic->pdev->error_state != pci_channel_io_normal) && - (nic->pdev->error_state != 0)) + if (atomic_read(&nic->card_state) == CARD_DOWN) + return; + if (nic->pdev->error_state != pci_channel_io_normal) return; - nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0; /* Handling the XPAK counters update */ if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) { @@ -3221,7 +3240,7 @@ static void alarm_intr_handler(struct s2 if (val64 & SERR_SOURCE_ANY) { nic->mac_control.stats_info->sw_stat.serious_err_cnt++; DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); - DBG_PRINT(ERR_DBG, "serious error %llx!!\n", + DBG_PRINT(ERR_DBG, "serious error %llx!!\n", (unsigned long long)val64); netif_stop_queue(dev); schedule_work(&nic->rst_timer_task); @@ -3287,28 +3306,58 @@ static void alarm_intr_handler(struct s2 * SUCCESS on success and FAILURE on failure. */ -static int wait_for_cmd_complete(void *addr, u64 busy_bit) +static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit, + int bit_state) { - int ret = FAILURE, cnt = 0; + int ret = FAILURE, cnt = 0, delay = 1; u64 val64; - while (TRUE) { + if ((bit_state != S2IO_BIT_RESET) && (bit_state != S2IO_BIT_SET)) + return FAILURE; + + do { val64 = readq(addr); - if (!(val64 & busy_bit)) { - ret = SUCCESS; - break; + if (bit_state == S2IO_BIT_RESET) { + if (!(val64 & busy_bit)) { + ret = SUCCESS; + break; + } + } else { + if (!(val64 & busy_bit)) { + ret = SUCCESS; + break; + } } if(in_interrupt()) - mdelay(50); + mdelay(delay); else - msleep(50); + msleep(delay); - if (cnt++ > 10) - break; - } + if (++cnt >= 10) + delay = 50; + } while (cnt < 20); return ret; } +/* + * 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) +{ + switch (id) { + case PCI_DEVICE_ID_HERC_WIN: + case PCI_DEVICE_ID_HERC_UNI: + return XFRAME_II_DEVICE; + case PCI_DEVICE_ID_S2IO_UNI: + case PCI_DEVICE_ID_S2IO_WIN: + return XFRAME_I_DEVICE; + default: + return PCI_ANY_ID; + } +} /** * s2io_reset - Resets the card. @@ -3320,42 +3369,45 @@ static int wait_for_cmd_complete(void *a * void. */ -static void s2io_reset(nic_t * sp) +static void s2io_reset(struct s2io_nic * sp) { - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64; u16 subid, pci_cmd; + int i; + u16 val16; + unsigned long long up_cnt, down_cnt, up_time, down_time, reset_cnt; + unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt; + + DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n", + __FUNCTION__, sp->dev->name); /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); val64 = SW_RESET_ALL; writeq(val64, &bar0->sw_reset); - - /* - * At this stage, if the PCI write is indeed completed, the - * card is reset and so is the PCI Config space of the device. - * So a read cannot be issued at this stage on any of the - * registers to ensure the write into "sw_reset" register - * has gone through. - * Question: Is there any system call that will explicitly force - * all the write commands still pending on the bus to be pushed - * through? - * As of now I'am just giving a 250ms delay and hoping that the - * PCI write to sw_reset register is done by this time. - */ - msleep(250); if (strstr(sp->product_name, "CX4")) { msleep(750); } + msleep(250); + for (i = 0; i < S2IO_MAX_PCI_CONFIG_SPACE_REINIT; i++) { - /* Restore the PCI state saved during initialization. */ - pci_restore_state(sp->pdev); - pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, - pci_cmd); - s2io_init_pci(sp); + /* Restore the PCI state saved during initialization. */ + pci_restore_state(sp->pdev); + pci_read_config_word(sp->pdev, 0x2, &val16); + if (check_pci_device_id(val16) != (u16)PCI_ANY_ID) + break; + msleep(200); + } - msleep(250); + if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) { + DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __FUNCTION__); + } + + pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd); + + s2io_init_pci(sp); /* Set swapper to enable I/O register access */ s2io_set_swapper(sp); @@ -3377,6 +3429,26 @@ static void s2io_reset(nic_t * sp) /* Reset device statistics maintained by OS */ memset(&sp->stats, 0, sizeof (struct net_device_stats)); + + up_cnt = sp->mac_control.stats_info->sw_stat.link_up_cnt; + down_cnt = sp->mac_control.stats_info->sw_stat.link_down_cnt; + up_time = sp->mac_control.stats_info->sw_stat.link_up_time; + down_time = sp->mac_control.stats_info->sw_stat.link_down_time; + reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt; + mem_alloc_cnt = sp->mac_control.stats_info->sw_stat.mem_allocated; + mem_free_cnt = sp->mac_control.stats_info->sw_stat.mem_freed; + watchdog_cnt = sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt; + /* save link up/down time/cnt, reset/memory/watchdog cnt */ + memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block)); + /* restore link up/down time/cnt, reset/memory/watchdog cnt */ + sp->mac_control.stats_info->sw_stat.link_up_cnt = up_cnt; + sp->mac_control.stats_info->sw_stat.link_down_cnt = down_cnt; + sp->mac_control.stats_info->sw_stat.link_up_time = up_time; + sp->mac_control.stats_info->sw_stat.link_down_time = down_time; + sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt; + sp->mac_control.stats_info->sw_stat.mem_allocated = mem_alloc_cnt; + sp->mac_control.stats_info->sw_stat.mem_freed = mem_free_cnt; + sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt = watchdog_cnt; /* SXE-002: Configure link and activity LED to turn it off */ subid = sp->pdev->subsystem_device; @@ -3398,6 +3470,9 @@ static void s2io_reset(nic_t * sp) writeq(val64, &bar0->pcc_err_reg); } + /* restore the previously assigned mac address */ + s2io_set_mac_addr(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr); + sp->device_enabled_once = FALSE; } @@ -3411,10 +3486,10 @@ static void s2io_reset(nic_t * sp) * SUCCESS on success and FAILURE on failure. */ -static int s2io_set_swapper(nic_t * sp) +static int s2io_set_swapper(struct s2io_nic * sp) { struct net_device *dev = sp->dev; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64, valt, valr; /* @@ -3539,9 +3614,9 @@ static int s2io_set_swapper(nic_t * sp) return SUCCESS; } -static int wait_for_msix_trans(nic_t *nic, int i) +static int wait_for_msix_trans(struct s2io_nic *nic, int i) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; u64 val64; int ret = 0, cnt = 0; @@ -3560,9 +3635,9 @@ static int wait_for_msix_trans(nic_t *ni return ret; } -static void restore_xmsi_data(nic_t *nic) +static void restore_xmsi_data(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; u64 val64; int i; @@ -3578,9 +3653,9 @@ static void restore_xmsi_data(nic_t *nic } } -static void store_xmsi_data(nic_t *nic) +static void store_xmsi_data(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; u64 val64, addr, data; int i; @@ -3601,79 +3676,39 @@ static void store_xmsi_data(nic_t *nic) } } -int s2io_enable_msi(nic_t *nic) +static int s2io_enable_msi_x(struct s2io_nic *nic) { - XENA_dev_config_t __iomem *bar0 = nic->bar0; - u16 msi_ctrl, msg_val; - struct config_param *config = &nic->config; - struct net_device *dev = nic->dev; - u64 val64, tx_mat, rx_mat; - int i, err; - - val64 = readq(&bar0->pic_control); - val64 &= ~BIT(1); - writeq(val64, &bar0->pic_control); + struct XENA_dev_config __iomem *bar0 = nic->bar0; + u64 tx_mat, rx_mat; + u16 msi_control; /* Temp variable */ + int ret, i, j, msix_indx = 1; - err = pci_enable_msi(nic->pdev); - if (err) { - DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n", - nic->dev->name); - return err; + nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry), + GFP_KERNEL); + if (nic->entries == NULL) { + DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ + __FUNCTION__); + nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; + return -ENOMEM; } - - /* - * Enable MSI and use MSI-1 in stead of the standard MSI-0 - * for interrupt handling. - */ - pci_read_config_word(nic->pdev, 0x4c, &msg_val); - msg_val ^= 0x1; - pci_write_config_word(nic->pdev, 0x4c, msg_val); - pci_read_config_word(nic->pdev, 0x4c, &msg_val); - - pci_read_config_word(nic->pdev, 0x42, &msi_ctrl); - msi_ctrl |= 0x10; - pci_write_config_word(nic->pdev, 0x42, msi_ctrl); - - /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */ - tx_mat = readq(&bar0->tx_mat0_n[0]); - for (i=0; i<config->tx_fifo_num; i++) { - tx_mat |= TX_MAT_SET(i, 1); - } - writeq(tx_mat, &bar0->tx_mat0_n[0]); - - rx_mat = readq(&bar0->rx_mat); - for (i=0; i<config->rx_ring_num; i++) { - rx_mat |= RX_MAT_SET(i, 1); - } - writeq(rx_mat, &bar0->rx_mat); - - dev->irq = nic->pdev->irq; - return 0; -} - -static int s2io_enable_msi_x(nic_t *nic) -{ - XENA_dev_config_t __iomem *bar0 = nic->bar0; - u64 tx_mat, rx_mat; - u16 msi_control; /* Temp variable */ - int ret, i, j, msix_indx = 1; - - nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry), - GFP_KERNEL); - if (nic->entries == NULL) { - DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__); - return -ENOMEM; - } - memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + nic->mac_control.stats_info->sw_stat.mem_allocated + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + memset(nic->entries, 0,MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); nic->s2io_entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry), GFP_KERNEL); if (nic->s2io_entries == NULL) { - DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__); + DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", + __FUNCTION__); + nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; kfree(nic->entries); + nic->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); return -ENOMEM; } + nic->mac_control.stats_info->sw_stat.mem_allocated + += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); memset(nic->s2io_entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); @@ -3697,7 +3732,8 @@ static int s2io_enable_msi_x(nic_t *nic) rx_mat = readq(&bar0->rx_mat); for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) { rx_mat |= RX_MAT_SET(j, msix_indx); - nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j]; + nic->s2io_entries[msix_indx].arg + = &nic->mac_control.rings[j]; nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; nic->s2io_entries[msix_indx].in_use = MSIX_FLG; } @@ -3706,7 +3742,8 @@ static int s2io_enable_msi_x(nic_t *nic) tx_mat = readq(&bar0->tx_mat0_n[7]); for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) { tx_mat |= TX_MAT_SET(i, msix_indx); - nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j]; + nic->s2io_entries[msix_indx].arg + = &nic->mac_control.rings[j]; nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; nic->s2io_entries[msix_indx].in_use = MSIX_FLG; } @@ -3723,7 +3760,11 @@ static int s2io_enable_msi_x(nic_t *nic) if (ret) { DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); kfree(nic->entries); + nic->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); kfree(nic->s2io_entries); + nic->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); nic->entries = NULL; nic->s2io_entries = NULL; nic->avail_msix_vectors = 0; @@ -3761,7 +3802,7 @@ static int s2io_enable_msi_x(nic_t *nic) static int s2io_open(struct net_device *dev) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; int err = 0; /* @@ -3791,10 +3832,16 @@ static int s2io_open(struct net_device * hw_init_failed: if (sp->intr_type == MSI_X) { - if (sp->entries) + if (sp->entries) { kfree(sp->entries); - if (sp->s2io_entries) + sp->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + } + if (sp->s2io_entries) { kfree(sp->s2io_entries); + sp->mac_control.stats_info->sw_stat.mem_freed + += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); + } } return err; } @@ -3814,14 +3861,12 @@ hw_init_failed: static int s2io_close(struct net_device *dev) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; - flush_scheduled_work(); netif_stop_queue(dev); /* Reset card, kill tasklet and free Tx and Rx buffers. */ s2io_card_down(sp); - sp->device_close_flag = TRUE; /* Device is shut down. */ return 0; } @@ -3840,22 +3885,30 @@ static int s2io_close(struct net_device static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; register u64 val64; - TxD_t *txdp; - TxFIFO_element_t __iomem *tx_fifo; + struct TxD *txdp; + struct TxFIFO_element __iomem *tx_fifo; unsigned long flags; u16 vlan_tag = 0; int vlan_priority = 0; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; int offload_type; + struct swStat *stats = &sp->mac_control.stats_info->sw_stat; mac_control = &sp->mac_control; config = &sp->config; DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name); + + if (unlikely(skb->len <= 0)) { + DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); + dev_kfree_skb_any(skb); + return 0; +} + spin_lock_irqsave(&sp->tx_lock, flags); if (atomic_read(&sp->card_state) == CARD_DOWN) { DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", @@ -3866,7 +3919,6 @@ static int s2io_xmit(struct sk_buff *skb } queue = 0; - /* Get Fifo number to Transmit based on vlan priority */ if (sp->vlgrp && vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); @@ -3876,7 +3928,7 @@ static int s2io_xmit(struct sk_buff *skb put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset; get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset; - txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off]. + txdp = (struct TxD *) mac_control->fifos[queue].list_info[put_off]. list_virt_addr; queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; @@ -3890,21 +3942,13 @@ static int s2io_xmit(struct sk_buff *skb return 0; } - /* A buffer with no data will be dropped */ - if (!skb->len) { - DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); - dev_kfree_skb(skb); - spin_unlock_irqrestore(&sp->tx_lock, flags); - return 0; - } - offload_type = s2io_offload_type(skb); -#ifdef NETIF_F_TSO + if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { txdp->Control_1 |= TXD_TCP_LSO_EN; txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); } -#endif + if (skb->ip_summed == CHECKSUM_HW) { txdp->Control_2 |= (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | @@ -3939,11 +3983,18 @@ static int s2io_xmit(struct sk_buff *skb txdp->Buffer_Pointer = pci_map_single(sp->pdev, sp->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); + if((txdp->Buffer_Pointer == 0) || + (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + goto pci_map_failed; + txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); if (offload_type == SKB_GSO_UDP) @@ -3995,23 +4046,30 @@ static int s2io_xmit(struct sk_buff *skb put_off, get_off); netif_stop_queue(dev); } - + mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; dev->trans_start = jiffies; spin_unlock_irqrestore(&sp->tx_lock, flags); return 0; +pci_map_failed: + stats->pci_map_fail_cnt++; + netif_stop_queue(dev); + stats->mem_freed += skb->truesize; + dev_kfree_skb(skb); + spin_unlock_irqrestore(&sp->tx_lock, flags); + return 0; } static void s2io_alarm_handle(unsigned long data) { - nic_t *sp = (nic_t *)data; + struct s2io_nic *sp = (struct s2io_nic *)data; alarm_intr_handler(sp); mod_timer(&sp->alarm_timer, jiffies + HZ / 2); } -static int s2io_chk_rx_buffers(nic_t *sp, int rng_n) +static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) { int rxb_size, level; @@ -4024,7 +4082,7 @@ static int s2io_chk_rx_buffers(nic_t *sp DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); DBG_PRINT(INTR_DBG, "PANIC levels\n"); if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "Out of memory in %s", + DBG_PRINT(INFO_DBG, "Out of memory in %s", __FUNCTION__); clear_bit(0, (&sp->tasklet_status)); return -1; @@ -4034,51 +4092,17 @@ static int s2io_chk_rx_buffers(nic_t *sp tasklet_schedule(&sp->task); } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name); - DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); + DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name); + DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } return 0; } static irqreturn_t -s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) -{ - struct net_device *dev = (struct net_device *) dev_id; - nic_t *sp = dev->priv; - int i; - mac_info_t *mac_control; - struct config_param *config; - - atomic_inc(&sp->isr_cnt); - mac_control = &sp->mac_control; - config = &sp->config; - DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__); - - /* If Intr is because of Rx Traffic */ - for (i = 0; i < config->rx_ring_num; i++) - rx_intr_handler(&mac_control->rings[i]); - - /* If Intr is because of Tx Traffic */ - for (i = 0; i < config->tx_fifo_num; i++) - tx_intr_handler(&mac_control->fifos[i]); - - /* - * If the Rx buffer count is below the panic threshold then - * reallocate the buffers from the interrupt handler itself, - * else schedule a tasklet to reallocate the buffers. - */ - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); - - atomic_dec(&sp->isr_cnt); - return IRQ_HANDLED; -} - -static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) { - ring_info_t *ring = (ring_info_t *)dev_id; - nic_t *sp = ring->nic; + struct ring_info *ring = (struct ring_info *)dev_id; + struct s2io_nic *sp = ring->nic; atomic_inc(&sp->isr_cnt); @@ -4092,17 +4116,17 @@ s2io_msix_ring_handle(int irq, void *dev static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs) { - fifo_info_t *fifo = (fifo_info_t *)dev_id; - nic_t *sp = fifo->nic; + struct fifo_info *fifo = (struct fifo_info *)dev_id; + struct s2io_nic *sp = fifo->nic; atomic_inc(&sp->isr_cnt); tx_intr_handler(fifo); atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; } -static void s2io_txpic_intr_handle(nic_t *sp) +static void s2io_txpic_intr_handle(struct s2io_nic *sp) { - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64; val64 = readq(&bar0->pic_int_status); @@ -4124,39 +4148,38 @@ static void s2io_txpic_intr_handle(nic_t } else if (val64 & GPIO_INT_REG_LINK_UP) { val64 = readq(&bar0->adapter_status); - if (verify_xena_quiescence(sp, val64, - sp->device_enabled_once)) { /* Enable Adapter */ - val64 = readq(&bar0->adapter_control); - val64 |= ADAPTER_CNTL_EN; - writeq(val64, &bar0->adapter_control); - val64 |= ADAPTER_LED_ON; - writeq(val64, &bar0->adapter_control); - if (!sp->device_enabled_once) - sp->device_enabled_once = 1; + val64 = readq(&bar0->adapter_control); + val64 |= ADAPTER_CNTL_EN; + writeq(val64, &bar0->adapter_control); + val64 |= ADAPTER_LED_ON; + writeq(val64, &bar0->adapter_control); + if (!sp->device_enabled_once) + sp->device_enabled_once = 1; - s2io_link(sp, LINK_UP); - /* - * unmask link down interrupt and mask link-up - * intr - */ - val64 = readq(&bar0->gpio_int_mask); - val64 &= ~GPIO_INT_MASK_LINK_DOWN; - val64 |= GPIO_INT_MASK_LINK_UP; - writeq(val64, &bar0->gpio_int_mask); + s2io_link(sp, LINK_UP); + /* + * unmask link down interrupt and mask link-up + * intr + */ + val64 = readq(&bar0->gpio_int_mask); + val64 &= ~GPIO_INT_MASK_LINK_DOWN; + val64 |= GPIO_INT_MASK_LINK_UP; + writeq(val64, &bar0->gpio_int_mask); - } }else if (val64 & GPIO_INT_REG_LINK_DOWN) { val64 = readq(&bar0->adapter_status); - if (verify_xena_quiescence(sp, val64, - sp->device_enabled_once)) { - s2io_link(sp, LINK_DOWN); - /* Link is down so unmaks link up interrupt */ - val64 = readq(&bar0->gpio_int_mask); - val64 &= ~GPIO_INT_MASK_LINK_UP; - val64 |= GPIO_INT_MASK_LINK_DOWN; - writeq(val64, &bar0->gpio_int_mask); - } + s2io_link(sp, LINK_DOWN); + /* Link is down so unmaks link up interrupt */ + val64 = readq(&bar0->gpio_int_mask); + val64 &= ~GPIO_INT_MASK_LINK_UP; + val64 |= GPIO_INT_MASK_LINK_DOWN; + writeq(val64, &bar0->gpio_int_mask); + + /* turn off LED */ + val64 = readq(&bar0->adapter_control); + val64 = val64 &(~ADAPTER_LED_ON); + writeq(val64, &bar0->adapter_control); } } val64 = readq(&bar0->gpio_int_mask); @@ -4179,17 +4202,16 @@ static void s2io_txpic_intr_handle(nic_t static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; - nic_t *sp = dev->priv; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; int i; - u64 reason = 0, val64, org_mask; - mac_info_t *mac_control; + u64 reason = 0; + struct mac_info *mac_control; struct config_param *config; /* Pretend we handled any irq's from a disconnected card */ - if ((sp->pdev->error_state != pci_channel_io_normal) && - (sp->pdev->error_state != 0)) - return IRQ_HANDLED; + if (sp->pdev->error_state != pci_channel_io_normal) + return IRQ_NONE; atomic_inc(&sp->isr_cnt); mac_control = &sp->mac_control; @@ -4206,43 +4228,48 @@ static irqreturn_t s2io_isr(int irq, voi reason = readq(&bar0->general_int_status); if (!reason) { - /* The interrupt was not raised by Xena. */ + /* The interrupt was not raised by us. */ + atomic_dec(&sp->isr_cnt); + return IRQ_NONE; + } + else if (unlikely(reason == S2IO_MINUS_ONE) ) { + /* Disable device and get out */ atomic_dec(&sp->isr_cnt); return IRQ_NONE; } - val64 = 0xFFFFFFFFFFFFFFFFULL; - /* Store current mask before masking all interrupts */ - org_mask = readq(&bar0->general_int_mask); - writeq(val64, &bar0->general_int_mask); - -#ifdef CONFIG_S2IO_NAPI - if (reason & GEN_INTR_RXTRAFFIC) { - if (netif_rx_schedule_prep(dev)) { - writeq(val64, &bar0->rx_traffic_mask); - __netif_rx_schedule(dev); + if (napi) { + if (reason & GEN_INTR_RXTRAFFIC) { + if ( likely ( netif_rx_schedule_prep(dev)) ) { + __netif_rx_schedule(dev); + writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); + } + else + writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); + } + } else { + /* + * Rx handler is called by default, without checking for the + * cause of interrupt. + * rx_traffic_int reg is an R1 register, writing all 1's + * will ensure that the actual interrupt causing bit get's + * cleared and hence a read can be avoided. + */ + if (reason & GEN_INTR_RXTRAFFIC) + writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); + + for (i = 0; i < config->rx_ring_num; i++) { + rx_intr_handler(&mac_control->rings[i]); } } -#else - /* - * Rx handler is called by default, without checking for the - * cause of interrupt. - * rx_traffic_int reg is an R1 register, writing all 1's - * will ensure that the actual interrupt causing bit get's - * cleared and hence a read can be avoided. - */ - writeq(val64, &bar0->rx_traffic_int); - for (i = 0; i < config->rx_ring_num; i++) { - rx_intr_handler(&mac_control->rings[i]); - } -#endif /* * tx_traffic_int reg is an R1 register, writing all 1's * will ensure that the actual interrupt causing bit get's * cleared and hence a read can be avoided. */ - writeq(val64, &bar0->tx_traffic_int); + if (reason & GEN_INTR_TXTRAFFIC) + writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); for (i = 0; i < config->tx_fifo_num; i++) tx_intr_handler(&mac_control->fifos[i]); @@ -4254,11 +4281,14 @@ static irqreturn_t s2io_isr(int irq, voi * reallocate the buffers from the interrupt handler itself, * else schedule a tasklet to reallocate the buffers. */ -#ifndef CONFIG_S2IO_NAPI - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); -#endif - writeq(org_mask, &bar0->general_int_mask); + if (!napi) { + for (i = 0; i < config->rx_ring_num; i++) + s2io_chk_rx_buffers(sp, i); + } + + writeq(0, &bar0->general_int_mask); + readl(&bar0->general_int_status); + atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; } @@ -4266,9 +4296,9 @@ static irqreturn_t s2io_isr(int irq, voi /** * s2io_updt_stats - */ -static void s2io_updt_stats(nic_t *sp) +static void s2io_updt_stats(struct s2io_nic *sp) { - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64; int cnt = 0; @@ -4286,9 +4316,7 @@ static void s2io_updt_stats(nic_t *sp) if (cnt == 5) break; /* Updt failed */ } while(1); - } else { - memset(sp->mac_control.stats_info, 0, sizeof(StatInfo_t)); - } + } } /** @@ -4303,8 +4331,8 @@ static void s2io_updt_stats(nic_t *sp) static struct net_device_stats *s2io_get_stats(struct net_device *dev) { - nic_t *sp = dev->priv; - mac_info_t *mac_control; + struct s2io_nic *sp = dev->priv; + struct mac_info *mac_control; struct config_param *config; @@ -4319,11 +4347,11 @@ static struct net_device_stats *s2io_get sp->stats.tx_errors = le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); sp->stats.rx_errors = - le32_to_cpu(mac_control->stats_info->rmac_drop_frms); + le64_to_cpu(mac_control->stats_info->rmac_drop_frms); sp->stats.multicast = le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); sp->stats.rx_length_errors = - le32_to_cpu(mac_control->stats_info->rmac_long_frms); + le64_to_cpu(mac_control->stats_info->rmac_long_frms); return (&sp->stats); } @@ -4345,8 +4373,8 @@ static void s2io_set_multicast(struct ne { int i, j, prev_cnt; struct dev_mc_list *mclist; - nic_t *sp = dev->priv; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64 = 0, multi_mac = 0x010203040506ULL, mask = 0xfeffffffffffULL; u64 dis_addr = 0xffffffffffffULL, mac_addr = 0; @@ -4364,7 +4392,8 @@ static void s2io_set_multicast(struct ne writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, + S2IO_BIT_RESET); sp->m_cast_flg = 1; sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; @@ -4380,7 +4409,8 @@ static void s2io_set_multicast(struct ne writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, + S2IO_BIT_RESET); sp->m_cast_flg = 0; sp->all_multi_pos = 0; @@ -4397,6 +4427,13 @@ static void s2io_set_multicast(struct ne writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); writel((u32) (val64 >> 32), (add + 4)); + if (vlan_tag_strip != 1) { + val64 = readq(&bar0->rx_pa_cfg); + val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG; + writeq(val64, &bar0->rx_pa_cfg); + vlan_strip_flag = 0; + } + val64 = readq(&bar0->mac_cfg); sp->promisc_flg = 1; DBG_PRINT(INFO_DBG, "%s: entered promiscuous mode\n", @@ -4412,6 +4449,13 @@ static void s2io_set_multicast(struct ne writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); writel((u32) (val64 >> 32), (add + 4)); + if (vlan_tag_strip != 0) { + val64 = readq(&bar0->rx_pa_cfg); + val64 |= RX_PA_CFG_STRIP_VLAN_TAG; + writeq(val64, &bar0->rx_pa_cfg); + vlan_strip_flag = 1; + } + val64 = readq(&bar0->mac_cfg); sp->promisc_flg = 0; DBG_PRINT(INFO_DBG, "%s: left promiscuous mode\n", @@ -4446,7 +4490,8 @@ static void s2io_set_multicast(struct ne /* Wait for command completes */ if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, + S2IO_BIT_RESET)) { DBG_PRINT(ERR_DBG, "%s: Adding ", dev->name); DBG_PRINT(ERR_DBG, "Multicasts failed\n"); @@ -4477,7 +4522,8 @@ static void s2io_set_multicast(struct ne /* Wait for command completes */ if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, + S2IO_BIT_RESET)) { DBG_PRINT(ERR_DBG, "%s: Adding ", dev->name); DBG_PRINT(ERR_DBG, "Multicasts failed\n"); @@ -4499,10 +4545,11 @@ static void s2io_set_multicast(struct ne static int s2io_set_mac_addr(struct net_device *dev, u8 * addr) { - nic_t *sp = dev->priv; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; register u64 val64, mac_addr = 0; int i; + u64 old_mac_addr = 0; /* * Set the new MAC address as the new unicast filter and reflect this @@ -4512,6 +4559,22 @@ static int s2io_set_mac_addr(struct net_ for (i = 0; i < ETH_ALEN; i++) { mac_addr <<= 8; mac_addr |= addr[i]; + old_mac_addr <<= 8; + old_mac_addr |= sp->def_mac_addr[0].mac_addr[i]; + } + + if(0 == mac_addr) + return SUCCESS; + + /* Update the internal structure with this new mac address */ + if(mac_addr != old_mac_addr) { + memset(sp->def_mac_addr[0].mac_addr, 0, sizeof(ETH_ALEN)); + sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_addr); + sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_addr >> 8); + sp->def_mac_addr[0].mac_addr[3] = (u8) (mac_addr >> 16); + sp->def_mac_addr[0].mac_addr[2] = (u8) (mac_addr >> 24); + sp->def_mac_addr[0].mac_addr[1] = (u8) (mac_addr >> 32); + sp->def_mac_addr[0].mac_addr[0] = (u8) (mac_addr >> 40); } writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr), @@ -4523,7 +4586,7 @@ static int s2io_set_mac_addr(struct net_ writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET)) { DBG_PRINT(ERR_DBG, "%s: set_mac_addr failed\n", dev->name); return FAILURE; } @@ -4546,7 +4609,7 @@ static int s2io_set_mac_addr(struct net_ static int s2io_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; if ((info->autoneg == AUTONEG_ENABLE) || (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL)) return -EINVAL; @@ -4572,7 +4635,7 @@ static int s2io_ethtool_sset(struct net_ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); info->advertising = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); info->port = PORT_FIBRE; @@ -4605,7 +4668,7 @@ static int s2io_ethtool_gset(struct net_ static void s2io_ethtool_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; strncpy(info->driver, s2io_driver_name, sizeof(info->driver)); strncpy(info->version, s2io_driver_version, sizeof(info->version)); @@ -4614,7 +4677,11 @@ static void s2io_ethtool_gdrvinfo(struct info->regdump_len = XENA_REG_SPACE; info->eedump_len = XENA_EEPROM_SPACE; info->testinfo_len = S2IO_TEST_LEN; - info->n_stats = S2IO_STAT_LEN; + + if (sp->device_type == XFRAME_I_DEVICE) + info->n_stats = XFRAME_I_STAT_LEN; + else + info->n_stats = XFRAME_II_STAT_LEN; } /** @@ -4637,7 +4704,7 @@ static void s2io_ethtool_gregs(struct ne int i; u64 reg; u8 *reg_space = (u8 *) space; - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; regs->len = XENA_REG_SPACE; regs->version = sp->pdev->subsystem_device; @@ -4659,8 +4726,8 @@ static void s2io_ethtool_gregs(struct ne */ static void s2io_phy_id(unsigned long data) { - nic_t *sp = (nic_t *) data; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct s2io_nic *sp = (struct s2io_nic *) data; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64 = 0; u16 subid; @@ -4697,8 +4764,8 @@ static void s2io_phy_id(unsigned long da static int s2io_ethtool_idnic(struct net_device *dev, u32 data) { u64 val64 = 0, last_gpio_ctrl_val; - nic_t *sp = dev->priv; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u16 subid; subid = sp->pdev->subsystem_device; @@ -4732,6 +4799,38 @@ static int s2io_ethtool_idnic(struct net return 0; } +static void s2io_ethtool_gringparam(struct net_device *dev, + struct ethtool_ringparam *ering) +{ + struct s2io_nic *sp = dev->priv; + int i,tx_desc_count=0,rx_desc_count=0; + + if (sp->rxd_mode == RXD_MODE_1) + ering->rx_max_pending = MAX_RX_DESC_1; + else if (sp->rxd_mode == RXD_MODE_3B) + ering->rx_max_pending = MAX_RX_DESC_2; + + ering->tx_max_pending = MAX_TX_DESC; + for (i = 0 ; i < sp->config.tx_fifo_num ; i++) + tx_desc_count += sp->config.tx_cfg[i].fifo_len; + + DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds); + ering->tx_pending = tx_desc_count; + rx_desc_count = 0; + for (i = 0 ; i < sp->config.rx_ring_num ; i++) + rx_desc_count += sp->config.rx_cfg[i].num_rxd; + + ering->rx_pending = rx_desc_count; + + ering->rx_mini_max_pending = 0; + ering->rx_mini_pending = 0; + if(sp->rxd_mode == RXD_MODE_1) + ering->rx_jumbo_max_pending = MAX_RX_DESC_1; + else if (sp->rxd_mode == RXD_MODE_3B) + ering->rx_jumbo_max_pending = MAX_RX_DESC_2; + ering->rx_jumbo_pending = rx_desc_count; +} + /** * s2io_ethtool_getpause_data -Pause frame frame generation and reception. * @sp : private member of the device structure, which is a pointer to the @@ -4746,8 +4845,8 @@ static void s2io_ethtool_getpause_data(s struct ethtool_pauseparam *ep) { u64 val64; - nic_t *sp = dev->priv; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; val64 = readq(&bar0->rmac_pause_cfg); if (val64 & RMAC_PAUSE_GEN_ENABLE) @@ -4773,8 +4872,8 @@ static int s2io_ethtool_setpause_data(st struct ethtool_pauseparam *ep) { u64 val64; - nic_t *sp = dev->priv; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct s2io_nic *sp = dev->priv; + struct XENA_dev_config __iomem *bar0 = sp->bar0; val64 = readq(&bar0->rmac_pause_cfg); if (ep->tx_pause) @@ -4806,12 +4905,12 @@ static int s2io_ethtool_setpause_data(st */ #define S2IO_DEV_ID 5 -static int read_eeprom(nic_t * sp, int off, u64 * data) +static int read_eeprom(struct s2io_nic * sp, int off, u64 * data) { int ret = -1; u32 exit_cnt = 0; u64 val64; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; if (sp->device_type == XFRAME_I_DEVICE) { val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | @@ -4833,7 +4932,7 @@ static int read_eeprom(nic_t * sp, int o if (sp->device_type == XFRAME_II_DEVICE) { val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | - SPI_CONTROL_BYTECNT(0x3) | + SPI_CONTROL_BYTECNT(0x3) | SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off); SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); val64 |= SPI_CONTROL_REQ; @@ -4871,11 +4970,11 @@ static int read_eeprom(nic_t * sp, int o * 0 on success, -1 on failure. */ -static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) +static int write_eeprom(struct s2io_nic * sp, int off, u64 data, int cnt) { int exit_cnt = 0, ret = -1; u64 val64; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; if (sp->device_type == XFRAME_I_DEVICE) { val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | @@ -4900,7 +4999,7 @@ static int write_eeprom(nic_t * sp, int writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data); val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | - SPI_CONTROL_BYTECNT(write_cnt) | + SPI_CONTROL_BYTECNT(write_cnt) | SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off); SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); val64 |= SPI_CONTROL_REQ; @@ -4920,7 +5019,7 @@ static int write_eeprom(nic_t * sp, int } return ret; } -static void s2io_vpd_read(nic_t *nic) +static void s2io_vpd_read(struct s2io_nic *nic) { u8 *vpd_data; u8 data; @@ -4935,10 +5034,14 @@ static void s2io_vpd_read(nic_t *nic) strcpy(nic->product_name, "Xframe I 10GbE network adapter"); vpd_addr = 0x50; } + strcpy(nic->serial_num, "NOT AVAILABLE"); vpd_data = kmalloc(256, GFP_KERNEL); - if (!vpd_data) + if (!vpd_data) { + nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; return; + } + nic->mac_control.stats_info->sw_stat.mem_allocated += 256; for (i = 0; i < 256; i +=4 ) { pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); @@ -4958,11 +5061,27 @@ static void s2io_vpd_read(nic_t *nic) pci_read_config_dword(nic->pdev, (vpd_addr + 4), (u32 *)&vpd_data[i]); } - if ((!fail) && (vpd_data[1] < VPD_PRODUCT_NAME_LEN)) { + + if(!fail) { + /* read serial number of adapter */ + for (cnt = 0; cnt < 256; cnt++) { + if ((vpd_data[cnt] == 'S') && + (vpd_data[cnt+1] == 'N') && + (vpd_data[cnt+2] < VPD_STRING_LEN)) { + memset(nic->serial_num, 0, VPD_STRING_LEN); + memcpy(nic->serial_num, &vpd_data[cnt + 3], + vpd_data[cnt+2]); + break; + } + } + } + + if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) { memset(nic->product_name, 0, vpd_data[1]); memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); } kfree(vpd_data); + nic->mac_control.stats_info->sw_stat.mem_freed += 256; } /** @@ -4983,7 +5102,7 @@ static int s2io_ethtool_geeprom(struct n { u32 i, valid; u64 data; - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16); @@ -5021,7 +5140,7 @@ static int s2io_ethtool_seeprom(struct n { int len = eeprom->len, cnt = 0; u64 valid = 0, data; - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) { DBG_PRINT(ERR_DBG, @@ -5065,9 +5184,9 @@ static int s2io_ethtool_seeprom(struct n * 0 on success. */ -static int s2io_register_test(nic_t * sp, uint64_t * data) +static int s2io_register_test(struct s2io_nic * sp, uint64_t * data) { - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64 = 0, exp_val; int fail = 0; @@ -5132,7 +5251,7 @@ static int s2io_register_test(nic_t * sp * 0 on success. */ -static int s2io_eeprom_test(nic_t * sp, uint64_t * data) +static int s2io_eeprom_test(struct s2io_nic * sp, uint64_t * data) { int fail = 0; u64 ret_data, org_4F0, org_7F0; @@ -5234,7 +5353,7 @@ static int s2io_eeprom_test(nic_t * sp, * 0 on success and -1 on failure. */ -static int s2io_bist_test(nic_t * sp, uint64_t * data) +static int s2io_bist_test(struct s2io_nic * sp, uint64_t * data) { u8 bist = 0; int cnt = 0, ret = -1; @@ -5270,9 +5389,9 @@ static int s2io_bist_test(nic_t * sp, ui * 0 on success. */ -static int s2io_link_test(nic_t * sp, uint64_t * data) +static int s2io_link_test(struct s2io_nic * sp, uint64_t * data) { - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64; val64 = readq(&bar0->adapter_status); @@ -5297,9 +5416,9 @@ static int s2io_link_test(nic_t * sp, ui * 0 on success. */ -static int s2io_rldram_test(nic_t * sp, uint64_t * data) +static int s2io_rldram_test(struct s2io_nic * sp, uint64_t * data) { - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64; int cnt, iteration = 0, test_fail = 0; @@ -5401,7 +5520,7 @@ static void s2io_ethtool_test(struct net struct ethtool_test *ethtest, uint64_t * data) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; int orig_state = netif_running(sp->dev); if (ethtest->flags == ETH_TEST_FL_OFFLINE) { @@ -5457,8 +5576,8 @@ static void s2io_get_ethtool_stats(struc u64 * tmp_stats) { int i = 0; - nic_t *sp = dev->priv; - StatInfo_t *stat_info = sp->mac_control.stats_info; + struct s2io_nic *sp = dev->priv; + struct stat_block *stat_info = sp->mac_control.stats_info; s2io_updt_stats(sp); tmp_stats[i++] = @@ -5620,22 +5739,30 @@ static void s2io_get_ethtool_stats(struc tmp_stats[i++] = le32_to_cpu(stat_info->rxd_wr_cnt); tmp_stats[i++] = le32_to_cpu(stat_info->txf_rd_cnt); tmp_stats[i++] = le32_to_cpu(stat_info->rxf_wr_cnt); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_1519_4095_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_4096_8191_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_8192_max_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_gt_max_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_osized_alt_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_jabber_alt_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_gt_max_alt_frms); - tmp_stats[i++] = le64_to_cpu(stat_info->rmac_vlan_frms); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_len_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_fcs_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pf_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_da_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_red_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_rts_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ingm_full_discard); - tmp_stats[i++] = le32_to_cpu(stat_info->link_fault_cnt); + + /* Enhanced statistics exist only for Hercules */ + if(sp->device_type == XFRAME_II_DEVICE) { + tmp_stats[i++] = + le64_to_cpu(stat_info->rmac_ttl_1519_4095_frms); + tmp_stats[i++] = + le64_to_cpu(stat_info->rmac_ttl_4096_8191_frms); + tmp_stats[i++] = + le64_to_cpu(stat_info->rmac_ttl_8192_max_frms); + tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_gt_max_frms); + tmp_stats[i++] = le64_to_cpu(stat_info->rmac_osized_alt_frms); + tmp_stats[i++] = le64_to_cpu(stat_info->rmac_jabber_alt_frms); + tmp_stats[i++] = le64_to_cpu(stat_info->rmac_gt_max_alt_frms); + tmp_stats[i++] = le64_to_cpu(stat_info->rmac_vlan_frms); + tmp_stats[i++] = le32_to_cpu(stat_info->rmac_len_discard); + tmp_stats[i++] = le32_to_cpu(stat_info->rmac_fcs_discard); + tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pf_discard); + tmp_stats[i++] = le32_to_cpu(stat_info->rmac_da_discard); + tmp_stats[i++] = le32_to_cpu(stat_info->rmac_red_discard); + tmp_stats[i++] = le32_to_cpu(stat_info->rmac_rts_discard); + tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ingm_full_discard); + tmp_stats[i++] = le32_to_cpu(stat_info->link_fault_cnt); + } + tmp_stats[i++] = 0; tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; @@ -5663,7 +5790,7 @@ static void s2io_get_ethtool_stats(struc if (stat_info->sw_stat.num_aggregations) { u64 tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; int count = 0; - /* + /* * Since 64-bit divide does not work on all platforms, * do repeated subtraction. */ @@ -5675,6 +5802,31 @@ static void s2io_get_ethtool_stats(struc } else tmp_stats[i++] = 0; + tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt; + tmp_stats[i++] = stat_info->sw_stat.mem_allocated; + tmp_stats[i++] = stat_info->sw_stat.mem_freed; + tmp_stats[i++] = stat_info->sw_stat.link_up_cnt; + tmp_stats[i++] = stat_info->sw_stat.link_down_cnt; + tmp_stats[i++] = stat_info->sw_stat.link_up_time; + tmp_stats[i++] = stat_info->sw_stat.link_down_time; + + tmp_stats[i++] = stat_info->sw_stat.tx_buf_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_desc_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_parity_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_link_loss_cnt; + tmp_stats[i++] = stat_info->sw_stat.tx_list_proc_err_cnt; + + tmp_stats[i++] = stat_info->sw_stat.rx_parity_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_parity_abort_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_rda_fail_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_unkn_prot_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_fcs_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt; + tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt; } static int s2io_ethtool_get_regs_len(struct net_device *dev) @@ -5685,14 +5837,14 @@ static int s2io_ethtool_get_regs_len(str static u32 s2io_ethtool_get_rx_csum(struct net_device * dev) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; return (sp->rx_csum); } static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; if (data) sp->rx_csum = 1; @@ -5715,18 +5867,42 @@ static int s2io_ethtool_self_test_count( static void s2io_ethtool_get_strings(struct net_device *dev, u32 stringset, u8 * data) { + int stat_size = 0; + struct s2io_nic *sp = dev->priv; + switch (stringset) { case ETH_SS_TEST: memcpy(data, s2io_gstrings, S2IO_STRINGS_LEN); break; case ETH_SS_STATS: - memcpy(data, ðtool_stats_keys, - sizeof(ethtool_stats_keys)); + stat_size = sizeof(ethtool_xena_stats_keys); + memcpy(data, ðtool_xena_stats_keys,stat_size); + if(sp->device_type == XFRAME_II_DEVICE) { + memcpy(data + stat_size, + ðtool_enhanced_stats_keys, + sizeof(ethtool_enhanced_stats_keys)); + stat_size += sizeof(ethtool_enhanced_stats_keys); + } + + memcpy(data + stat_size, ðtool_driver_stats_keys, + sizeof(ethtool_driver_stats_keys)); } } static int s2io_ethtool_get_stats_count(struct net_device *dev) { - return (S2IO_STAT_LEN); + struct s2io_nic *sp = dev->priv; + int stat_count = 0; + switch(sp->device_type) { + case XFRAME_I_DEVICE: + stat_count = XFRAME_I_STAT_LEN; + break; + + case XFRAME_II_DEVICE: + stat_count = XFRAME_II_STAT_LEN; + break; + } + + return stat_count; } static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) @@ -5763,6 +5939,7 @@ static struct ethtool_ops netdev_ethtool .get_eeprom_len = s2io_get_eeprom_len, .get_eeprom = s2io_ethtool_geeprom, .set_eeprom = s2io_ethtool_seeprom, + .get_ringparam = s2io_ethtool_gringparam, .get_pauseparam = s2io_ethtool_getpause_data, .set_pauseparam = s2io_ethtool_setpause_data, .get_rx_csum = s2io_ethtool_get_rx_csum, @@ -5771,10 +5948,8 @@ static struct ethtool_ops netdev_ethtool .set_tx_csum = s2io_ethtool_op_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, -#ifdef NETIF_F_TSO .get_tso = s2io_ethtool_op_get_tso, .set_tso = s2io_ethtool_op_set_tso, -#endif .get_ufo = ethtool_op_get_ufo, .set_ufo = ethtool_op_set_ufo, .self_test_count = s2io_ethtool_self_test_count, @@ -5815,7 +5990,7 @@ static int s2io_ioctl(struct net_device static int s2io_change_mtu(struct net_device *dev, int new_mtu) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", @@ -5834,7 +6009,7 @@ static int s2io_change_mtu(struct net_de if (netif_queue_stopped(dev)) netif_wake_queue(dev); } else { /* Device is down */ - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64 = new_mtu; writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); @@ -5859,9 +6034,9 @@ static int s2io_change_mtu(struct net_de static void s2io_tasklet(unsigned long dev_addr) { struct net_device *dev = (struct net_device *) dev_addr; - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; int i, ret; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; mac_control = &sp->mac_control; @@ -5871,12 +6046,12 @@ static void s2io_tasklet(unsigned long d for (i = 0; i < config->rx_ring_num; i++) { ret = fill_rx_buffers(sp, i); if (ret == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s: Out of ", + DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); - DBG_PRINT(ERR_DBG, "memory in tasklet\n"); + DBG_PRINT(INFO_DBG, "memory in tasklet\n"); break; } else if (ret == -EFILL) { - DBG_PRINT(ERR_DBG, + DBG_PRINT(INFO_DBG, "%s: Rx Ring %d is full\n", dev->name, i); break; @@ -5894,15 +6069,20 @@ static void s2io_tasklet(unsigned long d static void s2io_set_link(unsigned long data) { - nic_t *nic = (nic_t *) data; + struct s2io_nic *nic = (struct s2io_nic *) data; struct net_device *dev = nic->dev; - XENA_dev_config_t __iomem *bar0 = nic->bar0; + struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64; u16 subid; + rtnl_lock(); + + if (!netif_running(dev)) + goto out_unlock; + if (test_and_set_bit(0, &(nic->link_state))) { /* The card is being reset, no point doing anything */ - return; + goto out_unlock; } subid = nic->pdev->subsystem_device; @@ -5915,62 +6095,62 @@ static void s2io_set_link(unsigned long } val64 = readq(&bar0->adapter_status); - if (verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { - if (LINK_IS_UP(val64)) { - val64 = readq(&bar0->adapter_control); - val64 |= ADAPTER_CNTL_EN; - writeq(val64, &bar0->adapter_control); - if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, - subid)) { - val64 = readq(&bar0->gpio_control); - val64 |= GPIO_CTRL_GPIO_0; - writeq(val64, &bar0->gpio_control); - val64 = readq(&bar0->gpio_control); - } else { - val64 |= ADAPTER_LED_ON; + if (LINK_IS_UP(val64)) { + if (!(readq(&bar0->adapter_control) & ADAPTER_CNTL_EN)) { + if (verify_xena_quiescence(nic)) { + val64 = readq(&bar0->adapter_control); + val64 |= ADAPTER_CNTL_EN; writeq(val64, &bar0->adapter_control); - } - if (s2io_link_fault_indication(nic) == - MAC_RMAC_ERR_TIMER) { - val64 = readq(&bar0->adapter_status); - if (!LINK_IS_UP(val64)) { - DBG_PRINT(ERR_DBG, "%s:", dev->name); - DBG_PRINT(ERR_DBG, " Link down"); - DBG_PRINT(ERR_DBG, "after "); - DBG_PRINT(ERR_DBG, "enabling "); - DBG_PRINT(ERR_DBG, "device \n"); + if (CARDS_WITH_FAULTY_LINK_INDICATORS( + nic->device_type, subid)) { + val64 = readq(&bar0->gpio_control); + val64 |= GPIO_CTRL_GPIO_0; + writeq(val64, &bar0->gpio_control); + val64 = readq(&bar0->gpio_control); + } else { + val64 |= ADAPTER_LED_ON; + writeq(val64, &bar0->adapter_control); } - } - if (nic->device_enabled_once == FALSE) { nic->device_enabled_once = TRUE; + } else { + DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); + DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); + netif_stop_queue(dev); } + } + val64 = readq(&bar0->adapter_status); + if (!LINK_IS_UP(val64)) { + DBG_PRINT(ERR_DBG, "%s:", dev->name); + DBG_PRINT(ERR_DBG, " Link down after enabling "); + DBG_PRINT(ERR_DBG, "device \n"); + } else s2io_link(nic, LINK_UP); - } else { - if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, - subid)) { - val64 = readq(&bar0->gpio_control); - val64 &= ~GPIO_CTRL_GPIO_0; - writeq(val64, &bar0->gpio_control); - val64 = readq(&bar0->gpio_control); - } - s2io_link(nic, LINK_DOWN); - } - } else { /* NIC is not Quiescent. */ - DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); - DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); - netif_stop_queue(dev); + } else { + if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, + subid)) { + val64 = readq(&bar0->gpio_control); + val64 &= ~GPIO_CTRL_GPIO_0; + writeq(val64, &bar0->gpio_control); + val64 = readq(&bar0->gpio_control); + } + s2io_link(nic, LINK_DOWN); } clear_bit(0, &(nic->link_state)); + +out_unlock: + rtnl_unlock(); } -static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, - struct sk_buff **skb, u64 *temp0, u64 *temp1, - u64 *temp2, int size) +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) { struct net_device *dev = sp->dev; - struct sk_buff *frag_list; + struct swStat *stats = &sp->mac_control.stats_info->sw_stat; if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) { + struct RxD1 *rxdp1 = (struct RxD1 *)rxdp; /* allocate skb */ if (*skb) { DBG_PRINT(INFO_DBG, "SKB is not NULL\n"); @@ -5979,87 +6159,98 @@ static int set_rxd_buffer_pointer(nic_t * using same mapped address for the Rxd * buffer pointer */ - ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0; + rxdp1->Buffer0_ptr = *temp0; } else { *skb = dev_alloc_skb(size); if (!(*skb)) { - DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); - DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); + DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); + DBG_PRINT(INFO_DBG, "memory to allocate "); + DBG_PRINT(INFO_DBG, "1 buf mode SKBs\n"); + sp->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; return -ENOMEM ; } + sp->mac_control.stats_info->sw_stat.mem_allocated + += (*skb)->truesize; /* storing the mapped addr in a temp variable * such it will be used for next rxd whose * Host Control is NULL */ - ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0 = + rxdp1->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + if( (rxdp1->Buffer0_ptr == 0) || + (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { + goto memalloc_failed; + } rxdp->Host_Control = (unsigned long) (*skb); } } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { + struct RxD3 *rxdp3 = (struct RxD3 *)rxdp; /* Two buffer Mode */ if (*skb) { - ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; - ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; - ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; + rxdp3->Buffer2_ptr = *temp2; + rxdp3->Buffer0_ptr = *temp0; + rxdp3->Buffer1_ptr = *temp1; } else { *skb = dev_alloc_skb(size); - ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = + if (!(*skb)) { + DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name); + DBG_PRINT(INFO_DBG, "memory to allocate "); + DBG_PRINT(INFO_DBG, "2 buf mode SKBs\n"); + sp->mac_control.stats_info->sw_stat. \ + mem_alloc_fail_cnt++; + return -ENOMEM; + } + sp->mac_control.stats_info->sw_stat.mem_allocated + += (*skb)->truesize; + rxdp3->Buffer2_ptr = *temp2 = pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = + if( (rxdp3->Buffer2_ptr == 0) || + (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { + goto memalloc_failed; + } + rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); + if( (rxdp3->Buffer0_ptr == 0) || + (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { + pci_unmap_single (sp->pdev, + (dma_addr_t)rxdp3->Buffer2_ptr, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + goto memalloc_failed; + } rxdp->Host_Control = (unsigned long) (*skb); /* Buffer-1 will be dummy buffer not used */ - ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1 = + rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, - PCI_DMA_FROMDEVICE); - } - } else if ((rxdp->Host_Control == 0)) { - /* Three buffer mode */ - if (*skb) { - ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; - ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; - ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; - } else { - *skb = dev_alloc_skb(size); - - ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = - pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, - PCI_DMA_FROMDEVICE); - /* Buffer-1 receives L3/L4 headers */ - ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1 = - pci_map_single( sp->pdev, (*skb)->data, - l3l4hdr_size + 4, PCI_DMA_FROMDEVICE); - /* - * skb_shinfo(skb)->frag_list will have L4 - * data payload - */ - skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu + - ALIGN_SIZE); - if (skb_shinfo(*skb)->frag_list == NULL) { - DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \ - failed\n ", dev->name); - return -ENOMEM ; + if( (rxdp3->Buffer1_ptr == 0) || + (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { + pci_unmap_single (sp->pdev, + (dma_addr_t)rxdp3->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single (sp->pdev, + (dma_addr_t)rxdp3->Buffer2_ptr, + dev->mtu + 4, PCI_DMA_FROMDEVICE); + goto memalloc_failed; } - frag_list = skb_shinfo(*skb)->frag_list; - frag_list->next = NULL; - /* - * Buffer-2 receives L4 data payload - */ - ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = - pci_map_single( sp->pdev, frag_list->data, - dev->mtu, PCI_DMA_FROMDEVICE); } } return 0; + memalloc_failed: + stats->pci_map_fail_cnt++; + stats->mem_freed += (*skb)->truesize; + dev_kfree_skb(*skb); + return -ENOMEM; } -static void set_rxd_buffer_size(nic_t *sp, RxD_t *rxdp, int size) + +static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp, + int size) { struct net_device *dev = sp->dev; if (sp->rxd_mode == RXD_MODE_1) { @@ -6068,22 +6259,18 @@ static void set_rxd_buffer_size(nic_t *s rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4); - } else { - rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); - rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); - rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); } } -static int rxd_owner_bit_reset(nic_t *sp) +static int rxd_owner_bit_reset(struct s2io_nic *sp) { int i, j, k, blk_cnt = 0, size; - mac_info_t * mac_control = &sp->mac_control; + struct mac_info * mac_control = &sp->mac_control; struct config_param *config = &sp->config; struct net_device *dev = sp->dev; - RxD_t *rxdp = NULL; + struct RxD_t *rxdp = NULL; struct sk_buff *skb = NULL; - buffAdd_t *ba = NULL; + struct buffAdd *ba = NULL; u64 temp0_64 = 0, temp1_64 = 0, temp2_64 = 0; /* Calculate the size based on ring mode */ @@ -6093,8 +6280,6 @@ static int rxd_owner_bit_reset(nic_t *s size += NET_IP_ALIGN; else if (sp->rxd_mode == RXD_MODE_3B) size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; - else - size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; for (i = 0; i < config->rx_ring_num; i++) { blk_cnt = config->rx_cfg[i].num_rxd / @@ -6104,12 +6289,15 @@ static int rxd_owner_bit_reset(nic_t *s for (k = 0; k < rxd_count[sp->rxd_mode]; k++) { rxdp = mac_control->rings[i]. rx_blocks[j].rxds[k].virt_addr; - if(sp->rxd_mode >= RXD_MODE_3A) + if(sp->rxd_mode == RXD_MODE_3B) ba = &mac_control->rings[i].ba[j][k]; - set_rxd_buffer_pointer(sp, rxdp, ba, + if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb,(u64 *)&temp0_64, (u64 *)&temp1_64, - (u64 *)&temp2_64, size); + (u64 *)&temp2_64, + size) == ENOMEM) { + return 0; + } set_rxd_buffer_size(sp, rxdp, size); wmb(); @@ -6122,37 +6310,25 @@ static int rxd_owner_bit_reset(nic_t *s } -static int s2io_add_isr(nic_t * sp) +static int s2io_add_isr(struct s2io_nic * sp) { int ret = 0; struct net_device *dev = sp->dev; int err = 0; - if (sp->intr_type == MSI) - ret = s2io_enable_msi(sp); - else if (sp->intr_type == MSI_X) + if (sp->intr_type == MSI_X) ret = s2io_enable_msi_x(sp); if (ret) { DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); sp->intr_type = INTA; } - /* Store the values of the MSIX table in the nic_t structure */ + /* Store the values of the MSIX table in the struct s2io_nic structure */ store_xmsi_data(sp); /* After proper initialization of H/W, register ISR */ - if (sp->intr_type == MSI) { - err = request_irq((int) sp->pdev->irq, s2io_msi_handle, - IRQF_SHARED, sp->name, dev); - if (err) { - pci_disable_msi(sp->pdev); - DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n", - dev->name); - return -1; - } - } if (sp->intr_type == MSI_X) { - int i; + int i, msix_tx_cnt=0,msix_rx_cnt=0; for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { @@ -6161,16 +6337,36 @@ static int s2io_add_isr(nic_t * sp) err = request_irq(sp->entries[i].vector, s2io_msix_fifo_handle, 0, sp->desc[i], sp->s2io_entries[i].arg); - DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc[i], - (unsigned long long)sp->msix_info[i].addr); + /* If either data or addr is zero print it */ + if(!(sp->msix_info[i].addr && + sp->msix_info[i].data)) { + DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx" + "Data:0x%lx\n",sp->desc[i], + (unsigned long long) + sp->msix_info[i].addr, + (unsigned long) + ntohl(sp->msix_info[i].data)); + } else { + msix_tx_cnt++; + } } else { sprintf(sp->desc[i], "%s:MSI-X-%d-RX", dev->name, i); err = request_irq(sp->entries[i].vector, s2io_msix_ring_handle, 0, sp->desc[i], sp->s2io_entries[i].arg); - DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc[i], - (unsigned long long)sp->msix_info[i].addr); + /* If either data or addr is zero print it */ + if(!(sp->msix_info[i].addr && + sp->msix_info[i].data)) { + DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx" + "Data:0x%lx\n",sp->desc[i], + (unsigned long long) + sp->msix_info[i].addr, + (unsigned long) + ntohl(sp->msix_info[i].data)); + } else { + msix_rx_cnt++; + } } if (err) { DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " @@ -6180,6 +6376,8 @@ static int s2io_add_isr(nic_t * sp) } sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; } + printk("MSI-X-TX %d entries enabled\n",msix_tx_cnt); + printk("MSI-X-RX %d entries enabled\n",msix_rx_cnt); } if (sp->intr_type == INTA) { err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED, @@ -6192,7 +6390,7 @@ static int s2io_add_isr(nic_t * sp) } return 0; } -static void s2io_rem_isr(nic_t * sp) +static void s2io_rem_isr(struct s2io_nic * sp) { int cnt = 0; struct net_device *dev = sp->dev; @@ -6215,14 +6413,6 @@ static void s2io_rem_isr(nic_t * sp) pci_disable_msix(sp->pdev); } else { free_irq(sp->pdev->irq, dev); - if (sp->intr_type == MSI) { - u16 val; - - pci_disable_msi(sp->pdev); - pci_read_config_word(sp->pdev, 0x4c, &val); - val ^= 0x1; - pci_write_config_word(sp->pdev, 0x4c, val); - } } /* Waiting till all Interrupt handlers are complete */ cnt = 0; @@ -6234,10 +6424,10 @@ static void s2io_rem_isr(nic_t * sp) } while(cnt < 5); } -static void s2io_card_down(nic_t * sp) +static void do_s2io_card_down(struct s2io_nic * sp, int do_io) { int cnt = 0; - XENA_dev_config_t __iomem *bar0 = sp->bar0; + struct XENA_dev_config __iomem *bar0 = sp->bar0; unsigned long flags; register u64 val64 = 0; @@ -6249,7 +6439,8 @@ static void s2io_card_down(nic_t * sp) atomic_set(&sp->card_state, CARD_DOWN); /* disable Tx and Rx traffic on the NIC */ - stop_nic(sp); + if (do_io) + stop_nic(sp); s2io_rem_isr(sp); @@ -6257,7 +6448,7 @@ static void s2io_card_down(nic_t * sp) tasklet_kill(&sp->task); /* Check if the device is Quiescent and then Reset the NIC */ - do { + while(do_io) { /* As per the HW requirement we need to replenish the * receive buffer to avoid the ring bump. Since there is * no intention of processing the Rx frame at this pointwe are @@ -6268,7 +6459,8 @@ static void s2io_card_down(nic_t * sp) rxd_owner_bit_reset(sp); val64 = readq(&bar0->adapter_status); - if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) { + if (verify_xena_quiescence(sp)) { + if(verify_pcc_quiescent(sp, sp->device_enabled_once)) break; } @@ -6281,8 +6473,9 @@ static void s2io_card_down(nic_t * sp) (unsigned long long) val64); break; } - } while (1); - s2io_reset(sp); + } + if (do_io) + s2io_reset(sp); spin_lock_irqsave(&sp->tx_lock, flags); /* Free all Tx buffers */ @@ -6297,10 +6490,15 @@ static void s2io_card_down(nic_t * sp) clear_bit(0, &(sp->link_state)); } -static int s2io_card_up(nic_t * sp) +static void s2io_card_down(struct s2io_nic * sp) +{ + do_s2io_card_down(sp, 1); +} + +static int s2io_card_up(struct s2io_nic * sp) { int i, ret = 0; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; struct net_device *dev = (struct net_device *) sp->dev; u16 interruptible; @@ -6331,6 +6529,13 @@ static int s2io_card_up(nic_t * sp) DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i, atomic_read(&sp->rx_bufs_left[i])); } + /* Maintain the state prior to the open */ + if (sp->promisc_flg) + sp->promisc_flg = 0; + if (sp->m_cast_flg) { + sp->m_cast_flg = 0; + sp->all_multi_pos= 0; + } /* Setting its receive mode */ s2io_set_multicast(dev); @@ -6393,7 +6598,12 @@ static int s2io_card_up(nic_t * sp) static void s2io_restart_nic(unsigned long data) { struct net_device *dev = (struct net_device *) data; - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; + + rtnl_lock(); + + if (!netif_running(dev)) + goto out_unlock; s2io_card_down(sp); if (s2io_card_up(sp)) { @@ -6403,7 +6613,8 @@ static void s2io_restart_nic(unsigned lo netif_wake_queue(dev); DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", dev->name); - +out_unlock: + rtnl_unlock(); } /** @@ -6421,9 +6632,10 @@ static void s2io_restart_nic(unsigned lo static void s2io_tx_watchdog(struct net_device *dev) { - nic_t *sp = dev->priv; + struct s2io_nic *sp = dev->priv; if (netif_carrier_ok(dev)) { + sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt++; schedule_work(&sp->rst_timer_task); sp->mac_control.stats_info->sw_stat.soft_reset_cnt++; } @@ -6446,16 +6658,17 @@ static void s2io_tx_watchdog(struct net_ * Return value: * SUCCESS on success and -1 on failure. */ -static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) +static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) { - nic_t *sp = ring_data->nic; + struct s2io_nic *sp = ring_data->nic; struct net_device *dev = (struct net_device *) sp->dev; struct sk_buff *skb = (struct sk_buff *) ((unsigned long) rxdp->Host_Control); int ring_no = ring_data->ring_no; u16 l3_csum, l4_csum; unsigned long long err = rxdp->Control_1 & RXD_T_CODE; - lro_t *lro; + struct lro *lro; + u8 err_mask; skb->dev = dev; @@ -6464,7 +6677,53 @@ static int rx_osm_handler(ring_info_t *r if (err & 0x1) { sp->mac_control.stats_info->sw_stat.parity_err_cnt++; } + err_mask = err >> 48; + switch(err_mask) { + case 1: + sp->mac_control.stats_info->sw_stat. + rx_parity_err_cnt++; + break; + + case 2: + sp->mac_control.stats_info->sw_stat. + rx_abort_cnt++; + break; + + case 3: + sp->mac_control.stats_info->sw_stat. + rx_parity_abort_cnt++; + break; + + case 4: + sp->mac_control.stats_info->sw_stat. + rx_rda_fail_cnt++; + break; + + case 5: + sp->mac_control.stats_info->sw_stat. + rx_unkn_prot_cnt++; + break; + + case 6: + sp->mac_control.stats_info->sw_stat. + rx_fcs_err_cnt++; + break; + case 7: + sp->mac_control.stats_info->sw_stat. + rx_buf_size_err_cnt++; + break; + + case 8: + sp->mac_control.stats_info->sw_stat. + rx_rxd_corrupt_cnt++; + break; + + case 15: + sp->mac_control.stats_info->sw_stat. + rx_unkn_err_cnt++; + break; + } /* * Drop the packet if bad transfer code. Exception being * 0x5, which could be due to unsupported IPv6 extension header. @@ -6472,10 +6731,12 @@ static int rx_osm_handler(ring_info_t *r * Note that in this case, since checksum will be incorrect, * stack will validate the same. */ - if (err && ((err >> 48) != 0x5)) { - DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", - dev->name, err); + if (err_mask != 0x5) { + DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%x\n", + dev->name, err_mask); sp->stats.rx_crc_errors++; + sp->mac_control.stats_info->sw_stat.mem_freed + += skb->truesize; dev_kfree_skb(skb); atomic_dec(&sp->rx_bufs_left[ring_no]); rxdp->Host_Control = 0; @@ -6484,38 +6745,25 @@ static int rx_osm_handler(ring_info_t *r } /* Updating statistics */ - rxdp->Host_Control = 0; - sp->rx_pkt_count++; sp->stats.rx_packets++; + rxdp->Host_Control = 0; if (sp->rxd_mode == RXD_MODE_1) { int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2); sp->stats.rx_bytes += len; skb_put(skb, len); - } else if (sp->rxd_mode >= RXD_MODE_3A) { + } else if (sp->rxd_mode == RXD_MODE_3B) { int get_block = ring_data->rx_curr_get_info.block_index; int get_off = ring_data->rx_curr_get_info.offset; int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2); int buf2_len = RXD_GET_BUFFER2_SIZE_3(rxdp->Control_2); unsigned char *buff = skb_push(skb, buf0_len); - buffAdd_t *ba = &ring_data->ba[get_block][get_off]; + struct buffAdd *ba = &ring_data->ba[get_block][get_off]; sp->stats.rx_bytes += buf0_len + buf2_len; memcpy(buff, ba->ba_0, buf0_len); - - if (sp->rxd_mode == RXD_MODE_3A) { - int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2); - - skb_put(skb, buf1_len); - skb->len += buf2_len; - skb->data_len += buf2_len; - skb->truesize += buf2_len; - skb_put(skb_shinfo(skb)->frag_list, buf2_len); - sp->stats.rx_bytes += buf1_len; - - } else - skb_put(skb, buf2_len); + skb_put(skb, buf2_len); } if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!sp->lro) || @@ -6591,30 +6839,28 @@ static int rx_osm_handler(ring_info_t *r } else { skb->ip_summed = CHECKSUM_NONE; } - + sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; if (!sp->lro) { skb->protocol = eth_type_trans(skb, dev); -#ifdef CONFIG_S2IO_NAPI - if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { + if ((sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2) && + vlan_strip_flag)) { /* Queueing the vlan frame to the upper layer */ - vlan_hwaccel_receive_skb(skb, sp->vlgrp, - RXD_GET_VLAN_TAG(rxdp->Control_2)); - } else { - netif_receive_skb(skb); - } -#else - if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { - /* Queueing the vlan frame to the upper layer */ - vlan_hwaccel_rx(skb, sp->vlgrp, - RXD_GET_VLAN_TAG(rxdp->Control_2)); + if (napi) + vlan_hwaccel_receive_skb(skb, sp->vlgrp, + RXD_GET_VLAN_TAG(rxdp->Control_2)); + else + vlan_hwaccel_rx(skb, sp->vlgrp, + RXD_GET_VLAN_TAG(rxdp->Control_2)); } else { - netif_rx(skb); + if (napi) + netif_receive_skb(skb); + else + netif_rx(skb); } -#endif } else { send_up: queue_rx_frame(skb); - } + } dev->last_rx = jiffies; aggregate: atomic_dec(&sp->rx_bufs_left[ring_no]); @@ -6634,7 +6880,7 @@ aggregate: * void. */ -static void s2io_link(nic_t * sp, int link) +static void s2io_link(struct s2io_nic * sp, int link) { struct net_device *dev = (struct net_device *) sp->dev; @@ -6642,12 +6888,21 @@ static void s2io_link(nic_t * sp, int li if (link == LINK_DOWN) { DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); netif_carrier_off(dev); + if(sp->mac_control.stats_info->sw_stat.link_up_cnt) + sp->mac_control.stats_info->sw_stat.link_up_time = + jiffies - sp->start_time; + sp->mac_control.stats_info->sw_stat.link_down_cnt++; } else { DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name); + if (sp->mac_control.stats_info->sw_stat.link_down_cnt) + sp->mac_control.stats_info->sw_stat.link_down_time = + jiffies - sp->start_time; + sp->mac_control.stats_info->sw_stat.link_up_cnt++; netif_carrier_on(dev); } } sp->last_link_state = link; + sp->start_time = jiffies; } /** @@ -6678,7 +6933,7 @@ static int get_xena_rev_id(struct pci_de * void */ -static void s2io_init_pci(nic_t * sp) +static void s2io_init_pci(struct s2io_nic * sp) { u16 pci_cmd = 0, pcix_cmd = 0; @@ -6711,13 +6966,9 @@ static int s2io_verify_parm(struct pci_d DBG_PRINT(ERR_DBG, "s2io: Default to 8 Rx rings\n"); rx_ring_num = 8; } -#ifdef CONFIG_S2IO_NAPI - if (*dev_intr_type != INTA) { - DBG_PRINT(ERR_DBG, "s2io: NAPI cannot be enabled when " - "MSI/MSI-X is enabled. Defaulting to INTA\n"); - *dev_intr_type = INTA; - } -#endif + if (*dev_intr_type != INTA) + napi = 0; + #ifndef CONFIG_PCI_MSI if (*dev_intr_type != INTA) { DBG_PRINT(ERR_DBG, "s2io: This kernel does not support" @@ -6725,7 +6976,7 @@ static int s2io_verify_parm(struct pci_d *dev_intr_type = INTA; } #else - if (*dev_intr_type > MSI_X) { + if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " "Defaulting to INTA\n"); *dev_intr_type = INTA; @@ -6734,19 +6985,51 @@ static int s2io_verify_parm(struct pci_d if ((*dev_intr_type == MSI_X) && ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { - DBG_PRINT(ERR_DBG, "s2io: Xframe I does not support MSI_X. " + DBG_PRINT(ERR_DBG, "s2io: Xframe I does not support MSI_X. " "Defaulting to INTA\n"); *dev_intr_type = INTA; } - if (rx_ring_mode > 3) { + + if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) { DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n"); - DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n"); - rx_ring_mode = 3; + DBG_PRINT(ERR_DBG, "s2io: Defaulting to 1-buffer mode\n"); + rx_ring_mode = 1; } return SUCCESS; } /** + * rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS + * or Traffic class respectively. + * @nic: device peivate variable + * 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) +{ + struct XENA_dev_config __iomem *bar0 = nic->bar0; + register u64 val64 = 0; + + if (ds_codepoint > 63) + return FAILURE; + + val64 = RTS_DS_MEM_DATA(ring); + writeq(val64, &bar0->rts_ds_mem_data); + + val64 = RTS_DS_MEM_CTRL_WE | + RTS_DS_MEM_CTRL_STROBE_NEW_CMD | + RTS_DS_MEM_CTRL_OFFSET(ds_codepoint); + + writeq(val64, &bar0->rts_ds_mem_ctrl); + + return wait_for_cmd_complete(&bar0->rts_ds_mem_ctrl, + RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED, + S2IO_BIT_RESET); +} + +/** * 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. @@ -6763,15 +7046,15 @@ static int s2io_verify_parm(struct pci_d static int __devinit s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) { - nic_t *sp; + struct s2io_nic *sp; struct net_device *dev; int i, j, ret; int dma_flag = FALSE; u32 mac_up, mac_down; u64 val64 = 0, tmp64 = 0; - XENA_dev_config_t __iomem *bar0 = NULL; + struct XENA_dev_config __iomem *bar0 = NULL; u16 subid; - mac_info_t *mac_control; + struct mac_info *mac_control; struct config_param *config; int mode; u8 dev_intr_type = intr_type; @@ -6802,31 +7085,13 @@ s2io_init_nic(struct pci_dev *pdev, cons pci_disable_device(pdev); return -ENOMEM; } - if (dev_intr_type != MSI_X) { - if (pci_request_regions(pdev, s2io_driver_name)) { - DBG_PRINT(ERR_DBG, "Request Regions failed\n"); - pci_disable_device(pdev); - return -ENODEV; - } - } - else { - if (!(request_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), s2io_driver_name))) { - DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n"); - pci_disable_device(pdev); - return -ENODEV; - } - if (!(request_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2), s2io_driver_name))) { - DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n"); - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - pci_disable_device(pdev); - return -ENODEV; - } + if ((ret = pci_request_regions(pdev, s2io_driver_name))) { + DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret); + pci_disable_device(pdev); + return -ENODEV; } - dev = alloc_etherdev(sizeof(nic_t)); + dev = alloc_etherdev(sizeof(struct s2io_nic)); if (dev == NULL) { DBG_PRINT(ERR_DBG, "Device allocation failed\n"); pci_disable_device(pdev); @@ -6841,7 +7106,7 @@ s2io_init_nic(struct pci_dev *pdev, cons /* Private member variable initialized to s2io NIC structure */ sp = dev->priv; - memset(sp, 0, sizeof(nic_t)); + memset(sp, 0, sizeof(struct s2io_nic)); sp->dev = dev; sp->pdev = pdev; sp->high_dma_flag = dma_flag; @@ -6850,8 +7115,6 @@ s2io_init_nic(struct pci_dev *pdev, cons sp->rxd_mode = RXD_MODE_1; if (rx_ring_mode == 2) sp->rxd_mode = RXD_MODE_3B; - if (rx_ring_mode == 3) - sp->rxd_mode = RXD_MODE_3A; sp->intr_type = dev_intr_type; @@ -6862,7 +7125,7 @@ s2io_init_nic(struct pci_dev *pdev, cons sp->device_type = XFRAME_I_DEVICE; sp->lro = lro; - + /* Initialize some PCI/PCI-X fields of the NIC. */ s2io_init_pci(sp); @@ -6937,7 +7200,7 @@ s2io_init_nic(struct pci_dev *pdev, cons sp->bar0 = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!sp->bar0) { - DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem1\n", + DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem1\n", dev->name); ret = -ENOMEM; goto bar0_remap_failed; @@ -6946,7 +7209,7 @@ s2io_init_nic(struct pci_dev *pdev, cons sp->bar1 = ioremap(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); if (!sp->bar1) { - DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem2\n", + DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem2\n", dev->name); ret = -ENOMEM; goto bar1_remap_failed; @@ -6957,7 +7220,7 @@ s2io_init_nic(struct pci_dev *pdev, cons /* Initializing the BAR1 address as the start of the FIFO pointer. */ for (j = 0; j < MAX_TX_FIFOS; j++) { - mac_control->tx_FIFO_start[j] = (TxFIFO_element_t __iomem *) + mac_control->tx_FIFO_start[j] = (struct TxFIFO_element __iomem *) (sp->bar1 + (j * 0x00020000)); } @@ -6972,16 +7235,13 @@ s2io_init_nic(struct pci_dev *pdev, cons SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->vlan_rx_register = s2io_vlan_rx_register; - dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid; /* * will use eth_mac_addr() for dev->set_mac_address * mac address will be set every time dev->open() is called */ -#if defined(CONFIG_S2IO_NAPI) dev->poll = s2io_poll; dev->weight = 32; -#endif #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = s2io_netpoll; @@ -6990,13 +7250,9 @@ s2io_init_nic(struct pci_dev *pdev, cons dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; -#ifdef NETIF_F_TSO dev->features |= NETIF_F_TSO; -#endif -#ifdef NETIF_F_TSO6 dev->features |= NETIF_F_TSO6; -#endif - if (sp->device_type & XFRAME_II_DEVICE) { + if ((sp->device_type & XFRAME_II_DEVICE) && (ufo)) { dev->features |= NETIF_F_UFO; dev->features |= NETIF_F_HW_CSUM; } @@ -7048,13 +7304,11 @@ s2io_init_nic(struct pci_dev *pdev, cons RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); writeq(val64, &bar0->rmac_addr_cmd_mem); wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, - RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET); tmp64 = readq(&bar0->rmac_addr_data0_mem); mac_down = (u32) tmp64; mac_up = (u32) (tmp64 >> 32); - memset(sp->def_mac_addr[0].mac_addr, 0, sizeof(ETH_ALEN)); - sp->def_mac_addr[0].mac_addr[3] = (u8) (mac_up); sp->def_mac_addr[0].mac_addr[2] = (u8) (mac_up >> 8); sp->def_mac_addr[0].mac_addr[1] = (u8) (mac_up >> 16); @@ -7079,9 +7333,9 @@ s2io_init_nic(struct pci_dev *pdev, cons /* Initialize spinlocks */ spin_lock_init(&sp->tx_lock); -#ifndef CONFIG_S2IO_NAPI - spin_lock_init(&sp->put_lock); -#endif + + if (!napi) + spin_lock_init(&sp->put_lock); spin_lock_init(&sp->rx_lock); /* @@ -7106,19 +7360,20 @@ s2io_init_nic(struct pci_dev *pdev, cons goto register_failed; } s2io_vpd_read(sp); - DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); + DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2007 Neterion Inc.\n"); DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name, sp->product_name, get_xena_rev_id(sp->pdev)); DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, s2io_driver_version); DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " - "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, + "%02x:%02x:%02x:%02x:%02x:%02x", dev->name, sp->def_mac_addr[0].mac_addr[0], sp->def_mac_addr[0].mac_addr[1], sp->def_mac_addr[0].mac_addr[2], sp->def_mac_addr[0].mac_addr[3], sp->def_mac_addr[0].mac_addr[4], sp->def_mac_addr[0].mac_addr[5]); + DBG_PRINT(ERR_DBG, "SERIAL NUMBER: %s\n", sp->serial_num); if (sp->device_type & XFRAME_II_DEVICE) { mode = s2io_print_pci_mode(sp); if (mode < 0) { @@ -7137,21 +7392,14 @@ s2io_init_nic(struct pci_dev *pdev, cons DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n", dev->name); break; - case RXD_MODE_3A: - DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n", - dev->name); - break; } -#ifdef CONFIG_S2IO_NAPI - DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); -#endif + + if (napi) + DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); switch(sp->intr_type) { case INTA: DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); break; - case MSI: - DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name); - break; case MSI_X: DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); break; @@ -7159,7 +7407,9 @@ s2io_init_nic(struct pci_dev *pdev, cons if (sp->lro) DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", dev->name); - + if (ufo) + DBG_PRINT(ERR_DBG, "%s: UDP Fragmentation Offload(UFO)" + " enabled\n", dev->name); /* Initialize device name */ sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); @@ -7189,14 +7439,7 @@ s2io_init_nic(struct pci_dev *pdev, cons mem_alloc_failed: free_shared_mem(sp); pci_disable_device(pdev); - if (dev_intr_type != MSI_X) - pci_release_regions(pdev); - else { - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - release_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); - } + pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); free_netdev(dev); @@ -7216,30 +7459,25 @@ static void __devexit s2io_rem_nic(struc { struct net_device *dev = (struct net_device *) pci_get_drvdata(pdev); - nic_t *sp; + struct s2io_nic *sp; if (dev == NULL) { DBG_PRINT(ERR_DBG, "Driver Data is NULL!!\n"); return; } + flush_scheduled_work(); + sp = dev->priv; unregister_netdev(dev); free_shared_mem(sp); iounmap(sp->bar0); iounmap(sp->bar1); - pci_disable_device(pdev); - if (sp->intr_type != MSI_X) - pci_release_regions(pdev); - else { - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - release_mem_region(pci_resource_start(pdev, 2), - pci_resource_len(pdev, 2)); - } + pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); free_netdev(dev); + pci_disable_device(pdev); } /** @@ -7250,7 +7488,7 @@ static void __devexit s2io_rem_nic(struc int __init s2io_starter(void) { - return pci_module_init(&s2io_driver); + return pci_register_driver(&s2io_driver); } /** @@ -7258,7 +7496,7 @@ int __init s2io_starter(void) * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. */ -static void s2io_closer(void) +static __exit void s2io_closer(void) { pci_unregister_driver(&s2io_driver); DBG_PRINT(INIT_DBG, "cleanup done\n"); @@ -7267,8 +7505,8 @@ static void s2io_closer(void) module_init(s2io_starter); module_exit(s2io_closer); -static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, - struct tcphdr **tcp, RxD_t *rxdp) +static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, + struct tcphdr **tcp, struct RxD_t *rxdp) { int ip_off; u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len; @@ -7302,7 +7540,7 @@ static int check_L2_lro_capable(u8 *buff return 0; } -static int check_for_socket_match(lro_t *lro, struct iphdr *ip, +static int check_for_socket_match(struct lro *lro, struct iphdr *ip, struct tcphdr *tcp) { DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); @@ -7317,7 +7555,7 @@ static inline int get_l4_pyld_length(str return(ntohs(ip->tot_len) - (ip->ihl << 2) - (tcp->doff << 2)); } -static void initiate_new_session(lro_t *lro, u8 *l2h, +static void initiate_new_session(struct lro *lro, u8 *l2h, struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) { DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); @@ -7329,7 +7567,7 @@ static void initiate_new_session(lro_t * lro->sg_num = 1; lro->total_len = ntohs(ip->tot_len); lro->frags_len = 0; - /* + /* * check if we saw TCP timestamp. Other consistency checks have * already been done. */ @@ -7343,12 +7581,12 @@ static void initiate_new_session(lro_t * lro->in_use = 1; } -static void update_L3L4_header(nic_t *sp, lro_t *lro) +static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) { struct iphdr *ip = lro->iph; struct tcphdr *tcp = lro->tcph; - u16 nchk; - StatInfo_t *statinfo = sp->mac_control.stats_info; + __sum16 nchk; + struct stat_block *statinfo = sp->mac_control.stats_info; DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); /* Update L3 header */ @@ -7374,7 +7612,7 @@ static void update_L3L4_header(nic_t *sp statinfo->sw_stat.num_aggregations++; } -static void aggregate_new_rx(lro_t *lro, struct iphdr *ip, +static void aggregate_new_rx(struct lro *lro, struct iphdr *ip, struct tcphdr *tcp, u32 l4_pyld) { DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); @@ -7386,17 +7624,17 @@ static void aggregate_new_rx(lro_t *lro, /* Update ack seq no. and window ad(from this pkt) in LRO object */ lro->tcp_ack = tcp->ack_seq; lro->window = tcp->window; - + if (lro->saw_ts) { u32 *ptr; /* Update tsecr and tsval from this packet */ ptr = (u32 *) (tcp + 1); - lro->cur_tsval = *(ptr + 1); + lro->cur_tsval = *(ptr + 1); lro->cur_tsecr = *(ptr + 2); } } -static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, +static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) { u8 *ptr; @@ -7426,7 +7664,7 @@ static int verify_l3_l4_lro_capable(lro_ return -1; } - /* + /* * Allow only one TCP timestamp option. Don't aggregate if * any other options are detected. */ @@ -7434,7 +7672,7 @@ static int verify_l3_l4_lro_capable(lro_ return -1; if (tcp->doff == 8) { - ptr = (u8 *)(tcp + 1); + ptr = (u8 *)(tcp + 1); while (*ptr == TCPOPT_NOP) ptr++; if (*ptr != TCPOPT_TIMESTAMP || *(ptr+1) != TCPOLEN_TIMESTAMP) @@ -7446,7 +7684,7 @@ static int verify_l3_l4_lro_capable(lro_ return -1; /* timestamp echo reply should be non-zero */ - if (*((u32 *)(ptr+6)) == 0) + if (*((u32 *)(ptr+6)) == 0) return -1; } @@ -7454,8 +7692,8 @@ static int verify_l3_l4_lro_capable(lro_ } static int -s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, lro_t **lro, - RxD_t *rxdp, nic_t *sp) +s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, + struct RxD_t *rxdp, struct s2io_nic *sp) { struct iphdr *ip; struct tcphdr *tcph; @@ -7472,7 +7710,7 @@ s2io_club_tcp_session(u8 *buffer, u8 **t tcph = (struct tcphdr *)*tcp; *tcp_len = get_l4_pyld_length(ip, tcph); for (i=0; i<MAX_LRO_SESSIONS; i++) { - lro_t *l_lro = &sp->lro0_n[i]; + struct lro *l_lro = &sp->lro0_n[i]; if (l_lro->in_use) { if (check_for_socket_match(l_lro, ip, tcph)) continue; @@ -7510,7 +7748,7 @@ s2io_club_tcp_session(u8 *buffer, u8 **t } for (i=0; i<MAX_LRO_SESSIONS; i++) { - lro_t *l_lro = &sp->lro0_n[i]; + struct lro *l_lro = &sp->lro0_n[i]; if (!(l_lro->in_use)) { *lro = l_lro; ret = 3; /* Begin anew */ @@ -7549,9 +7787,9 @@ s2io_club_tcp_session(u8 *buffer, u8 **t return ret; } -static void clear_lro_session(lro_t *lro) +static void clear_lro_session(struct lro *lro) { - static u16 lro_struct_size = sizeof(lro_t); + static u16 lro_struct_size = sizeof(struct lro); memset(lro, 0, lro_struct_size); } @@ -7561,14 +7799,14 @@ static void queue_rx_frame(struct sk_buf struct net_device *dev = skb->dev; skb->protocol = eth_type_trans(skb, dev); -#ifdef CONFIG_S2IO_NAPI - netif_receive_skb(skb); -#else - netif_rx(skb); -#endif + if (napi) + netif_receive_skb(skb); + else + netif_rx(skb); } -static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, +static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, + struct sk_buff *skb, u32 tcp_len) { struct sk_buff *first = lro->parent; @@ -7580,6 +7818,7 @@ static void lro_append_pkt(nic_t *sp, lr lro->last_frag->next = skb; else skb_shinfo(first)->frag_list = skb; + first->truesize += skb->truesize; lro->last_frag = skb; sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; return; @@ -7597,35 +7836,13 @@ static pci_ers_result_t s2io_io_error_de pci_channel_state_t state) { struct net_device *netdev = pci_get_drvdata(pdev); - nic_t *sp = netdev->priv; + struct s2io_nic *sp = netdev->priv; netif_device_detach(netdev); if (netif_running(netdev)) { - unsigned long flags; - - /* The folowing is an abreviated subset of the - * steps taken by s2io_card_down(), avoiding - * steps that touch the card itself. - */ - del_timer_sync(&sp->alarm_timer); - atomic_set(&sp->card_state, CARD_DOWN); - - /* Kill tasklet. */ - tasklet_kill(&sp->task); - - /* Free all Tx buffers */ - spin_lock_irqsave(&sp->tx_lock, flags); - free_tx_buffers(sp); - spin_unlock_irqrestore(&sp->tx_lock, flags); - - /* Free all Rx buffers */ - spin_lock_irqsave(&sp->rx_lock, flags); - free_rx_buffers(sp); - spin_unlock_irqrestore(&sp->rx_lock, flags); - - clear_bit(0, &(sp->link_state)); - sp->device_close_flag = TRUE; /* Device is shut down. */ + /* Bring down the card, while avoiding PCI I/O */ + do_s2io_card_down(sp, 0); } pci_disable_device(pdev); @@ -7644,7 +7861,7 @@ static pci_ers_result_t s2io_io_error_de static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); - nic_t *sp = netdev->priv; + struct s2io_nic *sp = netdev->priv; if (pci_enable_device(pdev)) { printk(KERN_ERR "s2io: " @@ -7668,19 +7885,19 @@ static pci_ers_result_t s2io_io_slot_res static void s2io_io_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); - nic_t *sp = netdev->priv; + struct s2io_nic *sp = netdev->priv; if (netif_running(netdev)) { if (s2io_card_up(sp)) { printk(KERN_ERR "s2io: " - "can't bring device back up after reset\n"); + "Can't bring device back up after reset.\n"); return; } if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) { s2io_card_down(sp); printk(KERN_ERR "s2io: " - "can't resetore mac addr after reset\n"); + "Can't resetore mac addr after reset.\n"); return; } } --- linux-2.6.18.i386/drivers/net/s2io.h.orig +++ linux-2.6.18.i386/drivers/net/s2io.h @@ -1,6 +1,6 @@ /************************************************************************ * s2io.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC - * Copyright(c) 2002-2005 Neterion Inc. + * Copyright(c) 2002-2007 Neterion Inc. * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by reference. @@ -30,14 +30,17 @@ #undef SUCCESS #define SUCCESS 0 #define FAILURE -1 - +#define S2IO_MINUS_ONE 0xFFFFFFFFFFFFFFFFULL +#define S2IO_MAX_PCI_CONFIG_SPACE_REINIT 100 +#define S2IO_BIT_RESET 1 +#define S2IO_BIT_SET 2 #define CHECKBIT(value, nbit) (value & (1 << nbit)) /* Maximum time to flicker LED when asked to identify NIC using ethtool */ #define MAX_FLICKER_TIME 60000 /* 60 Secs */ /* Maximum outstanding splits to be configured into xena. */ -typedef enum xena_max_outstanding_splits { +enum { XENA_ONE_SPLIT_TRANSACTION = 0, XENA_TWO_SPLIT_TRANSACTION = 1, XENA_THREE_SPLIT_TRANSACTION = 2, @@ -46,7 +49,7 @@ typedef enum xena_max_outstanding_splits XENA_TWELVE_SPLIT_TRANSACTION = 5, XENA_SIXTEEN_SPLIT_TRANSACTION = 6, XENA_THIRTYTWO_SPLIT_TRANSACTION = 7 -} xena_max_outstanding_splits; +}; #define XENA_MAX_OUTSTANDING_SPLITS(n) (n << 4) /* OS concerned variables and constants */ @@ -71,13 +74,17 @@ static int debug_level = ERR_DBG; /* DEBUG message print. */ #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) +#ifndef DMA_ERROR_CODE +#define DMA_ERROR_CODE (~(dma_addr_t)0x0) +#endif + /* Protocol assist features of the NIC */ #define L3_CKSUM_OK 0xFFFF #define L4_CKSUM_OK 0xFFFF #define S2IO_JUMBO_SIZE 9600 /* Driver statistics maintained by driver */ -typedef struct { +struct swStat { unsigned long long single_ecc_errs; unsigned long long double_ecc_errs; unsigned long long parity_err_cnt; @@ -92,10 +99,37 @@ typedef struct { unsigned long long flush_max_pkts; unsigned long long sum_avg_pkts_aggregated; unsigned long long num_aggregations; -} swStat_t; + /* Other statistics */ + unsigned long long mem_alloc_fail_cnt; + unsigned long long pci_map_fail_cnt; + unsigned long long watchdog_timer_cnt; + unsigned long long mem_allocated; + unsigned long long mem_freed; + unsigned long long link_up_cnt; + unsigned long long link_down_cnt; + unsigned long long link_up_time; + unsigned long long link_down_time; + + /* Transfer Code statistics */ + unsigned long long tx_buf_abort_cnt; + unsigned long long tx_desc_abort_cnt; + unsigned long long tx_parity_err_cnt; + unsigned long long tx_link_loss_cnt; + unsigned long long tx_list_proc_err_cnt; + + unsigned long long rx_parity_err_cnt; + unsigned long long rx_abort_cnt; + unsigned long long rx_parity_abort_cnt; + unsigned long long rx_rda_fail_cnt; + unsigned long long rx_unkn_prot_cnt; + unsigned long long rx_fcs_err_cnt; + unsigned long long rx_buf_size_err_cnt; + unsigned long long rx_rxd_corrupt_cnt; + unsigned long long rx_unkn_err_cnt; +}; /* Xpak releated alarm and warnings */ -typedef struct { +struct xpakStat { u64 alarm_transceiver_temp_high; u64 alarm_transceiver_temp_low; u64 alarm_laser_bias_current_high; @@ -110,189 +144,192 @@ typedef struct { u64 warn_laser_output_power_low; u64 xpak_regs_stat; u32 xpak_timer_count; -} xpakStat_t; +}; /* The statistics block of Xena */ -typedef struct stat_block { +struct stat_block { /* Tx MAC statistics counters. */ - u32 tmac_data_octets; - u32 tmac_frms; - u64 tmac_drop_frms; - u32 tmac_bcst_frms; - u32 tmac_mcst_frms; - u64 tmac_pause_ctrl_frms; - u32 tmac_ucst_frms; - u32 tmac_ttl_octets; - u32 tmac_any_err_frms; - u32 tmac_nucst_frms; - u64 tmac_ttl_less_fb_octets; - u64 tmac_vld_ip_octets; - u32 tmac_drop_ip; - u32 tmac_vld_ip; - u32 tmac_rst_tcp; - u32 tmac_icmp; - u64 tmac_tcp; - u32 reserved_0; - u32 tmac_udp; + __le32 tmac_data_octets; + __le32 tmac_frms; + __le64 tmac_drop_frms; + __le32 tmac_bcst_frms; + __le32 tmac_mcst_frms; + __le64 tmac_pause_ctrl_frms; + __le32 tmac_ucst_frms; + __le32 tmac_ttl_octets; + __le32 tmac_any_err_frms; + __le32 tmac_nucst_frms; + __le64 tmac_ttl_less_fb_octets; + __le64 tmac_vld_ip_octets; + __le32 tmac_drop_ip; + __le32 tmac_vld_ip; + __le32 tmac_rst_tcp; + __le32 tmac_icmp; + __le64 tmac_tcp; + __le32 reserved_0; + __le32 tmac_udp; /* Rx MAC Statistics counters. */ - u32 rmac_data_octets; - u32 rmac_vld_frms; - u64 rmac_fcs_err_frms; - u64 rmac_drop_frms; - u32 rmac_vld_bcst_frms; - u32 rmac_vld_mcst_frms; - u32 rmac_out_rng_len_err_frms; - u32 rmac_in_rng_len_err_frms; - u64 rmac_long_frms; - u64 rmac_pause_ctrl_frms; - u64 rmac_unsup_ctrl_frms; - u32 rmac_accepted_ucst_frms; - u32 rmac_ttl_octets; - u32 rmac_discarded_frms; - u32 rmac_accepted_nucst_frms; - u32 reserved_1; - u32 rmac_drop_events; - u64 rmac_ttl_less_fb_octets; - u64 rmac_ttl_frms; - u64 reserved_2; - u32 rmac_usized_frms; - u32 reserved_3; - u32 rmac_frag_frms; - u32 rmac_osized_frms; - u32 reserved_4; - u32 rmac_jabber_frms; - u64 rmac_ttl_64_frms; - u64 rmac_ttl_65_127_frms; - u64 reserved_5; - u64 rmac_ttl_128_255_frms; - u64 rmac_ttl_256_511_frms; - u64 reserved_6; - u64 rmac_ttl_512_1023_frms; - u64 rmac_ttl_1024_1518_frms; - u32 rmac_ip; - u32 reserved_7; - u64 rmac_ip_octets; - u32 rmac_drop_ip; - u32 rmac_hdr_err_ip; - u32 reserved_8; - u32 rmac_icmp; - u64 rmac_tcp; - u32 rmac_err_drp_udp; - u32 rmac_udp; - u64 rmac_xgmii_err_sym; - u64 rmac_frms_q0; - u64 rmac_frms_q1; - u64 rmac_frms_q2; - u64 rmac_frms_q3; - u64 rmac_frms_q4; - u64 rmac_frms_q5; - u64 rmac_frms_q6; - u64 rmac_frms_q7; - u16 rmac_full_q3; - u16 rmac_full_q2; - u16 rmac_full_q1; - u16 rmac_full_q0; - u16 rmac_full_q7; - u16 rmac_full_q6; - u16 rmac_full_q5; - u16 rmac_full_q4; - u32 reserved_9; - u32 rmac_pause_cnt; - u64 rmac_xgmii_data_err_cnt; - u64 rmac_xgmii_ctrl_err_cnt; - u32 rmac_err_tcp; - u32 rmac_accepted_ip; + __le32 rmac_data_octets; + __le32 rmac_vld_frms; + __le64 rmac_fcs_err_frms; + __le64 rmac_drop_frms; + __le32 rmac_vld_bcst_frms; + __le32 rmac_vld_mcst_frms; + __le32 rmac_out_rng_len_err_frms; + __le32 rmac_in_rng_len_err_frms; + __le64 rmac_long_frms; + __le64 rmac_pause_ctrl_frms; + __le64 rmac_unsup_ctrl_frms; + __le32 rmac_accepted_ucst_frms; + __le32 rmac_ttl_octets; + __le32 rmac_discarded_frms; + __le32 rmac_accepted_nucst_frms; + __le32 reserved_1; + __le32 rmac_drop_events; + __le64 rmac_ttl_less_fb_octets; + __le64 rmac_ttl_frms; + __le64 reserved_2; + __le32 rmac_usized_frms; + __le32 reserved_3; + __le32 rmac_frag_frms; + __le32 rmac_osized_frms; + __le32 reserved_4; + __le32 rmac_jabber_frms; + __le64 rmac_ttl_64_frms; + __le64 rmac_ttl_65_127_frms; + __le64 reserved_5; + __le64 rmac_ttl_128_255_frms; + __le64 rmac_ttl_256_511_frms; + __le64 reserved_6; + __le64 rmac_ttl_512_1023_frms; + __le64 rmac_ttl_1024_1518_frms; + __le32 rmac_ip; + __le32 reserved_7; + __le64 rmac_ip_octets; + __le32 rmac_drop_ip; + __le32 rmac_hdr_err_ip; + __le32 reserved_8; + __le32 rmac_icmp; + __le64 rmac_tcp; + __le32 rmac_err_drp_udp; + __le32 rmac_udp; + __le64 rmac_xgmii_err_sym; + __le64 rmac_frms_q0; + __le64 rmac_frms_q1; + __le64 rmac_frms_q2; + __le64 rmac_frms_q3; + __le64 rmac_frms_q4; + __le64 rmac_frms_q5; + __le64 rmac_frms_q6; + __le64 rmac_frms_q7; + __le16 rmac_full_q3; + __le16 rmac_full_q2; + __le16 rmac_full_q1; + __le16 rmac_full_q0; + __le16 rmac_full_q7; + __le16 rmac_full_q6; + __le16 rmac_full_q5; + __le16 rmac_full_q4; + __le32 reserved_9; + __le32 rmac_pause_cnt; + __le64 rmac_xgmii_data_err_cnt; + __le64 rmac_xgmii_ctrl_err_cnt; + __le32 rmac_err_tcp; + __le32 rmac_accepted_ip; /* PCI/PCI-X Read transaction statistics. */ - u32 new_rd_req_cnt; - u32 rd_req_cnt; - u32 rd_rtry_cnt; - u32 new_rd_req_rtry_cnt; + __le32 new_rd_req_cnt; + __le32 rd_req_cnt; + __le32 rd_rtry_cnt; + __le32 new_rd_req_rtry_cnt; /* PCI/PCI-X Write/Read transaction statistics. */ - u32 wr_req_cnt; - u32 wr_rtry_rd_ack_cnt; - u32 new_wr_req_rtry_cnt; - u32 new_wr_req_cnt; - u32 wr_disc_cnt; - u32 wr_rtry_cnt; + __le32 wr_req_cnt; + __le32 wr_rtry_rd_ack_cnt; + __le32 new_wr_req_rtry_cnt; + __le32 new_wr_req_cnt; + __le32 wr_disc_cnt; + __le32 wr_rtry_cnt; /* PCI/PCI-X Write / DMA Transaction statistics. */ - u32 txp_wr_cnt; - u32 rd_rtry_wr_ack_cnt; - u32 txd_wr_cnt; - u32 txd_rd_cnt; - u32 rxd_wr_cnt; - u32 rxd_rd_cnt; - u32 rxf_wr_cnt; - u32 txf_rd_cnt; + __le32 txp_wr_cnt; + __le32 rd_rtry_wr_ack_cnt; + __le32 txd_wr_cnt; + __le32 txd_rd_cnt; + __le32 rxd_wr_cnt; + __le32 rxd_rd_cnt; + __le32 rxf_wr_cnt; + __le32 txf_rd_cnt; /* Tx MAC statistics overflow counters. */ - u32 tmac_data_octets_oflow; - u32 tmac_frms_oflow; - u32 tmac_bcst_frms_oflow; - u32 tmac_mcst_frms_oflow; - u32 tmac_ucst_frms_oflow; - u32 tmac_ttl_octets_oflow; - u32 tmac_any_err_frms_oflow; - u32 tmac_nucst_frms_oflow; - u64 tmac_vlan_frms; - u32 tmac_drop_ip_oflow; - u32 tmac_vld_ip_oflow; - u32 tmac_rst_tcp_oflow; - u32 tmac_icmp_oflow; - u32 tpa_unknown_protocol; - u32 tmac_udp_oflow; - u32 reserved_10; - u32 tpa_parse_failure; + __le32 tmac_data_octets_oflow; + __le32 tmac_frms_oflow; + __le32 tmac_bcst_frms_oflow; + __le32 tmac_mcst_frms_oflow; + __le32 tmac_ucst_frms_oflow; + __le32 tmac_ttl_octets_oflow; + __le32 tmac_any_err_frms_oflow; + __le32 tmac_nucst_frms_oflow; + __le64 tmac_vlan_frms; + __le32 tmac_drop_ip_oflow; + __le32 tmac_vld_ip_oflow; + __le32 tmac_rst_tcp_oflow; + __le32 tmac_icmp_oflow; + __le32 tpa_unknown_protocol; + __le32 tmac_udp_oflow; + __le32 reserved_10; + __le32 tpa_parse_failure; /* Rx MAC Statistics overflow counters. */ - u32 rmac_data_octets_oflow; - u32 rmac_vld_frms_oflow; - u32 rmac_vld_bcst_frms_oflow; - u32 rmac_vld_mcst_frms_oflow; - u32 rmac_accepted_ucst_frms_oflow; - u32 rmac_ttl_octets_oflow; - u32 rmac_discarded_frms_oflow; - u32 rmac_accepted_nucst_frms_oflow; - u32 rmac_usized_frms_oflow; - u32 rmac_drop_events_oflow; - u32 rmac_frag_frms_oflow; - u32 rmac_osized_frms_oflow; - u32 rmac_ip_oflow; - u32 rmac_jabber_frms_oflow; - u32 rmac_icmp_oflow; - u32 rmac_drop_ip_oflow; - u32 rmac_err_drp_udp_oflow; - u32 rmac_udp_oflow; - u32 reserved_11; - u32 rmac_pause_cnt_oflow; - u64 rmac_ttl_1519_4095_frms; - u64 rmac_ttl_4096_8191_frms; - u64 rmac_ttl_8192_max_frms; - u64 rmac_ttl_gt_max_frms; - u64 rmac_osized_alt_frms; - u64 rmac_jabber_alt_frms; - u64 rmac_gt_max_alt_frms; - u64 rmac_vlan_frms; - u32 rmac_len_discard; - u32 rmac_fcs_discard; - u32 rmac_pf_discard; - u32 rmac_da_discard; - u32 rmac_red_discard; - u32 rmac_rts_discard; - u32 reserved_12; - u32 rmac_ingm_full_discard; - u32 reserved_13; - u32 rmac_accepted_ip_oflow; - u32 reserved_14; - u32 link_fault_cnt; + __le32 rmac_data_octets_oflow; + __le32 rmac_vld_frms_oflow; + __le32 rmac_vld_bcst_frms_oflow; + __le32 rmac_vld_mcst_frms_oflow; + __le32 rmac_accepted_ucst_frms_oflow; + __le32 rmac_ttl_octets_oflow; + __le32 rmac_discarded_frms_oflow; + __le32 rmac_accepted_nucst_frms_oflow; + __le32 rmac_usized_frms_oflow; + __le32 rmac_drop_events_oflow; + __le32 rmac_frag_frms_oflow; + __le32 rmac_osized_frms_oflow; + __le32 rmac_ip_oflow; + __le32 rmac_jabber_frms_oflow; + __le32 rmac_icmp_oflow; + __le32 rmac_drop_ip_oflow; + __le32 rmac_err_drp_udp_oflow; + __le32 rmac_udp_oflow; + __le32 reserved_11; + __le32 rmac_pause_cnt_oflow; + __le64 rmac_ttl_1519_4095_frms; + __le64 rmac_ttl_4096_8191_frms; + __le64 rmac_ttl_8192_max_frms; + __le64 rmac_ttl_gt_max_frms; + __le64 rmac_osized_alt_frms; + __le64 rmac_jabber_alt_frms; + __le64 rmac_gt_max_alt_frms; + __le64 rmac_vlan_frms; + __le32 rmac_len_discard; + __le32 rmac_fcs_discard; + __le32 rmac_pf_discard; + __le32 rmac_da_discard; + __le32 rmac_red_discard; + __le32 rmac_rts_discard; + __le32 reserved_12; + __le32 rmac_ingm_full_discard; + __le32 reserved_13; + __le32 rmac_accepted_ip_oflow; + __le32 reserved_14; + __le32 link_fault_cnt; u8 buffer[20]; - swStat_t sw_stat; - xpakStat_t xpak_stat; -} StatInfo_t; + struct swStat sw_stat; + struct xpakStat xpak_stat; +}; + +/* Default value for 'vlan_strip_tag' configuration parameter */ +#define NO_STRIP_IN_PROMISC 2 /* * Structures representing different init time configuration @@ -302,6 +339,11 @@ typedef struct stat_block { #define MAX_TX_FIFOS 8 #define MAX_RX_RINGS 8 +#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) +#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) +#define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) +#define MAX_TX_DESC (MAX_AVAILABLE_TXDS) + /* FIFO mappings for all possible number of fifos configured */ static int fifo_map[][MAX_TX_FIFOS] = { {0, 0, 0, 0, 0, 0, 0, 0}, @@ -315,7 +357,7 @@ static int fifo_map[][MAX_TX_FIFOS] = { }; /* Maintains Per FIFO related information. */ -typedef struct tx_fifo_config { +struct tx_fifo_config { #define MAX_AVAILABLE_TXDS 8192 u32 fifo_len; /* specifies len of FIFO upto 8192, ie no of TxDLs */ /* Priority definition */ @@ -332,11 +374,11 @@ typedef struct tx_fifo_config { u8 f_no_snoop; #define NO_SNOOP_TXD 0x01 #define NO_SNOOP_TXD_BUFFER 0x02 -} tx_fifo_config_t; +}; /* Maintains per Ring related information */ -typedef struct rx_ring_config { +struct rx_ring_config { u32 num_rxd; /*No of RxDs per Rx Ring */ #define RX_RING_PRI_0 0 /* highest */ #define RX_RING_PRI_1 1 @@ -357,7 +399,7 @@ typedef struct rx_ring_config { u8 f_no_snoop; #define NO_SNOOP_RXD 0x01 #define NO_SNOOP_RXD_BUFFER 0x02 -} rx_ring_config_t; +}; /* This structure provides contains values of the tunable parameters * of the H/W @@ -367,7 +409,7 @@ struct config_param { u32 tx_fifo_num; /*Number of Tx FIFOs */ u8 fifo_mapping[MAX_TX_FIFOS]; - tx_fifo_config_t tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ + struct tx_fifo_config tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ u64 tx_intr_type; /* Specifies if Tx Intr is UTILZ or PER_LIST type. */ @@ -376,7 +418,7 @@ struct config_param { u32 rx_ring_num; /*Number of receive rings */ #define MAX_RX_BLOCKS_PER_RING 150 - rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ + struct rx_ring_config rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ u8 bimodal; /*Flag for setting bimodal interrupts*/ #define HEADER_ETHERNET_II_802_3_SIZE 14 @@ -395,14 +437,14 @@ struct config_param { }; /* Structure representing MAC Addrs */ -typedef struct mac_addr { +struct mac_addr { u8 mac_addr[ETH_ALEN]; -} macaddr_t; +}; /* Structure that represent every FIFO element in the BAR1 * Address location. */ -typedef struct _TxFIFO_element { +struct TxFIFO_element { u64 TxDL_Pointer; u64 List_Control; @@ -413,10 +455,10 @@ typedef struct _TxFIFO_element { #define TX_FIFO_SPECIAL_FUNC BIT(23) #define TX_FIFO_DS_NO_SNOOP BIT(31) #define TX_FIFO_BUFF_NO_SNOOP BIT(30) -} TxFIFO_element_t; +}; /* Tx descriptor structure */ -typedef struct _TxD { +struct TxD { u64 Control_1; /* bit mask */ #define TXD_LIST_OWN_XENA BIT(7) @@ -447,16 +489,16 @@ typedef struct _TxD { u64 Buffer_Pointer; u64 Host_Control; /* reserved for host */ -} TxD_t; +}; /* Structure to hold the phy and virt addr of every TxDL. */ -typedef struct list_info_hold { +struct list_info_hold { dma_addr_t list_phy_addr; void *list_virt_addr; -} list_info_hold_t; +}; /* Rx descriptor structure for 1 buffer mode */ -typedef struct _RxD_t { +struct RxD_t { u64 Host_Control; /* reserved for host */ u64 Control_1; #define RXD_OWN_XENA BIT(7) @@ -481,21 +523,21 @@ typedef struct _RxD_t { #define SET_NUM_TAG(val) vBIT(val,16,32) -} RxD_t; +}; /* Rx descriptor structure for 1 buffer mode */ -typedef struct _RxD1_t { - struct _RxD_t h; +struct RxD1 { + struct RxD_t h; #define MASK_BUFFER0_SIZE_1 vBIT(0x3FFF,2,14) #define SET_BUFFER0_SIZE_1(val) vBIT(val,2,14) #define RXD_GET_BUFFER0_SIZE_1(_Control_2) \ (u16)((_Control_2 & MASK_BUFFER0_SIZE_1) >> 48) u64 Buffer0_ptr; -} RxD1_t; +}; /* Rx descriptor structure for 3 or 2 buffer mode */ -typedef struct _RxD3_t { - struct _RxD_t h; +struct RxD3 { + struct RxD_t h; #define MASK_BUFFER0_SIZE_3 vBIT(0xFF,2,14) #define MASK_BUFFER1_SIZE_3 vBIT(0xFFFF,16,16) @@ -515,15 +557,15 @@ typedef struct _RxD3_t { u64 Buffer0_ptr; u64 Buffer1_ptr; u64 Buffer2_ptr; -} RxD3_t; +}; /* Structure that represents the Rx descriptor block which contains * 128 Rx descriptors. */ -typedef struct _RxD_block { +struct RxD_block { #define MAX_RXDS_PER_BLOCK_1 127 - RxD1_t rxd[MAX_RXDS_PER_BLOCK_1]; + struct RxD1 rxd[MAX_RXDS_PER_BLOCK_1]; u64 reserved_0; #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL @@ -533,22 +575,21 @@ typedef struct _RxD_block { u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch * the upper 32 bits should * be 0 */ -} RxD_block_t; +}; #define SIZE_OF_BLOCK 4096 -#define RXD_MODE_1 0 -#define RXD_MODE_3A 1 -#define RXD_MODE_3B 2 +#define RXD_MODE_1 0 /* One Buffer mode */ +#define RXD_MODE_3B 1 /* Two Buffer mode */ /* Structure to hold virtual addresses of Buf0 and Buf1 in * 2buf mode. */ -typedef struct bufAdd { +struct buffAdd { void *ba_0_org; void *ba_1_org; void *ba_0; void *ba_1; -} buffAdd_t; +}; /* Structure which stores all the MAC control parameters */ @@ -556,43 +597,46 @@ typedef struct bufAdd { * from which the Rx Interrupt processor can start picking * up the RxDs for processing. */ -typedef struct _rx_curr_get_info_t { +struct rx_curr_get_info { u32 block_index; u32 offset; u32 ring_len; -} rx_curr_get_info_t; +}; -typedef rx_curr_get_info_t rx_curr_put_info_t; +struct rx_curr_put_info { + u32 block_index; + u32 offset; + u32 ring_len; +}; /* This structure stores the offset of the TxDl in the FIFO * from which the Tx Interrupt processor can start picking * up the TxDLs for send complete interrupt processing. */ -typedef struct { +struct tx_curr_get_info { u32 offset; u32 fifo_len; -} tx_curr_get_info_t; - -typedef tx_curr_get_info_t tx_curr_put_info_t; +}; +struct tx_curr_put_info { + u32 offset; + u32 fifo_len; +}; -typedef struct rxd_info { +struct rxd_info { void *virt_addr; dma_addr_t dma_addr; -}rxd_info_t; +}; /* Structure that holds the Phy and virt addresses of the Blocks */ -typedef struct rx_block_info { +struct rx_block_info { void *block_virt_addr; dma_addr_t block_dma_addr; - rxd_info_t *rxds; -} rx_block_info_t; - -/* pre declaration of the nic structure */ -typedef struct s2io_nic nic_t; + struct rxd_info *rxds; +}; /* Ring specific structure */ -typedef struct ring_info { +struct ring_info { /* The ring number */ int ring_no; @@ -600,7 +644,7 @@ typedef struct ring_info { * Place holders for the virtual and physical addresses of * all the Rx Blocks */ - rx_block_info_t rx_blocks[MAX_RX_BLOCKS_PER_RING]; + struct rx_block_info rx_blocks[MAX_RX_BLOCKS_PER_RING]; int block_count; int pkt_cnt; @@ -608,26 +652,24 @@ typedef struct ring_info { * Put pointer info which indictes which RxD has to be replenished * with a new buffer. */ - rx_curr_put_info_t rx_curr_put_info; + struct rx_curr_put_info rx_curr_put_info; /* * Get pointer info which indictes which is the last RxD that was * processed by the driver. */ - rx_curr_get_info_t rx_curr_get_info; + struct rx_curr_get_info rx_curr_get_info; -#ifndef CONFIG_S2IO_NAPI /* Index to the absolute position of the put pointer of Rx ring */ int put_pos; -#endif /* Buffer Address store. */ - buffAdd_t **ba; - nic_t *nic; -} ring_info_t; + struct buffAdd **ba; + struct s2io_nic *nic; +}; /* Fifo specific structure */ -typedef struct fifo_info { +struct fifo_info { /* FIFO number */ int fifo_no; @@ -635,40 +677,40 @@ typedef struct fifo_info { int max_txds; /* Place holder of all the TX List's Phy and Virt addresses. */ - list_info_hold_t *list_info; + struct list_info_hold *list_info; /* * Current offset within the tx FIFO where driver would write * new Tx frame */ - tx_curr_put_info_t tx_curr_put_info; + struct tx_curr_put_info tx_curr_put_info; /* * Current offset within tx FIFO from where the driver would start freeing * the buffers */ - tx_curr_get_info_t tx_curr_get_info; + struct tx_curr_get_info tx_curr_get_info; - nic_t *nic; -}fifo_info_t; + struct s2io_nic *nic; +}; /* Information related to the Tx and Rx FIFOs and Rings of Xena * is maintained in this structure. */ -typedef struct mac_info { +struct mac_info { /* tx side stuff */ /* logical pointer of start of each Tx FIFO */ - TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS]; + struct TxFIFO_element __iomem *tx_FIFO_start[MAX_TX_FIFOS]; /* Fifo specific structure */ - fifo_info_t fifos[MAX_TX_FIFOS]; + struct fifo_info fifos[MAX_TX_FIFOS]; /* Save virtual address of TxD page with zero DMA addr(if any) */ void *zerodma_virt_addr; /* rx side stuff */ /* Ring specific structure */ - ring_info_t rings[MAX_RX_RINGS]; + struct ring_info rings[MAX_RX_RINGS]; u16 rmac_pause_time; u16 mc_pause_threshold_q0q3; @@ -677,14 +719,14 @@ typedef struct mac_info { void *stats_mem; /* orignal pointer to allocated mem */ dma_addr_t stats_mem_phy; /* Physical address of the stat block */ u32 stats_mem_sz; - StatInfo_t *stats_info; /* Logical address of the stat block */ -} mac_info_t; + struct stat_block *stats_info; /* Logical address of the stat block */ +}; /* structure representing the user defined MAC addresses */ -typedef struct { +struct usr_addr { char addr[ETH_ALEN]; int usage_cnt; -} usr_addr_t; +}; /* Default Tunable parameters of the NIC. */ #define DEFAULT_FIFO_0_LEN 4096 @@ -717,36 +759,34 @@ struct msix_info_st { }; /* Data structure to represent a LRO session */ -typedef struct lro { +struct lro { struct sk_buff *parent; struct sk_buff *last_frag; u8 *l2h; struct iphdr *iph; struct tcphdr *tcph; u32 tcp_next_seq; - u32 tcp_ack; + __be32 tcp_ack; int total_len; int frags_len; int sg_num; int in_use; - u16 window; + __be16 window; u32 cur_tsval; u32 cur_tsecr; u8 saw_ts; -}lro_t; +}; /* Structure representing one instance of the NIC */ struct s2io_nic { int rxd_mode; -#ifdef CONFIG_S2IO_NAPI /* * Count of packets to be processed in a given iteration, it will be indicated * by the quota field of the device structure when NAPI is enabled. */ int pkts_to_process; -#endif struct net_device *dev; - mac_info_t mac_control; + struct mac_info mac_control; struct config_param config; struct pci_dev *pdev; void __iomem *bar0; @@ -754,12 +794,10 @@ struct s2io_nic { #define MAX_MAC_SUPPORTED 16 #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED - macaddr_t def_mac_addr[MAX_MAC_SUPPORTED]; - macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED]; + struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED]; struct net_device_stats stats; int high_dma_flag; - int device_close_flag; int device_enabled_once; char name[60]; @@ -775,9 +813,7 @@ struct s2io_nic { atomic_t rx_bufs_left[MAX_RX_RINGS]; spinlock_t tx_lock; -#ifndef CONFIG_S2IO_NAPI spinlock_t put_lock; -#endif #define PROMISC 1 #define ALL_MULTI 2 @@ -785,17 +821,12 @@ struct s2io_nic { #define MAX_ADDRS_SUPPORTED 64 u16 usr_addr_count; u16 mc_addr_count; - usr_addr_t usr_addrs[MAX_ADDRS_SUPPORTED]; + struct usr_addr usr_addrs[MAX_ADDRS_SUPPORTED]; u16 m_cast_flg; u16 all_multi_pos; u16 promisc_flg; - u16 tx_pkt_count; - u16 rx_pkt_count; - u16 tx_err_count; - u16 rx_err_count; - /* Id timer, used to blink NIC to physically identify NIC. */ struct timer_list id_timer; @@ -822,6 +853,7 @@ struct s2io_nic { #define LINK_UP 2 int task_flag; + unsigned long long start_time; #define CARD_DOWN 1 #define CARD_UP 2 atomic_t card_state; @@ -841,22 +873,22 @@ struct s2io_nic { u8 device_type; #define MAX_LRO_SESSIONS 32 - lro_t lro0_n[MAX_LRO_SESSIONS]; + struct lro lro0_n[MAX_LRO_SESSIONS]; unsigned long clubbed_frms_cnt; unsigned long sending_both; u8 lro; u16 lro_max_aggr_per_sess; #define INTA 0 -#define MSI 1 #define MSI_X 2 u8 intr_type; spinlock_t rx_lock; atomic_t isr_cnt; u64 *ufo_in_band_v; -#define VPD_PRODUCT_NAME_LEN 50 - u8 product_name[VPD_PRODUCT_NAME_LEN]; +#define VPD_STRING_LEN 80 + u8 product_name[VPD_STRING_LEN]; + u8 serial_num[VPD_STRING_LEN]; }; #define RESET_ERROR 1; @@ -883,10 +915,10 @@ static inline void writeq(u64 val, void } #endif -/* - * Some registers have to be written in a particular order to - * expect correct hardware operation. The macro SPECIAL_REG_WRITE - * is used to perform such ordered writes. Defines UF (Upper First) +/* + * Some registers have to be written in a particular order to + * expect correct hardware operation. The macro SPECIAL_REG_WRITE + * is used to perform such ordered writes. Defines UF (Upper First) * and LF (Lower First) will be used to specify the required write order. */ #define UF 1 @@ -975,49 +1007,53 @@ static void __devexit s2io_rem_nic(struc static int init_shared_mem(struct s2io_nic *sp); static void free_shared_mem(struct s2io_nic *sp); static int init_nic(struct s2io_nic *nic); -static void rx_intr_handler(ring_info_t *ring_data); -static void tx_intr_handler(fifo_info_t *fifo_data); +static void rx_intr_handler(struct ring_info *ring_data); +static void tx_intr_handler(struct fifo_info *fifo_data); static void alarm_intr_handler(struct s2io_nic *sp); static int s2io_starter(void); +static void s2io_closer(void); static void s2io_tx_watchdog(struct net_device *dev); static void s2io_tasklet(unsigned long dev_addr); static void s2io_set_multicast(struct net_device *dev); -static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp); -static void s2io_link(nic_t * sp, int link); -#if defined(CONFIG_S2IO_NAPI) +static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); +static void s2io_link(struct s2io_nic * sp, int link); +static void s2io_reset(struct s2io_nic * sp); static int s2io_poll(struct net_device *dev, int *budget); -#endif -static void s2io_init_pci(nic_t * sp); +static void s2io_init_pci(struct s2io_nic * sp); static int s2io_set_mac_addr(struct net_device *dev, u8 * addr); static void s2io_alarm_handle(unsigned long data); -static int s2io_enable_msi(nic_t *nic); -static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs); -static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); +static int verify_xena_quiescence(struct s2io_nic *sp); static struct ethtool_ops netdev_ethtool_ops; static void s2io_set_link(unsigned long data); -static int s2io_set_swapper(nic_t * sp); -static void s2io_card_down(nic_t *nic); -static int s2io_card_up(nic_t *nic); +static int s2io_set_swapper(struct s2io_nic * sp); +static void s2io_card_down(struct s2io_nic *nic); +static int s2io_card_up(struct s2io_nic *nic); static int get_xena_rev_id(struct pci_dev *pdev); -static void restore_xmsi_data(nic_t *nic); +static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit, + int bit_state); +static int s2io_add_isr(struct s2io_nic * sp); +static void s2io_rem_isr(struct s2io_nic * sp); + +static void restore_xmsi_data(struct s2io_nic *nic); + +static int s2io_club_tcp_session(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); +static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro); +static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, struct sk_buff *skb, u32 tcp_len); +static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring); static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev, - pci_channel_state_t state); + pci_channel_state_t state); static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev); static void s2io_io_resume(struct pci_dev *pdev); -static int s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, lro_t **lro, RxD_t *rxdp, nic_t *sp); -static void clear_lro_session(lro_t *lro); -static void queue_rx_frame(struct sk_buff *skb); -static void update_L3L4_header(nic_t *sp, lro_t *lro); -static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len); - #define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size #define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size #define s2io_offload_type(skb) skb_shinfo(skb)->gso_type --- linux-2.6.18.i386/drivers/net/s2io-regs.h.orig +++ linux-2.6.18.i386/drivers/net/s2io-regs.h @@ -1,6 +1,6 @@ /************************************************************************ * regs.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC - * Copyright(c) 2002-2005 Neterion Inc. + * Copyright(c) 2002-2007 Neterion Inc. * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by reference. @@ -15,7 +15,7 @@ #define TBD 0 -typedef struct _XENA_dev_config { +struct XENA_dev_config { /* Convention: mHAL_XXX is mask, vHAL_XXX is value */ /* General Control-Status Registers */ @@ -300,6 +300,7 @@ typedef struct _XENA_dev_config { u64 gpio_control; #define GPIO_CTRL_GPIO_0 BIT(8) u64 misc_control; +#define FAULT_BEHAVIOUR BIT(0) #define EXT_REQ_EN BIT(1) #define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3) @@ -429,6 +430,7 @@ typedef struct _XENA_dev_config { #define TX_PA_CFG_IGNORE_SNAP_OUI BIT(2) #define TX_PA_CFG_IGNORE_LLC_CTRL BIT(3) #define TX_PA_CFG_IGNORE_L2_ERR BIT(6) +#define RX_PA_CFG_STRIP_VLAN_TAG BIT(15) /* Recent add, used only debug purposes. */ u64 pcc_enable; @@ -656,8 +658,8 @@ typedef struct _XENA_dev_config { u64 rmac_addr_cfg; #define RMAC_ADDR_UCASTn_EN(n) mBIT(0)_n(n) #define RMAC_ADDR_MCASTn_EN(n) mBIT(0)_n(n) -#define RMAC_ADDR_BCAST_EN vBIT(0)_48 -#define RMAC_ADDR_ALL_ADDR_EN vBIT(0)_49 +#define RMAC_ADDR_BCAST_EN vBIT(0)_48 +#define RMAC_ADDR_ALL_ADDR_EN vBIT(0)_49 */ u64 tmac_ipg_cfg; @@ -745,10 +747,9 @@ typedef struct _XENA_dev_config { #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) #define MC_ERR_REG_SM_ERR BIT(31) #define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\ - BIT(6) | BIT(7) | BIT(17) | BIT(19)) + BIT(17) | BIT(19)) #define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\ - BIT(13) | BIT(14) | BIT(15) |\ - BIT(18) | BIT(20)) + BIT(13) | BIT(18) | BIT(20)) u64 mc_err_mask; u64 mc_err_alarm; @@ -851,9 +852,9 @@ typedef struct _XENA_dev_config { #define SPI_CONTROL_DONE BIT(6) u64 spi_data; #define SPI_DATA_WRITE(data,len) vBIT(data,0,len) -} XENA_dev_config_t; +}; -#define XENA_REG_SPACE sizeof(XENA_dev_config_t) +#define XENA_REG_SPACE sizeof(struct XENA_dev_config) #define XENA_EEPROM_SPACE (0x01 << 11) #endif /* _REGS_H */