#ifndef _IONIC_H_
#define _IONIC_H_
+struct ionic_lif;
+
#include "ionic_if.h"
#include "ionic_dev.h"
#include "ionic_devlink.h"
unsigned int nrxqs_per_lif;
DECLARE_BITMAP(lifbits, IONIC_LIFS_MAX);
unsigned int nintrs;
+ DECLARE_BITMAP(intrs, IONIC_INTR_CTRL_REGS_MAX);
};
int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);
void ionic_bus_free_irq_vectors(struct ionic *ionic);
int ionic_bus_register_driver(void);
void ionic_bus_unregister_driver(void);
+void __iomem *ionic_bus_map_dbpage(struct ionic *ionic, int page_num);
+void ionic_bus_unmap_dbpage(struct ionic *ionic, void __iomem *page);
#endif /* _IONIC_BUS_H_ */
}
}
+void __iomem *ionic_bus_map_dbpage(struct ionic *ionic, int page_num)
+{
+ return pci_iomap_range(ionic->pdev,
+ ionic->bars[IONIC_PCI_BAR_DBELL].res_index,
+ (u64)page_num << PAGE_SHIFT, PAGE_SIZE);
+}
+
+void ionic_bus_unmap_dbpage(struct ionic *ionic, void __iomem *page)
+{
+ iounmap(page);
+}
+
static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct device *dev = &pdev->dev;
#include <linux/etherdevice.h>
#include "ionic.h"
#include "ionic_dev.h"
+#include "ionic_lif.h"
void ionic_init_devinfo(struct ionic *ionic)
{
ionic_dev_cmd_go(idev, &cmd);
}
+
+int ionic_db_page_num(struct ionic_lif *lif, int pid)
+{
+ return (lif->hw_index * lif->dbid_count) + pid;
+}
struct ionic_devinfo dev_info;
};
+#define INTR_INDEX_NOT_ASSIGNED -1
+#define INTR_NAME_MAX_SZ 32
+
+struct ionic_intr_info {
+ char name[INTR_NAME_MAX_SZ];
+ unsigned int index;
+ unsigned int vector;
+ u64 rearm_count;
+ unsigned int cpu;
+ cpumask_t affinity_mask;
+};
+
struct ionic;
+static inline void ionic_intr_init(struct ionic_dev *idev,
+ struct ionic_intr_info *intr,
+ unsigned long index)
+{
+ ionic_intr_clean(idev->intr_ctrl, index);
+ intr->index = index;
+}
+
void ionic_init_devinfo(struct ionic *ionic);
int ionic_dev_setup(struct ionic *ionic);
void ionic_dev_teardown(struct ionic *ionic);
dma_addr_t addr);
void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, u16 lif_index);
+int ionic_db_page_num(struct ionic_lif *lif, int pid);
+
#endif /* _IONIC_DEV_H_ */
lif->info = NULL;
lif->info_pa = 0;
+ /* unmap doorbell page */
+ ionic_bus_unmap_dbpage(lif->ionic, lif->kern_dbpage);
+ lif->kern_dbpage = NULL;
+ kfree(lif->dbid_inuse);
+ lif->dbid_inuse = NULL;
+
/* free netdev & lif */
ionic_debugfs_del_lif(lif);
list_del(&lif->list);
static int ionic_lif_init(struct ionic_lif *lif)
{
struct ionic_dev *idev = &lif->ionic->idev;
+ struct device *dev = lif->ionic->dev;
struct ionic_lif_init_comp comp;
+ int dbpage_num;
int err;
ionic_debugfs_add_lif(lif);
lif->hw_index = le16_to_cpu(comp.hw_index);
+ /* now that we have the hw_index we can figure out our doorbell page */
+ lif->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif);
+ if (!lif->dbid_count) {
+ dev_err(dev, "No doorbell pages, aborting\n");
+ return -EINVAL;
+ }
+
+ lif->dbid_inuse = bitmap_alloc(lif->dbid_count, GFP_KERNEL);
+ if (!lif->dbid_inuse) {
+ dev_err(dev, "Failed alloc doorbell id bitmap, aborting\n");
+ return -ENOMEM;
+ }
+
+ /* first doorbell id reserved for kernel (dbid aka pid == zero) */
+ set_bit(0, lif->dbid_inuse);
+ lif->kern_pid = 0;
+
+ dbpage_num = ionic_db_page_num(lif, lif->kern_pid);
+ lif->kern_dbpage = ionic_bus_map_dbpage(lif->ionic, dbpage_num);
+ if (!lif->kern_dbpage) {
+ dev_err(dev, "Cannot map dbpage, aborting\n");
+ err = -ENOMEM;
+ goto err_out_free_dbid;
+ }
+
set_bit(IONIC_LIF_INITED, lif->state);
return 0;
+
+err_out_free_dbid:
+ kfree(lif->dbid_inuse);
+ lif->dbid_inuse = NULL;
+
+ return err;
}
int ionic_lifs_init(struct ionic *ionic)
bool registered;
unsigned int index;
unsigned int hw_index;
+ unsigned int kern_pid;
+ u64 __iomem *kern_dbpage;
unsigned int neqs;
unsigned int nxqs;
dma_addr_t info_pa;
u32 info_sz;
+ unsigned long *dbid_inuse;
+ unsigned int dbid_count;
struct dentry *dentry;
u32 flags;
};
u32 rsvd[3];
};
+#define IONIC_INTR_CTRL_REGS_MAX 2048
+#define IONIC_INTR_CTRL_COAL_MAX 0x3F
+
/** enum ionic_intr_mask_vals - valid values for mask and mask_assert.
* @IONIC_INTR_MASK_CLEAR: unmask interrupt.
* @IONIC_INTR_MASK_SET: mask interrupt.