aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSivakumar Subramani <sivakumar.subramani@neterion.com>2007-09-17 16:05:35 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:51:09 -0400
commit8116f3cf4a2a5a4fa2335e6f32023ac50506698f (patch)
tree4db08fb067fd37c892f9a98e127854acd0fa3956 /drivers/net
parent9caab4587b8320c54fc666a6c820e966e6403aea (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/net')
-rw-r--r--drivers/net/s2io.c469
-rw-r--r--drivers/net/s2io.h24
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
3266static 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
4246s2io_alarm_handle(unsigned long data) 4142s2io_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 */
4275int 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 */
4297static 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
4544reset:
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
6011static int s2io_ethtool_get_regs_len(struct net_device *dev) 6212static 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);
1018static int init_nic(struct s2io_nic *nic); 1038static int init_nic(struct s2io_nic *nic);
1019static void rx_intr_handler(struct ring_info *ring_data); 1039static void rx_intr_handler(struct ring_info *ring_data);
1020static void tx_intr_handler(struct fifo_info *fifo_data); 1040static void tx_intr_handler(struct fifo_info *fifo_data);
1021static void alarm_intr_handler(struct s2io_nic *sp); 1041static void s2io_handle_errors(void * dev_id);
1022 1042
1023static int s2io_starter(void); 1043static int s2io_starter(void);
1024static void s2io_closer(void); 1044static void s2io_closer(void);