aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
diff options
context:
space:
mode:
authorSantosh Rastapur <santosh@chelsio.com>2013-03-14 01:08:52 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-14 11:35:54 -0400
commit2cc301d20f80ecf532754aad39e150f488acdcb7 (patch)
tree79b3644cf36764230bdb0de858058411fb5918da /drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
parent22adfe0a85ca3808e09e7b4787cb08299d89aeaa (diff)
cxgb4: Enable doorbell drop recovery only for T4 adapter
Signed-off-by: Santosh Rastapur <santosh@chelsio.com> Signed-off-by: Vipul Pandya <vipul@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c')
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c87
1 files changed, 71 insertions, 16 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index ce1451cb5a26..177d0c199e01 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -3227,10 +3227,18 @@ EXPORT_SYMBOL(cxgb4_port_chan);
3227unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo) 3227unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo)
3228{ 3228{
3229 struct adapter *adap = netdev2adap(dev); 3229 struct adapter *adap = netdev2adap(dev);
3230 u32 v; 3230 u32 v1, v2, lp_count, hp_count;
3231 3231
3232 v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); 3232 v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
3233 return lpfifo ? G_LP_COUNT(v) : G_HP_COUNT(v); 3233 v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2);
3234 if (is_t4(adap->chip)) {
3235 lp_count = G_LP_COUNT(v1);
3236 hp_count = G_HP_COUNT(v1);
3237 } else {
3238 lp_count = G_LP_COUNT_T5(v1);
3239 hp_count = G_HP_COUNT_T5(v2);
3240 }
3241 return lpfifo ? lp_count : hp_count;
3234} 3242}
3235EXPORT_SYMBOL(cxgb4_dbfifo_count); 3243EXPORT_SYMBOL(cxgb4_dbfifo_count);
3236 3244
@@ -3368,14 +3376,23 @@ static struct notifier_block cxgb4_netevent_nb = {
3368 3376
3369static void drain_db_fifo(struct adapter *adap, int usecs) 3377static void drain_db_fifo(struct adapter *adap, int usecs)
3370{ 3378{
3371 u32 v; 3379 u32 v1, v2, lp_count, hp_count;
3372 3380
3373 do { 3381 do {
3382 v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
3383 v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2);
3384 if (is_t4(adap->chip)) {
3385 lp_count = G_LP_COUNT(v1);
3386 hp_count = G_HP_COUNT(v1);
3387 } else {
3388 lp_count = G_LP_COUNT_T5(v1);
3389 hp_count = G_HP_COUNT_T5(v2);
3390 }
3391
3392 if (lp_count == 0 && hp_count == 0)
3393 break;
3374 set_current_state(TASK_UNINTERRUPTIBLE); 3394 set_current_state(TASK_UNINTERRUPTIBLE);
3375 schedule_timeout(usecs_to_jiffies(usecs)); 3395 schedule_timeout(usecs_to_jiffies(usecs));
3376 v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
3377 if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0)
3378 break;
3379 } while (1); 3396 } while (1);
3380} 3397}
3381 3398
@@ -3484,24 +3501,62 @@ static void process_db_drop(struct work_struct *work)
3484 3501
3485 adap = container_of(work, struct adapter, db_drop_task); 3502 adap = container_of(work, struct adapter, db_drop_task);
3486 3503
3504 if (is_t4(adap->chip)) {
3505 disable_dbs(adap);
3506 notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
3507 drain_db_fifo(adap, 1);
3508 recover_all_queues(adap);
3509 enable_dbs(adap);
3510 } else {
3511 u32 dropped_db = t4_read_reg(adap, 0x010ac);
3512 u16 qid = (dropped_db >> 15) & 0x1ffff;
3513 u16 pidx_inc = dropped_db & 0x1fff;
3514 unsigned int s_qpp;
3515 unsigned short udb_density;
3516 unsigned long qpshift;
3517 int page;
3518 u32 udb;
3519
3520 dev_warn(adap->pdev_dev,
3521 "Dropped DB 0x%x qid %d bar2 %d coalesce %d pidx %d\n",
3522 dropped_db, qid,
3523 (dropped_db >> 14) & 1,
3524 (dropped_db >> 13) & 1,
3525 pidx_inc);
3526
3527 drain_db_fifo(adap, 1);
3528
3529 s_qpp = QUEUESPERPAGEPF1 * adap->fn;
3530 udb_density = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adap,
3531 SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp);
3532 qpshift = PAGE_SHIFT - ilog2(udb_density);
3533 udb = qid << qpshift;
3534 udb &= PAGE_MASK;
3535 page = udb / PAGE_SIZE;
3536 udb += (qid - (page * udb_density)) * 128;
3537
3538 writel(PIDX(pidx_inc), adap->bar2 + udb + 8);
3539
3540 /* Re-enable BAR2 WC */
3541 t4_set_reg_field(adap, 0x10b0, 1<<15, 1<<15);
3542 }
3543
3487 t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_DROPPED_DB, 0); 3544 t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_DROPPED_DB, 0);
3488 disable_dbs(adap);
3489 notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
3490 drain_db_fifo(adap, 1);
3491 recover_all_queues(adap);
3492 enable_dbs(adap);
3493} 3545}
3494 3546
3495void t4_db_full(struct adapter *adap) 3547void t4_db_full(struct adapter *adap)
3496{ 3548{
3497 t4_set_reg_field(adap, SGE_INT_ENABLE3, 3549 if (is_t4(adap->chip)) {
3498 DBFIFO_HP_INT | DBFIFO_LP_INT, 0); 3550 t4_set_reg_field(adap, SGE_INT_ENABLE3,
3499 queue_work(workq, &adap->db_full_task); 3551 DBFIFO_HP_INT | DBFIFO_LP_INT, 0);
3552 queue_work(workq, &adap->db_full_task);
3553 }
3500} 3554}
3501 3555
3502void t4_db_dropped(struct adapter *adap) 3556void t4_db_dropped(struct adapter *adap)
3503{ 3557{
3504 queue_work(workq, &adap->db_drop_task); 3558 if (is_t4(adap->chip))
3559 queue_work(workq, &adap->db_drop_task);
3505} 3560}
3506 3561
3507static void uld_attach(struct adapter *adap, unsigned int uld) 3562static void uld_attach(struct adapter *adap, unsigned int uld)