diff -Naur orig/drivers/net/Kconfig new/drivers/net/Kconfig --- orig/drivers/net/Kconfig 2004-08-06 06:55:01.000000000 -0700 +++ new/drivers/net/Kconfig 2004-08-06 06:57:47.000000000 -0700 @@ -2161,6 +2161,17 @@ bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" depends on S2IO && EXPERIMENTAL +config 2BUFF_MODE + bool "Use 2 Buffer mode on Receive side." + depends on S2IO + ---help--- + On enabling 2 buffer mode, the received frame will be + split into 2 parts before being DMA'ed to the host's + memory. the 2 parts are the ethernet header and ethernet + payload. This is useful on systems where DMA'ing to + unaligned memory locations comes with a heavy price. If + not sure please say N. + endmenu source "drivers/net/tokenring/Kconfig" diff -Naur orig/drivers/net/s2io-regs.h new/drivers/net/s2io-regs.h --- orig/drivers/net/s2io-regs.h 2004-08-06 06:55:01.000000000 -0700 +++ new/drivers/net/s2io-regs.h 2004-08-06 06:58:44.000000000 -0700 @@ -1,5 +1,5 @@ /************************************************************************ - * regs.h: A Linux PCI-X Ethernet driver for S2IO 10GbE Server NIC + * s2io-regs.h: A Linux PCI-X Ethernet driver for S2IO 10GbE Server NIC * Copyright 2002 Raghavendra Koushik (raghavendra.koushik@s2io.com) * This software may be used and distributed according to the terms of @@ -289,6 +289,8 @@ u64 tda_err_alarm; u64 pcc_err_reg; +#define PCC_FB_ECC_DB_ERR vBIT(0xFF, 16, 8) + u64 pcc_err_mask; u64 pcc_err_alarm; @@ -451,10 +453,6 @@ /* Per-ring controller regs */ #define RX_MAX_RINGS 8 -#if 0 -#define RX_MAX_RINGS_SZ 0xFFFF /* 65536 */ -#define RX_MIN_RINGS_SZ 0x3F /* 63 */ -#endif u64 prc_rxd0_n[RX_MAX_RINGS]; u64 prc_ctrl_n[RX_MAX_RINGS]; #define PRC_CTRL_RC_ENABLED BIT(7) @@ -512,6 +510,7 @@ #define RX_PA_CFG_IGNORE_FRM_ERR BIT(1) #define RX_PA_CFG_IGNORE_SNAP_OUI BIT(2) #define RX_PA_CFG_IGNORE_LLC_CTRL BIT(3) +#define RX_PA_CFG_IGNORE_L2_ERR BIT(6) u8 unused12[0x700 - 0x1D8]; diff -Naur orig/drivers/net/s2io.c new/drivers/net/s2io.c --- orig/drivers/net/s2io.c 2004-08-06 06:55:01.000000000 -0700 +++ new/drivers/net/s2io.c 2004-08-06 06:58:44.000000000 -0700 @@ -61,6 +61,7 @@ #include #include #include +#include #include /* local include */ @@ -69,18 +70,23 @@ /* S2io Driver name & version. */ static char s2io_driver_name[] = "s2io"; -static char s2io_driver_version[] = "Version 1.0"; +static char s2io_driver_version[] = "Version 1.1"; +/* Often used checks defined as macros. */ #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ ADAPTER_STATUS_RMAC_LOCAL_FAULT))) #define TASKLET_IN_USE test_and_set_bit(0, \ (unsigned long *)(&sp->tasklet_status)) + +/* An inline function to determine the status with respect to + * availability of Rx side buffers. + */ #define PANIC 1 #define LOW 2 static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) { int level = 0; - if ((sp->pkt_cnt[ring] - rxb_size) > 128) { + if ((sp->pkt_cnt[ring] - rxb_size) > 16) { level = LOW; if (rxb_size < sp->pkt_cnt[ring] / 8) level = PANIC; @@ -99,45 +105,45 @@ }; static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { - "tmac_frms", - "tmac_data_octets", - "tmac_drop_frms", - "tmac_mcst_frms", - "tmac_bcst_frms", - "tmac_pause_ctrl_frms", - "tmac_any_err_frms", - "tmac_vld_ip_octets", - "tmac_vld_ip", - "tmac_drop_ip", - "tmac_icmp", - "tmac_rst_tcp", - "tmac_tcp", - "tmac_udp", - "rmac_vld_frms", - "rmac_data_octets", - "rmac_fcs_err_frms", - "rmac_drop_frms", - "rmac_vld_mcst_frms", - "rmac_vld_bcst_frms", - "rmac_in_rng_len_err_frms", - "rmac_long_frms", - "rmac_pause_ctrl_frms", - "rmac_discarded_frms", - "rmac_usized_frms", - "rmac_osized_frms", - "rmac_frag_frms", - "rmac_jabber_frms", - "rmac_ip", - "rmac_ip_octets", - "rmac_hdr_err_ip", - "rmac_drop_ip", - "rmac_icmp", - "rmac_tcp", - "rmac_udp", - "rmac_err_drp_udp", - "rmac_pause_cnt", - "rmac_accepted_ip", - "rmac_err_tcp", + {"tmac_frms"}, + {"tmac_data_octets"}, + {"tmac_drop_frms"}, + {"tmac_mcst_frms"}, + {"tmac_bcst_frms"}, + {"tmac_pause_ctrl_frms"}, + {"tmac_any_err_frms"}, + {"tmac_vld_ip_octets"}, + {"tmac_vld_ip"}, + {"tmac_drop_ip"}, + {"tmac_icmp"}, + {"tmac_rst_tcp"}, + {"tmac_tcp"}, + {"tmac_udp"}, + {"rmac_vld_frms"}, + {"rmac_data_octets"}, + {"rmac_fcs_err_frms"}, + {"rmac_drop_frms"}, + {"rmac_vld_mcst_frms"}, + {"rmac_vld_bcst_frms"}, + {"rmac_in_rng_len_err_frms"}, + {"rmac_long_frms"}, + {"rmac_pause_ctrl_frms"}, + {"rmac_discarded_frms"}, + {"rmac_usized_frms"}, + {"rmac_osized_frms"}, + {"rmac_frag_frms"}, + {"rmac_jabber_frms"}, + {"rmac_ip"}, + {"rmac_ip_octets"}, + {"rmac_hdr_err_ip"}, + {"rmac_drop_ip"}, + {"rmac_icmp"}, + {"rmac_tcp"}, + {"rmac_udp"}, + {"rmac_err_drp_udp"}, + {"rmac_pause_cnt"}, + {"rmac_accepted_ip"}, + {"rmac_err_tcp"}, }; #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN @@ -209,16 +215,65 @@ END_SIGN }; - /* Module Loadable parameters. */ -static u32 ring_num; static u32 frame_len[MAX_RX_RINGS]; -static u32 ring_len[MAX_RX_RINGS]; -static u32 fifo_num; -static u32 fifo_len[MAX_TX_FIFOS]; static u32 rx_prio; static u32 tx_prio; -static u8 latency_timer = 0; + +static unsigned int lso_enable = 1; +static unsigned int indicate_max_pkts = 0; +static unsigned int cksum_offload_enable = 1; +static unsigned int TxFifoNum = 1; +static unsigned int TxFIFOLen_0 = DEFAULT_FIFO_LEN; +static unsigned int TxFIFOLen_1 = 0; +static unsigned int TxFIFOLen_2 = 0; +static unsigned int TxFIFOLen_3 = 0; +static unsigned int TxFIFOLen_4 = 0; +static unsigned int TxFIFOLen_5 = 0; +static unsigned int TxFIFOLen_6 = 0; +static unsigned int TxFIFOLen_7 = 0; +static unsigned int MaxTxDs = MAX_SKB_FRAGS; +static unsigned int RxRingNum = 1; +static unsigned int RxRingSz_0 = SMALL_BLK_CNT; +static unsigned int RxRingSz_1 = 0; +static unsigned int RxRingSz_2 = 0; +static unsigned int RxRingSz_3 = 0; +static unsigned int RxRingSz_4 = 0; +static unsigned int RxRingSz_5 = 0; +static unsigned int RxRingSz_6 = 0; +static unsigned int RxRingSz_7 = 0; +static unsigned int Stats_refresh_time = 4; +static unsigned int rmac_pause_time = 65535; +static unsigned int mc_pause_threshold_q0q3 = 187; +static unsigned int mc_pause_threshold_q4q7 = 187; +static unsigned int shared_splits = 0; +#if defined(__ia64__) +static unsigned int max_splits_trans = XENA_THREE_SPLIT_TRANSACTION; +#else +static unsigned int max_splits_trans = XENA_TWO_SPLIT_TRANSACTION; +#endif +static unsigned int tmac_util_period = 5; +static unsigned int rmac_util_period = 5; +static unsigned int tx_timer_val = 0xFFF; +static unsigned int tx_utilz_periodic = 1; +static unsigned int rx_timer_val = 0xFFF; +static unsigned int rx_utilz_periodic = 1; +static unsigned int tx_urange_a = 0xA; +static unsigned int tx_ufc_a = 0x10; +static unsigned int tx_urange_b = 0x10; +static unsigned int tx_ufc_b = 0x20; +static unsigned int tx_urange_c = 0x30; +static unsigned int tx_ufc_c = 0x40; +static unsigned int tx_ufc_d = 0x80; +static unsigned int rx_urange_a = 0xA; +static unsigned int rx_ufc_a = 0x1; +static unsigned int rx_urange_b = 0x10; +static unsigned int rx_ufc_b = 0x2; +static unsigned int rx_urange_c = 0x30; +static unsigned int rx_ufc_c = 0x40; +static unsigned int rx_ufc_d = 0x80; +static u8 latency_timer = 0xf8; +static u8 max_read_byte_cnt = 3; /* * S2IO device table. @@ -241,23 +296,22 @@ remove:__devexit_p(s2io_rem_nic), }; -/* - * Input Arguments: - * Device private variable. - * Return Value: - * SUCCESS on success and an appropriate -ve value on failure. - * Description: - * The function allocates the all memory areas shared - * between the NIC and the driver. This includes Tx descriptors, - * Rx descriptors and the statistics block. +/** + * init_shared_mem - Allocation and Initialization of Memory + * @nic: Device private variable. + * Description: The function allocates the all memory areas shared + * between the NIC and the driver. This includes Tx descriptors, + * Rx descriptors and the statistics block. */ -static int initSharedMem(struct s2io_nic *nic) + +static int init_shared_mem(struct s2io_nic *nic) { 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; + int lst_size, lst_per_page; struct net_device *dev = nic->dev; mac_info_t *mac_control; @@ -279,39 +333,55 @@ DBG_PRINT(ERR_DBG, "that can be used\n"); return FAILURE; } - size *= (sizeof(TxD_t) * config->MaxTxDs); - - mac_control->txd_list_mem = pci_alloc_consistent - (nic->pdev, size, &mac_control->txd_list_mem_phy); - if (!mac_control->txd_list_mem) { - return -ENOMEM; - } - mac_control->txd_list_mem_sz = size; - tmp_v_addr = mac_control->txd_list_mem; - tmp_p_addr = mac_control->txd_list_mem_phy; - memset(tmp_v_addr, 0, size); + lst_size = (sizeof(TxD_t) * config->MaxTxDs); + lst_per_page = PAGE_SIZE / lst_size; - DBG_PRINT(INIT_DBG, "%s:List Mem PHY: 0x%llx\n", dev->name, - (unsigned long long) tmp_p_addr); + for(i=0; iTxFIFONum; i++) { + int fifo_len = config->TxCfg[i].FifoLen; + int list_holder_size = fifo_len * sizeof(list_info_hold_t); + nic->list_info[i] = kmalloc(list_holder_size, GFP_KERNEL); + if(!nic->list_info[i]) { + DBG_PRINT(ERR_DBG,"Malloc failed for list_info\n"); + return -ENOMEM; + } + memset(nic->list_info[i], 0, list_holder_size); + } + for(i=0; iTxFIFONum; i++) { + int tmp = config->TxCfg[i].FifoLen / lst_per_page; + int tmp1 = config->TxCfg[i].FifoLen % lst_per_page; + int page_num = tmp1? (tmp+1) : tmp; - for (i = 0; i < config->TxFIFONum; i++) { - mac_control->txdl_start_phy[i] = tmp_p_addr; - mac_control->txdl_start[i] = (TxD_t *) tmp_v_addr; mac_control->tx_curr_put_info[i].offset = 0; mac_control->tx_curr_put_info[i].fifo_len = config->TxCfg[i].FifoLen - 1; mac_control->tx_curr_get_info[i].offset = 0; mac_control->tx_curr_get_info[i].fifo_len = config->TxCfg[i].FifoLen - 1; - - tmp_p_addr += - (config->TxCfg[i].FifoLen * (sizeof(TxD_t)) * - config->MaxTxDs); - tmp_v_addr += - (config->TxCfg[i].FifoLen * (sizeof(TxD_t)) * - config->MaxTxDs); + for(j=0; jpdev, + PAGE_SIZE, &tmp_p); + if(!tmp_v) { + DBG_PRINT(ERR_DBG,"Malloc failed for TxDL\n"); + return -ENOMEM; + } + memset(tmp_v, 0, PAGE_SIZE); + while (k < lst_per_page) { + int l = (j * lst_per_page)+k; + if(l == config->TxCfg[i].FifoLen) + goto end_txd_alloc; + nic->list_info[i][l].list_virt_addr = + tmp_v + (k * lst_size); + nic->list_info[i][l].list_phy_addr = + tmp_p + (k * lst_size); + k++; + } + } } + end_txd_alloc: /* Allocation and initialization of RXDs in Rings */ size = 0; @@ -345,11 +415,15 @@ config->RxCfg[i].NumRxd / (MAX_RXDS_PER_BLOCK + 1); /* Allocating all the Rx blocks */ for (j = 0; j < blk_cnt; j++) { +#ifndef CONFIG_2BUFF_MODE size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t)); +#else + size = SIZE_OF_BLOCK; +#endif tmp_v_addr = pci_alloc_consistent(nic->pdev, size, &tmp_p_addr); if (tmp_v_addr == NULL) { - /* In case of failure, freeSharedMem() + /* In case of failure, free_shared_mem() * is called, which should free any * memory that was alloced till the * failure happened. @@ -377,8 +451,10 @@ pre_rxd_blk->reserved_1 = END_OF_BLOCK; /* last RxD * marker. */ +#ifndef CONFIG_2BUFF_MODE pre_rxd_blk->reserved_2_pNext_RxD_block = (unsigned long) tmp_v_addr_next; +#endif pre_rxd_blk->pNext_RxD_Blk_physical = (u64) tmp_p_addr_next; } @@ -390,7 +466,7 @@ (nic->pdev, size, &mac_control->stats_mem_phy); if (!mac_control->stats_mem) { - /* In case of failure, freeSharedMem() is called, which + /* In case of failure, free_shared_mem() is called, which * should free any memory that was alloced till the * failure happened. */ @@ -408,22 +484,21 @@ return SUCCESS; } -/* - * Input Arguments: - * Device peivate variable. - * Return Value: - * NONE - * Description: - * This function is to free all memory locations allocated by - * the initSharedMem() function and return it to the kernel. +/** + * free_shared_mem - Free the allocated Memory + * @nic: Device private variable. + * Description: This function is to free all memory locations allocated by + * the init_shared_mem() function and return it to the kernel. */ -static void freeSharedMem(struct s2io_nic *nic) + +static void free_shared_mem(struct s2io_nic *nic) { int i, j, blk_cnt, size; void *tmp_v_addr; dma_addr_t tmp_p_addr; mac_info_t *mac_control; struct config_param *config; + int lst_size, lst_per_page; if (!nic) @@ -432,14 +507,29 @@ mac_control = &nic->mac_control; config = &nic->config; - if (mac_control->txd_list_mem) { - pci_free_consistent(nic->pdev, - mac_control->txd_list_mem_sz, - mac_control->txd_list_mem, - mac_control->txd_list_mem_phy); + lst_size = (sizeof(TxD_t) * config->MaxTxDs); + lst_per_page = PAGE_SIZE / lst_size; + + for(i=0; iTxFIFONum; i++) { + int tmp = config->TxCfg[i].FifoLen / lst_per_page; + int tmp1 = config->TxCfg[i].FifoLen % lst_per_page; + int page_num = tmp1?(tmp+1) : tmp; + for(j=0; jlist_info[i][mem_blks].list_virt_addr) + break; + pci_free_consistent(nic->pdev, PAGE_SIZE, + nic->list_info[i][mem_blks].list_virt_addr, + nic->list_info[i][mem_blks].list_phy_addr); + } + kfree(nic->list_info[i]); } +#ifndef CONFIG_2BUFF_MODE size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t)); +#else + size = SIZE_OF_BLOCK; +#endif for (i = 0; i < config->RxRingNum; i++) { blk_cnt = nic->block_count[i]; for (j = 0; j < blk_cnt; j++) { @@ -460,16 +550,16 @@ } } -/* - * Input Arguments: - * device peivate variable - * Return Value: - * SUCCESS on success and '-1' on failure (endian settings incorrect). - * Description: - * The function sequentially configures every block +/** + * init_nic - Initialization of hardware + * @nic: device peivate variable + * Description: The function sequentially configures every block * of the H/W from their reset values. + * Returns: SUCCESS on success and + * '-1' on failure (endian settings incorrect). */ -static int initNic(struct s2io_nic *nic) + +static int init_nic(struct s2io_nic *nic) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; struct net_device *dev = nic->dev; @@ -559,10 +649,13 @@ schedule_timeout(HZ / 2); /* Enable Receiving broadcasts */ + add = (void *) &bar0->mac_cfg; val64 = readq(&bar0->mac_cfg); val64 |= MAC_RMAC_BCAST_ENABLE; writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); - writeq(val64, &bar0->mac_cfg); + writel((u32) val64, add); + writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); + writel((u32) (val64 >> 32), (add + 4)); /* Read registers in all blocks */ val64 = readq(&bar0->mac_int_mask); @@ -760,13 +853,15 @@ /* Enable statistics */ writeq(mac_control->stats_mem_phy, &bar0->stat_addr); - val64 = SET_UPDT_PERIOD(8) | STAT_CFG_STAT_RO | STAT_CFG_STAT_EN; + val64 = SET_UPDT_PERIOD(Stats_refresh_time) | + STAT_CFG_STAT_RO | STAT_CFG_STAT_EN; writeq(val64, &bar0->stat_cfg); /* Initializing the sampling rate for the device to calculate the * bandwidth utilization. */ - val64 = MAC_TX_LINK_UTIL_VAL(0x5) | MAC_RX_LINK_UTIL_VAL(0x5); + val64 = MAC_TX_LINK_UTIL_VAL(tmac_util_period) | + MAC_RX_LINK_UTIL_VAL(rmac_util_period); writeq(val64, &bar0->mac_link_util); @@ -774,14 +869,18 @@ * Scheme. */ /* TTI Initialization */ - val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0xFFF) | - TTI_DATA1_MEM_TX_URNG_A(0xA) | TTI_DATA1_MEM_TX_URNG_B(0x10) | - TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN; + val64 = TTI_DATA1_MEM_TX_TIMER_VAL(tx_timer_val) | + TTI_DATA1_MEM_TX_URNG_A(tx_urange_a) | + TTI_DATA1_MEM_TX_URNG_B(tx_urange_b) | + TTI_DATA1_MEM_TX_URNG_C(tx_urange_c); + if (tx_utilz_periodic) + val64 |= TTI_DATA1_MEM_TX_TIMER_AC_EN; writeq(val64, &bar0->tti_data1_mem); - val64 = - TTI_DATA2_MEM_TX_UFC_A(0x10) | TTI_DATA2_MEM_TX_UFC_B(0x20) | - TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80); + val64 = TTI_DATA2_MEM_TX_UFC_A(tx_ufc_a) | + TTI_DATA2_MEM_TX_UFC_B(tx_ufc_b) | + TTI_DATA2_MEM_TX_UFC_C(tx_ufc_c) | + TTI_DATA2_MEM_TX_UFC_D(tx_ufc_d); writeq(val64, &bar0->tti_data2_mem); val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; @@ -809,13 +908,19 @@ } /* RTI Initialization */ - val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF) | - RTI_DATA1_MEM_RX_URNG_A(0xA) | RTI_DATA1_MEM_RX_URNG_B(0x10) | - RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; + val64 = RTI_DATA1_MEM_RX_TIMER_VAL(rx_timer_val) | + RTI_DATA1_MEM_RX_URNG_A(rx_urange_a) | + RTI_DATA1_MEM_RX_URNG_B(rx_urange_b) | + RTI_DATA1_MEM_RX_URNG_C(rx_urange_c); + if (rx_utilz_periodic) + val64 |= RTI_DATA1_MEM_RX_TIMER_AC_EN; + writeq(val64, &bar0->rti_data1_mem); - val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | RTI_DATA2_MEM_RX_UFC_B(0x2) | - RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); + val64 = RTI_DATA2_MEM_RX_UFC_A(rx_ufc_a) | + RTI_DATA2_MEM_RX_UFC_B(rx_ufc_b) | + RTI_DATA2_MEM_RX_UFC_C(rx_ufc_c) | + RTI_DATA2_MEM_RX_UFC_D(rx_ufc_d); writeq(val64, &bar0->rti_data2_mem); val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD; @@ -858,22 +963,57 @@ writel((u32) (val64 >> 32), (add + 4)); val64 = readq(&bar0->mac_cfg); + /*Set the time value to be inserted in the pause frame generated by xena */ + val64 = readq(&bar0->rmac_pause_cfg); + val64 &= ~(RMAC_PAUSE_HG_PTIME(0xffff)); + val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time); + writeq(val64, &bar0->rmac_pause_cfg); + + /* Set the Threshold Limit for Generating the pause frame + * If the amount of data in any Queue exceeds ratio of + * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256 + * pause frame is generated + */ + val64 = 0; + for (i = 0; i < 4; i++) { + val64 |= + (((u64) 0xFF00 | nic->mac_control. + mc_pause_threshold_q0q3) + << (i * 2 * 8)); + } + writeq(val64, &bar0->mc_pause_thresh_q0q3); + + val64 = 0; + for (i = 0; i < 4; i++) { + val64 |= + (((u64) 0xFF00 | nic->mac_control. + mc_pause_threshold_q4q7) + << (i * 2 * 8)); + } + writeq(val64, &bar0->mc_pause_thresh_q4q7); + + /* TxDMA will stop Read request if the number of read split has exceeded + * the limit pointed by shared_splits + */ + val64 = readq(&bar0->pic_control); + val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); + writeq(val64, &bar0->pic_control); + return SUCCESS; } -/* - * Input Arguments: - * device private variable, - * A mask indicating which Intr block must be modified and, - * A flag indicating whether to enable or disable the Intrs. - * Return Value: - * NONE. - * Description: - * This function will either disable or enable the interrupts +/** + * en_dis_able_nicintrs - Enable or Disable the interrupts + * @nic: device private variable, + * @mask: A mask indicating which Intr block must be modified and, + * @flag: A flag indicating whether to enable or disable the Intrs. + * Description: This function will either disable or enable the interrupts * depending on the flag argument. The mask argument can be used to * enable/disable any Intr block. + * Return Value: NONE. */ -static void en_dis_able_NicIntrs(struct s2io_nic *nic, u16 mask, int flag) + +static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; register u64 val64 = 0, temp64 = 0; @@ -913,15 +1053,20 @@ temp64 = readq(&bar0->general_int_mask); temp64 &= ~((u64) val64); writeq(temp64, &bar0->general_int_mask); - /* Disable all interrupts other than PFC interrupt in - * DMA level. + /* Keep all interrupts other than PFC interrupt + * and PCC interrupt disabled in DMA level. */ - val64 = DISABLE_ALL_INTRS & (~TXDMA_PFC_INT_M); + 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 */ @@ -1075,17 +1220,19 @@ } } -/* - * Input Arguments: - * val64 - Value read from adapter status register. - * flag - indicates if the adapter enable bit was ever written once before. - * Return Value: - * void. - * Description: - * Returns whether the H/W is ready to go or not. Depending on whether - * adapter enable bit was written or not the comparison differs and the - * calling function passes the input argument flag to indicate this. +/** + * 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 + * indicate this. + * Return: 1 If xena is quiescence + * 0 If Xena is not quiescence */ + static int verify_xena_quiescence(u64 val64, int flag) { int ret = 0; @@ -1122,11 +1269,15 @@ return ret; } -/* +/** + * fix_mac_address - Fix for Mac addr problem on Alpha platforms + * @sp: Pointer to device specifc structure + * Description : * New procedure to clear mac address reading problems on Alpha platforms * */ -void FixMacAddress(nic_t * sp) + +void fix_mac_address(nic_t * sp) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; u64 val64; @@ -1138,19 +1289,20 @@ } } -/* - * Input Arguments: - * device private variable. - * Return Value: - * SUCCESS on success and -1 on failure. +/** + * start_nic - Turns the device on + * @nic : device private variable. * Description: - * This function actually turns the device on. Before this - * function is called, all Registers are configured from their reset states + * This function actually turns the device on. Before this function is + * called,all Registers are configured from their reset states * and shared memory is allocated but the NIC is still quiescent. On * calling this function, the device interrupts are cleared and the NIC is * literally switched on by writing into the adapter control register. + * Return Value: + * SUCCESS on success and -1 on failure. */ -static int startNic(struct s2io_nic *nic) + +static int start_nic(struct s2io_nic *nic) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; struct net_device *dev = nic->dev; @@ -1169,10 +1321,21 @@ &bar0->prc_rxd0_n[i]); val64 = readq(&bar0->prc_ctrl_n[i]); +#ifndef CONFIG_2BUFF_MODE val64 |= PRC_CTRL_RC_ENABLED; +#else + val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3; +#endif writeq(val64, &bar0->prc_ctrl_n[i]); } +#ifdef CONFIG_2BUFF_MODE + /* Enabling 2 buffer mode by writing into Rx_pa_cfg reg. */ + val64 = readq(&bar0->rx_pa_cfg); + val64 |= RX_PA_CFG_IGNORE_L2_ERR; + writeq(val64, &bar0->rx_pa_cfg); +#endif + /* Enabling MC-RLDRAM. After enabling the device, we timeout * for around 100ms, which is approximately the time required * for the device to be ready for operation. @@ -1211,7 +1374,7 @@ /* Enable select interrupts */ interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | RX_MAC_INTR; - en_dis_able_NicIntrs(nic, interruptible, ENABLE_INTRS); + en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); /* With some switches, link might be already up at this point. * Because of this weird behavior, when we enable laser, @@ -1250,23 +1413,19 @@ return SUCCESS; } -/* - * Input Arguments: - * nic - device private variable. - * Return Value: - * void. +/** + * Free_tx_buffers - Free all queued Tx buffers + * @nic : device private variable. * Description: - * Free all queued Tx buffers. - */ -void freeTxBuffers(struct s2io_nic *nic) + * Free all queued Tx buffers. + * Return Value: void +*/ + +void free_tx_buffers(struct s2io_nic *nic) { - struct net_device *dev = nic->dev; struct sk_buff *skb; TxD_t *txdp; int i, j; -#if DEBUG_ON - int cnt = 0; -#endif mac_info_t *mac_control; struct config_param *config; @@ -1275,47 +1434,34 @@ for (i = 0; i < config->TxFIFONum; i++) { for (j = 0; j < config->TxCfg[i].FifoLen - 1; j++) { - txdp = mac_control->txdl_start[i] + - (config->MaxTxDs * j); - - if (!(txdp->Control_1 & TXD_LIST_OWN_XENA)) { - /* If owned by host, ignore */ - continue; - } + txdp = (TxD_t *)nic->list_info[i][j]. + list_virt_addr; skb = (struct sk_buff *) ((unsigned long) txdp-> Host_Control); if (skb == NULL) { - DBG_PRINT(ERR_DBG, "%s: NULL skb ", - dev->name); - DBG_PRINT(ERR_DBG, "in Tx Int\n"); - return; + memset(txdp, 0, sizeof(TxD_t)); + continue; } -#if DEBUG_ON - cnt++; -#endif dev_kfree_skb(skb); memset(txdp, 0, sizeof(TxD_t)); } -#if DEBUG_ON - DBG_PRINT(INTR_DBG, - "%s:forcibly freeing %d skbs on FIFO%d\n", - dev->name, cnt, i); -#endif + mac_control->tx_curr_get_info[i].offset = 0; + mac_control->tx_curr_put_info[i].offset = 0; } } -/* - * Input Arguments: - * nic - device private variable. - * Return Value: +/** + * stop_nic - To stop the nic + * @nic ; device private variable. + * Description: + * This function does exactly the opposite of what the start_nic() + * function does. This function is called to stop the device. + * Return Value: * void. - * Description: - * This function does exactly the opposite of what the startNic() - * function does. This function is called to stop - * the device. */ -static void stopNic(struct s2io_nic *nic) + +static void stop_nic(struct s2io_nic *nic) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; register u64 val64 = 0; @@ -1329,7 +1475,7 @@ /* Disable all interrupts */ interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | RX_MAC_INTR; - en_dis_able_NicIntrs(nic, interruptible, DISABLE_INTRS); + en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); /* Disable PRCs */ for (i = 0; i < config->RxRingNum; i++) { @@ -1339,11 +1485,10 @@ } } -/* - * Input Arguments: - * device private variable - * Return Value: - * SUCCESS on success or an appropriate -ve value on failure. +/** + * fill_rx_buffers - Allocates the Rx side skbs + * @nic: device private variable + * @ring_no: ring number * Description: * The function allocates Rx side skbs and puts the physical * address of these buffers into the RxD buffer pointers, so that the NIC @@ -1354,9 +1499,13 @@ * 3. Five buffer modes. * Each mode defines how many fragments the received frame will be split * up into by the NIC. The frame is split into L3 header, L4 Header, - * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself - * is split into 3 fragments. As of now only single buffer mode is supported. + * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself + * is split into 3 fragments. As of now only single buffer mode is + * supported. + * Return Value: + * SUCCESS on success or an appropriate -ve value on failure. */ + int fill_rx_buffers(struct s2io_nic *nic, int ring_no) { struct net_device *dev = nic->dev; @@ -1369,6 +1518,13 @@ atomic_read(&nic->rx_bufs_left[ring_no]); mac_info_t *mac_control; struct config_param *config; +#ifdef CONFIG_2BUFF_MODE + RxD_t *rxdpnext; + int nextblk; + u64 tmp; + buffAdd_t *ba; + dma_addr_t rxdpphys; +#endif mac_control = &nic->mac_control; config = &nic->config; @@ -1390,8 +1546,13 @@ block_index; off = mac_control->rx_curr_put_info[ring_no].offset; off1 = mac_control->rx_curr_get_info[ring_no].offset; +#ifndef CONFIG_2BUFF_MODE offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off; offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1; +#else + offset = block_no * (MAX_RXDS_PER_BLOCK) + off; + offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1; +#endif rxdp = nic->rx_blocks[ring_no][block_no]. block_virt_addr + off; @@ -1400,7 +1561,7 @@ DBG_PRINT(INTR_DBG, " info equated\n"); goto end; } - +#ifndef CONFIG_2BUFF_MODE if (rxdp->Control_1 == END_OF_BLOCK) { mac_control->rx_curr_put_info[ring_no]. block_index++; @@ -1418,19 +1579,70 @@ DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", dev->name, rxdp); } +#else + if (rxdp->Host_Control == END_OF_BLOCK) { + mac_control->rx_curr_put_info[ring_no]. + block_index++; + mac_control->rx_curr_put_info[ring_no]. + block_index %= nic->block_count[ring_no]; + block_no = mac_control->rx_curr_put_info + [ring_no].block_index; + off = 0; + DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n", + dev->name, block_no, + (unsigned long long) rxdp->Control_1); + mac_control->rx_curr_put_info[ring_no].offset = + off; + rxdp = nic->rx_blocks[ring_no][block_no]. + block_virt_addr; + } +#endif +#ifndef CONFIG_2BUFF_MODE if (rxdp->Control_1 & RXD_OWN_XENA) { +#else + if (rxdp->Control_2 & BIT(0)) { +#endif mac_control->rx_curr_put_info[ring_no]. offset = off; goto end; } +#ifdef CONFIG_2BUFF_MODE + /* RxDs Spanning chachelines will be replenished only + * if the succeeding RxD is also owned by Host. It + * will always be the ((8*i)+3) and ((8*i)+6) + * descriptors for the 48 byte descriptor. The offending + * decsriptor is of-course the 3rd descriptor. + */ + rxdpphys = nic->rx_blocks[ring_no][block_no]. + block_dma_addr + (off * sizeof(RxD_t)); + if (((u64) (rxdpphys)) % 128 > 80) { + rxdpnext = nic->rx_blocks[ring_no][block_no]. + block_virt_addr + (off + 1); + if (rxdpnext->Host_Control == END_OF_BLOCK) { + nextblk = (block_no + 1) % + (nic->block_count[ring_no]); + rxdpnext = nic->rx_blocks[ring_no] + [nextblk].block_virt_addr; + } + if (rxdpnext->Control_2 & BIT(0)) + goto end; + } +#endif +#ifndef CONFIG_2BUFF_MODE skb = dev_alloc_skb(size + HEADER_ALIGN_LAYER_3); +#else + skb = + dev_alloc_skb(dev->mtu + ALIGN_SIZE + + /*BUF0_LEN + */ 22); +#endif if (!skb) { DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); return -ENOMEM; } +#ifndef CONFIG_2BUFF_MODE skb_reserve(skb, HEADER_ALIGN_LAYER_3); memset(rxdp, 0, sizeof(RxD_t)); rxdp->Buffer0_ptr = pci_map_single @@ -1442,6 +1654,52 @@ off++; off %= (MAX_RXDS_PER_BLOCK + 1); mac_control->rx_curr_put_info[ring_no].offset = off; +#else + ba = &nic->ba[block_no][off]; + tmp = (u64) skb->data; + tmp += ALIGN_SIZE; + tmp &= ~ALIGN_SIZE; + skb->data = (void *) tmp; + + ba->ba_0_org = (void *) + kmalloc(BUF0_LEN + ALIGN_SIZE, GFP_ATOMIC); + if (!ba->ba_0_org) + return -ENOMEM; + tmp = (u64) ba->ba_0_org; + tmp += ALIGN_SIZE; + tmp &= ~((u64) ALIGN_SIZE); + ba->ba_0 = (void *) tmp; + + ba->ba_1_org = (void *) + kmalloc(BUF1_LEN + ALIGN_SIZE, GFP_ATOMIC); + if (!ba->ba_1_org) + return -ENOMEM; + tmp = (u64) ba->ba_1_org; + tmp += ALIGN_SIZE; + tmp &= ~((u64) ALIGN_SIZE); + ba->ba_1 = (void *) tmp; + + memset(rxdp, 0, sizeof(RxD_t)); + + rxdp->Buffer2_ptr = pci_map_single + (nic->pdev, skb->data, dev->mtu + 22, + PCI_DMA_FROMDEVICE); + rxdp->Buffer0_ptr = + pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, + PCI_DMA_FROMDEVICE); + rxdp->Buffer1_ptr = + pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, + PCI_DMA_FROMDEVICE); + + rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 22); + rxdp->Control_2 |= SET_BUFFER0_SIZE(BUF0_LEN); + rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */ + rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */ + rxdp->Host_Control = (u64) ((unsigned long) (skb)); + rxdp->Control_1 |= RXD_OWN_XENA; + off++; + mac_control->rx_curr_put_info[ring_no].offset = off; +#endif atomic_inc(&nic->rx_bufs_left[ring_no]); alloc_tab++; } @@ -1450,15 +1708,16 @@ return SUCCESS; } -/* - * Input Arguments: - * device private variable. - * Return Value: - * NONE. +/** + * free_rx_buffers - Frees all Rx buffers + * @sp: device private variable. * Description: * This function will free all Rx buffers allocated by host. + * Return Value: + * NONE. */ -static void freeRxBuffers(struct s2io_nic *sp) + +static void free_rx_buffers(struct s2io_nic *sp) { struct net_device *dev = sp->dev; int i, j, blk = 0, off, buf_cnt = 0; @@ -1466,6 +1725,9 @@ struct sk_buff *skb; mac_info_t *mac_control; struct config_param *config; +#ifdef CONFIG_2BUFF_MODE + buffAdd_t *ba; +#endif mac_control = &sp->mac_control; config = &sp->config; @@ -1475,6 +1737,7 @@ off = j % (MAX_RXDS_PER_BLOCK + 1); rxdp = sp->rx_blocks[i][blk].block_virt_addr + off; +#ifndef CONFIG_2BUFF_MODE if (rxdp->Control_1 == END_OF_BLOCK) { rxdp = (RxD_t *) ((unsigned long) rxdp-> @@ -1482,11 +1745,23 @@ j++; blk++; } +#else + if (rxdp->Host_Control == END_OF_BLOCK) { + blk++; + continue; + } +#endif + + if (!(rxdp->Control_1 & RXD_OWN_XENA)) { + memset(rxdp, 0, sizeof(RxD_t)); + continue; + } skb = (struct sk_buff *) ((unsigned long) rxdp-> Host_Control); if (skb) { +#ifndef CONFIG_2BUFF_MODE pci_unmap_single(sp->pdev, (dma_addr_t) rxdp->Buffer0_ptr, dev->mtu + @@ -1494,6 +1769,23 @@ + HEADER_802_2_SIZE + HEADER_SNAP_SIZE, PCI_DMA_FROMDEVICE); +#else + ba = &sp->ba[blk][off]; + pci_unmap_single(sp->pdev, (dma_addr_t) + rxdp->Buffer0_ptr, + BUF0_LEN, + PCI_DMA_FROMDEVICE); + pci_unmap_single(sp->pdev, (dma_addr_t) + rxdp->Buffer1_ptr, + BUF1_LEN, + PCI_DMA_FROMDEVICE); + pci_unmap_single(sp->pdev, (dma_addr_t) + rxdp->Buffer2_ptr, + dev->mtu + 22, + PCI_DMA_FROMDEVICE); + kfree(ba->ba_0_org); + kfree(ba->ba_1_org); +#endif dev_kfree_skb(skb); atomic_dec(&sp->rx_bufs_left[i]); buf_cnt++; @@ -1510,18 +1802,19 @@ } } -/* - * Input Argument: - * dev - pointer to the device structure. - * budget - The number of packets that were budgeted to be processed during - * one pass through the 'Poll" function. - * Return value: - * 0 on success and 1 if there are No Rx packets to be processed. - * Description: - * Comes into picture only if NAPI support has been incorporated. It does - * the same thing that rxIntrHandler does, but not in a interrupt context - * also It will process only a given number of packets. +/** + * s2io_poll - Rx interrupt handler for NAPI support + * @dev : pointer to the device structure. + * @budget : The number of packets that were budgeted to be processed + * during one pass through the 'Poll" function. + * Description: + * Comes into picture only if NAPI support has been incorporated. It does + * the same thing that rx_intr_handler does, but not in a interrupt context + * also It will process only a given number of packets. + * Return value: + * 0 on success and 1 if there are No Rx packets to be processed. */ + #ifdef CONFIG_S2IO_NAPI static int s2io_poll(struct net_device *dev, int *budget) { @@ -1531,11 +1824,16 @@ register u64 val64 = 0; rx_curr_get_info_t offset_info; int i, block_no; +#ifndef CONFIG_2BUFF_MODE u16 val16, cksum; +#endif struct sk_buff *skb; RxD_t *rxdp; mac_info_t *mac_control; struct config_param *config; +#ifdef CONFIG_2BUFF_MODE + buffAdd_t *ba; +#endif mac_control = &nic->mac_control; config = &nic->config; @@ -1554,6 +1852,7 @@ block_no = offset_info.block_index; rxdp = nic->rx_blocks[i][block_no].block_virt_addr + offset_info.offset; +#ifndef CONFIG_2BUFF_MODE while (!(rxdp->Control_1 & RXD_OWN_XENA)) { if (rxdp->Control_1 == END_OF_BLOCK) { rxdp = @@ -1589,7 +1888,7 @@ HEADER_802_2_SIZE + HEADER_SNAP_SIZE, PCI_DMA_FROMDEVICE); - rxOsmHandler(nic, val16, rxdp, i); + rx_osm_handler(nic, val16, rxdp, i); pkt_cnt++; offset_info.offset++; offset_info.offset %= (MAX_RXDS_PER_BLOCK + 1); @@ -1598,7 +1897,64 @@ offset_info.offset; mac_control->rx_curr_get_info[i].offset = offset_info.offset; + if ((indicate_max_pkts) + && (pkt_cnt > indicate_max_pkts)) + break; + } +#else + while ((!(rxdp->Control_1 & RXD_OWN_XENA)) && + !(rxdp->Control_2 & BIT(0))) { + skb = (struct sk_buff *) ((unsigned long) + rxdp->Host_Control); + if (skb == NULL) { + DBG_PRINT(ERR_DBG, "%s: The skb is ", + dev->name); + DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); + return; + } + + pci_unmap_single(nic->pdev, (dma_addr_t) + rxdp->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single(nic->pdev, (dma_addr_t) + rxdp->Buffer1_ptr, + BUF1_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single(nic->pdev, (dma_addr_t) + rxdp->Buffer2_ptr, + dev->mtu + 22, + PCI_DMA_FROMDEVICE); + ba = &nic->ba[block_no][offset_info.offset]; + + rx_osm_handler(nic, rxdp, i, ba); + + offset_info.offset++; + mac_control->rx_curr_get_info[i].offset = + offset_info.offset; + rxdp = + nic->rx_blocks[i][block_no].block_virt_addr + + offset_info.offset; + + if (offset_info.offset && + (!(offset_info.offset % MAX_RXDS_PER_BLOCK))) { + offset_info.offset = 0; + mac_control->rx_curr_get_info[i]. + offset = offset_info.offset; + block_no++; + block_no %= nic->block_count[i]; + mac_control->rx_curr_get_info[i]. + block_index = block_no; + rxdp = + nic->rx_blocks[i][block_no]. + block_virt_addr; + } + pkt_cnt++; + if ((indicate_max_pkts) && + (pkt_cnt > indicate_max_pkts)) + break; } +#endif + if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) + break; } if (!pkt_cnt) pkt_cnt = 1; @@ -1611,7 +1967,7 @@ netif_rx_complete(dev); /* Re enable the Rx interrupts. */ - en_dis_able_NicIntrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); + en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); return 0; no_rx: @@ -1622,37 +1978,40 @@ return 1; } #else -/* - * Input Arguments: - * device private variable. - * Return Value: - * NONE. +/** + * rx_intr_handler - Rx interrupt handler + * @nic: device private variable. * Description: - * If the interrupt is because of a received frame or if the - * receive ring contains fresh as yet un-processed frames, this function is + * If the interrupt is because of a received frame or if the + * receive ring contains fresh as yet un-processed frames,this function is * called. It picks out the RxD at which place the last Rx processing had * stopped and sends the skb to the OSM's Rx handler and then increments * the offset. + * Return Value: + * NONE. */ -static void rxIntrHandler(struct s2io_nic *nic) + +static void rx_intr_handler(struct s2io_nic *nic) { struct net_device *dev = (struct net_device *) nic->dev; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; rx_curr_get_info_t offset_info; RxD_t *rxdp; struct sk_buff *skb; +#ifndef CONFIG_2BUFF_MODE u16 val16, cksum; +#endif register u64 val64 = 0; - int i, block_no; + int i, block_no, pkt_cnt = 0; mac_info_t *mac_control; struct config_param *config; +#ifdef CONFIG_2BUFF_MODE + buffAdd_t *ba; +#endif mac_control = &nic->mac_control; config = &nic->config; -#if DEBUG_ON - nic->rxint_cnt++; -#endif /* rx_traffic_int reg is an R1 register, hence we read and write back * the samevalue in the register to clear it. @@ -1665,6 +2024,7 @@ block_no = offset_info.block_index; rxdp = nic->rx_blocks[i][block_no].block_virt_addr + offset_info.offset; +#ifndef CONFIG_2BUFF_MODE while (!(rxdp->Control_1 & RXD_OWN_XENA)) { if (rxdp->Control_1 == END_OF_BLOCK) { rxdp = (RxD_t *) ((unsigned long) @@ -1698,7 +2058,7 @@ HEADER_802_2_SIZE + HEADER_SNAP_SIZE, PCI_DMA_FROMDEVICE); - rxOsmHandler(nic, val16, rxdp, i); + rx_osm_handler(nic, val16, rxdp, i); offset_info.offset++; offset_info.offset %= (MAX_RXDS_PER_BLOCK + 1); rxdp = @@ -1706,27 +2066,85 @@ offset_info.offset; mac_control->rx_curr_get_info[i].offset = offset_info.offset; + pkt_cnt++; + if ((indicate_max_pkts) + && (pkt_cnt > indicate_max_pkts)) + break; + } +#else + while ((!(rxdp->Control_1 & RXD_OWN_XENA)) && + !(rxdp->Control_2 & BIT(0))) { + skb = (struct sk_buff *) ((unsigned long) + rxdp->Host_Control); + if (skb == NULL) { + DBG_PRINT(ERR_DBG, "%s: The skb is ", + dev->name); + DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); + return; + } + + pci_unmap_single(nic->pdev, (dma_addr_t) + rxdp->Buffer0_ptr, + BUF0_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single(nic->pdev, (dma_addr_t) + rxdp->Buffer1_ptr, + BUF1_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single(nic->pdev, (dma_addr_t) + rxdp->Buffer2_ptr, + dev->mtu + 22, + PCI_DMA_FROMDEVICE); + ba = &nic->ba[block_no][offset_info.offset]; + + rx_osm_handler(nic, rxdp, i, ba); + + offset_info.offset++; + mac_control->rx_curr_get_info[i].offset = + offset_info.offset; + rxdp = + nic->rx_blocks[i][block_no].block_virt_addr + + offset_info.offset; + + if (offset_info.offset && + (!(offset_info.offset % MAX_RXDS_PER_BLOCK))) { + offset_info.offset = 0; + mac_control->rx_curr_get_info[i]. + offset = offset_info.offset; + block_no++; + block_no %= nic->block_count[i]; + mac_control->rx_curr_get_info[i]. + block_index = block_no; + rxdp = + nic->rx_blocks[i][block_no]. + block_virt_addr; + } + pkt_cnt++; + if ((indicate_max_pkts) + && (pkt_cnt > indicate_max_pkts)) + break; } +#endif + if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) + break; } } #endif - -/* - * Input Arguments: - * device private variable - * Return Value: - * NONE +/** + * tx_intr_handler - Transmit interrupt handler + * @nic : device private variable * Description: * If an interrupt was raised to indicate DMA complete of the - * Tx packet, this function is called. It identifies the last TxD whose buffer - * was freed and frees all skbs whose data have already DMA'ed into the NICs - * internal memory. + * Tx packet, this function is called. It identifies the last TxD + * whose buffer was freed and frees all skbs whose data have already + * DMA'ed into the NICs internal memory. + * Return Value: + * NONE */ -static void txIntrHandler(struct s2io_nic *nic) + +static void tx_intr_handler(struct s2io_nic *nic) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; struct net_device *dev = (struct net_device *) nic->dev; - tx_curr_get_info_t offset_info, offset_info1; + tx_curr_get_info_t get_info, put_info; struct sk_buff *skb; TxD_t *txdlp; register u64 val64 = 0; @@ -1734,10 +2152,6 @@ u16 j, frg_cnt; mac_info_t *mac_control; struct config_param *config; -#if DEBUG_ON - int cnt = 0; - nic->txint_cnt++; -#endif mac_control = &nic->mac_control; config = &nic->config; @@ -1749,12 +2163,12 @@ writeq(val64, &bar0->tx_traffic_int); for (i = 0; i < config->TxFIFONum; i++) { - offset_info = mac_control->tx_curr_get_info[i]; - offset_info1 = mac_control->tx_curr_put_info[i]; - txdlp = mac_control->txdl_start[i] + - (config->MaxTxDs * offset_info.offset); + get_info = mac_control->tx_curr_get_info[i]; + put_info = mac_control->tx_curr_put_info[i]; + txdlp = (TxD_t *)nic->list_info[i][get_info.offset]. + list_virt_addr; while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && - (offset_info.offset != offset_info1.offset) && + (get_info.offset != put_info.offset) && (txdlp->Host_Control)) { /* Check for TxD errors */ if (txdlp->Control_1 & TXD_T_CODE) { @@ -1802,23 +2216,15 @@ /* Updating the statistics block */ nic->stats.tx_packets++; nic->stats.tx_bytes += skb->len; -#if DEBUG_ON - nic->txpkt_bytes += skb->len; - cnt++; -#endif dev_kfree_skb_irq(skb); - offset_info.offset++; - offset_info.offset %= offset_info.fifo_len + 1; - txdlp = mac_control->txdl_start[i] + - (config->MaxTxDs * offset_info.offset); + get_info.offset++; + get_info.offset %= get_info.fifo_len + 1; + txdlp = (TxD_t *)nic->list_info[i] + [get_info.offset].list_virt_addr; mac_control->tx_curr_get_info[i].offset = - offset_info.offset; + get_info.offset; } -#if DEBUG_ON - DBG_PRINT(INTR_DBG, "%s: freed %d Tx Pkts\n", dev->name, - cnt); -#endif } spin_lock(&nic->tx_lock); @@ -1827,55 +2233,70 @@ spin_unlock(&nic->tx_lock); } -/* - * Input Arguments: - * device private variable - * Return Value: +/** + * alarm_intr_handler - Alarm Interrrupt handler + * @nic: device private variable + * Description: If the interrupt was neither because of Rx packet or Tx + * complete, this function is called. If the interrupt was to indicate + * a loss of link, the OSM link status handler is invoked for any other + * alarm interrupt the block that raised the interrupt is displayed + * and a H/W reset is issued. + * Return Value: * NONE - * Description: - * If the interrupt was neither because of Rx packet or Tx - * complete, this function is called. If the interrupt was to indicate a loss - * of link, the OSM link status handler is invoked for any other alarm - * interrupt the block that raised the interrupt is displayed and a H/W reset - * is issued. - */ -static void alarmIntrHandler(struct s2io_nic *nic) +*/ + +static void alarm_intr_handler(struct s2io_nic *nic) { struct net_device *dev = (struct net_device *) nic->dev; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; register u64 val64 = 0, err_reg = 0; - /* Handling link status change error Intr */ err_reg = readq(&bar0->mac_rmac_err_reg); + writeq(err_reg, &bar0->mac_rmac_err_reg); if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { schedule_work(&nic->set_link_task); } - /* Handling SERR errors by stopping device Xmit queue and forcing - * a H/W reset. - */ + /* In case of a serious error, the device will be Reset. */ val64 = readq(&bar0->serr_source); if (val64 & SERR_SOURCE_ANY) { DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); DBG_PRINT(ERR_DBG, "serious error!!\n"); - netif_stop_queue(dev); + schedule_work(&nic->rst_timer_task); } + + /* + * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC + * Error occurs, the adapter will be recycled by disabling the + * adapter enable bit and enabling it again after the device + * becomes Quiescent. + */ + val64 = readq(&bar0->pcc_err_reg); + writeq(val64, &bar0->pcc_err_reg); + if (val64 & PCC_FB_ECC_DB_ERR) { + u64 ac = readq(&bar0->adapter_control); + ac &= ~(ADAPTER_CNTL_EN); + writeq(ac, &bar0->adapter_control); + ac = readq(&bar0->adapter_control); + schedule_work(&nic->set_link_task); + } + /* Other type of interrupts are not being handled now, TODO*/ } -/* - * Input Argument: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. +/** + * waitFor Cmd Complete - waits for a command to complete. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * Description: Function that waits for a command to Write into RMAC + * ADDR DATA registers to be completed and returns either success or + * error depending on whether the command was complete or not. * Return value: * SUCCESS on success and FAILURE on failure. - * Description: - * Function that waits for a command to Write into RMAC ADDR DATA registers - * to be completed and returns either success or error depending on whether - * the command was complete or not. */ -int waitForCmdComplete(nic_t * sp) + +int wait_for_cmd_complete(nic_t * sp) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; int ret = FAILURE, cnt = 0; @@ -1900,17 +2321,16 @@ return ret; } -/* - * Input Argument: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. +/** + * s2io_reset - Resets the card. + * @sp : private member of the device structure. + * Description: Function to Reset the card. This function then also + * restores the previously saved PCI configuration space registers as + * the card reset also resets the Configration space. * Return value: - * void. - * Description: - * Function to Reset the card. This function then also restores the previously - * saved PCI configuration space registers as the card reset also resets the - * Configration space. + * void. */ + void s2io_reset(nic_t * sp) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; @@ -1954,16 +2374,16 @@ sp->device_enabled_once = FALSE; } -/* - * Input Argument: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. +/** + * s2io_set_swapper - to set the swapper controle on the card + * @sp : private member of the device structure, + * pointer to the s2io_nic structure. + * Description: Function to set the swapper control on the card + * correctly depending on the 'endianness' of the system. * Return value: * SUCCESS on success and FAILURE on failure. - * Description: - * Function to set the swapper control on the card correctly depending on the - * 'endianness' of the system. */ + int s2io_set_swapper(nic_t * sp) { struct net_device *dev = sp->dev; @@ -2041,17 +2461,18 @@ * Functions defined below concern the OS part of the driver * * ********************************************************* */ -/* - * Input Argument: - * dev - pointer to the device structure. - * Return value: - * '0' on success and an appropriate (-)ve integer as defined in errno.h - * file on failure. +/** + * s2io-open - open entry point of the driver + * @dev : pointer to the device structure. * Description: * This function is the open entry point of the driver. It mainly calls a * function to allocate Rx buffers and inserts them into the buffer * descriptors and then enables the Rx part of the NIC. - */ + * Return value: + * '0' on success and an appropriate (-)ve integer as defined in errno.h + * file on failure. +*/ + int s2io_open(struct net_device *dev) { nic_t *sp = dev->priv; @@ -2065,7 +2486,7 @@ sp->last_link_state = LINK_DOWN; /* Initialize the H/W I/O registers */ - if (initNic(sp) != 0) { + if (init_nic(sp) != 0) { DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", dev->name); return -ENODEV; @@ -2102,7 +2523,7 @@ dev->name); s2io_reset(sp); free_irq(dev->irq, dev); - freeRxBuffers(sp); + free_rx_buffers(sp); return -ENOMEM; } DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i, @@ -2113,12 +2534,12 @@ tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev); /* Enable Rx Traffic and interrupts on the NIC */ - if (startNic(sp)) { + if (start_nic(sp)) { DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name); tasklet_kill(&sp->task); s2io_reset(sp); free_irq(dev->irq, dev); - freeRxBuffers(sp); + free_rx_buffers(sp); return -ENODEV; } @@ -2128,32 +2549,32 @@ return 0; } -/* - * Input Argument/s: - * dev - device pointer. - * Return value: - * '0' on success and an appropriate (-)ve integer as defined in errno.h - * file on failure. +/** + * s2io_close -close entry point of the driver + * @dev : device pointer. * Description: * This is the stop entry point of the driver. It needs to undo exactly - * whatever was done by the open entry point, thus it's usually referred to - * as the close function. Among other things this function mainly stops the + * whatever was done by the open entry point,thus it's usually referred to + * as the close function.Among other things this function mainly stops the * Rx side of the NIC and frees all the Rx buffers in the Rx rings. - */ + * Return value: + * '0' on success and an appropriate (-)ve integer as defined in errno.h + * file on failure. +*/ + int s2io_close(struct net_device *dev) { nic_t *sp = dev->priv; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; register u64 val64 = 0; u16 cnt = 0; + unsigned long flags; - spin_lock(&sp->isr_lock); + spin_lock_irqsave(&sp->tx_lock, flags); netif_stop_queue(dev); /* disable Tx and Rx traffic on the NIC */ - stopNic(sp); - - spin_unlock(&sp->isr_lock); + stop_nic(sp); /* If the device tasklet is running, wait till its done before killing it */ while (atomic_read(&(sp->tasklet_status))) { @@ -2162,6 +2583,17 @@ } tasklet_kill(&sp->task); + /* Free the Registered IRQ */ + free_irq(dev->irq, dev); + + /* Flush all scheduled tasks */ + if(sp->task_flag == 1) { + DBG_PRINT(INFO_DBG,"%s: Calling close from a task\n", + dev->name); + } else { + flush_scheduled_work(); + } + /* Check if the device is Quiescent and then Reset the NIC */ do { val64 = readq(&bar0->adapter_status); @@ -2182,36 +2614,36 @@ } while (1); s2io_reset(sp); -/* Free the Registered IRQ */ - free_irq(dev->irq, dev); - /* Free all Tx Buffers waiting for transmission */ - freeTxBuffers(sp); + free_tx_buffers(sp); /* Free all Rx buffers allocated by host */ - freeRxBuffers(sp); + free_rx_buffers(sp); sp->device_close_flag = TRUE; /* Device is shut down. */ + spin_unlock_irqrestore(&sp->tx_lock, flags); +// sp->cls_flg = 1; return 0; } -/* - * Input Argument/s: - * skb - the socket buffer containing the Tx data. - * dev - device pointer. - * Return value: - * '0' on success & 1 on failure. - * NOTE: when device cant queue the pkt, just the trans_start variable will - * not be upadted. - * Description: +/** + * s2io_xmit - Tx entry point of te driver + * @skb : the socket buffer containing the Tx data. + * @dev : device pointer. + * Description : * This function is the Tx entry point of the driver. S2IO NIC supports * certain protocol assist features on Tx side, namely CSO, S/G, LSO. - */ + * NOTE: when device cant queue the pkt,just the trans_start variable will + * not be upadted. + * Return value: + * '0' on success & 1 on failure. +*/ + int s2io_xmit(struct sk_buff *skb, struct net_device *dev) { nic_t *sp = dev->priv; - u16 off, txd_len, frg_cnt, frg_len, i, queue, off1, queue_len; + u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; register u64 val64; TxD_t *txdp; TxFIFO_element_t *tx_fifo; @@ -2221,6 +2653,7 @@ #endif mac_info_t *mac_control; struct config_param *config; + XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; mac_control = &sp->mac_control; config = &sp->config; @@ -2228,6 +2661,14 @@ DBG_PRINT(TX_DBG, "%s: In S2IO Tx routine\n", dev->name); spin_lock_irqsave(&sp->tx_lock, flags); + if(netif_queue_stopped(dev)) { + DBG_PRINT(ERR_DBG,"%s:s2io_xmit: Tx Queue stopped\n", + dev->name); + dev_kfree_skb(skb); + spin_unlock_irqrestore(&sp->tx_lock, flags); + return 0; + } + queue = 0; /* Multi FIFO Tx is disabled for now. */ if (!queue && tx_prio) { @@ -2236,21 +2677,20 @@ } - off = (u16) mac_control->tx_curr_put_info[queue].offset; - off1 = (u16) mac_control->tx_curr_get_info[queue].offset; - txd_len = mac_control->txdl_len; - txdp = mac_control->txdl_start[queue] + (config->MaxTxDs * off); + put_off = (u16) mac_control->tx_curr_put_info[queue].offset; + get_off = (u16) mac_control->tx_curr_get_info[queue].offset; + txdp = (TxD_t *)sp->list_info[queue][put_off].list_virt_addr; queue_len = mac_control->tx_curr_put_info[queue].fifo_len + 1; /* Avoid "put" pointer going beyond "get" pointer */ - if (txdp->Host_Control || (((off + 1) % queue_len) == off1)) { + if (txdp->Host_Control || + (((put_off + 1) % queue_len) == get_off)) { DBG_PRINT(ERR_DBG, "Error in xmit, No free TXDs.\n"); netif_stop_queue(dev); dev_kfree_skb(skb); spin_unlock_irqrestore(&sp->tx_lock, flags); return 0; } - #ifdef NETIF_F_TSO mss = skb_shinfo(skb)->tso_size; if (mss) { @@ -2289,8 +2729,7 @@ txdp->Control_1 |= TXD_GATHER_CODE_LAST; tx_fifo = mac_control->tx_FIFO_start[queue]; - val64 = (mac_control->txdl_start_phy[queue] + - (sizeof(TxD_t) * txd_len * off)); + val64 = sp->list_info[queue][put_off].list_phy_addr; writeq(val64, &tx_fifo->TxDL_Pointer); val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | @@ -2301,15 +2740,18 @@ #endif writeq(val64, &tx_fifo->List_Control); - off++; - off %= mac_control->tx_curr_put_info[queue].fifo_len + 1; - mac_control->tx_curr_put_info[queue].offset = off; + /* Perform a PCI read to flush previous writes */ + val64 = readq(&bar0->general_int_status); + + put_off++; + put_off %= mac_control->tx_curr_put_info[queue].fifo_len + 1; + mac_control->tx_curr_put_info[queue].offset = put_off; /* Avoid "put" pointer going beyond "get" pointer */ - if (((off + 1) % queue_len) == off1) { - DBG_PRINT(TX_DBG, - "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", - off, off1); + if (((put_off + 1) % queue_len) == get_off) { + DBG_PRINT(TX_DBG, + "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", + put_off, get_off); netif_stop_queue(dev); } @@ -2319,26 +2761,26 @@ return 0; } -/* - * Input Argument/s: - * irq: the irq of the device. - * dev_id: a void pointer to the dev structure of the NIC. - * ptregs: pointer to the registers pushed on the stack. +/** + * s2io_isr - ISR handler of the device . + * @irq: the irq of the device. + * @dev_id: a void pointer to the dev structure of the NIC. + * @ptregs: pointer to the registers pushed on the stack. + * Description: This function is the ISR handler of the device. It + * identifies the reason for the interrupt and calls the relevant + * service routines. As a contongency measure, this ISR allocates the + * recv buffers, if their numbers are below the panic value which is + * presently set to 25% of the original number of rcv buffers allocated. * Return value: * void. - * Description: - * This function is the ISR handler of the device. It identifies the reason - * for the interrupt and calls the relevant service routines. - * As a contongency measure, this ISR allocates the recv buffers, if their - * numbers are below the panic value which is presently set to 25% of the - * original number of rcv buffers allocated. - */ +*/ 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 *bar0 = (XENA_dev_config_t *) sp->bar0; + int i, ret; u64 reason = 0, general_mask = 0; mac_info_t *mac_control; struct config_param *config; @@ -2346,8 +2788,6 @@ mac_control = &sp->mac_control; config = &sp->config; - spin_lock(&sp->isr_lock); - /* Identify the cause for interrupt and call the appropriate * interrupt handler. Causes for the interrupt could be; * 1. Rx of packet. @@ -2359,42 +2799,38 @@ if (!reason) { /* The interrupt was not raised by Xena. */ - spin_unlock(&sp->isr_lock); return IRQ_NONE; } /* Mask the interrupts on the NIC */ general_mask = readq(&bar0->general_int_mask); writeq(0xFFFFFFFFFFFFFFFFULL, &bar0->general_int_mask); -#if DEBUG_ON - sp->int_cnt++; -#endif /* If Intr is because of Tx Traffic */ if (reason & GEN_INTR_TXTRAFFIC) { - txIntrHandler(sp); + tx_intr_handler(sp); } /* If Intr is because of an error */ if (reason & (GEN_ERROR_INTR)) - alarmIntrHandler(sp); + alarm_intr_handler(sp); #ifdef CONFIG_S2IO_NAPI if (reason & GEN_INTR_RXTRAFFIC) { if (netif_rx_schedule_prep(dev)) { - en_dis_able_NicIntrs(sp, RX_TRAFFIC_INTR, - DISABLE_INTRS); - /* We retake the snap shot of the general interrupt - * register. + en_dis_able_nic_intrs(sp, RX_TRAFFIC_INTR, + DISABLE_INTRS); + /* We reflect the disable Rx Intr into the + * general interrupt mask register's snap shot. */ - general_mask = readq(&bar0->general_int_mask); + general_mask |= BIT(40); __netif_rx_schedule(dev); } } #else /* If Intr is because of Rx Traffic */ if (reason & GEN_INTR_RXTRAFFIC) { - rxIntrHandler(sp); + rx_intr_handler(sp); } #endif @@ -2402,26 +2838,21 @@ * buffers from the interrupt handler itself, else schedule a tasklet to * reallocate the buffers. */ -#if 1 - { - int i; - for (i = 0; i < config->RxRingNum; i++) { int rxb_size = atomic_read(&sp->rx_bufs_left[i]); int level = rx_buffer_level(sp, rxb_size, i); if ((level == PANIC) && (!TASKLET_IN_USE)) { - int ret; - - DBG_PRINT(ERR_DBG, "%s: Rx BD hit ", dev->name); - DBG_PRINT(ERR_DBG, "PANIC levels\n"); + DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name); + DBG_PRINT(INTR_DBG, "PANIC levels\n"); if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); DBG_PRINT(ERR_DBG, " in ISR!!\n"); writeq(general_mask, &bar0->general_int_mask); - spin_unlock(&sp->isr_lock); + clear_bit(0, + (unsigned long *) (&sp->tasklet_status)); return IRQ_HANDLED; } clear_bit(0, @@ -2433,27 +2864,25 @@ } - } -#else - tasklet_schedule(&sp->task); -#endif - /* Unmask all the previously enabled interrupts on the NIC */ writeq(general_mask, &bar0->general_int_mask); - spin_unlock(&sp->isr_lock); + /* Perform a PCI read to flush previous writes */ + reason = readq(&bar0->general_int_mask); + return IRQ_HANDLED; } -/* - * Input Argument/s: - * dev - pointer to the device structure. - * Return value: - * pointer to the updated net_device_stats structure. +/** + * s2io_get_stats - Updates the device statistics structure. + * @dev : pointer to the device structure. * Description: * This function updates the device statistics structure in the s2io_nic * structure and returns a pointer to the same. + * Return value: + * pointer to the updated net_device_stats structure. */ + struct net_device_stats *s2io_get_stats(struct net_device *dev) { nic_t *sp = dev->priv; @@ -2472,18 +2901,19 @@ return (&sp->stats); } -/* - * Input Argument/s: - * dev - pointer to the device structure - * Return value: - * void. +/** + * s2io_set_multicast - entry point for multicast address enable/disable. + * @dev : pointer to the device structure * Description: * This function is a driver entry point which gets called by the kernel * whenever multicast addresses must be enabled/disabled. This also gets * called to set/reset promiscuous mode. Depending on the deivce flag, we * determine, if multicast address must be enabled or if promiscuous mode * is to be disabled etc. + * Return value: + * void. */ + static void s2io_set_multicast(struct net_device *dev) { int i, j, prev_cnt; @@ -2506,7 +2936,7 @@ RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ - waitForCmdComplete(sp); + wait_for_cmd_complete(sp); sp->m_cast_flg = 1; sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; @@ -2519,7 +2949,7 @@ RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ - waitForCmdComplete(sp); + wait_for_cmd_complete(sp); sp->m_cast_flg = 0; sp->all_multi_pos = 0; @@ -2582,7 +3012,7 @@ writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ - if (waitForCmdComplete(sp)) { + if (wait_for_cmd_complete(sp)) { DBG_PRINT(ERR_DBG, "%s: Adding ", dev->name); DBG_PRINT(ERR_DBG, "Multicasts failed\n"); @@ -2609,7 +3039,7 @@ writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ - if (waitForCmdComplete(sp)) { + if (wait_for_cmd_complete(sp)) { DBG_PRINT(ERR_DBG, "%s: Adding ", dev->name); DBG_PRINT(ERR_DBG, "Multicasts failed\n"); @@ -2619,17 +3049,16 @@ } } -/* - * Input Argument/s: - * dev - pointer to the device structure. - * new_mac - a uchar pointer to the new mac address which is to be set. - * Return value: - * SUCCESS on success and an appropriate (-)ve integer as defined in errno.h - * file on failure. - * Description: - * This procedure will program the Xframe to receive frames with new - * Mac Address +/** + * s2io_set_mac_address - Programs the Xframe mac address + * @dev : pointer to the device structure. + * @new_mac : a uchar pointer to the new mac address which is to be set. + * Description : This procedure will program the Xframe to receive + * frames with new Mac Address + * Return value: SUCCESS on success and an appropriate (-)ve integer + * as defined in errno.h file on failure. */ + int s2io_set_mac_addr(struct net_device *dev, u8 * addr) { nic_t *sp = dev->priv; @@ -2655,7 +3084,7 @@ RMAC_ADDR_CMD_MEM_OFFSET(0); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ - if (waitForCmdComplete(sp)) { + if (wait_for_cmd_complete(sp)) { DBG_PRINT(ERR_DBG, "%s: set_mac_addr failed\n", dev->name); return FAILURE; } @@ -2663,18 +3092,18 @@ return SUCCESS; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * info - pointer to the structure with parameters given by ethtool to set - * link information. - * Return value: - * 0 on success. +/** + * s2io_ethtool_sset - Sets different link parameters. + * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. + * @info: pointer to the structure with parameters given by ethtool to set + * link information. * Description: - * The function sets different link parameters provided by the user onto - * the NIC. - */ + * The function sets different link parameters provided by the user onto + * the NIC. + * Return value: + * 0 on success. +*/ + static int s2io_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info) { @@ -2690,17 +3119,18 @@ return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * info - pointer to the structure with parameters given by ethtool to return - * link information. - * Return value: - * void +/** + * s2io_ethtol_gset - Return link specific information. + * @sp : private member of the device structure, pointer to the + * s2io_nic structure. + * @info : pointer to the structure with parameters given by ethtool + * to return link information. * Description: - * Returns link specefic information like speed, duplex etc.. to ethtool. + * Returns link specefic information like speed, duplex etc.. to ethtool. + * Return value : + * void. */ + int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) { nic_t *sp = dev->priv; @@ -2721,17 +3151,18 @@ return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * info - pointer to the structure with parameters given by ethtool to return - * driver information. +/** + * s2io_ethtool_gdrvinfo - Returns driver specific information. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @info : pointer to the structure with parameters given by ethtool to + * return driver information. + * Description: + * Returns driver specefic information like name, version etc.. to ethtool. * Return value: * void - * Description: - * Returns driver specefic information like name, version etc.. to ethtool. */ + static void s2io_ethtool_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -2748,19 +3179,20 @@ info->n_stats = S2IO_STAT_LEN; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * regs - pointer to the structure with parameters given by ethtool for +/** + * s2io_ethtool_gregs - dumps the entire space of Xfame into te buffer. + * @sp: private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @regs : pointer to the structure with parameters given by ethtool for * dumping the registers. - * reg_space - The input argumnet into which all the registers are dumped. - * Return value: - * void - * Description: - * Dumps the entire register space of xFrame NIC into the user given buffer - * area. - */ + * @reg_space: The input argumnet into which all the registers are dumped. + * Description: + * Dumps the entire register space of xFrame NIC into the user given + * buffer area. + * Return value : + * void . +*/ + static void s2io_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *space) { @@ -2778,17 +3210,15 @@ } } -/* - * Input Argument/s: - * data - address of the private member of the device structure, which +/** + * s2io_phy_id - timer function that alternates adapter LED. + * @data : address of the private member of the device structure, which * is a pointer to the s2io_nic structure, provided as an u32. - * Return value: - * void - * Description: - * This is actually the timer function that alternates the adapter LED bit - * of the adapter control bit to set/reset every time on invocation. - * The timer is set for 1/2 a second, hence tha NIC blinks once every second. - */ + * Description: This is actually the timer function that alternates the + * adapter LED bit of the adapter control bit to set/reset every time on + * invocation. The timer is set for 1/2 a second, hence tha NIC blinks + * once every second. +*/ static void s2io_phy_id(unsigned long data) { nic_t *sp = (nic_t *) data; @@ -2810,28 +3240,30 @@ mod_timer(&sp->id_timer, jiffies + HZ / 2); } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * id - pointer to the structure with identification parameters given by - * ethtool. +/** + * s2io_ethtool_idnic - To physically ientify the nic on the system. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @id : pointer to the structure with identification parameters given by + * ethtool. + * Description: Used to physically identify the NIC on the system. + * The Link LED will blink for a time specified by the user for + * identification. + * NOTE: The Link has to be Up to be able to blink the LED. Hence + * identification is possible only if it's link is up. * Return value: - * int , returns '0' on success - * Description: - * Used to physically identify the NIC on the system. The Link LED will blink - * for a time specified by the user for identification. - * NOTE: The Link has to be Up to be able to blink the LED. Hence - * identification is possible only if it's link is up. + * int , returns '0' on success */ + static int s2io_ethtool_idnic(struct net_device *dev, u32 data) { - u64 val64 = 0; + u64 val64 = 0, last_gpio_ctrl_val; nic_t *sp = dev->priv; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; u16 subid; subid = sp->pdev->subsystem_device; + last_gpio_ctrl_val = readq(&bar0->gpio_control); if ((subid & 0xFF) < 0x07) { val64 = readq(&bar0->adapter_control); if (!(val64 & ADAPTER_CNTL_EN)) { @@ -2853,19 +3285,23 @@ schedule_timeout(MAX_SCHEDULE_TIMEOUT); del_timer_sync(&sp->id_timer); + if(CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) { + writeq(last_gpio_ctrl_val, &bar0->gpio_control); + last_gpio_ctrl_val = readq(&bar0->gpio_control); + } + return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * ep - pointer to the structure with pause parameters given by ethtool. +/** + * s2io_ethtool_getpause_data -Pause frame frame generation and reception. + * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. + * @ep : pointer to the structure with pause parameters given by ethtool. + * Description: + * Returns the Pause frame generation and reception capability of the NIC. * Return value: * void - * Description: - * Returns the Pause frame generation and reception capability of the NIC. - */ +*/ static void s2io_ethtool_getpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { @@ -2881,17 +3317,18 @@ ep->autoneg = FALSE; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * ep - pointer to the structure with pause parameters given by ethtool. +/** + * s2io_ethtool-setpause_data - set/reset pause frame generation. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @ep : pointer to the structure with pause parameters given by ethtool. + * Description: + * It can be used to set or reset Pause frame generation or reception + * support of the NIC. * Return value: * int, returns '0' on Success - * Description: - * It can be used to set or reset Pause frame generation or reception support - * of the NIC. - */ +*/ + int s2io_ethtool_setpause_data(struct net_device *dev, struct ethtool_pauseparam *ep) { @@ -2912,21 +3349,22 @@ return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * off - offset at which the data must be written - * Return value: - * -1 on failure and the value read from the Eeprom if successful. +/** + * read_eeprom - reads 4 bytes of data from user given offset. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @off : offset at which the data must be written * Description: - * Will read 4 bytes of data from the user given offset and return the - * read data. + * Will read 4 bytes of data from the user given offset and return the + * read data. * NOTE: Will allow to read only part of the EEPROM visible through the - * I2C bus. - */ + * I2C bus. + * Return value: + * -1 on failure and the value read from the Eeprom if successful. +*/ + #define S2IO_DEV_ID 5 -static u32 readEeprom(nic_t * sp, int off) +static u32 read_eeprom(nic_t * sp, int off) { u32 data = -1, exit_cnt = 0; u64 val64; @@ -2951,21 +3389,22 @@ return data; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * off - offset at which the data must be written - * data - The data that is to be written - * cnt - Number of bytes of the data that are actually to be written into +/** + * write_eeprom - actually writes the relevant part of the data value. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @off : offset at which the data must be written + * @data : The data that is to be written + * @cnt : Number of bytes of the data that are actually to be written into * the Eeprom. (max of 3) - * Return value: - * '0' on success, -1 on failure. * Description: * Actually writes the relevant part of the data value into the Eeprom * through the I2C bus. - */ -static int writeEeprom(nic_t * sp, int off, u32 data, int cnt) + * Return value: + * '0' on success, -1 on failure. +*/ + +static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) { int exit_cnt = 0, ret = -1; u64 val64; @@ -2991,39 +3430,19 @@ return ret; } -/* - * A helper function used to invert the 4 byte u32 data field - * byte by byte. This will be used by the Read Eeprom function - * for display purposes. - */ -u32 inv(u32 data) -{ - static u32 ret = 0; - - if (data) { - u8 c = data; - ret = ((ret << 8) + c); - data >>= 8; - inv(data); - } - - return ret; -} - -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * eeprom - pointer to the user level structure provided by ethtool, - * containing all relevant information. - * data_buf - user defined value to be written into Eeprom. - * Return value: +/** + * s2io_ethtool_geeprom - reads the value stored in the Eeprom. + * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. + * @eeprom : pointer to the user level structure provided by ethtool, + * containing all relevant information. + * @data_buf : user defined value to be written into Eeprom. + * Description: Reads the values stored in the Eeprom at given offset + * for a given length. Stores these values int the input argument data + * buffer 'data_buf' and returns these to the caller (ethtool.) + * Return value: * int '0' on success - * Description: - * Reads the values stored in the Eeprom at given offset for a given length. - * Stores these values int the input argument data buffer 'data_buf' and - * returns these to the caller (ethtool.) - */ +*/ + int s2io_ethtool_geeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * data_buf) { @@ -3036,30 +3455,31 @@ eeprom->len = XENA_EEPROM_SPACE - eeprom->offset; for (i = 0; i < eeprom->len; i += 4) { - data = readEeprom(sp, eeprom->offset + i); + data = read_eeprom(sp, eeprom->offset + i); if (data < 0) { DBG_PRINT(ERR_DBG, "Read of EEPROM failed\n"); return -EFAULT; } - valid = inv(data); + valid = INV(data); memcpy((data_buf + i), &valid, 4); } return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * eeprom - pointer to the user level structure provided by ethtool, - * containing all relevant information. - * data_buf - user defined value to be written into Eeprom. - * Return value: - * '0' on success, -EFAULT on failure. - * Description: +/** + * s2io_ethtool_seeprom - tries to write the user provided value in Eeprom + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @eeprom : pointer to the user level structure provided by ethtool, + * containing all relevant information. + * @data_buf ; user defined value to be written into Eeprom. + * Description: * Tries to write the user provided value in the Eeprom, at the offset * given by the user. - */ + * Return value: + * '0' on success, -EFAULT on failure. +*/ + static int s2io_ethtool_seeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * data_buf) @@ -3083,7 +3503,7 @@ } else valid = data; - if (writeEeprom(sp, (eeprom->offset + cnt), valid, 0)) { + if (write_eeprom(sp, (eeprom->offset + cnt), valid, 0)) { DBG_PRINT(ERR_DBG, "ETHTOOL_WRITE_EEPROM Err: Cannot "); DBG_PRINT(ERR_DBG, @@ -3097,19 +3517,20 @@ return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * data - variable that returns the result of each of the test conducted by - * the driver. - * Return value: - * '0' on success. +/** + * s2io_register_test - reads and writes into all clock domains. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @data : variable that returns the result of each of the test conducted b + * by the driver. * Description: - * Read and write into all clock domains. The NIC has 3 clock domains, - * see that registers in all the three regions are accessible. - */ -static int s2io_registerTest(nic_t * sp, uint64_t * data) + * Read and write into all clock domains. The NIC has 3 clock domains, + * see that registers in all the three regions are accessible. + * Return value: + * '0' on success. +*/ + +static int s2io_register_test(nic_t * sp, uint64_t * data) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; u64 val64 = 0; @@ -3159,88 +3580,90 @@ return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * data - variable that returns the result of each of the test conducted by - * the driver. - * Return value: - * '0' on success. +/** + * s2io_eeprom_test - to verify that EEprom in the xena can be programmed. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @data:variable that returns the result of each of the test conducted by + * the driver. * Description: - * Verify that EEPROM in the xena can be programmed using I2C_CONTROL - * register. - */ -static int s2io_eepromTest(nic_t * sp, uint64_t * data) + * Verify that EEPROM in the xena can be programmed using I2C_CONTROL + * register. + * Return value: + * '0' on success. +*/ + +static int s2io_eeprom_test(nic_t * sp, uint64_t * data) { int fail = 0, ret_data; /* Test Write Error at offset 0 */ - if (!writeEeprom(sp, 0, 0, 3)) + if (!write_eeprom(sp, 0, 0, 3)) fail = 1; /* Test Write at offset 4f0 */ - if (writeEeprom(sp, 0x4F0, 0x01234567, 3)) + if (write_eeprom(sp, 0x4F0, 0x01234567, 3)) fail = 1; - if ((ret_data = readEeprom(sp, 0x4f0)) < 0) + if ((ret_data = read_eeprom(sp, 0x4f0)) < 0) fail = 1; if (ret_data != 0x01234567) fail = 1; /* Reset the EEPROM data go FFFF */ - writeEeprom(sp, 0x4F0, 0xFFFFFFFF, 3); + write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3); /* Test Write Request Error at offset 0x7c */ - if (!writeEeprom(sp, 0x07C, 0, 3)) + if (!write_eeprom(sp, 0x07C, 0, 3)) fail = 1; /* Test Write Request at offset 0x7fc */ - if (writeEeprom(sp, 0x7FC, 0x01234567, 3)) + if (write_eeprom(sp, 0x7FC, 0x01234567, 3)) fail = 1; - if ((ret_data = readEeprom(sp, 0x7FC)) < 0) + if ((ret_data = read_eeprom(sp, 0x7FC)) < 0) fail = 1; if (ret_data != 0x01234567) fail = 1; /* Reset the EEPROM data go FFFF */ - writeEeprom(sp, 0x7FC, 0xFFFFFFFF, 3); + write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3); /* Test Write Error at offset 0x80 */ - if (!writeEeprom(sp, 0x080, 0, 3)) + if (!write_eeprom(sp, 0x080, 0, 3)) fail = 1; /* Test Write Error at offset 0xfc */ - if (!writeEeprom(sp, 0x0FC, 0, 3)) + if (!write_eeprom(sp, 0x0FC, 0, 3)) fail = 1; /* Test Write Error at offset 0x100 */ - if (!writeEeprom(sp, 0x100, 0, 3)) + if (!write_eeprom(sp, 0x100, 0, 3)) fail = 1; /* Test Write Error at offset 4ec */ - if (!writeEeprom(sp, 0x4EC, 0, 3)) + if (!write_eeprom(sp, 0x4EC, 0, 3)) fail = 1; *data = fail; return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * data - variable that returns the result of each of the test conducted by - * the driver. - * Return value: - * '0' on success and -1 on failure. +/** + * s2io_bist_test - invokes the MemBist test of the card . + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @data:variable that returns the result of each of the test conducted by + * the driver. * Description: - * This invokes the MemBist test of the card. We give around - * 2 secs time for the Test to complete. If it's still not complete - * within this peiod, we consider that the test failed. - */ -static int s2io_bistTest(nic_t * sp, uint64_t * data) + * This invokes the MemBist test of the card. We give around + * 2 secs time for the Test to complete. If it's still not complete + * within this peiod, we consider that the test failed. + * Return value: + * '0' on success and -1 on failure. +*/ + +static int s2io_bist_test(nic_t * sp, uint64_t * data) { u8 bist = 0; int cnt = 0, ret = -1; @@ -3264,19 +3687,20 @@ return ret; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * data - variable that returns the result of each of the test conducted by - * the driver. - * Return value: - * '0' on success. +/** + * s2io-link_test - verifies the link state of the nic + * @sp ; private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @data: variable that returns the result of each of the test conducted by + * the driver. * Description: - * The function verifies the link state of the NIC and updates the input - * argument 'data' appropriately. - */ -static int s2io_linkTest(nic_t * sp, uint64_t * data) + * The function verifies the link state of the NIC and updates the input + * argument 'data' appropriately. + * Return value: + * '0' on success. +*/ + +static int s2io_link_test(nic_t * sp, uint64_t * data) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; u64 val64; @@ -3288,19 +3712,19 @@ return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * data - variable that returns the result of each of the test conducted by - * the driver. - * Return value: - * '0' on success. +/** + * s2io_rldram_test - offline test for access to the RldRam chip on the NIC + * @sp - private member of the device structure, which is a pointer to the * s2io_nic structure. + * @data - variable that returns the result of each of the test + * conducted by the driver. * Description: * This is one of the offline test that tests the read and write * access to the RldRam chip on the NIC. - */ -static int s2io_rldramTest(nic_t * sp, uint64_t * data) + * Return value: + * '0' on success. +*/ + +static int s2io_rldram_test(nic_t * sp, uint64_t * data) { XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; u64 val64; @@ -3395,20 +3819,21 @@ return 0; } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * ethtest - pointer to a ethtool command specific structure that will be - * returned to the user. - * data - variable that returns the result of each of the test conducted by - * the driver. - * Return value: - * SUCCESS on success and an appropriate -1 on failure. +/** + * s2io_ethtool_test - conducts 6 tsets to determine the health of card. + * @sp : private member of the device structure, which is a pointer to the + * s2io_nic structure. + * @ethtest : pointer to a ethtool command specific structure that will be + * returned to the user. + * @data : variable that returns the result of each of the test + * conducted by the driver. * Description: * This function conducts 6 tests ( 4 offline and 2 online) to determine - * the health of the card. - */ + * the health of the card. + * Return value: + * SUCCESS on success and an appropriate -1 on failure. +*/ + static void s2io_ethtool_test(struct net_device *dev, struct ethtool_test *ethtest, uint64_t * data) @@ -3424,22 +3849,22 @@ } else s2io_set_swapper(sp); - if (s2io_registerTest(sp, &data[0])) + if (s2io_register_test(sp, &data[0])) ethtest->flags |= ETH_TEST_FL_FAILED; s2io_reset(sp); s2io_set_swapper(sp); - if (s2io_rldramTest(sp, &data[3])) + if (s2io_rldram_test(sp, &data[3])) ethtest->flags |= ETH_TEST_FL_FAILED; s2io_reset(sp); s2io_set_swapper(sp); - if (s2io_eepromTest(sp, &data[1])) + if (s2io_eeprom_test(sp, &data[1])) ethtest->flags |= ETH_TEST_FL_FAILED; - if (s2io_bistTest(sp, &data[4])) + if (s2io_bist_test(sp, &data[4])) ethtest->flags |= ETH_TEST_FL_FAILED; if (orig_state) @@ -3459,7 +3884,7 @@ data[4] = -1; } - if (s2io_linkTest(sp, &data[2])) + if (s2io_link_test(sp, &data[2])) ethtest->flags |= ETH_TEST_FL_FAILED; data[0] = 0; @@ -3567,6 +3992,17 @@ return (S2IO_STAT_LEN); } +int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) +{ + if (data) + dev->features |= NETIF_F_IP_CSUM; + else + dev->features &= ~NETIF_F_IP_CSUM; + + return 0; +} + + static struct ethtool_ops netdev_ethtool_ops = { .get_settings = s2io_ethtool_gset, .set_settings = s2io_ethtool_sset, @@ -3582,7 +4018,7 @@ .get_rx_csum = s2io_ethtool_get_rx_csum, .set_rx_csum = s2io_ethtool_set_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .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 @@ -3597,36 +4033,37 @@ .get_ethtool_stats = s2io_get_ethtool_stats }; -/* - * Input Argument/s: - * dev - Device pointer. - * ifr - An IOCTL specefic structure, that can contain a pointer to - * a proprietary structure used to pass information to the driver. - * cmd - This is used to distinguish between the different commands that - * can be passed to the IOCTL functions. - * Return value: - * '0' on success and an appropriate (-)ve integer as defined in errno.h - * file on failure. +/** + * s2io_ioctl -Entry point for the Ioctl + * @dev : Device pointer. + * @ifr : An IOCTL specefic structure, that can contain a pointer to + * a proprietary structure used to pass information to the driver. + * @cmd : This is used to distinguish between the different commands that + * can be passed to the IOCTL functions. * Description: * This function has support for ethtool, adding multiple MAC addresses on * the NIC and some DBG commands for the util tool. - */ + * Return value: + * '0' on success and an appropriate (-)ve integer as defined in errno.h + * file on failure. +*/ + int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { return -EOPNOTSUPP; } -/* - * Input Argument/s: - * dev - device pointer. - * new_mtu - the new MTU size for the device. - * Return value: +/** + * s2io_change-mtu - entry point to change MTU size for the device. + * @dev : device pointer. + * @new_mtu : the new MTU size for the device. + * Description: A driver entry point to change MTU size for the device. + * Before changing the MTU the device must be stopped. + * Return value: * '0' on success and an appropriate (-)ve integer as defined in errno.h * file on failure. - * Description: - * A driver entry point to change MTU size for the device. Before changing - * the MTU the device must be stopped. - */ +*/ + int s2io_change_mtu(struct net_device *dev, int new_mtu) { nic_t *sp = dev->priv; @@ -3654,18 +4091,19 @@ return 0; } -/* - * Input Argument/s: - * dev_adr - address of the device structure in dma_addr_t format. - * Return value: - * void. +/** + * s2io_tasklet - Bottom half of the ISR. + * @dev_adr : address of the device structure in dma_addr_t format. * Description: * This is the tasklet or the bottom half of the ISR. This is * an extension of the ISR which is scheduled by the scheduler to be run * when the load on the CPU is low. All low priority tasks of the ISR can * be pushed into the tasklet. For now the tasklet is used only to * replenish the Rx buffers in the Rx buffer descriptors. - */ + * Return value: + * void. +*/ + static void s2io_tasklet(unsigned long dev_addr) { struct net_device *dev = (struct net_device *) dev_addr; @@ -3684,30 +4122,33 @@ DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); DBG_PRINT(ERR_DBG, "memory in tasklet\n"); - return; + break; } else if (ret == -EFILL) { DBG_PRINT(ERR_DBG, "%s: Rx Ring %d is full\n", dev->name, i); - return; + break; } } clear_bit(0, (unsigned long *) (&sp->tasklet_status)); } } - -/* - * Description: - * +/** + * s2io_set_link- Set the LInk status + * @data: long pointer to device private structue + * Description: Sets the link status for the adapter */ + static void s2io_set_link(unsigned long data) { nic_t *nic = (nic_t *) data; struct net_device *dev = nic->dev; XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; - register u64 val64, err_reg; + register u64 val64; + u16 subid; + subid = nic->pdev->subsystem_device; /* Allow a small delay for the NICs self initiated * cleanup to complete. */ @@ -3716,16 +4157,19 @@ val64 = readq(&bar0->adapter_status); if (verify_xena_quiescence(val64, nic->device_enabled_once)) { - /* Acknowledge interrupt and clear the R1 register */ - err_reg = readq(&bar0->mac_rmac_err_reg); - writeq(err_reg, &bar0->mac_rmac_err_reg); - if (LINK_IS_UP(val64)) { val64 = readq(&bar0->adapter_control); val64 |= ADAPTER_CNTL_EN; writeq(val64, &bar0->adapter_control); - val64 |= ADAPTER_LED_ON; - writeq(val64, &bar0->adapter_control); + if(CARDS_WITH_FAULTY_LINK_INDICATORS(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); + } val64 = readq(&bar0->adapter_status); if (!LINK_IS_UP(val64)) { DBG_PRINT(ERR_DBG, "%s:", dev->name); @@ -3739,6 +4183,12 @@ } s2io_link(nic, LINK_UP); } else { + if(CARDS_WITH_FAULTY_LINK_INDICATORS(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. */ @@ -3748,37 +4198,43 @@ } } -/* +/** + * s2io-restart_nic -Resets the NIC. + * @data : long pointer to the device private structure * Description: * This function is scheduled to be run by the s2io_tx_watchdog * function after 0.5 secs to reset the NIC. The idea is to reduce * the run time of the watch dog routine which is run holding a * spin lock. */ + static void s2io_restart_nic(unsigned long data) { struct net_device *dev = (struct net_device *) data; nic_t *sp = dev->priv; + sp->task_flag = 1; s2io_close(dev); + sp->task_flag = 0; sp->device_close_flag = TRUE; s2io_open(dev); DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer.\n", dev->name); } -/* - * Input Argument/s: - * dev - device pointer. - * Return value: - * void +/** + * s2io_tx_watchdog - Watchdog for transmit side. + * @dev : Pointer to net device structure * Description: * This function is triggered if the Tx Queue is stopped * for a pre-defined amount of time when the Interface is still up. * If the Interface is jammed in such a situation, the hardware is * reset (by s2io_close) and restarted again (by s2io_open) to * overcome any problem that might have been caused in the hardware. - */ + * Return value: + * void +*/ + static void s2io_tx_watchdog(struct net_device *dev) { nic_t *sp = dev->priv; @@ -3788,30 +4244,38 @@ } } -/* - * Input Argument/s: - * sp - private member of the device structure, which is a pointer to the - * s2io_nic structure. - * skb - the socket buffer pointer. - * len - length of the packet - * cksum - FCS checksum of the frame. - * ring_no - the ring from which this RxD was extracted. - * Return value: - * SUCCESS on success and -1 on failure. - * Description: - * This function is called by the Tx interrupt serivce routine to perform +/** + * rx_osm_handler - To perform some OS related operations on SKB. + * @sp: private member of the device structure,pointer to s2io_nic structure. + * @skb : the socket buffer pointer. + * @len : length of the packet + * @cksum : FCS checksum of the frame. + * @ring_no : the ring from which this RxD was extracted. + * Description: + * This function is called by the Tx interrupt serivce routine to perform * some OS related operations on the SKB before passing it to the upper * layers. It mainly checks if the checksum is OK, if so adds it to the * SKBs cksum variable, increments the Rx packet count and passes the SKB * to the upper layer. If the checksum is wrong, it increments the Rx * packet error count, frees the SKB and returns error. - */ -static int rxOsmHandler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no) + * Return value: + * SUCCESS on success and -1 on failure. +*/ +#ifndef CONFIG_2BUFF_MODE +static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no) +#else +static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, + buffAdd_t * ba) +#endif { struct net_device *dev = (struct net_device *) sp->dev; struct sk_buff *skb = (struct sk_buff *) ((unsigned long) rxdp->Host_Control); u16 l3_csum, l4_csum; +#ifdef CONFIG_2BUFF_MODE + int buf0_len, buf2_len; + struct ethhdr *eth = (struct ethhdr *) ba->ba_0; +#endif l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1); if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && (sp->rx_csum)) { @@ -3833,9 +4297,36 @@ skb->ip_summed = CHECKSUM_NONE; } + if (rxdp->Control_1 & RXD_T_CODE) { + unsigned long long err = rxdp->Control_1 & RXD_T_CODE; + DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", + dev->name, err); + } +#ifdef CONFIG_2BUFF_MODE + buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); + buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2); +#endif + skb->dev = dev; +#ifndef CONFIG_2BUFF_MODE skb_put(skb, len); skb->protocol = eth_type_trans(skb, dev); +#else + skb_put(skb, buf2_len); + /* Reproducing eth_type_trans functionality and running + * on the ethernet header 'eth' stripped and given to us + * by the hardware in 2Buff mode. + */ + if (*eth->h_dest & 1) { + if (!memcmp(eth->h_dest, dev->broadcast, ETH_ALEN)) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_MULTICAST; + } else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) { + skb->pkt_type = PACKET_OTHERHOST; + } + skb->protocol = eth->h_proto; +#endif #ifdef CONFIG_S2IO_NAPI netif_receive_skb(skb); @@ -3843,21 +4334,26 @@ netif_rx(skb); #endif - dev->last_rx = jiffies; -#if DEBUG_ON - sp->rxpkt_cnt++; +#ifdef CONFIG_2BUFF_MODE + kfree(ba->ba_0_org); + kfree(ba->ba_1_org); #endif + + dev->last_rx = jiffies; sp->rx_pkt_count++; sp->stats.rx_packets++; +#ifndef CONFIG_2BUFF_MODE sp->stats.rx_bytes += len; - sp->rxpkt_bytes += len; +#else + sp->stats.rx_bytes += buf0_len + buf2_len; +#endif atomic_dec(&sp->rx_bufs_left[ring_no]); rxdp->Host_Control = 0; return SUCCESS; } -int check_for_txSpace(nic_t * sp) +int check_for_tx_space(nic_t * sp) { u32 put_off, get_off, queue_len; int ret = TRUE, i; @@ -3876,18 +4372,19 @@ return ret; } -/* -* Input Argument/s: -* sp - private member of the device structure, which is a pointer to the -* s2io_nic structure. -* link - inidicates whether link is UP/DOWN. -* Return value: -* void. +/** +* s2io_link - stops/starts the Tx queue. +* @sp : private member of the device structure, which is a pointer to the +* s2io_nic structure. +* @link : inidicates whether link is UP/DOWN. * Description: -* This function stops/starts the Tx queue depending on whether the link -* status of the NIC is is down or up. This is called by the Alarm interrupt -* handler whenever a link change interrupt comes up. +* This function stops/starts the Tx queue depending on whether the link +* status of the NIC is is down or up. This is called by the Alarm +* interrupt handler whenever a link change interrupt comes up. +* Return value: +* void. */ + void s2io_link(nic_t * sp, int link) { struct net_device *dev = (struct net_device *) sp->dev; @@ -3900,7 +4397,7 @@ } else { DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name); netif_carrier_on(dev); - if (check_for_txSpace(sp) == TRUE) { + if (check_for_tx_space(sp) == TRUE) { /* Don't wake the queue, if we know there * are no free TxDs available. */ @@ -3911,14 +4408,15 @@ sp->last_link_state = link; } -/* -* Input Argument/s: -* pdev - structure containing the PCI related information of the device. -* Return value: -* returns the revision ID of the device. +/** +* get_xena_rev_id - to identify revision ID of xena. +* @pdev : PCI Dev structure * Description: -* Function to identify the Revision ID of xena. +* Function to identify the Revision ID of xena. +* Return value: +* returns the revision ID of the device. */ + int get_xena_rev_id(struct pci_dev *pdev) { u8 id = 0; @@ -3927,21 +4425,22 @@ return id; } -/* -* Input Argument/s: -* sp - private member of the device structure, which is a pointer to the -* s2io_nic structure. -* Return value: -* void +/** +* s2io_init_pci -Initialization of PCI and PCI-X configuration registers . +* @sp : private member of the device structure, which is a pointer to the +* s2io_nic structure. * Description: -* This function initializes a few of the PCI and PCI-X configuration registers -* with recommended values. +* This function initializes a few of the PCI and PCI-X configuration registers +* with recommended values. +* Return value: +* void */ + static void s2io_init_pci(nic_t * sp) { u16 pci_cmd = 0; -/* Enable Data Parity Error Recovery in PCI-X command register. */ + /* Enable Data Parity Error Recovery in PCI-X command register. */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(sp->pcix_cmd)); pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, @@ -3949,13 +4448,13 @@ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(sp->pcix_cmd)); -/* Set the PErr Response bit in PCI command register. */ + /* Set the PErr Response bit in PCI command register. */ pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); pci_write_config_word(sp->pdev, PCI_COMMAND, (pci_cmd | PCI_COMMAND_PARITY)); pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); -/* Set user specified value in Latency Timer */ + /* Set user specified value in Latency Timer */ if (latency_timer) { pci_write_config_byte(sp->pdev, PCI_LATENCY_TIMER, latency_timer); @@ -3963,49 +4462,95 @@ &latency_timer); } -/* Set MMRB count to 4096 in PCI-X Command register. */ + /* Set MMRB count to 4096 in PCI-X Command register. */ + sp->pcix_cmd &= 0xFFF3; pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, - (sp->pcix_cmd | 0x0C)); + (sp->pcix_cmd | (max_read_byte_cnt << 2)) ); pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(sp->pcix_cmd)); -/* Setting Maximum outstanding splits to two for now. */ - sp->pcix_cmd &= 0xFF1F; + /* Setting Maximum outstanding splits based on system type. */ + sp->pcix_cmd &= 0xFF8F; - sp->pcix_cmd |= - XENA_MAX_OUTSTANDING_SPLITS(XENA_TWO_SPLIT_TRANSACTION); + sp->pcix_cmd |= XENA_MAX_OUTSTANDING_SPLITS(max_splits_trans); + pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, + sp->pcix_cmd); + pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, + &(sp->pcix_cmd)); + /* Forcibly disabling relaxed ordering capability of the card. */ + sp->pcix_cmd &= 0xfffd; pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, sp->pcix_cmd); pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(sp->pcix_cmd)); - } MODULE_AUTHOR("Raghavendra Koushik "); MODULE_LICENSE("GPL"); -MODULE_PARM(ring_num, "1-" __MODULE_STRING(1) "i"); -MODULE_PARM(frame_len, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(ring_len, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(fifo_num, "1-" __MODULE_STRING(1) "i"); -MODULE_PARM(fifo_len, "1-" __MODULE_STRING(8) "i"); -MODULE_PARM(rx_prio, "1-" __MODULE_STRING(1) "i"); -MODULE_PARM(tx_prio, "1-" __MODULE_STRING(1) "i"); -MODULE_PARM(latency_timer, "1-" __MODULE_STRING(1) "i"); - -/* -* Input Argument/s: -* pdev - structure containing the PCI related information of the device. -* pre - the List of PCI devices supported by the driver listed in s2io_tbl. -* Return value: -* returns '0' on success and negative on failure. +MODULE_PARM(lso_enable, "i"); +MODULE_PARM(indicate_max_pkts, "i"); +MODULE_PARM(cksum_offload_enable, "i"); +MODULE_PARM(TxFifoNum, "i"); +MODULE_PARM(TxFIFOLen_0, "i"); +MODULE_PARM(TxFIFOLen_1, "i"); +MODULE_PARM(TxFIFOLen_2, "i"); +MODULE_PARM(TxFIFOLen_3, "i"); +MODULE_PARM(TxFIFOLen_4, "i"); +MODULE_PARM(TxFIFOLen_5, "i"); +MODULE_PARM(TxFIFOLen_6, "i"); +MODULE_PARM(TxFIFOLen_7, "i"); +MODULE_PARM(MaxTxDs, "i"); +MODULE_PARM(RxRingNum, "i"); +MODULE_PARM(RxRingSz_0, "i"); +MODULE_PARM(RxRingSz_1, "i"); +MODULE_PARM(RxRingSz_2, "i"); +MODULE_PARM(RxRingSz_3, "i"); +MODULE_PARM(RxRingSz_4, "i"); +MODULE_PARM(RxRingSz_5, "i"); +MODULE_PARM(RxRingSz_6, "i"); +MODULE_PARM(RxRingSz_7, "i"); +MODULE_PARM(Stats_refresh_time, "i"); +MODULE_PARM(rmac_pause_time, "i"); +MODULE_PARM(mc_pause_threshold_q0q3, "i"); +MODULE_PARM(mc_pause_threshold_q4q7, "i"); +MODULE_PARM(shared_splits, "i"); +MODULE_PARM(max_splits_trans, "i"); +MODULE_PARM(tmac_util_period, "i"); +MODULE_PARM(rmac_util_period, "i"); +MODULE_PARM(tx_timer_val, "i"); +MODULE_PARM(tx_utilz_periodic, "i"); +MODULE_PARM(rx_timer_val, "i"); +MODULE_PARM(rx_utilz_periodic, "i"); +MODULE_PARM(tx_urange_a, "i"); +MODULE_PARM(tx_ufc_a, "i"); +MODULE_PARM(tx_urange_b, "i"); +MODULE_PARM(tx_ufc_b, "i"); +MODULE_PARM(tx_urange_c, "i"); +MODULE_PARM(tx_ufc_c, "i"); +MODULE_PARM(tx_ufc_d, "i"); +MODULE_PARM(rx_urange_a, "i"); +MODULE_PARM(rx_ufc_a, "i"); +MODULE_PARM(rx_urange_b, "i"); +MODULE_PARM(rx_ufc_b, "i"); +MODULE_PARM(rx_urange_c, "i"); +MODULE_PARM(rx_ufc_c, "i"); +MODULE_PARM(rx_ufc_d, "i"); +MODULE_PARM(latency_timer, "i"); +MODULE_PARM(max_read_byte_cnt, "i"); +/** +* s2io_init_nic - Initialization of the adapter . +* @pdev : structure containing the PCI related information of the device. +* @pre: List of PCI devices supported by the driver listed in s2io_tbl. * Description: * The function initializes an adapter identified by the pci_dec structure. * All OS related initialization including memory and device structure and * initlaization of the device private variable is done. Also the swapper * control register is initialized to enable read and write into the I/O * registers of the device. -* +* Return value: +* returns '0' on success and negative on failure. */ + static int __devinit s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) { @@ -4031,6 +4576,7 @@ if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) { DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); dma_flag = TRUE; + if (pci_set_consistent_dma_mask (pdev, 0xffffffffffffffffULL)) { DBG_PRINT(ERR_DBG, @@ -4090,69 +4636,64 @@ config = &sp->config; /* Tx side parameters. */ - config->TxFIFONum = fifo_num ? fifo_num : 1; - - if (!fifo_len[0] && (fifo_num > 1)) { - printk(KERN_ERR "Fifo Lens not specified for all FIFOs\n"); - goto init_failed; - } - - if (fifo_len[0]) { - int cnt; - - for (cnt = 0; fifo_len[cnt]; cnt++); - if (fifo_num) { - if (cnt < fifo_num) { - printk(KERN_ERR - "Fifo Lens not specified for "); - printk(KERN_ERR "all FIFOs\n"); - goto init_failed; - } - } - for (cnt = 0; cnt < config->TxFIFONum; cnt++) { - config->TxCfg[cnt].FifoLen = fifo_len[cnt]; - config->TxCfg[cnt].FifoPriority = cnt; - } - } else { - config->TxCfg[0].FifoLen = DEFAULT_FIFO_LEN; - config->TxCfg[0].FifoPriority = 0; - } + config->TxFIFONum = TxFifoNum; + config->TxCfg[0].FifoLen = TxFIFOLen_0; + config->TxCfg[0].FifoPriority = 0; + config->TxCfg[1].FifoLen = TxFIFOLen_1; + config->TxCfg[1].FifoPriority = 1; + config->TxCfg[2].FifoLen = TxFIFOLen_2; + config->TxCfg[2].FifoPriority = 2; + config->TxCfg[3].FifoLen = TxFIFOLen_3; + config->TxCfg[3].FifoPriority = 3; + config->TxCfg[4].FifoLen = TxFIFOLen_4; + config->TxCfg[4].FifoPriority = 4; + config->TxCfg[5].FifoLen = TxFIFOLen_5; + config->TxCfg[5].FifoPriority = 5; + config->TxCfg[6].FifoLen = TxFIFOLen_6; + config->TxCfg[6].FifoPriority = 6; + config->TxCfg[7].FifoLen = TxFIFOLen_7; + config->TxCfg[7].FifoPriority = 7; config->TxIntrType = TXD_INT_TYPE_UTILZ; for (i = 0; i < config->TxFIFONum; i++) { + config->TxCfg[i].fNoSnoop = + (NO_SNOOP_TXD | NO_SNOOP_TXD_BUFFER); if (config->TxCfg[i].FifoLen < 65) { config->TxIntrType = TXD_INT_TYPE_PER_LIST; break; } } - - config->TxCfg[0].fNoSnoop = (NO_SNOOP_TXD | NO_SNOOP_TXD_BUFFER); config->MaxTxDs = MAX_SKB_FRAGS; config->TxFlow = TRUE; +// sp->cls_flg = 0; /* Rx side parameters. */ - config->RxRingNum = ring_num ? ring_num : 1; - - if (ring_len[0]) { - int cnt; - for (cnt = 0; cnt < config->RxRingNum; cnt++) { - config->RxCfg[cnt].NumRxd = ring_len[cnt]; - config->RxCfg[cnt].RingPriority = cnt; - } - } else { - int id; - if ((id = get_xena_rev_id(pdev)) == 1) { - config->RxCfg[0].NumRxd = LARGE_RXD_CNT; - - } else { - config->RxCfg[0].NumRxd = SMALL_RXD_CNT; - } - config->RxCfg[0].RingPriority = 0; + config->RxRingNum = RxRingNum; + config->RxCfg[0].NumRxd = RxRingSz_0 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[0].RingPriority = 0; + config->RxCfg[1].NumRxd = RxRingSz_1 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[1].RingPriority = 1; + config->RxCfg[2].NumRxd = RxRingSz_2 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[2].RingPriority = 2; + config->RxCfg[3].NumRxd = RxRingSz_3 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[3].RingPriority = 3; + config->RxCfg[4].NumRxd = RxRingSz_4 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[4].RingPriority = 4; + config->RxCfg[5].NumRxd = RxRingSz_5 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[5].RingPriority = 5; + config->RxCfg[6].NumRxd = RxRingSz_6 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[6].RingPriority = 6; + config->RxCfg[7].NumRxd = RxRingSz_7 * (MAX_RXDS_PER_BLOCK + 1); + config->RxCfg[7].RingPriority = 7; + + for (i = 0; i < RxRingNum; i++) { + config->RxCfg[i].RingOrg = RING_ORG_BUFF1; + config->RxCfg[i].RxdThresh = DEFAULT_RXD_THRESHOLD; + config->RxCfg[i].fNoSnoop = + (NO_SNOOP_RXD | NO_SNOOP_RXD_BUFFER); + config->RxCfg[i].RxD_BackOff_Interval = TBD; } - config->RxCfg[0].RingOrg = RING_ORG_BUFF1; - config->RxCfg[0].RxdThresh = DEFAULT_RXD_THRESHOLD; - config->RxCfg[0].fNoSnoop = (NO_SNOOP_RXD | NO_SNOOP_RXD_BUFFER); - config->RxCfg[0].RxD_BackOff_Interval = TBD; + config->RxFlow = TRUE; /* Miscellaneous parameters. */ @@ -4162,14 +4703,17 @@ /* Setting Mac Control parameters */ mac_control->txdl_len = MAX_SKB_FRAGS; - mac_control->rmac_pause_time = 0; + mac_control->rmac_pause_time = rmac_pause_time; + mac_control->mc_pause_threshold_q0q3 = mc_pause_threshold_q0q3; + mac_control->mc_pause_threshold_q4q7 = mc_pause_threshold_q4q7; + /* Initialize Ring buffer parameters. */ for (i = 0; i < config->RxRingNum; i++) atomic_set(&sp->rx_bufs_left[i], 0); /* initialize the shared memory used by the NIC and the host */ - if (initSharedMem(sp)) { + if (init_shared_mem(sp)) { DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", dev->name); goto mem_alloc_failed; @@ -4209,21 +4753,19 @@ dev->do_ioctl = &s2io_ioctl; dev->change_mtu = &s2io_change_mtu; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - - /* - * will use eth_mac_addr() for dev->set_mac_address - * mac address will be set every time dev->open() is called - */ #ifdef CONFIG_S2IO_NAPI dev->poll = s2io_poll; dev->weight = 128; /* For now. */ #endif - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + dev->features |= NETIF_F_SG; + if (cksum_offload_enable) + dev->features |= NETIF_F_IP_CSUM; if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; #ifdef NETIF_F_TSO - dev->features |= NETIF_F_TSO; + if (lso_enable) + dev->features |= NETIF_F_TSO; #endif dev->tx_timeout = &s2io_tx_watchdog; @@ -4233,11 +4775,6 @@ INIT_WORK(&sp->set_link_task, (void (*)(void *)) s2io_set_link, sp); - if (register_netdev(dev)) { - DBG_PRINT(ERR_DBG, "Device registration failed\n"); - goto register_failed; - } - pci_save_state(sp->pdev, sp->config_space); /* Setting swapper control on the NIC, for proper reset operation */ @@ -4248,7 +4785,7 @@ } /* Fix for all "FFs" MAC address problems observed on Alpha platforms */ - FixMacAddress(sp); + fix_mac_address(sp); s2io_reset(sp); /* Setting swapper control on the NIC, so the MAC address can be read. @@ -4267,7 +4804,7 @@ val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); writeq(val64, &bar0->rmac_addr_cmd_mem); - waitForCmdComplete(sp); + wait_for_cmd_complete(sp); tmp64 = readq(&bar0->rmac_addr_data0_mem); mac_down = (u32) tmp64; @@ -4300,7 +4837,6 @@ /* Initialize spinlocks */ - spin_lock_init(&sp->isr_lock); spin_lock_init(&sp->tx_lock); /* SXE-002: Configure link and activity LED to init state @@ -4316,6 +4852,13 @@ val64 = readq(&bar0->gpio_control); } + sp->rx_csum = 1; /* Rx chksum verify enabled by default */ + + if (register_netdev(dev)) { + DBG_PRINT(ERR_DBG, "Device registration failed\n"); + goto register_failed; + } + /* Make Link state as off at this point, when the Link change * interrupt comes the state will be automatically changed to * the right state. @@ -4323,20 +4866,16 @@ netif_carrier_off(dev); sp->last_link_state = LINK_DOWN; - sp->rx_csum = 1; /* Rx chksum verify enabled by default */ - return 0; - set_swap_failed: - unregister_netdev(dev); register_failed: + set_swap_failed: iounmap(sp->bar1); bar1_remap_failed: iounmap(sp->bar0); bar0_remap_failed: mem_alloc_failed: - freeSharedMem(sp); - init_failed: + free_shared_mem(sp); pci_disable_device(pdev); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); @@ -4345,16 +4884,15 @@ return -ENODEV; } -/* -* Input Argument/s: -* pdev - structure containing the PCI related information of the device. -* Return value: -* void -* Description: -* This function is called by the Pci subsystem to release a PCI device -* and free up all resource held up by the device. This could be in response -* to a Hot plug event or when the driver is to be removed from memory. +/** +* s2io_rem_nic - Free the PCI device +* @pdev: structure containing the PCI related information of the device. +* Description: This function is called by the Pci subsystem to release a +* PCI device and free up all resource held up by the device. This could +* be in response to a Hot plug event or when the driver is to be removed +* from memory. */ + static void __devexit s2io_rem_nic(struct pci_dev *pdev) { struct net_device *dev = @@ -4365,24 +4903,38 @@ DBG_PRINT(ERR_DBG, "Driver Data is NULL!!\n"); return; } + sp = dev->priv; - freeSharedMem(sp); + unregister_netdev(dev); + + free_shared_mem(sp); iounmap(sp->bar0); iounmap(sp->bar1); pci_disable_device(pdev); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); - unregister_netdev(dev); - free_netdev(dev); } +/** + * s2io_starter - Entry point for the driver + * Description: This function is the entry point for the driver. It verifies + * the module loadable parameters and initializes PCI configuration space. + */ + int __init s2io_starter(void) { + if (verify_load_parm()) + return -ENODEV; return pci_module_init(&s2io_driver); } +/** + * s2io_closer - Cleanup routine for the driver + * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. + */ + void s2io_closer(void) { pci_unregister_driver(&s2io_driver); @@ -4391,3 +4943,201 @@ module_init(s2io_starter); module_exit(s2io_closer); +/** + * verify_load_parm - verifies the module loadable parameters + * Descriptions: Verifies the module loadable paramters and initializes the + * Tx Fifo, Rx Ring and other paramters. + */ + +int verify_load_parm() +{ + int fail = 0; + if (!((lso_enable == 0) || (lso_enable == 1))) { + printk("lso_enable can be either '1' or '0'\n"); + fail = 1; + } + if ((indicate_max_pkts > (0xFFFFFFFF))) { + printk + ("indicate_max_pkts can take value greater than zero but less than 2power(32)\n"); + fail = 1; + } + if (!((cksum_offload_enable == 0) || (cksum_offload_enable == 1))) { + printk("cksum_offload_enable can be only '0' or '1' \n"); + fail = 1; + } + if ((TxFifoNum == 0) || (TxFifoNum > 8)) { + printk("TxFifoNum can take value from 1 to 8\n"); + fail = 1; + } + switch (TxFifoNum) { + case 8: + if ((TxFIFOLen_7 == 0) || TxFIFOLen_7 > 8192) { + printk("TxFIFOLen_7 can take value from 1 to 8192\n"); + fail = 1; + } + case 7: + if ((TxFIFOLen_6 == 0) || TxFIFOLen_6 > 8192) { + printk("TxFIFOLen_6 can take value from 1 to 8192\n"); + fail = 1; + } + case 6: + if ((TxFIFOLen_5 == 0) || TxFIFOLen_5 > 8192) { + printk("TxFIFOLen_5 can take value from 1 to 8192\n"); + fail = 1; + } + case 5: + if ((TxFIFOLen_4 == 0) || TxFIFOLen_4 > 8192) { + printk("TxFIFOLen_4 can take value from 1 to 8192\n"); + fail = 1; + } + case 4: + if ((TxFIFOLen_3 == 0) || TxFIFOLen_3 > 8192) { + printk("TxFIFOLen_3 can take value from 1 to 8192\n"); + fail = 1; + } + case 3: + if ((TxFIFOLen_2 == 0) || TxFIFOLen_2 > 8192) { + printk("TxFIFOLen_2 can take value from 1 to 8192\n"); + fail = 1; + } + case 2: + if ((TxFIFOLen_1 == 0) || TxFIFOLen_1 > 8192) { + printk("TxFIFOLen_1 can take value from 1 to 8192\n"); + fail = 1; + } + case 1: + if ((TxFIFOLen_0 == 0) || TxFIFOLen_0 > 8192) { + printk("TxFIFOLen_0 can take value from 1 to 8192\n"); + fail = 1; + } + } + if ((MaxTxDs > 32) || (MaxTxDs < 1)) { + printk("MaxTxDs can take falue from 1 to 32\n"); + fail = 1; + } + if ((RxRingNum > 8) || (RxRingNum < 1)) { + printk("RxRingNum can take falue from 1 to 8\n"); + fail = 1; + } + switch(RxRingNum) { + case 8: + if (RxRingSz_7 < 1) { + printk("RxRingSz_7 can take value greater than 0\n"); + fail = 1; + } + case 7: + if (RxRingSz_6 < 1) { + printk("RxRingSz_6 can take value greater than 0\n"); + fail = 1; + } + case 6: + if (RxRingSz_5 < 1) { + printk("RxRingSz_5 can take value greater than 0\n"); + fail = 1; + } + case 5: + if (RxRingSz_4 < 1) { + printk("RxRingSz_4 can take value greater than 0\n"); + fail = 1; + } + case 4: + if (RxRingSz_3 < 1) { + printk("RxRingSz_3 can take value greater than 0\n"); + fail = 1; + } + case 3: + if (RxRingSz_2 < 1) { + printk("RxRingSz_2 can take value greater than 0\n"); + fail = 1; + } + case 2: + if (RxRingSz_1 < 1) { + printk("RxRingSz_1 can take value greater than 0\n"); + fail = 1; + } + case 1: + if (RxRingSz_0 < 1) { + printk("RxRingSz_0 can take value greater than 0\n"); + fail = 1; + } + } + if ((Stats_refresh_time < 1)) { + printk + ("Stats_refresh_time cannot be less than 1 second \n"); + fail = 1; + } + if (((rmac_pause_time < 0x10) && (rmac_pause_time != 0)) || + (rmac_pause_time > 0xFFFF)) { + printk + ("rmac_pause_time can take value from 16 to 65535\n"); + fail = 1; + } + if ((max_splits_trans < 0) || (max_splits_trans > 7)) { + printk("max_splits_trans can take value from 0 to 7\n"); + fail = 1; + } + if ((mc_pause_threshold_q0q3 > 0xFE)) { + printk("mc_pause_threshold_q0q3 cannot exceed 254\n"); + fail = 1; + } + if ((mc_pause_threshold_q4q7 > 0xFE)) { + printk("mc_pause_threshold_q4q7 cannot exceed 254\n"); + fail = 1; + } + if ((latency_timer) + && ((latency_timer < 8) || (latency_timer > 255))) { + printk("latency_timer can take value from 8 to 255\n"); + fail = 1; + } + if (max_read_byte_cnt > 3) { + printk("max_read_byte_cnt can take value from 0 to 3\n"); + fail = 1; + } + if ((shared_splits > 31)) { + printk("shared_splits can exceed 31\n"); + fail = 1; + } + if (rmac_util_period > 0xF) { + printk("rmac_util_period can exceed 15\n"); + fail = 1; + } + if (tmac_util_period > 0xF) { + printk("tmac_util_period can exceed 15\n"); + fail = 1; + } + if ((tx_utilz_periodic > 1) || (rx_utilz_periodic > 1)) { + printk + ("tx_utilz_periodic & rx_utilz_periodic can be either " + "'0' or '1'\n"); + fail = 1; + } + if ((tx_urange_a > 127) || (tx_urange_b > 127) + || (tx_urange_c > 127)) { + printk + ("tx_urange_a, tx_urange_b & tx_urange_c can take value " + "from 0 to 127\n"); + fail = 1; + } + if ((rx_urange_a > 127) || (rx_urange_b > 127) + || (rx_urange_c > 127)) { + printk + ("rx_urange_a, rx_urange_b & rx_urange_c can take value " + "from 0 to 127\n"); + fail = 1; + } + if ((tx_ufc_a > 0xffff) || (tx_ufc_b > 0xffff) || + (tx_ufc_c > 0xffff) || (tx_ufc_d > 0xffff)) { + printk + (" tx_ufc_a, tx_ufc_b, tx_ufc_c, tx_ufc_d can take value" + "from 0 to 65535(0xFFFF)\n"); + fail = 1; + } + if ((rx_ufc_a > 0xffff) || (rx_ufc_b > 0xffff) || + (rx_ufc_c > 0xffff) || (rx_ufc_d > 0xffff)) { + printk + (" rx_ufc_a, rx_ufc_b, rx_ufc_c, rx_ufc_d can take value" + "from 0 to 65535(0xFFFF)\n"); + fail = 1; + } + return fail; +} diff -Naur orig/drivers/net/s2io.h new/drivers/net/s2io.h --- orig/drivers/net/s2io.h 2004-08-06 06:55:01.000000000 -0700 +++ new/drivers/net/s2io.h 2004-08-06 07:16:40.000000000 -0700 @@ -16,6 +16,7 @@ #define TBD 0 #define BIT(loc) (0x8000000000000000ULL >> (loc)) #define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz)) +#define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff) #ifndef BOOL #define BOOL int @@ -49,11 +50,6 @@ #define ALIGN_SIZE 127 #define PCIX_COMMAND_REGISTER 0x62 -/* - * Debug related variables. - */ -#define DEBUG_ON TRUE - /* different debug levels. */ #define ERR_DBG 0 #define INIT_DBG 1 @@ -492,6 +488,12 @@ u64 Host_Control; /* reserved for host */ } TxD_t; +/* Structure to hold the phy and virt addr of every TxDL. */ +typedef struct list_info_hold { + dma_addr_t list_phy_addr; + void *list_virt_addr; +} list_info_hold_t; + /* Rx descriptor structure */ typedef struct _RxD_t { u64 Host_Control; /* reserved for host */ @@ -508,36 +510,80 @@ #define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF) u64 Control_2; +#ifndef CONFIG_2BUFF_MODE #define MASK_BUFFER0_SIZE vBIT(0xFFFF,0,16) #define SET_BUFFER0_SIZE(val) vBIT(val,0,16) +#else +#define MASK_BUFFER0_SIZE vBIT(0xFF,0,16) +#define MASK_BUFFER1_SIZE vBIT(0xFFFF,16,16) +#define MASK_BUFFER2_SIZE vBIT(0xFFFF,32,16) +#define SET_BUFFER0_SIZE(val) vBIT(val,8,8) +#define SET_BUFFER1_SIZE(val) vBIT(val,16,16) +#define SET_BUFFER2_SIZE(val) vBIT(val,32,16) +#endif + #define MASK_VLAN_TAG vBIT(0xFFFF,48,16) #define SET_VLAN_TAG(val) vBIT(val,48,16) #define SET_NUM_TAG(val) vBIT(val,16,32) +#ifndef CONFIG_2BUFF_MODE #define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0xFFFF,0,16))) -/* -#define TXD_GET_BUFFER1_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER1_SIZE) >> (63-31)) -#define TXD_GET_BUFFER2_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER2_SIZE) >> (63-47)) -*/ +#else +#define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \ + >> 48) +#define RXD_GET_BUFFER1_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER1_SIZE) \ + >> 32) +#define RXD_GET_BUFFER2_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER2_SIZE) \ + >> 16) +#define BUF0_LEN 40 +#define BUF1_LEN 1 +#endif + u64 Buffer0_ptr; +#ifdef CONFIG_2BUFF_MODE + u64 Buffer1_ptr; + u64 Buffer2_ptr; +#endif } RxD_t; - /* Structure that represents the Rx descriptor block which contains * 128 Rx descriptors. */ +#ifndef CONFIG_2BUFF_MODE typedef struct _RxD_block { #define MAX_RXDS_PER_BLOCK 127 RxD_t rxd[MAX_RXDS_PER_BLOCK]; u64 reserved_0; #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL - u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last Rxd in this blk */ - u64 reserved_2_pNext_RxD_block; /*@ Logical ptr to next */ - u64 pNext_RxD_Blk_physical; /* Buff0_ptr. - In a 32 bit arch the upper 32 bits - should be 0 */ + u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last + * Rxd in this blk */ + u64 reserved_2_pNext_RxD_block; /* Logical ptr to next */ + u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch + * the upper 32 bits should + * be 0 */ +} RxD_block_t; +#else +typedef struct _RxD_block { +#define MAX_RXDS_PER_BLOCK 85 + RxD_t rxd[MAX_RXDS_PER_BLOCK]; + +#define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL + u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last Rxd + * in this blk */ + u64 pNext_RxD_Blk_physical; /* Phy ponter to next blk. */ } RxD_block_t; +#define SIZE_OF_BLOCK 4096 + +/* Structure to hold virtual addresses of Buf0 and Buf1 in + * 2buf mode. */ +typedef struct bufAdd { + void *ba_0_org; + void *ba_1_org; + void *ba_0; + void *ba_1; +} buffAdd_t; +#endif /* Structure which stores all the MAC control parameters */ @@ -584,6 +630,9 @@ rx_curr_get_info_t rx_curr_get_info[MAX_RX_RINGS]; u16 rmac_pause_time; + u16 mc_pause_threshold_q0q3; + u16 mc_pause_threshold_q4q7; + /* this will be used in receive function, this decides which ring would be processed first. eg: ring with priority value 0 (highest) should @@ -633,6 +682,13 @@ dma_addr_t block_dma_addr; } rx_block_info_t; +/* Default Tunable parameters of the NIC. */ +#define DEFAULT_FIFO_LEN 4096 +#define SMALL_RXD_CNT 20 * (MAX_RXDS_PER_BLOCK+1) +#define LARGE_RXD_CNT 100 * (MAX_RXDS_PER_BLOCK+1) +#define SMALL_BLK_CNT 20 +#define LARGE_BLK_CNT 100 + /* Structure representing one instance of the NIC */ typedef struct s2io_nic { #define MAX_MAC_SUPPORTED 16 @@ -672,7 +728,6 @@ u32 irq; atomic_t rx_bufs_left[MAX_RX_RINGS]; - spinlock_t isr_lock; spinlock_t tx_lock; #define PROMISC 1 @@ -692,15 +747,6 @@ u16 tx_err_count; u16 rx_err_count; -#if DEBUG_ON - u64 rxpkt_bytes; - u64 txpkt_bytes; - int int_cnt; - int rxint_cnt; - int txint_cnt; - u64 rxpkt_cnt; -#endif - /* Place holders for the virtual and physical addresses of * all the Rx Blocks */ @@ -709,6 +755,9 @@ int block_count[MAX_RX_RINGS]; int pkt_cnt[MAX_RX_RINGS]; + /* Place holder of all the TX List's Phy and Virt addresses. */ + list_info_hold_t *list_info[MAX_TX_FIFOS]; + /* Id timer, used to blink NIC to physically identify NIC. */ struct timer_list id_timer; @@ -716,13 +765,8 @@ * a schedule task that will set the correct Link state once the * NIC's PHY has stabilized after a state change. */ -#ifdef INIT_TQUEUE - struct tq_struct rst_timer_task; - struct tq_struct set_link_task; -#else struct work_struct rst_timer_task; struct work_struct set_link_task; -#endif /* Flag that can be used to turn on or turn off the Rx checksum * offload feature. @@ -738,24 +782,26 @@ u16 last_link_state; #define LINK_DOWN 1 #define LINK_UP 2 + +#ifdef CONFIG_2BUFF_MODE + /* Buffer Address store. */ + buffAdd_t ba[SMALL_BLK_CNT][MAX_RXDS_PER_BLOCK + 1]; +#endif + int task_flag; + } nic_t; #define RESET_ERROR 1; #define CMD_ERROR 2; -/* Default Tunable parameters of the NIC. */ -#define DEFAULT_FIFO_LEN 4096 -#define SMALL_RXD_CNT 40 * (MAX_RXDS_PER_BLOCK+1) -#define LARGE_RXD_CNT 100 * (MAX_RXDS_PER_BLOCK+1) - /* OS related system calls */ #ifndef readq static inline u64 readq(void *addr) { u64 ret = 0; ret = readl(addr + 4); - ret <<= 32; - ret |= readl(addr); + (u64) ret <<= 32; + (u64) ret |= readl(addr); return ret; } @@ -817,30 +863,48 @@ /* DMA level Inressupts */ #define TXDMA_PFC_INT_M BIT(0) - /* PFC block interrupts */ +#define TXDMA_PCC_INT_M BIT(2) + +/* PFC block interrupts */ #define PFC_MISC_ERR_1 BIT(0) /* Interrupt to indicate FIFO full */ +/* PCC block interrupts. */ +#define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate + PCC_FB_ECC Error. */ + +/* Cards with following subsystem_id have a link state indication + * problem, 600B, 600C, 600D, 640B, 640C and 640D. + * macro below identifies these cards given the subsystem_id. + */ +#define CARDS_WITH_FAULTY_LINK_INDICATORS(subid) \ + (((subid >= 0x600B) && (subid <= 0x600D)) || \ + ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0 /* * Prototype declaration. */ static int __devinit s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre); static void __devexit s2io_rem_nic(struct pci_dev *pdev); -static int initSharedMem(struct s2io_nic *sp); -static void freeSharedMem(struct s2io_nic *sp); -static int initNic(struct s2io_nic *nic); +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); #ifndef CONFIG_S2IO_NAPI -static void rxIntrHandler(struct s2io_nic *sp); +static void rx_intr_handler(struct s2io_nic *sp); #endif -static void txIntrHandler(struct s2io_nic *sp); -static void alarmIntrHandler(struct s2io_nic *sp); +static void tx_intr_handler(struct s2io_nic *sp); +static void alarm_intr_handler(struct s2io_nic *sp); static int s2io_starter(void); 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 rxOsmHandler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no); +#ifndef CONFIG_2BUFF_MODE +static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no); +#else +static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, + buffAdd_t * ba); +#endif void s2io_link(nic_t * sp, int link); void s2io_reset(nic_t * sp); #ifdef CONFIG_S2IO_NAPI @@ -850,6 +914,8 @@ int s2io_set_mac_addr(struct net_device *dev, u8 * addr); static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs); static int verify_xena_quiescence(u64 val64, int flag); +int verify_load_parm(void); static struct ethtool_ops netdev_ethtool_ops; +static void s2io_set_link(unsigned long data); #endif /* _S2IO_H */