aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3/cxgb3_main.c
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2009-03-12 17:14:09 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-13 14:30:45 -0400
commitfc88219601aa3f94def89433a6afde154e8faa8c (patch)
tree8c921807f947ba25c7ce188c9ec586aa57b0a0f9 /drivers/net/cxgb3/cxgb3_main.c
parent42c8ea17e8f78752ed5a354791b0ea1697dc3480 (diff)
cxgb3: disable high freq non-data interrupts
Under RX pressure, The HW might generate a high load of interrupts to signal mac fifo or free lists overflow. Disable the interrupts, and poll the relevant status bits to maintain stats. Signed-off-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_main.c')
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index c32f514c41a7..9ff0452fcddd 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -2471,6 +2471,8 @@ static void t3_adap_check_task(struct work_struct *work)
2471 struct adapter *adapter = container_of(work, struct adapter, 2471 struct adapter *adapter = container_of(work, struct adapter,
2472 adap_check_task.work); 2472 adap_check_task.work);
2473 const struct adapter_params *p = &adapter->params; 2473 const struct adapter_params *p = &adapter->params;
2474 int port;
2475 unsigned int v, status, reset;
2474 2476
2475 adapter->check_task_cnt++; 2477 adapter->check_task_cnt++;
2476 2478
@@ -2489,6 +2491,54 @@ static void t3_adap_check_task(struct work_struct *work)
2489 if (p->rev == T3_REV_B2) 2491 if (p->rev == T3_REV_B2)
2490 check_t3b2_mac(adapter); 2492 check_t3b2_mac(adapter);
2491 2493
2494 /*
2495 * Scan the XGMAC's to check for various conditions which we want to
2496 * monitor in a periodic polling manner rather than via an interrupt
2497 * condition. This is used for conditions which would otherwise flood
2498 * the system with interrupts and we only really need to know that the
2499 * conditions are "happening" ... For each condition we count the
2500 * detection of the condition and reset it for the next polling loop.
2501 */
2502 for_each_port(adapter, port) {
2503 struct cmac *mac = &adap2pinfo(adapter, port)->mac;
2504 u32 cause;
2505
2506 cause = t3_read_reg(adapter, A_XGM_INT_CAUSE + mac->offset);
2507 reset = 0;
2508 if (cause & F_RXFIFO_OVERFLOW) {
2509 mac->stats.rx_fifo_ovfl++;
2510 reset |= F_RXFIFO_OVERFLOW;
2511 }
2512
2513 t3_write_reg(adapter, A_XGM_INT_CAUSE + mac->offset, reset);
2514 }
2515
2516 /*
2517 * We do the same as above for FL_EMPTY interrupts.
2518 */
2519 status = t3_read_reg(adapter, A_SG_INT_CAUSE);
2520 reset = 0;
2521
2522 if (status & F_FLEMPTY) {
2523 struct sge_qset *qs = &adapter->sge.qs[0];
2524 int i = 0;
2525
2526 reset |= F_FLEMPTY;
2527
2528 v = (t3_read_reg(adapter, A_SG_RSPQ_FL_STATUS) >> S_FL0EMPTY) &
2529 0xffff;
2530
2531 while (v) {
2532 qs->fl[i].empty += (v & 1);
2533 if (i)
2534 qs++;
2535 i ^= 1;
2536 v >>= 1;
2537 }
2538 }
2539
2540 t3_write_reg(adapter, A_SG_INT_CAUSE, reset);
2541
2492 /* Schedule the next check update if any port is active. */ 2542 /* Schedule the next check update if any port is active. */
2493 spin_lock_irq(&adapter->work_lock); 2543 spin_lock_irq(&adapter->work_lock);
2494 if (adapter->open_device_map & PORT_MASK) 2544 if (adapter->open_device_map & PORT_MASK)