diff options
author | Sivakumar Subramani <sivakumar.subramani@neterion.com> | 2007-09-17 16:05:35 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:09 -0400 |
commit | 8116f3cf4a2a5a4fa2335e6f32023ac50506698f (patch) | |
tree | 4db08fb067fd37c892f9a98e127854acd0fa3956 /drivers | |
parent | 9caab4587b8320c54fc666a6c820e966e6403aea (diff) |
[S2IO]: Handle and monitor all of the device errors and alarms
- Added support to poll entire set of device errors and alarams.
- A note on how device errors and alarms are handled:
- The adapter will automatically recover from uncorrectable ECC errors.
Packets containing corrupted data will be dropped (not transmitted) or tagged
as invalid before being passed to the host.
- The adapter cannot recover from any internal state machine errors. A state
machine error requires a device reset.
- Any internal error that could potentially result in .store trampling.
(undesirable PCI behaviour)is tagged as a "serious error". In such cases
the adapter will give up its ability to be a bus master. In this situation
the host will still be able to read internal device registers in order to
generate an error report. A device reset is necessary to return to normal
operation.
- In the event of a pcix data parity error, the adapter will automatically
disable itself. Adapter_En will automatically transition from '1' to '0' and
the adapter will enter its clean-up routine. Once the device has achieved
quiescence, an adapter reset should be performed.
- Replaced alarm_intr_handler() with s2io_handle_errors().
- Added statistic counters to monitor the alarms.
[ Fix warnings wrt. do_s2io_chk_alarm_bit(), Callers pass in an
"unsigned long long *" but the function takes a "u64 *" which is
different on many 64-bit platforms. -DaveM ]
Signed-off-by: Sivakumar Subramani <sivakumar.subramani@neterion.com>
Signed-off-by: Santosh Rastapur <santosh.rastapur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/s2io.c | 469 | ||||
-rw-r--r-- | drivers/net/s2io.h | 24 |
2 files changed, 357 insertions, 136 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 63473027b463..182643ff81e5 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -263,7 +263,14 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { | |||
263 | {"serious_err_cnt"}, | 263 | {"serious_err_cnt"}, |
264 | {"soft_reset_cnt"}, | 264 | {"soft_reset_cnt"}, |
265 | {"fifo_full_cnt"}, | 265 | {"fifo_full_cnt"}, |
266 | {"ring_full_cnt"}, | 266 | {"ring_0_full_cnt"}, |
267 | {"ring_1_full_cnt"}, | ||
268 | {"ring_2_full_cnt"}, | ||
269 | {"ring_3_full_cnt"}, | ||
270 | {"ring_4_full_cnt"}, | ||
271 | {"ring_5_full_cnt"}, | ||
272 | {"ring_6_full_cnt"}, | ||
273 | {"ring_7_full_cnt"}, | ||
267 | ("alarm_transceiver_temp_high"), | 274 | ("alarm_transceiver_temp_high"), |
268 | ("alarm_transceiver_temp_low"), | 275 | ("alarm_transceiver_temp_low"), |
269 | ("alarm_laser_bias_current_high"), | 276 | ("alarm_laser_bias_current_high"), |
@@ -303,7 +310,24 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { | |||
303 | ("rx_tcode_fcs_err_cnt"), | 310 | ("rx_tcode_fcs_err_cnt"), |
304 | ("rx_tcode_buf_size_err_cnt"), | 311 | ("rx_tcode_buf_size_err_cnt"), |
305 | ("rx_tcode_rxd_corrupt_cnt"), | 312 | ("rx_tcode_rxd_corrupt_cnt"), |
306 | ("rx_tcode_unkn_err_cnt") | 313 | ("rx_tcode_unkn_err_cnt"), |
314 | {"tda_err_cnt"}, | ||
315 | {"pfc_err_cnt"}, | ||
316 | {"pcc_err_cnt"}, | ||
317 | {"tti_err_cnt"}, | ||
318 | {"tpa_err_cnt"}, | ||
319 | {"sm_err_cnt"}, | ||
320 | {"lso_err_cnt"}, | ||
321 | {"mac_tmac_err_cnt"}, | ||
322 | {"mac_rmac_err_cnt"}, | ||
323 | {"xgxs_txgxs_err_cnt"}, | ||
324 | {"xgxs_rxgxs_err_cnt"}, | ||
325 | {"rc_err_cnt"}, | ||
326 | {"prc_pcix_err_cnt"}, | ||
327 | {"rpa_err_cnt"}, | ||
328 | {"rda_err_cnt"}, | ||
329 | {"rti_err_cnt"}, | ||
330 | {"mc_err_cnt"} | ||
307 | }; | 331 | }; |
308 | 332 | ||
309 | #define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN | 333 | #define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN |
@@ -1732,6 +1756,7 @@ static int s2io_link_fault_indication(struct s2io_nic *nic) | |||
1732 | else | 1756 | else |
1733 | return MAC_RMAC_ERR_TIMER; | 1757 | return MAC_RMAC_ERR_TIMER; |
1734 | } | 1758 | } |
1759 | |||
1735 | /** | 1760 | /** |
1736 | * do_s2io_write_bits - update alarm bits in alarm register | 1761 | * do_s2io_write_bits - update alarm bits in alarm register |
1737 | * @value: alarm bits | 1762 | * @value: alarm bits |
@@ -3252,135 +3277,6 @@ static void s2io_updt_xpak_counter(struct net_device *dev) | |||
3252 | } | 3277 | } |
3253 | 3278 | ||
3254 | /** | 3279 | /** |
3255 | * alarm_intr_handler - Alarm Interrrupt handler | ||
3256 | * @nic: device private variable | ||
3257 | * Description: If the interrupt was neither because of Rx packet or Tx | ||
3258 | * complete, this function is called. If the interrupt was to indicate | ||
3259 | * a loss of link, the OSM link status handler is invoked for any other | ||
3260 | * alarm interrupt the block that raised the interrupt is displayed | ||
3261 | * and a H/W reset is issued. | ||
3262 | * Return Value: | ||
3263 | * NONE | ||
3264 | */ | ||
3265 | |||
3266 | static void alarm_intr_handler(struct s2io_nic *nic) | ||
3267 | { | ||
3268 | struct net_device *dev = (struct net_device *) nic->dev; | ||
3269 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | ||
3270 | register u64 val64 = 0, err_reg = 0; | ||
3271 | u64 cnt; | ||
3272 | int i; | ||
3273 | if (atomic_read(&nic->card_state) == CARD_DOWN) | ||
3274 | return; | ||
3275 | if (pci_channel_offline(nic->pdev)) | ||
3276 | return; | ||
3277 | nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0; | ||
3278 | /* Handling the XPAK counters update */ | ||
3279 | if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) { | ||
3280 | /* waiting for an hour */ | ||
3281 | nic->mac_control.stats_info->xpak_stat.xpak_timer_count++; | ||
3282 | } else { | ||
3283 | s2io_updt_xpak_counter(dev); | ||
3284 | /* reset the count to zero */ | ||
3285 | nic->mac_control.stats_info->xpak_stat.xpak_timer_count = 0; | ||
3286 | } | ||
3287 | |||
3288 | /* Handling link status change error Intr */ | ||
3289 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { | ||
3290 | err_reg = readq(&bar0->mac_rmac_err_reg); | ||
3291 | writeq(err_reg, &bar0->mac_rmac_err_reg); | ||
3292 | if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { | ||
3293 | schedule_work(&nic->set_link_task); | ||
3294 | } | ||
3295 | } | ||
3296 | |||
3297 | /* Handling Ecc errors */ | ||
3298 | val64 = readq(&bar0->mc_err_reg); | ||
3299 | writeq(val64, &bar0->mc_err_reg); | ||
3300 | if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) { | ||
3301 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { | ||
3302 | nic->mac_control.stats_info->sw_stat. | ||
3303 | double_ecc_errs++; | ||
3304 | DBG_PRINT(INIT_DBG, "%s: Device indicates ", | ||
3305 | dev->name); | ||
3306 | DBG_PRINT(INIT_DBG, "double ECC error!!\n"); | ||
3307 | if (nic->device_type != XFRAME_II_DEVICE) { | ||
3308 | /* Reset XframeI only if critical error */ | ||
3309 | if (val64 & (MC_ERR_REG_MIRI_ECC_DB_ERR_0 | | ||
3310 | MC_ERR_REG_MIRI_ECC_DB_ERR_1)) { | ||
3311 | netif_stop_queue(dev); | ||
3312 | schedule_work(&nic->rst_timer_task); | ||
3313 | nic->mac_control.stats_info->sw_stat. | ||
3314 | soft_reset_cnt++; | ||
3315 | } | ||
3316 | } | ||
3317 | } else { | ||
3318 | nic->mac_control.stats_info->sw_stat. | ||
3319 | single_ecc_errs++; | ||
3320 | } | ||
3321 | } | ||
3322 | |||
3323 | /* In case of a serious error, the device will be Reset. */ | ||
3324 | val64 = readq(&bar0->serr_source); | ||
3325 | if (val64 & SERR_SOURCE_ANY) { | ||
3326 | nic->mac_control.stats_info->sw_stat.serious_err_cnt++; | ||
3327 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); | ||
3328 | DBG_PRINT(ERR_DBG, "serious error %llx!!\n", | ||
3329 | (unsigned long long)val64); | ||
3330 | netif_stop_queue(dev); | ||
3331 | schedule_work(&nic->rst_timer_task); | ||
3332 | nic->mac_control.stats_info->sw_stat.soft_reset_cnt++; | ||
3333 | } | ||
3334 | |||
3335 | /* | ||
3336 | * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC | ||
3337 | * Error occurs, the adapter will be recycled by disabling the | ||
3338 | * adapter enable bit and enabling it again after the device | ||
3339 | * becomes Quiescent. | ||
3340 | */ | ||
3341 | val64 = readq(&bar0->pcc_err_reg); | ||
3342 | writeq(val64, &bar0->pcc_err_reg); | ||
3343 | if (val64 & PCC_FB_ECC_DB_ERR) { | ||
3344 | u64 ac = readq(&bar0->adapter_control); | ||
3345 | ac &= ~(ADAPTER_CNTL_EN); | ||
3346 | writeq(ac, &bar0->adapter_control); | ||
3347 | ac = readq(&bar0->adapter_control); | ||
3348 | schedule_work(&nic->set_link_task); | ||
3349 | } | ||
3350 | /* Check for data parity error */ | ||
3351 | val64 = readq(&bar0->pic_int_status); | ||
3352 | if (val64 & PIC_INT_GPIO) { | ||
3353 | val64 = readq(&bar0->gpio_int_reg); | ||
3354 | if (val64 & GPIO_INT_REG_DP_ERR_INT) { | ||
3355 | nic->mac_control.stats_info->sw_stat.parity_err_cnt++; | ||
3356 | schedule_work(&nic->rst_timer_task); | ||
3357 | nic->mac_control.stats_info->sw_stat.soft_reset_cnt++; | ||
3358 | } | ||
3359 | } | ||
3360 | |||
3361 | /* Check for ring full counter */ | ||
3362 | if (nic->device_type & XFRAME_II_DEVICE) { | ||
3363 | val64 = readq(&bar0->ring_bump_counter1); | ||
3364 | for (i=0; i<4; i++) { | ||
3365 | cnt = ( val64 & vBIT(0xFFFF,(i*16),16)); | ||
3366 | cnt >>= 64 - ((i+1)*16); | ||
3367 | nic->mac_control.stats_info->sw_stat.ring_full_cnt | ||
3368 | += cnt; | ||
3369 | } | ||
3370 | |||
3371 | val64 = readq(&bar0->ring_bump_counter2); | ||
3372 | for (i=0; i<4; i++) { | ||
3373 | cnt = ( val64 & vBIT(0xFFFF,(i*16),16)); | ||
3374 | cnt >>= 64 - ((i+1)*16); | ||
3375 | nic->mac_control.stats_info->sw_stat.ring_full_cnt | ||
3376 | += cnt; | ||
3377 | } | ||
3378 | } | ||
3379 | |||
3380 | /* Other type of interrupts are not being handled now, TODO */ | ||
3381 | } | ||
3382 | |||
3383 | /** | ||
3384 | * wait_for_cmd_complete - waits for a command to complete. | 3280 | * wait_for_cmd_complete - waits for a command to complete. |
3385 | * @sp : private member of the device structure, which is a pointer to the | 3281 | * @sp : private member of the device structure, which is a pointer to the |
3386 | * s2io_nic structure. | 3282 | * s2io_nic structure. |
@@ -4246,8 +4142,9 @@ static void | |||
4246 | s2io_alarm_handle(unsigned long data) | 4142 | s2io_alarm_handle(unsigned long data) |
4247 | { | 4143 | { |
4248 | struct s2io_nic *sp = (struct s2io_nic *)data; | 4144 | struct s2io_nic *sp = (struct s2io_nic *)data; |
4145 | struct net_device *dev = sp->dev; | ||
4249 | 4146 | ||
4250 | alarm_intr_handler(sp); | 4147 | s2io_handle_errors(dev); |
4251 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 4148 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
4252 | } | 4149 | } |
4253 | 4150 | ||
@@ -4366,6 +4263,292 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp) | |||
4366 | } | 4263 | } |
4367 | 4264 | ||
4368 | /** | 4265 | /** |
4266 | * do_s2io_chk_alarm_bit - Check for alarm and incrment the counter | ||
4267 | * @value: alarm bits | ||
4268 | * @addr: address value | ||
4269 | * @cnt: counter variable | ||
4270 | * Description: Check for alarm and increment the counter | ||
4271 | * Return Value: | ||
4272 | * 1 - if alarm bit set | ||
4273 | * 0 - if alarm bit is not set | ||
4274 | */ | ||
4275 | int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr, | ||
4276 | unsigned long long *cnt) | ||
4277 | { | ||
4278 | u64 val64; | ||
4279 | val64 = readq(addr); | ||
4280 | if ( val64 & value ) { | ||
4281 | writeq(val64, addr); | ||
4282 | (*cnt)++; | ||
4283 | return 1; | ||
4284 | } | ||
4285 | return 0; | ||
4286 | |||
4287 | } | ||
4288 | |||
4289 | /** | ||
4290 | * s2io_handle_errors - Xframe error indication handler | ||
4291 | * @nic: device private variable | ||
4292 | * Description: Handle alarms such as loss of link, single or | ||
4293 | * double ECC errors, critical and serious errors. | ||
4294 | * Return Value: | ||
4295 | * NONE | ||
4296 | */ | ||
4297 | static void s2io_handle_errors(void * dev_id) | ||
4298 | { | ||
4299 | struct net_device *dev = (struct net_device *) dev_id; | ||
4300 | struct s2io_nic *sp = dev->priv; | ||
4301 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4302 | u64 temp64 = 0,val64=0; | ||
4303 | int i = 0; | ||
4304 | |||
4305 | struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat; | ||
4306 | struct xpakStat *stats = &sp->mac_control.stats_info->xpak_stat; | ||
4307 | |||
4308 | if (unlikely(atomic_read(&sp->card_state) == CARD_DOWN)) | ||
4309 | return; | ||
4310 | |||
4311 | if (pci_channel_offline(sp->pdev)) | ||
4312 | return; | ||
4313 | |||
4314 | memset(&sw_stat->ring_full_cnt, 0, | ||
4315 | sizeof(sw_stat->ring_full_cnt)); | ||
4316 | |||
4317 | /* Handling the XPAK counters update */ | ||
4318 | if(stats->xpak_timer_count < 72000) { | ||
4319 | /* waiting for an hour */ | ||
4320 | stats->xpak_timer_count++; | ||
4321 | } else { | ||
4322 | s2io_updt_xpak_counter(dev); | ||
4323 | /* reset the count to zero */ | ||
4324 | stats->xpak_timer_count = 0; | ||
4325 | } | ||
4326 | |||
4327 | /* Handling link status change error Intr */ | ||
4328 | if (s2io_link_fault_indication(sp) == MAC_RMAC_ERR_TIMER) { | ||
4329 | val64 = readq(&bar0->mac_rmac_err_reg); | ||
4330 | writeq(val64, &bar0->mac_rmac_err_reg); | ||
4331 | if (val64 & RMAC_LINK_STATE_CHANGE_INT) | ||
4332 | schedule_work(&sp->set_link_task); | ||
4333 | } | ||
4334 | |||
4335 | /* In case of a serious error, the device will be Reset. */ | ||
4336 | if (do_s2io_chk_alarm_bit(SERR_SOURCE_ANY, &bar0->serr_source, | ||
4337 | &sw_stat->serious_err_cnt)) | ||
4338 | goto reset; | ||
4339 | |||
4340 | /* Check for data parity error */ | ||
4341 | if (do_s2io_chk_alarm_bit(GPIO_INT_REG_DP_ERR_INT, &bar0->gpio_int_reg, | ||
4342 | &sw_stat->parity_err_cnt)) | ||
4343 | goto reset; | ||
4344 | |||
4345 | /* Check for ring full counter */ | ||
4346 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
4347 | val64 = readq(&bar0->ring_bump_counter1); | ||
4348 | for (i=0; i<4; i++) { | ||
4349 | temp64 = ( val64 & vBIT(0xFFFF,(i*16),16)); | ||
4350 | temp64 >>= 64 - ((i+1)*16); | ||
4351 | sw_stat->ring_full_cnt[i] += temp64; | ||
4352 | } | ||
4353 | |||
4354 | val64 = readq(&bar0->ring_bump_counter2); | ||
4355 | for (i=0; i<4; i++) { | ||
4356 | temp64 = ( val64 & vBIT(0xFFFF,(i*16),16)); | ||
4357 | temp64 >>= 64 - ((i+1)*16); | ||
4358 | sw_stat->ring_full_cnt[i+4] += temp64; | ||
4359 | } | ||
4360 | } | ||
4361 | |||
4362 | val64 = readq(&bar0->txdma_int_status); | ||
4363 | /*check for pfc_err*/ | ||
4364 | if (val64 & TXDMA_PFC_INT) { | ||
4365 | if (do_s2io_chk_alarm_bit(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM| | ||
4366 | PFC_MISC_0_ERR | PFC_MISC_1_ERR| | ||
4367 | PFC_PCIX_ERR, &bar0->pfc_err_reg, | ||
4368 | &sw_stat->pfc_err_cnt)) | ||
4369 | goto reset; | ||
4370 | do_s2io_chk_alarm_bit(PFC_ECC_SG_ERR, &bar0->pfc_err_reg, | ||
4371 | &sw_stat->pfc_err_cnt); | ||
4372 | } | ||
4373 | |||
4374 | /*check for tda_err*/ | ||
4375 | if (val64 & TXDMA_TDA_INT) { | ||
4376 | if(do_s2io_chk_alarm_bit(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM | | ||
4377 | TDA_SM1_ERR_ALARM, &bar0->tda_err_reg, | ||
4378 | &sw_stat->tda_err_cnt)) | ||
4379 | goto reset; | ||
4380 | do_s2io_chk_alarm_bit(TDA_Fn_ECC_SG_ERR | TDA_PCIX_ERR, | ||
4381 | &bar0->tda_err_reg, &sw_stat->tda_err_cnt); | ||
4382 | } | ||
4383 | /*check for pcc_err*/ | ||
4384 | if (val64 & TXDMA_PCC_INT) { | ||
4385 | if (do_s2io_chk_alarm_bit(PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM | ||
4386 | | PCC_N_SERR | PCC_6_COF_OV_ERR | ||
4387 | | PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR | ||
4388 | | PCC_7_LSO_OV_ERR | PCC_FB_ECC_DB_ERR | ||
4389 | | PCC_TXB_ECC_DB_ERR, &bar0->pcc_err_reg, | ||
4390 | &sw_stat->pcc_err_cnt)) | ||
4391 | goto reset; | ||
4392 | do_s2io_chk_alarm_bit(PCC_FB_ECC_SG_ERR | PCC_TXB_ECC_SG_ERR, | ||
4393 | &bar0->pcc_err_reg, &sw_stat->pcc_err_cnt); | ||
4394 | } | ||
4395 | |||
4396 | /*check for tti_err*/ | ||
4397 | if (val64 & TXDMA_TTI_INT) { | ||
4398 | if (do_s2io_chk_alarm_bit(TTI_SM_ERR_ALARM, &bar0->tti_err_reg, | ||
4399 | &sw_stat->tti_err_cnt)) | ||
4400 | goto reset; | ||
4401 | do_s2io_chk_alarm_bit(TTI_ECC_SG_ERR | TTI_ECC_DB_ERR, | ||
4402 | &bar0->tti_err_reg, &sw_stat->tti_err_cnt); | ||
4403 | } | ||
4404 | |||
4405 | /*check for lso_err*/ | ||
4406 | if (val64 & TXDMA_LSO_INT) { | ||
4407 | if (do_s2io_chk_alarm_bit(LSO6_ABORT | LSO7_ABORT | ||
4408 | | LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM, | ||
4409 | &bar0->lso_err_reg, &sw_stat->lso_err_cnt)) | ||
4410 | goto reset; | ||
4411 | do_s2io_chk_alarm_bit(LSO6_SEND_OFLOW | LSO7_SEND_OFLOW, | ||
4412 | &bar0->lso_err_reg, &sw_stat->lso_err_cnt); | ||
4413 | } | ||
4414 | |||
4415 | /*check for tpa_err*/ | ||
4416 | if (val64 & TXDMA_TPA_INT) { | ||
4417 | if (do_s2io_chk_alarm_bit(TPA_SM_ERR_ALARM, &bar0->tpa_err_reg, | ||
4418 | &sw_stat->tpa_err_cnt)) | ||
4419 | goto reset; | ||
4420 | do_s2io_chk_alarm_bit(TPA_TX_FRM_DROP, &bar0->tpa_err_reg, | ||
4421 | &sw_stat->tpa_err_cnt); | ||
4422 | } | ||
4423 | |||
4424 | /*check for sm_err*/ | ||
4425 | if (val64 & TXDMA_SM_INT) { | ||
4426 | if (do_s2io_chk_alarm_bit(SM_SM_ERR_ALARM, &bar0->sm_err_reg, | ||
4427 | &sw_stat->sm_err_cnt)) | ||
4428 | goto reset; | ||
4429 | } | ||
4430 | |||
4431 | val64 = readq(&bar0->mac_int_status); | ||
4432 | if (val64 & MAC_INT_STATUS_TMAC_INT) { | ||
4433 | if (do_s2io_chk_alarm_bit(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR, | ||
4434 | &bar0->mac_tmac_err_reg, | ||
4435 | &sw_stat->mac_tmac_err_cnt)) | ||
4436 | goto reset; | ||
4437 | do_s2io_chk_alarm_bit(TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR | ||
4438 | | TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR, | ||
4439 | &bar0->mac_tmac_err_reg, | ||
4440 | &sw_stat->mac_tmac_err_cnt); | ||
4441 | } | ||
4442 | |||
4443 | val64 = readq(&bar0->xgxs_int_status); | ||
4444 | if (val64 & XGXS_INT_STATUS_TXGXS) { | ||
4445 | if (do_s2io_chk_alarm_bit(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR, | ||
4446 | &bar0->xgxs_txgxs_err_reg, | ||
4447 | &sw_stat->xgxs_txgxs_err_cnt)) | ||
4448 | goto reset; | ||
4449 | do_s2io_chk_alarm_bit(TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR, | ||
4450 | &bar0->xgxs_txgxs_err_reg, | ||
4451 | &sw_stat->xgxs_txgxs_err_cnt); | ||
4452 | } | ||
4453 | |||
4454 | val64 = readq(&bar0->rxdma_int_status); | ||
4455 | if (val64 & RXDMA_INT_RC_INT_M) { | ||
4456 | if (do_s2io_chk_alarm_bit(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR | ||
4457 | | RC_PRCn_SM_ERR_ALARM |RC_FTC_SM_ERR_ALARM, | ||
4458 | &bar0->rc_err_reg, &sw_stat->rc_err_cnt)) | ||
4459 | goto reset; | ||
4460 | do_s2io_chk_alarm_bit(RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR | ||
4461 | | RC_RDA_FAIL_WR_Rn, &bar0->rc_err_reg, | ||
4462 | &sw_stat->rc_err_cnt); | ||
4463 | if (do_s2io_chk_alarm_bit(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn | ||
4464 | | PRC_PCI_AB_F_WR_Rn, &bar0->prc_pcix_err_reg, | ||
4465 | &sw_stat->prc_pcix_err_cnt)) | ||
4466 | goto reset; | ||
4467 | do_s2io_chk_alarm_bit(PRC_PCI_DP_RD_Rn | PRC_PCI_DP_WR_Rn | ||
4468 | | PRC_PCI_DP_F_WR_Rn, &bar0->prc_pcix_err_reg, | ||
4469 | &sw_stat->prc_pcix_err_cnt); | ||
4470 | } | ||
4471 | |||
4472 | if (val64 & RXDMA_INT_RPA_INT_M) { | ||
4473 | if (do_s2io_chk_alarm_bit(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR, | ||
4474 | &bar0->rpa_err_reg, &sw_stat->rpa_err_cnt)) | ||
4475 | goto reset; | ||
4476 | do_s2io_chk_alarm_bit(RPA_ECC_SG_ERR | RPA_ECC_DB_ERR, | ||
4477 | &bar0->rpa_err_reg, &sw_stat->rpa_err_cnt); | ||
4478 | } | ||
4479 | |||
4480 | if (val64 & RXDMA_INT_RDA_INT_M) { | ||
4481 | if (do_s2io_chk_alarm_bit(RDA_RXDn_ECC_DB_ERR | ||
4482 | | RDA_FRM_ECC_DB_N_AERR | RDA_SM1_ERR_ALARM | ||
4483 | | RDA_SM0_ERR_ALARM | RDA_RXD_ECC_DB_SERR, | ||
4484 | &bar0->rda_err_reg, &sw_stat->rda_err_cnt)) | ||
4485 | goto reset; | ||
4486 | do_s2io_chk_alarm_bit(RDA_RXDn_ECC_SG_ERR | RDA_FRM_ECC_SG_ERR | ||
4487 | | RDA_MISC_ERR | RDA_PCIX_ERR, | ||
4488 | &bar0->rda_err_reg, &sw_stat->rda_err_cnt); | ||
4489 | } | ||
4490 | |||
4491 | if (val64 & RXDMA_INT_RTI_INT_M) { | ||
4492 | if (do_s2io_chk_alarm_bit(RTI_SM_ERR_ALARM, &bar0->rti_err_reg, | ||
4493 | &sw_stat->rti_err_cnt)) | ||
4494 | goto reset; | ||
4495 | do_s2io_chk_alarm_bit(RTI_ECC_SG_ERR | RTI_ECC_DB_ERR, | ||
4496 | &bar0->rti_err_reg, &sw_stat->rti_err_cnt); | ||
4497 | } | ||
4498 | |||
4499 | val64 = readq(&bar0->mac_int_status); | ||
4500 | if (val64 & MAC_INT_STATUS_RMAC_INT) { | ||
4501 | if (do_s2io_chk_alarm_bit(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR, | ||
4502 | &bar0->mac_rmac_err_reg, | ||
4503 | &sw_stat->mac_rmac_err_cnt)) | ||
4504 | goto reset; | ||
4505 | do_s2io_chk_alarm_bit(RMAC_UNUSED_INT|RMAC_SINGLE_ECC_ERR| | ||
4506 | RMAC_DOUBLE_ECC_ERR, &bar0->mac_rmac_err_reg, | ||
4507 | &sw_stat->mac_rmac_err_cnt); | ||
4508 | } | ||
4509 | |||
4510 | val64 = readq(&bar0->xgxs_int_status); | ||
4511 | if (val64 & XGXS_INT_STATUS_RXGXS) { | ||
4512 | if (do_s2io_chk_alarm_bit(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR, | ||
4513 | &bar0->xgxs_rxgxs_err_reg, | ||
4514 | &sw_stat->xgxs_rxgxs_err_cnt)) | ||
4515 | goto reset; | ||
4516 | } | ||
4517 | |||
4518 | val64 = readq(&bar0->mc_int_status); | ||
4519 | if(val64 & MC_INT_STATUS_MC_INT) { | ||
4520 | if (do_s2io_chk_alarm_bit(MC_ERR_REG_SM_ERR, &bar0->mc_err_reg, | ||
4521 | &sw_stat->mc_err_cnt)) | ||
4522 | goto reset; | ||
4523 | |||
4524 | /* Handling Ecc errors */ | ||
4525 | if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) { | ||
4526 | writeq(val64, &bar0->mc_err_reg); | ||
4527 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { | ||
4528 | sw_stat->double_ecc_errs++; | ||
4529 | if (sp->device_type != XFRAME_II_DEVICE) { | ||
4530 | /* | ||
4531 | * Reset XframeI only if critical error | ||
4532 | */ | ||
4533 | if (val64 & | ||
4534 | (MC_ERR_REG_MIRI_ECC_DB_ERR_0 | | ||
4535 | MC_ERR_REG_MIRI_ECC_DB_ERR_1)) | ||
4536 | goto reset; | ||
4537 | } | ||
4538 | } else | ||
4539 | sw_stat->single_ecc_errs++; | ||
4540 | } | ||
4541 | } | ||
4542 | return; | ||
4543 | |||
4544 | reset: | ||
4545 | netif_stop_queue(dev); | ||
4546 | schedule_work(&sp->rst_timer_task); | ||
4547 | sw_stat->soft_reset_cnt++; | ||
4548 | return; | ||
4549 | } | ||
4550 | |||
4551 | /** | ||
4369 | * s2io_isr - ISR handler of the device . | 4552 | * s2io_isr - ISR handler of the device . |
4370 | * @irq: the irq of the device. | 4553 | * @irq: the irq of the device. |
4371 | * @dev_id: a void pointer to the dev structure of the NIC. | 4554 | * @dev_id: a void pointer to the dev structure of the NIC. |
@@ -5754,7 +5937,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
5754 | struct ethtool_stats *estats, | 5937 | struct ethtool_stats *estats, |
5755 | u64 * tmp_stats) | 5938 | u64 * tmp_stats) |
5756 | { | 5939 | { |
5757 | int i = 0; | 5940 | int i = 0, k; |
5758 | struct s2io_nic *sp = dev->priv; | 5941 | struct s2io_nic *sp = dev->priv; |
5759 | struct stat_block *stat_info = sp->mac_control.stats_info; | 5942 | struct stat_block *stat_info = sp->mac_control.stats_info; |
5760 | 5943 | ||
@@ -5949,7 +6132,8 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
5949 | tmp_stats[i++] = stat_info->sw_stat.serious_err_cnt; | 6132 | tmp_stats[i++] = stat_info->sw_stat.serious_err_cnt; |
5950 | tmp_stats[i++] = stat_info->sw_stat.soft_reset_cnt; | 6133 | tmp_stats[i++] = stat_info->sw_stat.soft_reset_cnt; |
5951 | tmp_stats[i++] = stat_info->sw_stat.fifo_full_cnt; | 6134 | tmp_stats[i++] = stat_info->sw_stat.fifo_full_cnt; |
5952 | tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt; | 6135 | for (k = 0; k < MAX_RX_RINGS; k++) |
6136 | tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt[k]; | ||
5953 | tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_high; | 6137 | tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_high; |
5954 | tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_low; | 6138 | tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_low; |
5955 | tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_high; | 6139 | tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_high; |
@@ -6006,6 +6190,23 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
6006 | tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt; | 6190 | tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt; |
6007 | tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt; | 6191 | tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt; |
6008 | tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt; | 6192 | tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt; |
6193 | tmp_stats[i++] = stat_info->sw_stat.tda_err_cnt; | ||
6194 | tmp_stats[i++] = stat_info->sw_stat.pfc_err_cnt; | ||
6195 | tmp_stats[i++] = stat_info->sw_stat.pcc_err_cnt; | ||
6196 | tmp_stats[i++] = stat_info->sw_stat.tti_err_cnt; | ||
6197 | tmp_stats[i++] = stat_info->sw_stat.tpa_err_cnt; | ||
6198 | tmp_stats[i++] = stat_info->sw_stat.sm_err_cnt; | ||
6199 | tmp_stats[i++] = stat_info->sw_stat.lso_err_cnt; | ||
6200 | tmp_stats[i++] = stat_info->sw_stat.mac_tmac_err_cnt; | ||
6201 | tmp_stats[i++] = stat_info->sw_stat.mac_rmac_err_cnt; | ||
6202 | tmp_stats[i++] = stat_info->sw_stat.xgxs_txgxs_err_cnt; | ||
6203 | tmp_stats[i++] = stat_info->sw_stat.xgxs_rxgxs_err_cnt; | ||
6204 | tmp_stats[i++] = stat_info->sw_stat.rc_err_cnt; | ||
6205 | tmp_stats[i++] = stat_info->sw_stat.prc_pcix_err_cnt; | ||
6206 | tmp_stats[i++] = stat_info->sw_stat.rpa_err_cnt; | ||
6207 | tmp_stats[i++] = stat_info->sw_stat.rda_err_cnt; | ||
6208 | tmp_stats[i++] = stat_info->sw_stat.rti_err_cnt; | ||
6209 | tmp_stats[i++] = stat_info->sw_stat.mc_err_cnt; | ||
6009 | } | 6210 | } |
6010 | 6211 | ||
6011 | static int s2io_ethtool_get_regs_len(struct net_device *dev) | 6212 | static int s2io_ethtool_get_regs_len(struct net_device *dev) |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index b9654dfeb877..1e2e72d6aad2 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -91,7 +91,7 @@ struct swStat { | |||
91 | unsigned long long serious_err_cnt; | 91 | unsigned long long serious_err_cnt; |
92 | unsigned long long soft_reset_cnt; | 92 | unsigned long long soft_reset_cnt; |
93 | unsigned long long fifo_full_cnt; | 93 | unsigned long long fifo_full_cnt; |
94 | unsigned long long ring_full_cnt; | 94 | unsigned long long ring_full_cnt[8]; |
95 | /* LRO statistics */ | 95 | /* LRO statistics */ |
96 | unsigned long long clubbed_frms_cnt; | 96 | unsigned long long clubbed_frms_cnt; |
97 | unsigned long long sending_both; | 97 | unsigned long long sending_both; |
@@ -126,6 +126,26 @@ struct swStat { | |||
126 | unsigned long long rx_buf_size_err_cnt; | 126 | unsigned long long rx_buf_size_err_cnt; |
127 | unsigned long long rx_rxd_corrupt_cnt; | 127 | unsigned long long rx_rxd_corrupt_cnt; |
128 | unsigned long long rx_unkn_err_cnt; | 128 | unsigned long long rx_unkn_err_cnt; |
129 | |||
130 | /* Error/alarm statistics*/ | ||
131 | unsigned long long tda_err_cnt; | ||
132 | unsigned long long pfc_err_cnt; | ||
133 | unsigned long long pcc_err_cnt; | ||
134 | unsigned long long tti_err_cnt; | ||
135 | unsigned long long lso_err_cnt; | ||
136 | unsigned long long tpa_err_cnt; | ||
137 | unsigned long long sm_err_cnt; | ||
138 | unsigned long long mac_tmac_err_cnt; | ||
139 | unsigned long long mac_rmac_err_cnt; | ||
140 | unsigned long long xgxs_txgxs_err_cnt; | ||
141 | unsigned long long xgxs_rxgxs_err_cnt; | ||
142 | unsigned long long rc_err_cnt; | ||
143 | unsigned long long prc_pcix_err_cnt; | ||
144 | unsigned long long rpa_err_cnt; | ||
145 | unsigned long long rda_err_cnt; | ||
146 | unsigned long long rti_err_cnt; | ||
147 | unsigned long long mc_err_cnt; | ||
148 | |||
129 | }; | 149 | }; |
130 | 150 | ||
131 | /* Xpak releated alarm and warnings */ | 151 | /* Xpak releated alarm and warnings */ |
@@ -1018,7 +1038,7 @@ static void free_shared_mem(struct s2io_nic *sp); | |||
1018 | static int init_nic(struct s2io_nic *nic); | 1038 | static int init_nic(struct s2io_nic *nic); |
1019 | static void rx_intr_handler(struct ring_info *ring_data); | 1039 | static void rx_intr_handler(struct ring_info *ring_data); |
1020 | static void tx_intr_handler(struct fifo_info *fifo_data); | 1040 | static void tx_intr_handler(struct fifo_info *fifo_data); |
1021 | static void alarm_intr_handler(struct s2io_nic *sp); | 1041 | static void s2io_handle_errors(void * dev_id); |
1022 | 1042 | ||
1023 | static int s2io_starter(void); | 1043 | static int s2io_starter(void); |
1024 | static void s2io_closer(void); | 1044 | static void s2io_closer(void); |