diff options
-rw-r--r-- | drivers/net/s2io.c | 95 | ||||
-rw-r--r-- | drivers/net/s2io.h | 5 |
2 files changed, 88 insertions, 12 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index e2144fc7df9a..e24c5e544734 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -158,6 +158,9 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
158 | {"rmac_pause_cnt"}, | 158 | {"rmac_pause_cnt"}, |
159 | {"rmac_accepted_ip"}, | 159 | {"rmac_accepted_ip"}, |
160 | {"rmac_err_tcp"}, | 160 | {"rmac_err_tcp"}, |
161 | {"\n DRIVER STATISTICS"}, | ||
162 | {"single_bit_ecc_errs"}, | ||
163 | {"double_bit_ecc_errs"}, | ||
161 | }; | 164 | }; |
162 | 165 | ||
163 | #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN | 166 | #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN |
@@ -237,7 +240,6 @@ static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | |||
237 | static unsigned int rx_ring_num = 1; | 240 | static unsigned int rx_ring_num = 1; |
238 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | 241 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = |
239 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 242 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; |
240 | static unsigned int Stats_refresh_time = 4; | ||
241 | static unsigned int rts_frm_len[MAX_RX_RINGS] = | 243 | static unsigned int rts_frm_len[MAX_RX_RINGS] = |
242 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 244 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; |
243 | static unsigned int use_continuous_tx_intrs = 1; | 245 | static unsigned int use_continuous_tx_intrs = 1; |
@@ -1083,9 +1085,6 @@ static int init_nic(struct s2io_nic *nic) | |||
1083 | 1085 | ||
1084 | /* Program statistics memory */ | 1086 | /* Program statistics memory */ |
1085 | writeq(mac_control->stats_mem_phy, &bar0->stat_addr); | 1087 | writeq(mac_control->stats_mem_phy, &bar0->stat_addr); |
1086 | val64 = SET_UPDT_PERIOD(Stats_refresh_time) | | ||
1087 | STAT_CFG_STAT_RO | STAT_CFG_STAT_EN; | ||
1088 | writeq(val64, &bar0->stat_cfg); | ||
1089 | 1088 | ||
1090 | /* | 1089 | /* |
1091 | * Initializing the sampling rate for the device to calculate the | 1090 | * Initializing the sampling rate for the device to calculate the |
@@ -2101,6 +2100,7 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
2101 | u64 val64; | 2100 | u64 val64; |
2102 | int i; | 2101 | int i; |
2103 | 2102 | ||
2103 | atomic_inc(&nic->isr_cnt); | ||
2104 | mac_control = &nic->mac_control; | 2104 | mac_control = &nic->mac_control; |
2105 | config = &nic->config; | 2105 | config = &nic->config; |
2106 | 2106 | ||
@@ -2136,6 +2136,7 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
2136 | } | 2136 | } |
2137 | /* Re enable the Rx interrupts. */ | 2137 | /* Re enable the Rx interrupts. */ |
2138 | en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); | 2138 | en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); |
2139 | atomic_dec(&nic->isr_cnt); | ||
2139 | return 0; | 2140 | return 0; |
2140 | 2141 | ||
2141 | no_rx: | 2142 | no_rx: |
@@ -2149,6 +2150,7 @@ no_rx: | |||
2149 | break; | 2150 | break; |
2150 | } | 2151 | } |
2151 | } | 2152 | } |
2153 | atomic_dec(&nic->isr_cnt); | ||
2152 | return 1; | 2154 | return 1; |
2153 | } | 2155 | } |
2154 | #endif | 2156 | #endif |
@@ -2179,6 +2181,13 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2179 | #endif | 2181 | #endif |
2180 | register u64 val64; | 2182 | register u64 val64; |
2181 | 2183 | ||
2184 | spin_lock(&nic->rx_lock); | ||
2185 | if (atomic_read(&nic->card_state) == CARD_DOWN) { | ||
2186 | DBG_PRINT(ERR_DBG, "%s: %s going down for reset\n", | ||
2187 | __FUNCTION__, dev->name); | ||
2188 | spin_unlock(&nic->rx_lock); | ||
2189 | } | ||
2190 | |||
2182 | /* | 2191 | /* |
2183 | * rx_traffic_int reg is an R1 register, hence we read and write | 2192 | * rx_traffic_int reg is an R1 register, hence we read and write |
2184 | * back the same value in the register to clear it | 2193 | * back the same value in the register to clear it |
@@ -2210,6 +2219,7 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2210 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 2219 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
2211 | dev->name); | 2220 | dev->name); |
2212 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 2221 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
2222 | spin_unlock(&nic->rx_lock); | ||
2213 | return; | 2223 | return; |
2214 | } | 2224 | } |
2215 | #ifndef CONFIG_2BUFF_MODE | 2225 | #ifndef CONFIG_2BUFF_MODE |
@@ -2262,6 +2272,7 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2262 | break; | 2272 | break; |
2263 | #endif | 2273 | #endif |
2264 | } | 2274 | } |
2275 | spin_unlock(&nic->rx_lock); | ||
2265 | } | 2276 | } |
2266 | 2277 | ||
2267 | /** | 2278 | /** |
@@ -2345,7 +2356,6 @@ static void tx_intr_handler(fifo_info_t *fifo_data) | |||
2345 | (sizeof(TxD_t) * fifo_data->max_txds)); | 2356 | (sizeof(TxD_t) * fifo_data->max_txds)); |
2346 | 2357 | ||
2347 | /* Updating the statistics block */ | 2358 | /* Updating the statistics block */ |
2348 | nic->stats.tx_packets++; | ||
2349 | nic->stats.tx_bytes += skb->len; | 2359 | nic->stats.tx_bytes += skb->len; |
2350 | dev_kfree_skb_irq(skb); | 2360 | dev_kfree_skb_irq(skb); |
2351 | 2361 | ||
@@ -2393,13 +2403,16 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2393 | writeq(val64, &bar0->mc_err_reg); | 2403 | writeq(val64, &bar0->mc_err_reg); |
2394 | if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) { | 2404 | if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) { |
2395 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { | 2405 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { |
2406 | nic->mac_control.stats_info->sw_stat. | ||
2407 | double_ecc_errs++; | ||
2396 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", | 2408 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", |
2397 | dev->name); | 2409 | dev->name); |
2398 | DBG_PRINT(ERR_DBG, "double ECC error!!\n"); | 2410 | DBG_PRINT(ERR_DBG, "double ECC error!!\n"); |
2399 | netif_stop_queue(dev); | 2411 | netif_stop_queue(dev); |
2400 | schedule_work(&nic->rst_timer_task); | 2412 | schedule_work(&nic->rst_timer_task); |
2401 | } else { | 2413 | } else { |
2402 | /* Device can recover from Single ECC errors */ | 2414 | nic->mac_control.stats_info->sw_stat. |
2415 | single_ecc_errs++; | ||
2403 | } | 2416 | } |
2404 | } | 2417 | } |
2405 | 2418 | ||
@@ -2695,7 +2708,7 @@ int s2io_open(struct net_device *dev) | |||
2695 | * Nic is initialized | 2708 | * Nic is initialized |
2696 | */ | 2709 | */ |
2697 | netif_carrier_off(dev); | 2710 | netif_carrier_off(dev); |
2698 | sp->last_link_state = LINK_DOWN; | 2711 | sp->last_link_state = 0; /* Unkown link state */ |
2699 | 2712 | ||
2700 | /* Initialize H/W and enable interrupts */ | 2713 | /* Initialize H/W and enable interrupts */ |
2701 | if (s2io_card_up(sp)) { | 2714 | if (s2io_card_up(sp)) { |
@@ -2909,6 +2922,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2909 | mac_info_t *mac_control; | 2922 | mac_info_t *mac_control; |
2910 | struct config_param *config; | 2923 | struct config_param *config; |
2911 | 2924 | ||
2925 | atomic_inc(&sp->isr_cnt); | ||
2912 | mac_control = &sp->mac_control; | 2926 | mac_control = &sp->mac_control; |
2913 | config = &sp->config; | 2927 | config = &sp->config; |
2914 | 2928 | ||
@@ -2924,6 +2938,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2924 | 2938 | ||
2925 | if (!reason) { | 2939 | if (!reason) { |
2926 | /* The interrupt was not raised by Xena. */ | 2940 | /* The interrupt was not raised by Xena. */ |
2941 | atomic_dec(&sp->isr_cnt); | ||
2927 | return IRQ_NONE; | 2942 | return IRQ_NONE; |
2928 | } | 2943 | } |
2929 | 2944 | ||
@@ -2972,6 +2987,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2972 | dev->name); | 2987 | dev->name); |
2973 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | 2988 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); |
2974 | clear_bit(0, (&sp->tasklet_status)); | 2989 | clear_bit(0, (&sp->tasklet_status)); |
2990 | atomic_dec(&sp->isr_cnt); | ||
2975 | return IRQ_HANDLED; | 2991 | return IRQ_HANDLED; |
2976 | } | 2992 | } |
2977 | clear_bit(0, (&sp->tasklet_status)); | 2993 | clear_bit(0, (&sp->tasklet_status)); |
@@ -2981,10 +2997,37 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2981 | } | 2997 | } |
2982 | #endif | 2998 | #endif |
2983 | 2999 | ||
3000 | atomic_dec(&sp->isr_cnt); | ||
2984 | return IRQ_HANDLED; | 3001 | return IRQ_HANDLED; |
2985 | } | 3002 | } |
2986 | 3003 | ||
2987 | /** | 3004 | /** |
3005 | * s2io_updt_stats - | ||
3006 | */ | ||
3007 | static void s2io_updt_stats(nic_t *sp) | ||
3008 | { | ||
3009 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
3010 | u64 val64; | ||
3011 | int cnt = 0; | ||
3012 | |||
3013 | if (atomic_read(&sp->card_state) == CARD_UP) { | ||
3014 | /* Apprx 30us on a 133 MHz bus */ | ||
3015 | val64 = SET_UPDT_CLICKS(10) | | ||
3016 | STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN; | ||
3017 | writeq(val64, &bar0->stat_cfg); | ||
3018 | do { | ||
3019 | udelay(100); | ||
3020 | val64 = readq(&bar0->stat_cfg); | ||
3021 | if (!(val64 & BIT(0))) | ||
3022 | break; | ||
3023 | cnt++; | ||
3024 | if (cnt == 5) | ||
3025 | break; /* Updt failed */ | ||
3026 | } while(1); | ||
3027 | } | ||
3028 | } | ||
3029 | |||
3030 | /** | ||
2988 | * s2io_get_stats - Updates the device statistics structure. | 3031 | * s2io_get_stats - Updates the device statistics structure. |
2989 | * @dev : pointer to the device structure. | 3032 | * @dev : pointer to the device structure. |
2990 | * Description: | 3033 | * Description: |
@@ -3004,6 +3047,11 @@ struct net_device_stats *s2io_get_stats(struct net_device *dev) | |||
3004 | mac_control = &sp->mac_control; | 3047 | mac_control = &sp->mac_control; |
3005 | config = &sp->config; | 3048 | config = &sp->config; |
3006 | 3049 | ||
3050 | /* Configure Stats for immediate updt */ | ||
3051 | s2io_updt_stats(sp); | ||
3052 | |||
3053 | sp->stats.tx_packets = | ||
3054 | le32_to_cpu(mac_control->stats_info->tmac_frms); | ||
3007 | sp->stats.tx_errors = | 3055 | sp->stats.tx_errors = |
3008 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); | 3056 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); |
3009 | sp->stats.rx_errors = | 3057 | sp->stats.rx_errors = |
@@ -4018,6 +4066,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
4018 | nic_t *sp = dev->priv; | 4066 | nic_t *sp = dev->priv; |
4019 | StatInfo_t *stat_info = sp->mac_control.stats_info; | 4067 | StatInfo_t *stat_info = sp->mac_control.stats_info; |
4020 | 4068 | ||
4069 | s2io_updt_stats(sp); | ||
4021 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_frms); | 4070 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_frms); |
4022 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_data_octets); | 4071 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_data_octets); |
4023 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms); | 4072 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms); |
@@ -4057,6 +4106,9 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
4057 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pause_cnt); | 4106 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pause_cnt); |
4058 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_accepted_ip); | 4107 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_accepted_ip); |
4059 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); | 4108 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); |
4109 | tmp_stats[i++] = 0; | ||
4110 | tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; | ||
4111 | tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; | ||
4060 | } | 4112 | } |
4061 | 4113 | ||
4062 | int s2io_ethtool_get_regs_len(struct net_device *dev) | 4114 | int s2io_ethtool_get_regs_len(struct net_device *dev) |
@@ -4353,14 +4405,27 @@ static void s2io_card_down(nic_t * sp) | |||
4353 | break; | 4405 | break; |
4354 | } | 4406 | } |
4355 | } while (1); | 4407 | } while (1); |
4356 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
4357 | s2io_reset(sp); | 4408 | s2io_reset(sp); |
4358 | 4409 | ||
4359 | /* Free all unused Tx and Rx buffers */ | 4410 | /* Waiting till all Interrupt handlers are complete */ |
4411 | cnt = 0; | ||
4412 | do { | ||
4413 | msleep(10); | ||
4414 | if (!atomic_read(&sp->isr_cnt)) | ||
4415 | break; | ||
4416 | cnt++; | ||
4417 | } while(cnt < 5); | ||
4418 | |||
4419 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
4420 | /* Free all Tx buffers */ | ||
4360 | free_tx_buffers(sp); | 4421 | free_tx_buffers(sp); |
4422 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
4423 | |||
4424 | /* Free all Rx buffers */ | ||
4425 | spin_lock_irqsave(&sp->rx_lock, flags); | ||
4361 | free_rx_buffers(sp); | 4426 | free_rx_buffers(sp); |
4427 | spin_unlock_irqrestore(&sp->rx_lock, flags); | ||
4362 | 4428 | ||
4363 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
4364 | clear_bit(0, &(sp->link_state)); | 4429 | clear_bit(0, &(sp->link_state)); |
4365 | } | 4430 | } |
4366 | 4431 | ||
@@ -4647,7 +4712,6 @@ module_param(tx_fifo_num, int, 0); | |||
4647 | module_param(rx_ring_num, int, 0); | 4712 | module_param(rx_ring_num, int, 0); |
4648 | module_param_array(tx_fifo_len, uint, NULL, 0); | 4713 | module_param_array(tx_fifo_len, uint, NULL, 0); |
4649 | module_param_array(rx_ring_sz, uint, NULL, 0); | 4714 | module_param_array(rx_ring_sz, uint, NULL, 0); |
4650 | module_param(Stats_refresh_time, int, 0); | ||
4651 | module_param_array(rts_frm_len, uint, NULL, 0); | 4715 | module_param_array(rts_frm_len, uint, NULL, 0); |
4652 | module_param(use_continuous_tx_intrs, int, 1); | 4716 | module_param(use_continuous_tx_intrs, int, 1); |
4653 | module_param(rmac_pause_time, int, 0); | 4717 | module_param(rmac_pause_time, int, 0); |
@@ -4804,6 +4868,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4804 | for (i = 0; i < config->rx_ring_num; i++) | 4868 | for (i = 0; i < config->rx_ring_num; i++) |
4805 | atomic_set(&sp->rx_bufs_left[i], 0); | 4869 | atomic_set(&sp->rx_bufs_left[i], 0); |
4806 | 4870 | ||
4871 | /* Initialize the number of ISRs currently running */ | ||
4872 | atomic_set(&sp->isr_cnt, 0); | ||
4873 | |||
4807 | /* initialize the shared memory used by the NIC and the host */ | 4874 | /* initialize the shared memory used by the NIC and the host */ |
4808 | if (init_shared_mem(sp)) { | 4875 | if (init_shared_mem(sp)) { |
4809 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", | 4876 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", |
@@ -4938,6 +5005,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4938 | #ifndef CONFIG_S2IO_NAPI | 5005 | #ifndef CONFIG_S2IO_NAPI |
4939 | spin_lock_init(&sp->put_lock); | 5006 | spin_lock_init(&sp->put_lock); |
4940 | #endif | 5007 | #endif |
5008 | spin_lock_init(&sp->rx_lock); | ||
4941 | 5009 | ||
4942 | /* | 5010 | /* |
4943 | * SXE-002: Configure link and activity LED to init state | 5011 | * SXE-002: Configure link and activity LED to init state |
@@ -4961,13 +5029,16 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4961 | goto register_failed; | 5029 | goto register_failed; |
4962 | } | 5030 | } |
4963 | 5031 | ||
5032 | /* Initialize device name */ | ||
5033 | strcpy(sp->name, dev->name); | ||
5034 | strcat(sp->name, ": Neterion Xframe I 10GbE adapter"); | ||
5035 | |||
4964 | /* | 5036 | /* |
4965 | * Make Link state as off at this point, when the Link change | 5037 | * Make Link state as off at this point, when the Link change |
4966 | * interrupt comes the state will be automatically changed to | 5038 | * interrupt comes the state will be automatically changed to |
4967 | * the right state. | 5039 | * the right state. |
4968 | */ | 5040 | */ |
4969 | netif_carrier_off(dev); | 5041 | netif_carrier_off(dev); |
4970 | sp->last_link_state = LINK_DOWN; | ||
4971 | 5042 | ||
4972 | return 0; | 5043 | return 0; |
4973 | 5044 | ||
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 92db59a0fb11..69dd0e51dda0 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -195,6 +195,9 @@ typedef struct stat_block { | |||
195 | u32 rxd_rd_cnt; | 195 | u32 rxd_rd_cnt; |
196 | u32 rxf_wr_cnt; | 196 | u32 rxf_wr_cnt; |
197 | u32 txf_rd_cnt; | 197 | u32 txf_rd_cnt; |
198 | |||
199 | /* Software statistics maintained by driver */ | ||
200 | swStat_t sw_stat; | ||
198 | } StatInfo_t; | 201 | } StatInfo_t; |
199 | 202 | ||
200 | /* | 203 | /* |
@@ -678,6 +681,8 @@ struct s2io_nic { | |||
678 | #define CARD_UP 2 | 681 | #define CARD_UP 2 |
679 | atomic_t card_state; | 682 | atomic_t card_state; |
680 | volatile unsigned long link_state; | 683 | volatile unsigned long link_state; |
684 | spinlock_t rx_lock; | ||
685 | atomic_t isr_cnt; | ||
681 | }; | 686 | }; |
682 | 687 | ||
683 | #define RESET_ERROR 1; | 688 | #define RESET_ERROR 1; |