aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorraghavendra.koushik@neterion.com <raghavendra.koushik@neterion.com>2005-08-03 15:29:20 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-11 00:10:44 -0400
commit7ba013ac029513eb4b70cfcd4b86e37c5f16c483 (patch)
tree67eb8b6d9e313f957aa228dab8cd62c1d1cea0cf
parent5e25b9ddb6683fe225a2266b53d73c57381a0c18 (diff)
[PATCH] S2io: Software fixes
Hi, Below patch includes fixes for few purely software bugs identified since last release. 1. Keep track and display(as part of ethtool command output) the no. of single-bit and double-bit ECC errors. 2. Handle race condition between intr handler and "interface down" routine. 3. Initial link state setting modified so that the link state displayed after "interface Up" is correct. 4. Fix for "Incorrect Tx packet count when TSO is enabled". 5. Disable periodic DMA of statistics and schedule one-shot DMA only when required. Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com> Signed-off-by: Raghavendra Koushik <raghavendra.koushik@neterion.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/net/s2io.c95
-rw-r--r--drivers/net/s2io.h5
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] =
237static unsigned int rx_ring_num = 1; 240static unsigned int rx_ring_num = 1;
238static unsigned int rx_ring_sz[MAX_RX_RINGS] = 241static unsigned int rx_ring_sz[MAX_RX_RINGS] =
239 {[0 ...(MAX_RX_RINGS - 1)] = 0 }; 242 {[0 ...(MAX_RX_RINGS - 1)] = 0 };
240static unsigned int Stats_refresh_time = 4;
241static unsigned int rts_frm_len[MAX_RX_RINGS] = 243static unsigned int rts_frm_len[MAX_RX_RINGS] =
242 {[0 ...(MAX_RX_RINGS - 1)] = 0 }; 244 {[0 ...(MAX_RX_RINGS - 1)] = 0 };
243static unsigned int use_continuous_tx_intrs = 1; 245static 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
2141no_rx: 2142no_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 */
3007static 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
4062int s2io_ethtool_get_regs_len(struct net_device *dev) 4114int 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);
4647module_param(rx_ring_num, int, 0); 4712module_param(rx_ring_num, int, 0);
4648module_param_array(tx_fifo_len, uint, NULL, 0); 4713module_param_array(tx_fifo_len, uint, NULL, 0);
4649module_param_array(rx_ring_sz, uint, NULL, 0); 4714module_param_array(rx_ring_sz, uint, NULL, 0);
4650module_param(Stats_refresh_time, int, 0);
4651module_param_array(rts_frm_len, uint, NULL, 0); 4715module_param_array(rts_frm_len, uint, NULL, 0);
4652module_param(use_continuous_tx_intrs, int, 1); 4716module_param(use_continuous_tx_intrs, int, 1);
4653module_param(rmac_pause_time, int, 0); 4717module_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;