diff options
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r-- | drivers/net/cxgb3/adapter.h | 5 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 57 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_offload.h | 5 | ||||
-rw-r--r-- | drivers/net/cxgb3/regs.h | 16 | ||||
-rw-r--r-- | drivers/net/cxgb3/sge.c | 10 | ||||
-rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 5 |
6 files changed, 93 insertions, 5 deletions
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 3e8618b4efbc..4cd7f420766a 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h | |||
@@ -264,6 +264,10 @@ struct adapter { | |||
264 | struct work_struct fatal_error_handler_task; | 264 | struct work_struct fatal_error_handler_task; |
265 | struct work_struct link_fault_handler_task; | 265 | struct work_struct link_fault_handler_task; |
266 | 266 | ||
267 | struct work_struct db_full_task; | ||
268 | struct work_struct db_empty_task; | ||
269 | struct work_struct db_drop_task; | ||
270 | |||
267 | struct dentry *debugfs_root; | 271 | struct dentry *debugfs_root; |
268 | 272 | ||
269 | struct mutex mdio_lock; | 273 | struct mutex mdio_lock; |
@@ -335,6 +339,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, | |||
335 | int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, | 339 | int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, |
336 | unsigned char *data); | 340 | unsigned char *data); |
337 | irqreturn_t t3_sge_intr_msix(int irq, void *cookie); | 341 | irqreturn_t t3_sge_intr_msix(int irq, void *cookie); |
342 | extern struct workqueue_struct *cxgb3_wq; | ||
338 | 343 | ||
339 | int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size); | 344 | int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size); |
340 | 345 | ||
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 6fd968abb073..3e453e1d97e7 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/firmware.h> | 45 | #include <linux/firmware.h> |
46 | #include <linux/log2.h> | 46 | #include <linux/log2.h> |
47 | #include <linux/stringify.h> | 47 | #include <linux/stringify.h> |
48 | #include <linux/sched.h> | ||
48 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
49 | 50 | ||
50 | #include "common.h" | 51 | #include "common.h" |
@@ -140,7 +141,7 @@ MODULE_PARM_DESC(ofld_disable, "whether to enable offload at init time or not"); | |||
140 | * will block keventd as it needs the rtnl lock, and we'll deadlock waiting | 141 | * will block keventd as it needs the rtnl lock, and we'll deadlock waiting |
141 | * for our work to complete. Get our own work queue to solve this. | 142 | * for our work to complete. Get our own work queue to solve this. |
142 | */ | 143 | */ |
143 | static struct workqueue_struct *cxgb3_wq; | 144 | struct workqueue_struct *cxgb3_wq; |
144 | 145 | ||
145 | /** | 146 | /** |
146 | * link_report - show link status and link speed/duplex | 147 | * link_report - show link status and link speed/duplex |
@@ -586,6 +587,19 @@ static void setup_rss(struct adapter *adap) | |||
586 | V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map); | 587 | V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map); |
587 | } | 588 | } |
588 | 589 | ||
590 | static void ring_dbs(struct adapter *adap) | ||
591 | { | ||
592 | int i, j; | ||
593 | |||
594 | for (i = 0; i < SGE_QSETS; i++) { | ||
595 | struct sge_qset *qs = &adap->sge.qs[i]; | ||
596 | |||
597 | if (qs->adap) | ||
598 | for (j = 0; j < SGE_TXQ_PER_SET; j++) | ||
599 | t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX | V_EGRCNTX(qs->txq[j].cntxt_id)); | ||
600 | } | ||
601 | } | ||
602 | |||
589 | static void init_napi(struct adapter *adap) | 603 | static void init_napi(struct adapter *adap) |
590 | { | 604 | { |
591 | int i; | 605 | int i; |
@@ -2750,6 +2764,42 @@ static void t3_adap_check_task(struct work_struct *work) | |||
2750 | spin_unlock_irq(&adapter->work_lock); | 2764 | spin_unlock_irq(&adapter->work_lock); |
2751 | } | 2765 | } |
2752 | 2766 | ||
2767 | static void db_full_task(struct work_struct *work) | ||
2768 | { | ||
2769 | struct adapter *adapter = container_of(work, struct adapter, | ||
2770 | db_full_task); | ||
2771 | |||
2772 | cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_FULL, 0); | ||
2773 | } | ||
2774 | |||
2775 | static void db_empty_task(struct work_struct *work) | ||
2776 | { | ||
2777 | struct adapter *adapter = container_of(work, struct adapter, | ||
2778 | db_empty_task); | ||
2779 | |||
2780 | cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_EMPTY, 0); | ||
2781 | } | ||
2782 | |||
2783 | static void db_drop_task(struct work_struct *work) | ||
2784 | { | ||
2785 | struct adapter *adapter = container_of(work, struct adapter, | ||
2786 | db_drop_task); | ||
2787 | unsigned long delay = 1000; | ||
2788 | unsigned short r; | ||
2789 | |||
2790 | cxgb3_event_notify(&adapter->tdev, OFFLOAD_DB_DROP, 0); | ||
2791 | |||
2792 | /* | ||
2793 | * Sleep a while before ringing the driver qset dbs. | ||
2794 | * The delay is between 1000-2023 usecs. | ||
2795 | */ | ||
2796 | get_random_bytes(&r, 2); | ||
2797 | delay += r & 1023; | ||
2798 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2799 | schedule_timeout(usecs_to_jiffies(delay)); | ||
2800 | ring_dbs(adapter); | ||
2801 | } | ||
2802 | |||
2753 | /* | 2803 | /* |
2754 | * Processes external (PHY) interrupts in process context. | 2804 | * Processes external (PHY) interrupts in process context. |
2755 | */ | 2805 | */ |
@@ -3218,6 +3268,11 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
3218 | INIT_LIST_HEAD(&adapter->adapter_list); | 3268 | INIT_LIST_HEAD(&adapter->adapter_list); |
3219 | INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); | 3269 | INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); |
3220 | INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task); | 3270 | INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task); |
3271 | |||
3272 | INIT_WORK(&adapter->db_full_task, db_full_task); | ||
3273 | INIT_WORK(&adapter->db_empty_task, db_empty_task); | ||
3274 | INIT_WORK(&adapter->db_drop_task, db_drop_task); | ||
3275 | |||
3221 | INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); | 3276 | INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); |
3222 | 3277 | ||
3223 | for (i = 0; i < ai->nports0 + ai->nports1; ++i) { | 3278 | for (i = 0; i < ai->nports0 + ai->nports1; ++i) { |
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h index 670aa62042da..929c298115ca 100644 --- a/drivers/net/cxgb3/cxgb3_offload.h +++ b/drivers/net/cxgb3/cxgb3_offload.h | |||
@@ -73,7 +73,10 @@ enum { | |||
73 | OFFLOAD_STATUS_UP, | 73 | OFFLOAD_STATUS_UP, |
74 | OFFLOAD_STATUS_DOWN, | 74 | OFFLOAD_STATUS_DOWN, |
75 | OFFLOAD_PORT_DOWN, | 75 | OFFLOAD_PORT_DOWN, |
76 | OFFLOAD_PORT_UP | 76 | OFFLOAD_PORT_UP, |
77 | OFFLOAD_DB_FULL, | ||
78 | OFFLOAD_DB_EMPTY, | ||
79 | OFFLOAD_DB_DROP | ||
77 | }; | 80 | }; |
78 | 81 | ||
79 | struct cxgb3_client { | 82 | struct cxgb3_client { |
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index 1b5327b5a965..cb42353c9fdd 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h | |||
@@ -254,6 +254,22 @@ | |||
254 | #define V_LOPIODRBDROPERR(x) ((x) << S_LOPIODRBDROPERR) | 254 | #define V_LOPIODRBDROPERR(x) ((x) << S_LOPIODRBDROPERR) |
255 | #define F_LOPIODRBDROPERR V_LOPIODRBDROPERR(1U) | 255 | #define F_LOPIODRBDROPERR V_LOPIODRBDROPERR(1U) |
256 | 256 | ||
257 | #define S_HIPRIORITYDBFULL 7 | ||
258 | #define V_HIPRIORITYDBFULL(x) ((x) << S_HIPRIORITYDBFULL) | ||
259 | #define F_HIPRIORITYDBFULL V_HIPRIORITYDBFULL(1U) | ||
260 | |||
261 | #define S_HIPRIORITYDBEMPTY 6 | ||
262 | #define V_HIPRIORITYDBEMPTY(x) ((x) << S_HIPRIORITYDBEMPTY) | ||
263 | #define F_HIPRIORITYDBEMPTY V_HIPRIORITYDBEMPTY(1U) | ||
264 | |||
265 | #define S_LOPRIORITYDBFULL 5 | ||
266 | #define V_LOPRIORITYDBFULL(x) ((x) << S_LOPRIORITYDBFULL) | ||
267 | #define F_LOPRIORITYDBFULL V_LOPRIORITYDBFULL(1U) | ||
268 | |||
269 | #define S_LOPRIORITYDBEMPTY 4 | ||
270 | #define V_LOPRIORITYDBEMPTY(x) ((x) << S_LOPRIORITYDBEMPTY) | ||
271 | #define F_LOPRIORITYDBEMPTY V_LOPRIORITYDBEMPTY(1U) | ||
272 | |||
257 | #define S_RSPQDISABLED 3 | 273 | #define S_RSPQDISABLED 3 |
258 | #define V_RSPQDISABLED(x) ((x) << S_RSPQDISABLED) | 274 | #define V_RSPQDISABLED(x) ((x) << S_RSPQDISABLED) |
259 | #define F_RSPQDISABLED V_RSPQDISABLED(1U) | 275 | #define F_RSPQDISABLED V_RSPQDISABLED(1U) |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 048205903741..78e265b484b6 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "sge_defs.h" | 42 | #include "sge_defs.h" |
43 | #include "t3_cpl.h" | 43 | #include "t3_cpl.h" |
44 | #include "firmware_exports.h" | 44 | #include "firmware_exports.h" |
45 | #include "cxgb3_offload.h" | ||
45 | 46 | ||
46 | #define USE_GTS 0 | 47 | #define USE_GTS 0 |
47 | 48 | ||
@@ -2841,8 +2842,13 @@ void t3_sge_err_intr_handler(struct adapter *adapter) | |||
2841 | } | 2842 | } |
2842 | 2843 | ||
2843 | if (status & (F_HIPIODRBDROPERR | F_LOPIODRBDROPERR)) | 2844 | if (status & (F_HIPIODRBDROPERR | F_LOPIODRBDROPERR)) |
2844 | CH_ALERT(adapter, "SGE dropped %s priority doorbell\n", | 2845 | queue_work(cxgb3_wq, &adapter->db_drop_task); |
2845 | status & F_HIPIODRBDROPERR ? "high" : "lo"); | 2846 | |
2847 | if (status & (F_HIPRIORITYDBFULL | F_LOPRIORITYDBFULL)) | ||
2848 | queue_work(cxgb3_wq, &adapter->db_full_task); | ||
2849 | |||
2850 | if (status & (F_HIPRIORITYDBEMPTY | F_LOPRIORITYDBEMPTY)) | ||
2851 | queue_work(cxgb3_wq, &adapter->db_empty_task); | ||
2846 | 2852 | ||
2847 | t3_write_reg(adapter, A_SG_INT_CAUSE, status); | 2853 | t3_write_reg(adapter, A_SG_INT_CAUSE, status); |
2848 | if (status & SGE_FATALERR) | 2854 | if (status & SGE_FATALERR) |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 3ab9f51918aa..95a8ba0759f1 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -1433,7 +1433,10 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg, | |||
1433 | F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \ | 1433 | F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \ |
1434 | V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \ | 1434 | V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \ |
1435 | F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \ | 1435 | F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \ |
1436 | F_HIRCQPARITYERROR) | 1436 | F_HIRCQPARITYERROR | F_LOPRIORITYDBFULL | \ |
1437 | F_HIPRIORITYDBFULL | F_LOPRIORITYDBEMPTY | \ | ||
1438 | F_HIPRIORITYDBEMPTY | F_HIPIODRBDROPERR | \ | ||
1439 | F_LOPIODRBDROPERR) | ||
1437 | #define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \ | 1440 | #define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \ |
1438 | F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \ | 1441 | F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \ |
1439 | F_NFASRCHFAIL) | 1442 | F_NFASRCHFAIL) |