Skip to content

Commit 5d3ac70

Browse files
Jiawen Wudavem330
authored andcommitted
net: txgbe: Add interrupt support
Determine proper interrupt scheme to enable and handle interrupt. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent e795613 commit 5d3ac70

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed

drivers/net/ethernet/wangxun/txgbe/txgbe_main.c

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <net/ip.h>
1212

1313
#include "../libwx/wx_type.h"
14+
#include "../libwx/wx_lib.h"
1415
#include "../libwx/wx_hw.h"
1516
#include "txgbe_type.h"
1617
#include "txgbe_hw.h"
@@ -72,9 +73,158 @@ static int txgbe_enumerate_functions(struct wx *wx)
7273
return physfns;
7374
}
7475

76+
/**
77+
* txgbe_irq_enable - Enable default interrupt generation settings
78+
* @wx: pointer to private structure
79+
* @queues: enable irqs for queues
80+
**/
81+
static void txgbe_irq_enable(struct wx *wx, bool queues)
82+
{
83+
/* unmask interrupt */
84+
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
85+
if (queues)
86+
wx_intr_enable(wx, TXGBE_INTR_QALL(wx));
87+
}
88+
89+
/**
90+
* txgbe_intr - msi/legacy mode Interrupt Handler
91+
* @irq: interrupt number
92+
* @data: pointer to a network interface device structure
93+
**/
94+
static irqreturn_t txgbe_intr(int __always_unused irq, void *data)
95+
{
96+
struct wx_q_vector *q_vector;
97+
struct wx *wx = data;
98+
struct pci_dev *pdev;
99+
u32 eicr;
100+
101+
q_vector = wx->q_vector[0];
102+
pdev = wx->pdev;
103+
104+
eicr = wx_misc_isb(wx, WX_ISB_VEC0);
105+
if (!eicr) {
106+
/* shared interrupt alert!
107+
* the interrupt that we masked before the ICR read.
108+
*/
109+
if (netif_running(wx->netdev))
110+
txgbe_irq_enable(wx, true);
111+
return IRQ_NONE; /* Not our interrupt */
112+
}
113+
wx->isb_mem[WX_ISB_VEC0] = 0;
114+
if (!(pdev->msi_enabled))
115+
wr32(wx, WX_PX_INTA, 1);
116+
117+
wx->isb_mem[WX_ISB_MISC] = 0;
118+
/* would disable interrupts here but it is auto disabled */
119+
napi_schedule_irqoff(&q_vector->napi);
120+
121+
/* re-enable link(maybe) and non-queue interrupts, no flush.
122+
* txgbe_poll will re-enable the queue interrupts
123+
*/
124+
if (netif_running(wx->netdev))
125+
txgbe_irq_enable(wx, false);
126+
127+
return IRQ_HANDLED;
128+
}
129+
130+
static irqreturn_t txgbe_msix_other(int __always_unused irq, void *data)
131+
{
132+
struct wx *wx = data;
133+
134+
/* re-enable the original interrupt state */
135+
if (netif_running(wx->netdev))
136+
txgbe_irq_enable(wx, false);
137+
138+
return IRQ_HANDLED;
139+
}
140+
141+
/**
142+
* txgbe_request_msix_irqs - Initialize MSI-X interrupts
143+
* @wx: board private structure
144+
*
145+
* Allocate MSI-X vectors and request interrupts from the kernel.
146+
**/
147+
static int txgbe_request_msix_irqs(struct wx *wx)
148+
{
149+
struct net_device *netdev = wx->netdev;
150+
int vector, err;
151+
152+
for (vector = 0; vector < wx->num_q_vectors; vector++) {
153+
struct wx_q_vector *q_vector = wx->q_vector[vector];
154+
struct msix_entry *entry = &wx->msix_entries[vector];
155+
156+
if (q_vector->tx.ring && q_vector->rx.ring)
157+
snprintf(q_vector->name, sizeof(q_vector->name) - 1,
158+
"%s-TxRx-%d", netdev->name, entry->entry);
159+
else
160+
/* skip this unused q_vector */
161+
continue;
162+
163+
err = request_irq(entry->vector, wx_msix_clean_rings, 0,
164+
q_vector->name, q_vector);
165+
if (err) {
166+
wx_err(wx, "request_irq failed for MSIX interrupt %s Error: %d\n",
167+
q_vector->name, err);
168+
goto free_queue_irqs;
169+
}
170+
}
171+
172+
err = request_irq(wx->msix_entries[vector].vector,
173+
txgbe_msix_other, 0, netdev->name, wx);
174+
if (err) {
175+
wx_err(wx, "request_irq for msix_other failed: %d\n", err);
176+
goto free_queue_irqs;
177+
}
178+
179+
return 0;
180+
181+
free_queue_irqs:
182+
while (vector) {
183+
vector--;
184+
free_irq(wx->msix_entries[vector].vector,
185+
wx->q_vector[vector]);
186+
}
187+
wx_reset_interrupt_capability(wx);
188+
return err;
189+
}
190+
191+
/**
192+
* txgbe_request_irq - initialize interrupts
193+
* @wx: board private structure
194+
*
195+
* Attempt to configure interrupts using the best available
196+
* capabilities of the hardware and kernel.
197+
**/
198+
static int txgbe_request_irq(struct wx *wx)
199+
{
200+
struct net_device *netdev = wx->netdev;
201+
struct pci_dev *pdev = wx->pdev;
202+
int err;
203+
204+
if (pdev->msix_enabled)
205+
err = txgbe_request_msix_irqs(wx);
206+
else if (pdev->msi_enabled)
207+
err = request_irq(wx->pdev->irq, &txgbe_intr, 0,
208+
netdev->name, wx);
209+
else
210+
err = request_irq(wx->pdev->irq, &txgbe_intr, IRQF_SHARED,
211+
netdev->name, wx);
212+
213+
if (err)
214+
wx_err(wx, "request_irq failed, Error %d\n", err);
215+
216+
return err;
217+
}
218+
75219
static void txgbe_up_complete(struct wx *wx)
76220
{
77221
wx_control_hw(wx, true);
222+
wx_configure_vectors(wx);
223+
224+
/* clear any pending interrupts, may auto mask */
225+
rd32(wx, WX_PX_IC);
226+
rd32(wx, WX_PX_MISC_IC);
227+
txgbe_irq_enable(wx, true);
78228
}
79229

80230
static void txgbe_reset(struct wx *wx)
@@ -104,6 +254,8 @@ static void txgbe_disable_device(struct wx *wx)
104254
netif_carrier_off(netdev);
105255
netif_tx_disable(netdev);
106256

257+
wx_irq_disable(wx);
258+
107259
if (wx->bus.func < 2)
108260
wr32m(wx, TXGBE_MIS_PRB_CTL, TXGBE_MIS_PRB_CTL_LAN_UP(wx->bus.func), 0);
109261
else
@@ -132,6 +284,7 @@ static void txgbe_down(struct wx *wx)
132284
**/
133285
static int txgbe_sw_init(struct wx *wx)
134286
{
287+
u16 msix_count = 0;
135288
int err;
136289

137290
wx->mac.num_rar_entries = TXGBE_SP_RAR_ENTRIES;
@@ -156,6 +309,25 @@ static int txgbe_sw_init(struct wx *wx)
156309
break;
157310
}
158311

312+
/* Set common capability flags and settings */
313+
wx->max_q_vectors = TXGBE_MAX_MSIX_VECTORS;
314+
err = wx_get_pcie_msix_counts(wx, &msix_count, TXGBE_MAX_MSIX_VECTORS);
315+
if (err)
316+
wx_err(wx, "Do not support MSI-X\n");
317+
wx->mac.max_msix_vectors = msix_count;
318+
319+
/* enable itr by default in dynamic mode */
320+
wx->rx_itr_setting = 1;
321+
wx->tx_itr_setting = 1;
322+
323+
/* set default ring sizes */
324+
wx->tx_ring_count = TXGBE_DEFAULT_TXD;
325+
wx->rx_ring_count = TXGBE_DEFAULT_RXD;
326+
327+
/* set default work limits */
328+
wx->tx_work_limit = TXGBE_DEFAULT_TX_WORK;
329+
wx->rx_work_limit = TXGBE_DEFAULT_RX_WORK;
330+
159331
return 0;
160332
}
161333

@@ -171,10 +343,28 @@ static int txgbe_sw_init(struct wx *wx)
171343
static int txgbe_open(struct net_device *netdev)
172344
{
173345
struct wx *wx = netdev_priv(netdev);
346+
int err;
347+
348+
err = wx_setup_isb_resources(wx);
349+
if (err)
350+
goto err_reset;
351+
352+
wx_configure(wx);
353+
354+
err = txgbe_request_irq(wx);
355+
if (err)
356+
goto err_free_isb;
174357

175358
txgbe_up_complete(wx);
176359

177360
return 0;
361+
362+
err_free_isb:
363+
wx_free_isb_resources(wx);
364+
err_reset:
365+
txgbe_reset(wx);
366+
367+
return err;
178368
}
179369

180370
/**
@@ -187,6 +377,9 @@ static int txgbe_open(struct net_device *netdev)
187377
static void txgbe_close_suspend(struct wx *wx)
188378
{
189379
txgbe_disable_device(wx);
380+
381+
wx_free_irq(wx);
382+
wx_free_isb_resources(wx);
190383
}
191384

192385
/**
@@ -205,6 +398,8 @@ static int txgbe_close(struct net_device *netdev)
205398
struct wx *wx = netdev_priv(netdev);
206399

207400
txgbe_down(wx);
401+
wx_free_irq(wx);
402+
wx_free_isb_resources(wx);
208403
wx_control_hw(wx, false);
209404

210405
return 0;
@@ -367,6 +562,10 @@ static int txgbe_probe(struct pci_dev *pdev,
367562
eth_hw_addr_set(netdev, wx->mac.perm_addr);
368563
wx_mac_set_default_filter(wx, wx->mac.perm_addr);
369564

565+
err = wx_init_interrupt_scheme(wx);
566+
if (err)
567+
goto err_free_mac_table;
568+
370569
/* Save off EEPROM version number and Option Rom version which
371570
* together make a unique identify for the eeprom
372571
*/
@@ -435,6 +634,7 @@ static int txgbe_probe(struct pci_dev *pdev,
435634
return 0;
436635

437636
err_release_hw:
637+
wx_clear_interrupt_scheme(wx);
438638
wx_control_hw(wx, false);
439639
err_free_mac_table:
440640
kfree(wx->mac_table);
@@ -468,6 +668,7 @@ static void txgbe_remove(struct pci_dev *pdev)
468668
pci_select_bars(pdev, IORESOURCE_MEM));
469669

470670
kfree(wx->mac_table);
671+
wx_clear_interrupt_scheme(wx);
471672

472673
pci_disable_pcie_error_reporting(pdev);
473674

drivers/net/ethernet/wangxun/txgbe/txgbe_type.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#define TXGBE_PBANUM1_PTR 0x06
6868
#define TXGBE_PBANUM_PTR_GUARD 0xFAFA
6969

70+
#define TXGBE_MAX_MSIX_VECTORS 64
7071
#define TXGBE_MAX_FDIR_INDICES 63
7172

7273
#define TXGBE_MAX_RX_QUEUES (TXGBE_MAX_FDIR_INDICES + 1)
@@ -77,6 +78,23 @@
7778
#define TXGBE_SP_RAR_ENTRIES 128
7879
#define TXGBE_SP_MC_TBL_SIZE 128
7980

81+
/* TX/RX descriptor defines */
82+
#define TXGBE_DEFAULT_TXD 512
83+
#define TXGBE_DEFAULT_TX_WORK 256
84+
85+
#if (PAGE_SIZE < 8192)
86+
#define TXGBE_DEFAULT_RXD 512
87+
#define TXGBE_DEFAULT_RX_WORK 256
88+
#else
89+
#define TXGBE_DEFAULT_RXD 256
90+
#define TXGBE_DEFAULT_RX_WORK 128
91+
#endif
92+
93+
#define TXGBE_INTR_MISC(A) BIT((A)->num_q_vectors)
94+
#define TXGBE_INTR_QALL(A) (TXGBE_INTR_MISC(A) - 1)
95+
96+
#define TXGBE_MAX_EITR GENMASK(11, 3)
97+
8098
extern char txgbe_driver_name[];
8199

82100
#endif /* _TXGBE_TYPE_H_ */

0 commit comments

Comments
 (0)