Skip to content

Commit 6461b44

Browse files
emuslndavem330
authored andcommitted
ionic: Add interrupts and doorbells
The ionic interrupt model is based on interrupt control blocks accessed through the PCI BAR. Doorbell registers are used by the driver to signal to the NIC that requests are waiting on the message queues. Interrupts are used by the NIC to signal to the driver that answers are waiting on the completion queues. Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1a58e19 commit 6461b44

File tree

8 files changed

+91
-0
lines changed

8 files changed

+91
-0
lines changed

drivers/net/ethernet/pensando/ionic/ionic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#ifndef _IONIC_H_
55
#define _IONIC_H_
66

7+
struct ionic_lif;
8+
79
#include "ionic_if.h"
810
#include "ionic_dev.h"
911
#include "ionic_devlink.h"
@@ -39,6 +41,7 @@ struct ionic {
3941
unsigned int nrxqs_per_lif;
4042
DECLARE_BITMAP(lifbits, IONIC_LIFS_MAX);
4143
unsigned int nintrs;
44+
DECLARE_BITMAP(intrs, IONIC_INTR_CTRL_REGS_MAX);
4245
};
4346

4447
int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);

drivers/net/ethernet/pensando/ionic/ionic_bus.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ int ionic_bus_alloc_irq_vectors(struct ionic *ionic, unsigned int nintrs);
99
void ionic_bus_free_irq_vectors(struct ionic *ionic);
1010
int ionic_bus_register_driver(void);
1111
void ionic_bus_unregister_driver(void);
12+
void __iomem *ionic_bus_map_dbpage(struct ionic *ionic, int page_num);
13+
void ionic_bus_unmap_dbpage(struct ionic *ionic, void __iomem *page);
1214

1315
#endif /* _IONIC_BUS_H_ */

drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ static void ionic_unmap_bars(struct ionic *ionic)
8787
}
8888
}
8989

90+
void __iomem *ionic_bus_map_dbpage(struct ionic *ionic, int page_num)
91+
{
92+
return pci_iomap_range(ionic->pdev,
93+
ionic->bars[IONIC_PCI_BAR_DBELL].res_index,
94+
(u64)page_num << PAGE_SHIFT, PAGE_SIZE);
95+
}
96+
97+
void ionic_bus_unmap_dbpage(struct ionic *ionic, void __iomem *page)
98+
{
99+
iounmap(page);
100+
}
101+
90102
static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
91103
{
92104
struct device *dev = &pdev->dev;

drivers/net/ethernet/pensando/ionic/ionic_dev.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/etherdevice.h>
1010
#include "ionic.h"
1111
#include "ionic_dev.h"
12+
#include "ionic_lif.h"
1213

1314
void ionic_init_devinfo(struct ionic *ionic)
1415
{
@@ -260,3 +261,8 @@ void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, u16 lif_index)
260261

261262
ionic_dev_cmd_go(idev, &cmd);
262263
}
264+
265+
int ionic_db_page_num(struct ionic_lif *lif, int pid)
266+
{
267+
return (lif->hw_index * lif->dbid_count) + pid;
268+
}

drivers/net/ethernet/pensando/ionic/ionic_dev.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,28 @@ struct ionic_dev {
126126
struct ionic_devinfo dev_info;
127127
};
128128

129+
#define INTR_INDEX_NOT_ASSIGNED -1
130+
#define INTR_NAME_MAX_SZ 32
131+
132+
struct ionic_intr_info {
133+
char name[INTR_NAME_MAX_SZ];
134+
unsigned int index;
135+
unsigned int vector;
136+
u64 rearm_count;
137+
unsigned int cpu;
138+
cpumask_t affinity_mask;
139+
};
140+
129141
struct ionic;
130142

143+
static inline void ionic_intr_init(struct ionic_dev *idev,
144+
struct ionic_intr_info *intr,
145+
unsigned long index)
146+
{
147+
ionic_intr_clean(idev->intr_ctrl, index);
148+
intr->index = index;
149+
}
150+
131151
void ionic_init_devinfo(struct ionic *ionic);
132152
int ionic_dev_setup(struct ionic *ionic);
133153
void ionic_dev_teardown(struct ionic *ionic);
@@ -155,4 +175,6 @@ void ionic_dev_cmd_lif_init(struct ionic_dev *idev, u16 lif_index,
155175
dma_addr_t addr);
156176
void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, u16 lif_index);
157177

178+
int ionic_db_page_num(struct ionic_lif *lif, int pid);
179+
158180
#endif /* _IONIC_DEV_H_ */

drivers/net/ethernet/pensando/ionic/ionic_lif.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ static void ionic_lif_free(struct ionic_lif *lif)
9494
lif->info = NULL;
9595
lif->info_pa = 0;
9696

97+
/* unmap doorbell page */
98+
ionic_bus_unmap_dbpage(lif->ionic, lif->kern_dbpage);
99+
lif->kern_dbpage = NULL;
100+
kfree(lif->dbid_inuse);
101+
lif->dbid_inuse = NULL;
102+
97103
/* free netdev & lif */
98104
ionic_debugfs_del_lif(lif);
99105
list_del(&lif->list);
@@ -136,7 +142,9 @@ void ionic_lifs_deinit(struct ionic *ionic)
136142
static int ionic_lif_init(struct ionic_lif *lif)
137143
{
138144
struct ionic_dev *idev = &lif->ionic->idev;
145+
struct device *dev = lif->ionic->dev;
139146
struct ionic_lif_init_comp comp;
147+
int dbpage_num;
140148
int err;
141149

142150
ionic_debugfs_add_lif(lif);
@@ -151,9 +159,40 @@ static int ionic_lif_init(struct ionic_lif *lif)
151159

152160
lif->hw_index = le16_to_cpu(comp.hw_index);
153161

162+
/* now that we have the hw_index we can figure out our doorbell page */
163+
lif->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif);
164+
if (!lif->dbid_count) {
165+
dev_err(dev, "No doorbell pages, aborting\n");
166+
return -EINVAL;
167+
}
168+
169+
lif->dbid_inuse = bitmap_alloc(lif->dbid_count, GFP_KERNEL);
170+
if (!lif->dbid_inuse) {
171+
dev_err(dev, "Failed alloc doorbell id bitmap, aborting\n");
172+
return -ENOMEM;
173+
}
174+
175+
/* first doorbell id reserved for kernel (dbid aka pid == zero) */
176+
set_bit(0, lif->dbid_inuse);
177+
lif->kern_pid = 0;
178+
179+
dbpage_num = ionic_db_page_num(lif, lif->kern_pid);
180+
lif->kern_dbpage = ionic_bus_map_dbpage(lif->ionic, dbpage_num);
181+
if (!lif->kern_dbpage) {
182+
dev_err(dev, "Cannot map dbpage, aborting\n");
183+
err = -ENOMEM;
184+
goto err_out_free_dbid;
185+
}
186+
154187
set_bit(IONIC_LIF_INITED, lif->state);
155188

156189
return 0;
190+
191+
err_out_free_dbid:
192+
kfree(lif->dbid_inuse);
193+
lif->dbid_inuse = NULL;
194+
195+
return err;
157196
}
158197

159198
int ionic_lifs_init(struct ionic *ionic)

drivers/net/ethernet/pensando/ionic/ionic_lif.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,17 @@ struct ionic_lif {
2323
bool registered;
2424
unsigned int index;
2525
unsigned int hw_index;
26+
unsigned int kern_pid;
27+
u64 __iomem *kern_dbpage;
2628
unsigned int neqs;
2729
unsigned int nxqs;
2830

2931
struct ionic_lif_info *info;
3032
dma_addr_t info_pa;
3133
u32 info_sz;
3234

35+
unsigned long *dbid_inuse;
36+
unsigned int dbid_count;
3337
struct dentry *dentry;
3438
u32 flags;
3539
};

drivers/net/ethernet/pensando/ionic/ionic_regs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ struct ionic_intr {
2222
u32 rsvd[3];
2323
};
2424

25+
#define IONIC_INTR_CTRL_REGS_MAX 2048
26+
#define IONIC_INTR_CTRL_COAL_MAX 0x3F
27+
2528
/** enum ionic_intr_mask_vals - valid values for mask and mask_assert.
2629
* @IONIC_INTR_MASK_CLEAR: unmask interrupt.
2730
* @IONIC_INTR_MASK_SET: mask interrupt.

0 commit comments

Comments
 (0)