Skip to content

Commit e795613

Browse files
Mengyuan Loudavem330
authored andcommitted
net: ngbe: Add irqs request flow
Add request_irq for tx/rx rings and misc other events. If the application is successful, config vertors for interrupts. Enable some base interrupts mask in ngbe_irq_enable. Signed-off-by: Mengyuan Lou <mengyuanlou@net-swift.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 3f70318 commit e795613

File tree

2 files changed

+202
-1
lines changed

2 files changed

+202
-1
lines changed

drivers/net/ethernet/wangxun/ngbe/ngbe_main.c

Lines changed: 188 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "../libwx/wx_type.h"
1515
#include "../libwx/wx_hw.h"
16+
#include "../libwx/wx_lib.h"
1617
#include "ngbe_type.h"
1718
#include "ngbe_mdio.h"
1819
#include "ngbe_hw.h"
@@ -148,6 +149,161 @@ static int ngbe_sw_init(struct wx *wx)
148149
return 0;
149150
}
150151

152+
/**
153+
* ngbe_irq_enable - Enable default interrupt generation settings
154+
* @wx: board private structure
155+
* @queues: enable all queues interrupts
156+
**/
157+
static void ngbe_irq_enable(struct wx *wx, bool queues)
158+
{
159+
u32 mask;
160+
161+
/* enable misc interrupt */
162+
mask = NGBE_PX_MISC_IEN_MASK;
163+
164+
wr32(wx, WX_GPIO_DDR, WX_GPIO_DDR_0);
165+
wr32(wx, WX_GPIO_INTEN, WX_GPIO_INTEN_0 | WX_GPIO_INTEN_1);
166+
wr32(wx, WX_GPIO_INTTYPE_LEVEL, 0x0);
167+
wr32(wx, WX_GPIO_POLARITY, wx->gpio_ctrl ? 0 : 0x3);
168+
169+
wr32(wx, WX_PX_MISC_IEN, mask);
170+
171+
/* mask interrupt */
172+
if (queues)
173+
wx_intr_enable(wx, NGBE_INTR_ALL);
174+
else
175+
wx_intr_enable(wx, NGBE_INTR_MISC(wx));
176+
}
177+
178+
/**
179+
* ngbe_intr - msi/legacy mode Interrupt Handler
180+
* @irq: interrupt number
181+
* @data: pointer to a network interface device structure
182+
**/
183+
static irqreturn_t ngbe_intr(int __always_unused irq, void *data)
184+
{
185+
struct wx_q_vector *q_vector;
186+
struct wx *wx = data;
187+
struct pci_dev *pdev;
188+
u32 eicr;
189+
190+
q_vector = wx->q_vector[0];
191+
pdev = wx->pdev;
192+
193+
eicr = wx_misc_isb(wx, WX_ISB_VEC0);
194+
if (!eicr) {
195+
/* shared interrupt alert!
196+
* the interrupt that we masked before the EICR read.
197+
*/
198+
if (netif_running(wx->netdev))
199+
ngbe_irq_enable(wx, true);
200+
return IRQ_NONE; /* Not our interrupt */
201+
}
202+
wx->isb_mem[WX_ISB_VEC0] = 0;
203+
if (!(pdev->msi_enabled))
204+
wr32(wx, WX_PX_INTA, 1);
205+
206+
wx->isb_mem[WX_ISB_MISC] = 0;
207+
/* would disable interrupts here but it is auto disabled */
208+
napi_schedule_irqoff(&q_vector->napi);
209+
210+
if (netif_running(wx->netdev))
211+
ngbe_irq_enable(wx, false);
212+
213+
return IRQ_HANDLED;
214+
}
215+
216+
static irqreturn_t ngbe_msix_other(int __always_unused irq, void *data)
217+
{
218+
struct wx *wx = data;
219+
220+
/* re-enable the original interrupt state, no lsc, no queues */
221+
if (netif_running(wx->netdev))
222+
ngbe_irq_enable(wx, false);
223+
224+
return IRQ_HANDLED;
225+
}
226+
227+
/**
228+
* ngbe_request_msix_irqs - Initialize MSI-X interrupts
229+
* @wx: board private structure
230+
*
231+
* ngbe_request_msix_irqs allocates MSI-X vectors and requests
232+
* interrupts from the kernel.
233+
**/
234+
static int ngbe_request_msix_irqs(struct wx *wx)
235+
{
236+
struct net_device *netdev = wx->netdev;
237+
int vector, err;
238+
239+
for (vector = 0; vector < wx->num_q_vectors; vector++) {
240+
struct wx_q_vector *q_vector = wx->q_vector[vector];
241+
struct msix_entry *entry = &wx->msix_entries[vector];
242+
243+
if (q_vector->tx.ring && q_vector->rx.ring)
244+
snprintf(q_vector->name, sizeof(q_vector->name) - 1,
245+
"%s-TxRx-%d", netdev->name, entry->entry);
246+
else
247+
/* skip this unused q_vector */
248+
continue;
249+
250+
err = request_irq(entry->vector, wx_msix_clean_rings, 0,
251+
q_vector->name, q_vector);
252+
if (err) {
253+
wx_err(wx, "request_irq failed for MSIX interrupt %s Error: %d\n",
254+
q_vector->name, err);
255+
goto free_queue_irqs;
256+
}
257+
}
258+
259+
err = request_irq(wx->msix_entries[vector].vector,
260+
ngbe_msix_other, 0, netdev->name, wx);
261+
262+
if (err) {
263+
wx_err(wx, "request_irq for msix_other failed: %d\n", err);
264+
goto free_queue_irqs;
265+
}
266+
267+
return 0;
268+
269+
free_queue_irqs:
270+
while (vector) {
271+
vector--;
272+
free_irq(wx->msix_entries[vector].vector,
273+
wx->q_vector[vector]);
274+
}
275+
wx_reset_interrupt_capability(wx);
276+
return err;
277+
}
278+
279+
/**
280+
* ngbe_request_irq - initialize interrupts
281+
* @wx: board private structure
282+
*
283+
* Attempts to configure interrupts using the best available
284+
* capabilities of the hardware and kernel.
285+
**/
286+
static int ngbe_request_irq(struct wx *wx)
287+
{
288+
struct net_device *netdev = wx->netdev;
289+
struct pci_dev *pdev = wx->pdev;
290+
int err;
291+
292+
if (pdev->msix_enabled)
293+
err = ngbe_request_msix_irqs(wx);
294+
else if (pdev->msi_enabled)
295+
err = request_irq(pdev->irq, ngbe_intr, 0,
296+
netdev->name, wx);
297+
else
298+
err = request_irq(pdev->irq, ngbe_intr, IRQF_SHARED,
299+
netdev->name, wx);
300+
301+
if (err)
302+
wx_err(wx, "request_irq failed, Error %d\n", err);
303+
304+
return err;
305+
}
306+
151307
static void ngbe_disable_device(struct wx *wx)
152308
{
153309
struct net_device *netdev = wx->netdev;
@@ -157,6 +313,7 @@ static void ngbe_disable_device(struct wx *wx)
157313
netif_tx_disable(netdev);
158314
if (wx->gpio_ctrl)
159315
ngbe_sfp_modules_txrx_powerctl(wx, false);
316+
wx_irq_disable(wx);
160317
}
161318

162319
static void ngbe_down(struct wx *wx)
@@ -167,8 +324,15 @@ static void ngbe_down(struct wx *wx)
167324

168325
static void ngbe_up(struct wx *wx)
169326
{
327+
wx_configure_vectors(wx);
328+
329+
/* clear any pending interrupts, may auto mask */
330+
rd32(wx, WX_PX_IC);
331+
rd32(wx, WX_PX_MISC_IC);
332+
ngbe_irq_enable(wx, true);
170333
if (wx->gpio_ctrl)
171334
ngbe_sfp_modules_txrx_powerctl(wx, true);
335+
172336
phy_start(wx->phydev);
173337
}
174338

@@ -187,12 +351,26 @@ static int ngbe_open(struct net_device *netdev)
187351
int err;
188352

189353
wx_control_hw(wx, true);
354+
355+
err = wx_setup_isb_resources(wx);
356+
if (err)
357+
return err;
358+
359+
wx_configure(wx);
360+
361+
err = ngbe_request_irq(wx);
362+
if (err)
363+
goto err_req_irq;
364+
190365
err = ngbe_phy_connect(wx);
191366
if (err)
192367
return err;
193368
ngbe_up(wx);
194369

195370
return 0;
371+
err_req_irq:
372+
wx_free_isb_resources(wx);
373+
return err;
196374
}
197375

198376
/**
@@ -211,6 +389,8 @@ static int ngbe_close(struct net_device *netdev)
211389
struct wx *wx = netdev_priv(netdev);
212390

213391
ngbe_down(wx);
392+
wx_free_irq(wx);
393+
wx_free_isb_resources(wx);
214394
phy_disconnect(wx->phydev);
215395
wx_control_hw(wx, false);
216396

@@ -411,10 +591,14 @@ static int ngbe_probe(struct pci_dev *pdev,
411591
eth_hw_addr_set(netdev, wx->mac.perm_addr);
412592
wx_mac_set_default_filter(wx, wx->mac.perm_addr);
413593

594+
err = wx_init_interrupt_scheme(wx);
595+
if (err)
596+
goto err_free_mac_table;
597+
414598
/* phy Interface Configuration */
415599
err = ngbe_mdio_init(wx);
416600
if (err)
417-
goto err_free_mac_table;
601+
goto err_clear_interrupt_scheme;
418602

419603
err = register_netdev(netdev);
420604
if (err)
@@ -431,6 +615,8 @@ static int ngbe_probe(struct pci_dev *pdev,
431615

432616
err_register:
433617
wx_control_hw(wx, false);
618+
err_clear_interrupt_scheme:
619+
wx_clear_interrupt_scheme(wx);
434620
err_free_mac_table:
435621
kfree(wx->mac_table);
436622
err_pci_release_regions:
@@ -462,6 +648,7 @@ static void ngbe_remove(struct pci_dev *pdev)
462648
pci_select_bars(pdev, IORESOURCE_MEM));
463649

464650
kfree(wx->mac_table);
651+
wx_clear_interrupt_scheme(wx);
465652
pci_disable_pcie_error_reporting(pdev);
466653

467654
pci_disable_device(pdev);

drivers/net/ethernet/wangxun/ngbe/ngbe_type.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ enum NGBE_MSCA_CMD_value {
9090
#define NGBE_GPIO_DDR_0 BIT(0) /* SDP0 IO direction */
9191
#define NGBE_GPIO_DDR_1 BIT(1) /* SDP1 IO direction */
9292

93+
/* Extended Interrupt Enable Set */
94+
#define NGBE_PX_MISC_IEN_DEV_RST BIT(10)
95+
#define NGBE_PX_MISC_IEN_ETH_LK BIT(18)
96+
#define NGBE_PX_MISC_IEN_INT_ERR BIT(20)
97+
#define NGBE_PX_MISC_IEN_GPIO BIT(26)
98+
#define NGBE_PX_MISC_IEN_MASK ( \
99+
NGBE_PX_MISC_IEN_DEV_RST | \
100+
NGBE_PX_MISC_IEN_ETH_LK | \
101+
NGBE_PX_MISC_IEN_INT_ERR | \
102+
NGBE_PX_MISC_IEN_GPIO)
103+
104+
#define NGBE_INTR_ALL 0x1FF
105+
#define NGBE_INTR_MISC(A) BIT((A)->num_q_vectors)
106+
93107
#define NGBE_PHY_CONFIG(reg_offset) (0x14000 + ((reg_offset) * 4))
94108
#define NGBE_CFG_LAN_SPEED 0x14440
95109
#define NGBE_CFG_PORT_ST 0x14404

0 commit comments

Comments
 (0)