Skip to content

Commit

Permalink
ionic: Add basic adminq support
Browse files Browse the repository at this point in the history
Most of the NIC configuration happens through the AdminQ message
queue.  NAPI is used for basic interrupt handling and message
queue management.  These routines are set up to be shared among
different types of queues when used in slow-path handling.

Signed-off-by: Shannon Nelson <snelson@pensando.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shannon Nelson authored and David S. Miller committed Sep 5, 2019
1 parent 6461b44 commit 1d062b7
Show file tree
Hide file tree
Showing 10 changed files with 941 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ struct ionic {
DECLARE_BITMAP(intrs, IONIC_INTR_CTRL_REGS_MAX);
};

int ionic_napi(struct napi_struct *napi, int budget, ionic_cq_cb cb,
ionic_cq_done_cb done_cb, void *done_arg);

int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait);
int ionic_set_dma_mask(struct ionic *ionic);
int ionic_setup(struct ionic *ionic);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef _IONIC_BUS_H_
#define _IONIC_BUS_H_

int ionic_bus_get_irq(struct ionic *ionic, unsigned int num);
const char *ionic_bus_info(struct ionic *ionic);
int ionic_bus_alloc_irq_vectors(struct ionic *ionic, unsigned int nintrs);
void ionic_bus_free_irq_vectors(struct ionic *ionic);
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ static const struct pci_device_id ionic_id_table[] = {
};
MODULE_DEVICE_TABLE(pci, ionic_id_table);

int ionic_bus_get_irq(struct ionic *ionic, unsigned int num)
{
return pci_irq_vector(ionic->pdev, num);
}

const char *ionic_bus_info(struct ionic *ionic)
{
return pci_name(ionic->pdev);
Expand Down
138 changes: 138 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,137 @@ void ionic_debugfs_add_sizes(struct ionic *ionic)
(u32 *)&ionic->ident.lif.eth.config.queue_count[IONIC_QTYPE_RXQ]);
}

static int q_tail_show(struct seq_file *seq, void *v)
{
struct ionic_queue *q = seq->private;

seq_printf(seq, "%d\n", q->tail->index);

return 0;
}
DEFINE_SHOW_ATTRIBUTE(q_tail);

static int q_head_show(struct seq_file *seq, void *v)
{
struct ionic_queue *q = seq->private;

seq_printf(seq, "%d\n", q->head->index);

return 0;
}
DEFINE_SHOW_ATTRIBUTE(q_head);

static int cq_tail_show(struct seq_file *seq, void *v)
{
struct ionic_cq *cq = seq->private;

seq_printf(seq, "%d\n", cq->tail->index);

return 0;
}
DEFINE_SHOW_ATTRIBUTE(cq_tail);

static const struct debugfs_reg32 intr_ctrl_regs[] = {
{ .name = "coal_init", .offset = 0, },
{ .name = "mask", .offset = 4, },
{ .name = "credits", .offset = 8, },
{ .name = "mask_on_assert", .offset = 12, },
{ .name = "coal_timer", .offset = 16, },
};

void ionic_debugfs_add_qcq(struct ionic_lif *lif, struct ionic_qcq *qcq)
{
struct dentry *q_dentry, *cq_dentry, *intr_dentry;
struct ionic_dev *idev = &lif->ionic->idev;
struct debugfs_regset32 *intr_ctrl_regset;
struct ionic_intr_info *intr = &qcq->intr;
struct debugfs_blob_wrapper *desc_blob;
struct device *dev = lif->ionic->dev;
struct ionic_queue *q = &qcq->q;
struct ionic_cq *cq = &qcq->cq;

qcq->dentry = debugfs_create_dir(q->name, lif->dentry);

debugfs_create_x32("total_size", 0400, qcq->dentry, &qcq->total_size);
debugfs_create_x64("base_pa", 0400, qcq->dentry, &qcq->base_pa);

q_dentry = debugfs_create_dir("q", qcq->dentry);

debugfs_create_u32("index", 0400, q_dentry, &q->index);
debugfs_create_x64("base_pa", 0400, q_dentry, &q->base_pa);
if (qcq->flags & IONIC_QCQ_F_SG) {
debugfs_create_x64("sg_base_pa", 0400, q_dentry,
&q->sg_base_pa);
debugfs_create_u32("sg_desc_size", 0400, q_dentry,
&q->sg_desc_size);
}
debugfs_create_u32("num_descs", 0400, q_dentry, &q->num_descs);
debugfs_create_u32("desc_size", 0400, q_dentry, &q->desc_size);
debugfs_create_u32("pid", 0400, q_dentry, &q->pid);
debugfs_create_u32("qid", 0400, q_dentry, &q->hw_index);
debugfs_create_u32("qtype", 0400, q_dentry, &q->hw_type);
debugfs_create_u64("drop", 0400, q_dentry, &q->drop);
debugfs_create_u64("stop", 0400, q_dentry, &q->stop);
debugfs_create_u64("wake", 0400, q_dentry, &q->wake);

debugfs_create_file("tail", 0400, q_dentry, q, &q_tail_fops);
debugfs_create_file("head", 0400, q_dentry, q, &q_head_fops);

desc_blob = devm_kzalloc(dev, sizeof(*desc_blob), GFP_KERNEL);
if (!desc_blob)
return;
desc_blob->data = q->base;
desc_blob->size = (unsigned long)q->num_descs * q->desc_size;
debugfs_create_blob("desc_blob", 0400, q_dentry, desc_blob);

if (qcq->flags & IONIC_QCQ_F_SG) {
desc_blob = devm_kzalloc(dev, sizeof(*desc_blob), GFP_KERNEL);
if (!desc_blob)
return;
desc_blob->data = q->sg_base;
desc_blob->size = (unsigned long)q->num_descs * q->sg_desc_size;
debugfs_create_blob("sg_desc_blob", 0400, q_dentry,
desc_blob);
}

cq_dentry = debugfs_create_dir("cq", qcq->dentry);

debugfs_create_x64("base_pa", 0400, cq_dentry, &cq->base_pa);
debugfs_create_u32("num_descs", 0400, cq_dentry, &cq->num_descs);
debugfs_create_u32("desc_size", 0400, cq_dentry, &cq->desc_size);
debugfs_create_u8("done_color", 0400, cq_dentry,
(u8 *)&cq->done_color);

debugfs_create_file("tail", 0400, cq_dentry, cq, &cq_tail_fops);

desc_blob = devm_kzalloc(dev, sizeof(*desc_blob), GFP_KERNEL);
if (!desc_blob)
return;
desc_blob->data = cq->base;
desc_blob->size = (unsigned long)cq->num_descs * cq->desc_size;
debugfs_create_blob("desc_blob", 0400, cq_dentry, desc_blob);

if (qcq->flags & IONIC_QCQ_F_INTR) {
intr_dentry = debugfs_create_dir("intr", qcq->dentry);

debugfs_create_u32("index", 0400, intr_dentry,
&intr->index);
debugfs_create_u32("vector", 0400, intr_dentry,
&intr->vector);

intr_ctrl_regset = devm_kzalloc(dev, sizeof(*intr_ctrl_regset),
GFP_KERNEL);
if (!intr_ctrl_regset)
return;
intr_ctrl_regset->regs = intr_ctrl_regs;
intr_ctrl_regset->nregs = ARRAY_SIZE(intr_ctrl_regs);
intr_ctrl_regset->base = &idev->intr_ctrl[intr->index];

debugfs_create_regset32("intr_ctrl", 0400, intr_dentry,
intr_ctrl_regset);
}
}

static int netdev_show(struct seq_file *seq, void *v)
{
struct net_device *netdev = seq->private;
Expand All @@ -94,4 +225,11 @@ void ionic_debugfs_del_lif(struct ionic_lif *lif)
debugfs_remove_recursive(lif->dentry);
lif->dentry = NULL;
}

void ionic_debugfs_del_qcq(struct ionic_qcq *qcq)
{
debugfs_remove_recursive(qcq->dentry);
qcq->dentry = NULL;
}

#endif
4 changes: 4 additions & 0 deletions drivers/net/ethernet/pensando/ionic/ionic_debugfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ void ionic_debugfs_del_dev(struct ionic *ionic);
void ionic_debugfs_add_ident(struct ionic *ionic);
void ionic_debugfs_add_sizes(struct ionic *ionic);
void ionic_debugfs_add_lif(struct ionic_lif *lif);
void ionic_debugfs_add_qcq(struct ionic_lif *lif, struct ionic_qcq *qcq);
void ionic_debugfs_del_lif(struct ionic_lif *lif);
void ionic_debugfs_del_qcq(struct ionic_qcq *qcq);
#else
static inline void ionic_debugfs_create(void) { }
static inline void ionic_debugfs_destroy(void) { }
Expand All @@ -24,7 +26,9 @@ static inline void ionic_debugfs_del_dev(struct ionic *ionic) { }
static inline void ionic_debugfs_add_ident(struct ionic *ionic) { }
static inline void ionic_debugfs_add_sizes(struct ionic *ionic) { }
static inline void ionic_debugfs_add_lif(struct ionic_lif *lif) { }
static inline void ionic_debugfs_add_qcq(struct ionic_lif *lif, struct ionic_qcq *qcq) { }
static inline void ionic_debugfs_del_lif(struct ionic_lif *lif) { }
static inline void ionic_debugfs_del_qcq(struct ionic_qcq *qcq) { }
#endif

#endif /* _IONIC_DEBUGFS_H_ */
Loading

0 comments on commit 1d062b7

Please sign in to comment.