From 94ac2ab3fff96814d7460a27a0e9d004abbd4128 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 23:00:37 +0200 Subject: Merging upstream version 6.9.2. Signed-off-by: Daniel Baumann --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 369 ++++++++++++++++-------- 1 file changed, 243 insertions(+), 126 deletions(-) (limited to 'drivers/net/ethernet/pensando/ionic/ionic_lif.c') diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 44d30115de..7f0c6cdc37 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -46,18 +46,26 @@ static int ionic_start_queues(struct ionic_lif *lif); static void ionic_stop_queues(struct ionic_lif *lif); static void ionic_lif_queue_identify(struct ionic_lif *lif); +static int ionic_xdp_queues_config(struct ionic_lif *lif); +static void ionic_xdp_unregister_rxq_info(struct ionic_queue *q); + static void ionic_dim_work(struct work_struct *work) { struct dim *dim = container_of(work, struct dim, work); - struct ionic_intr_info *intr; struct dim_cq_moder cur_moder; + struct ionic_intr_info *intr; struct ionic_qcq *qcq; struct ionic_lif *lif; + struct ionic_queue *q; u32 new_coal; - cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); qcq = container_of(dim, struct ionic_qcq, dim); - lif = qcq->q.lif; + q = &qcq->q; + if (q->type == IONIC_QTYPE_RXQ) + cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); + else + cur_moder = net_dim_get_tx_moderation(dim->mode, dim->profile_ix); + lif = q->lif; new_coal = ionic_coal_usec_to_hw(lif->ionic, cur_moder.usec); new_coal = new_coal ? new_coal : 1; @@ -422,10 +430,9 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq) qcq->sg_base_pa = 0; } + ionic_xdp_unregister_rxq_info(&qcq->q); ionic_qcq_intr_free(lif, qcq); - vfree(qcq->cq.info); - qcq->cq.info = NULL; vfree(qcq->q.info); qcq->q.info = NULL; } @@ -529,14 +536,11 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, unsigned int num_descs, unsigned int desc_size, unsigned int cq_desc_size, unsigned int sg_desc_size, + unsigned int desc_info_size, unsigned int pid, struct ionic_qcq **qcq) { struct ionic_dev *idev = &lif->ionic->idev; struct device *dev = lif->ionic->dev; - void *q_base, *cq_base, *sg_base; - dma_addr_t cq_base_pa = 0; - dma_addr_t sg_base_pa = 0; - dma_addr_t q_base_pa = 0; struct ionic_qcq *new; int err; @@ -552,7 +556,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, new->q.dev = dev; new->flags = flags; - new->q.info = vcalloc(num_descs, sizeof(*new->q.info)); + new->q.info = vcalloc(num_descs, desc_info_size); if (!new->q.info) { netdev_err(lif->netdev, "Cannot allocate queue info\n"); err = -ENOMEM; @@ -571,19 +575,12 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, err = ionic_alloc_qcq_interrupt(lif, new); if (err) - goto err_out; - - new->cq.info = vcalloc(num_descs, sizeof(*new->cq.info)); - if (!new->cq.info) { - netdev_err(lif->netdev, "Cannot allocate completion queue info\n"); - err = -ENOMEM; - goto err_out_free_irq; - } + goto err_out_free_q_info; err = ionic_cq_init(lif, &new->cq, &new->intr, num_descs, cq_desc_size); if (err) { netdev_err(lif->netdev, "Cannot initialize completion queue\n"); - goto err_out_free_cq_info; + goto err_out_free_irq; } if (flags & IONIC_QCQ_F_NOTIFYQ) { @@ -601,16 +598,15 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, if (!new->q_base) { netdev_err(lif->netdev, "Cannot allocate qcq DMA memory\n"); err = -ENOMEM; - goto err_out_free_cq_info; + goto err_out_free_irq; } - q_base = PTR_ALIGN(new->q_base, PAGE_SIZE); - q_base_pa = ALIGN(new->q_base_pa, PAGE_SIZE); - ionic_q_map(&new->q, q_base, q_base_pa); - - cq_base = PTR_ALIGN(q_base + q_size, PAGE_SIZE); - cq_base_pa = ALIGN(new->q_base_pa + q_size, PAGE_SIZE); - ionic_cq_map(&new->cq, cq_base, cq_base_pa); - ionic_cq_bind(&new->cq, &new->q); + new->q.base = PTR_ALIGN(new->q_base, PAGE_SIZE); + new->q.base_pa = ALIGN(new->q_base_pa, PAGE_SIZE); + + /* Base the NotifyQ cq.base off of the ALIGNed q.base */ + new->cq.base = PTR_ALIGN(new->q.base + q_size, PAGE_SIZE); + new->cq.base_pa = ALIGN(new->q_base_pa + q_size, PAGE_SIZE); + new->cq.bound_q = &new->q; } else { /* regular DMA q descriptors */ new->q_size = PAGE_SIZE + (num_descs * desc_size); @@ -619,11 +615,10 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, if (!new->q_base) { netdev_err(lif->netdev, "Cannot allocate queue DMA memory\n"); err = -ENOMEM; - goto err_out_free_cq_info; + goto err_out_free_irq; } - q_base = PTR_ALIGN(new->q_base, PAGE_SIZE); - q_base_pa = ALIGN(new->q_base_pa, PAGE_SIZE); - ionic_q_map(&new->q, q_base, q_base_pa); + new->q.base = PTR_ALIGN(new->q_base, PAGE_SIZE); + new->q.base_pa = ALIGN(new->q_base_pa, PAGE_SIZE); if (flags & IONIC_QCQ_F_CMB_RINGS) { /* on-chip CMB q descriptors */ @@ -648,7 +643,8 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, } new->cmb_q_base_pa -= idev->phy_cmb_pages; - ionic_q_cmb_map(&new->q, new->cmb_q_base, new->cmb_q_base_pa); + new->q.cmb_base = new->cmb_q_base; + new->q.cmb_base_pa = new->cmb_q_base_pa; } /* cq DMA descriptors */ @@ -660,10 +656,9 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, err = -ENOMEM; goto err_out_free_q; } - cq_base = PTR_ALIGN(new->cq_base, PAGE_SIZE); - cq_base_pa = ALIGN(new->cq_base_pa, PAGE_SIZE); - ionic_cq_map(&new->cq, cq_base, cq_base_pa); - ionic_cq_bind(&new->cq, &new->q); + new->cq.base = PTR_ALIGN(new->cq_base, PAGE_SIZE); + new->cq.base_pa = ALIGN(new->cq_base_pa, PAGE_SIZE); + new->cq.bound_q = &new->q; } if (flags & IONIC_QCQ_F_SG) { @@ -675,13 +670,12 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, err = -ENOMEM; goto err_out_free_cq; } - sg_base = PTR_ALIGN(new->sg_base, PAGE_SIZE); - sg_base_pa = ALIGN(new->sg_base_pa, PAGE_SIZE); - ionic_q_sg_map(&new->q, sg_base, sg_base_pa); + new->q.sg_base = PTR_ALIGN(new->sg_base, PAGE_SIZE); + new->q.sg_base_pa = ALIGN(new->sg_base_pa, PAGE_SIZE); } INIT_WORK(&new->dim.work, ionic_dim_work); - new->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + new->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_CQE; *qcq = new; @@ -695,8 +689,6 @@ err_out_free_q: ionic_put_cmb(lif, new->cmb_pgid, new->cmb_order); } dma_free_coherent(dev, new->q_size, new->q_base, new->q_base_pa); -err_out_free_cq_info: - vfree(new->cq.info); err_out_free_irq: if (flags & IONIC_QCQ_F_INTR) { devm_free_irq(dev, new->intr.vector, &new->napi); @@ -722,7 +714,9 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif) IONIC_ADMINQ_LENGTH, sizeof(struct ionic_admin_cmd), sizeof(struct ionic_admin_comp), - 0, lif->kern_pid, &lif->adminqcq); + 0, + sizeof(struct ionic_admin_desc_info), + lif->kern_pid, &lif->adminqcq); if (err) return err; ionic_debugfs_add_qcq(lif, lif->adminqcq); @@ -733,7 +727,9 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif) flags, IONIC_NOTIFYQ_LENGTH, sizeof(struct ionic_notifyq_cmd), sizeof(union ionic_notifyq_comp), - 0, lif->kern_pid, &lif->notifyqcq); + 0, + sizeof(struct ionic_admin_desc_info), + lif->kern_pid, &lif->notifyqcq); if (err) goto err_out; ionic_debugfs_add_qcq(lif, lif->notifyqcq); @@ -862,8 +858,7 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) .type = q->type, .ver = lif->qtype_info[q->type].version, .index = cpu_to_le32(q->index), - .flags = cpu_to_le16(IONIC_QINIT_F_IRQ | - IONIC_QINIT_F_SG), + .flags = cpu_to_le16(IONIC_QINIT_F_IRQ), .intr_index = cpu_to_le16(cq->bound_intr->index), .pid = cpu_to_le16(q->pid), .ring_size = ilog2(q->num_descs), @@ -875,6 +870,13 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) }; int err; + q->partner = &lif->txqcqs[q->index]->q; + q->partner->partner = q; + + if (!lif->xdp_prog || + (lif->xdp_prog->aux && lif->xdp_prog->aux->xdp_has_frags)) + ctx.cmd.q_init.flags |= cpu_to_le16(IONIC_QINIT_F_SG); + if (qcq->flags & IONIC_QCQ_F_CMB_RINGS) { ctx.cmd.q_init.flags |= cpu_to_le16(IONIC_QINIT_F_CMB); ctx.cmd.q_init.ring_base = cpu_to_le64(qcq->cmb_q_base_pa); @@ -945,6 +947,7 @@ int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif) err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, txq_i, "hwstamp_tx", flags, num_desc, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_tx_desc_info), lif->kern_pid, &txq); if (err) goto err_qcq_alloc; @@ -1004,6 +1007,7 @@ int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif) err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, rxq_i, "hwstamp_rx", flags, num_desc, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_rx_desc_info), lif->kern_pid, &rxq); if (err) goto err_qcq_alloc; @@ -1157,71 +1161,6 @@ int ionic_lif_set_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class) return ionic_lif_add_hwstamp_rxfilt(lif, pkt_class); } -static bool ionic_notifyq_service(struct ionic_cq *cq, - struct ionic_cq_info *cq_info) -{ - union ionic_notifyq_comp *comp = cq_info->cq_desc; - struct ionic_deferred_work *work; - struct net_device *netdev; - struct ionic_queue *q; - struct ionic_lif *lif; - u64 eid; - - q = cq->bound_q; - lif = q->info[0].cb_arg; - netdev = lif->netdev; - eid = le64_to_cpu(comp->event.eid); - - /* Have we run out of new completions to process? */ - if ((s64)(eid - lif->last_eid) <= 0) - return false; - - lif->last_eid = eid; - - dev_dbg(lif->ionic->dev, "notifyq event:\n"); - dynamic_hex_dump("event ", DUMP_PREFIX_OFFSET, 16, 1, - comp, sizeof(*comp), true); - - switch (le16_to_cpu(comp->event.ecode)) { - case IONIC_EVENT_LINK_CHANGE: - ionic_link_status_check_request(lif, CAN_NOT_SLEEP); - break; - case IONIC_EVENT_RESET: - if (lif->ionic->idev.fw_status_ready && - !test_bit(IONIC_LIF_F_FW_RESET, lif->state) && - !test_and_set_bit(IONIC_LIF_F_FW_STOPPING, lif->state)) { - work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) { - netdev_err(lif->netdev, "Reset event dropped\n"); - clear_bit(IONIC_LIF_F_FW_STOPPING, lif->state); - } else { - work->type = IONIC_DW_TYPE_LIF_RESET; - ionic_lif_deferred_enqueue(&lif->deferred, work); - } - } - break; - default: - netdev_warn(netdev, "Notifyq event ecode=%d eid=%lld\n", - comp->event.ecode, eid); - break; - } - - return true; -} - -static bool ionic_adminq_service(struct ionic_cq *cq, - struct ionic_cq_info *cq_info) -{ - struct ionic_admin_comp *comp = cq_info->cq_desc; - - if (!color_match(comp->color, cq->done_color)) - return false; - - ionic_q_service(cq->bound_q, cq_info, le16_to_cpu(comp->comp_index)); - - return true; -} - static int ionic_adminq_napi(struct napi_struct *napi, int budget) { struct ionic_intr_info *intr = napi_to_cq(napi)->bound_intr; @@ -1252,8 +1191,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget) ionic_rx_service, NULL, NULL); if (lif->hwstamp_txq) - tx_work = ionic_cq_service(&lif->hwstamp_txq->cq, budget, - ionic_tx_service, NULL, NULL); + tx_work = ionic_tx_cq_service(&lif->hwstamp_txq->cq, budget); work_done = max(max(n_work, a_work), max(rx_work, tx_work)); if (work_done < budget && napi_complete_done(napi, work_done)) { @@ -1640,6 +1578,12 @@ static int ionic_init_nic_features(struct ionic_lif *lif) netdev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE; + netdev->xdp_features = NETDEV_XDP_ACT_BASIC | + NETDEV_XDP_ACT_REDIRECT | + NETDEV_XDP_ACT_RX_SG | + NETDEV_XDP_ACT_NDO_XMIT | + NETDEV_XDP_ACT_NDO_XMIT_SG; + return 0; } @@ -1777,6 +1721,21 @@ static int ionic_start_queues_reconfig(struct ionic_lif *lif) return err; } +static bool ionic_xdp_is_valid_mtu(struct ionic_lif *lif, u32 mtu, + struct bpf_prog *xdp_prog) +{ + if (!xdp_prog) + return true; + + if (mtu <= IONIC_XDP_MAX_LINEAR_MTU) + return true; + + if (xdp_prog->aux && xdp_prog->aux->xdp_has_frags) + return true; + + return false; +} + static int ionic_change_mtu(struct net_device *netdev, int new_mtu) { struct ionic_lif *lif = netdev_priv(netdev); @@ -1789,8 +1748,13 @@ static int ionic_change_mtu(struct net_device *netdev, int new_mtu) .mtu = cpu_to_le32(new_mtu), }, }; + struct bpf_prog *xdp_prog; int err; + xdp_prog = READ_ONCE(lif->xdp_prog); + if (!ionic_xdp_is_valid_mtu(lif, new_mtu, xdp_prog)) + return -EINVAL; + err = ionic_adminq_post_wait(lif, &ctx); if (err) return err; @@ -2070,6 +2034,7 @@ static int ionic_txrx_alloc(struct ionic_lif *lif) for (i = 0; i < lif->nxqs; i++) { err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags, num_desc, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_tx_desc_info), lif->kern_pid, &lif->txqcqs[i]); if (err) goto err_out; @@ -2101,6 +2066,7 @@ static int ionic_txrx_alloc(struct ionic_lif *lif) for (i = 0; i < lif->nxqs; i++) { err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags, num_desc, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_rx_desc_info), lif->kern_pid, &lif->rxqcqs[i]); if (err) goto err_out; @@ -2166,6 +2132,10 @@ static int ionic_txrx_enable(struct ionic_lif *lif) int derr = 0; int i, err; + err = ionic_xdp_queues_config(lif); + if (err) + return err; + for (i = 0; i < lif->nxqs; i++) { if (!(lif->rxqcqs[i] && lif->txqcqs[i])) { dev_err(lif->ionic->dev, "%s: bad qcq %d\n", __func__, i); @@ -2211,6 +2181,8 @@ err_out: derr = ionic_qcq_disable(lif, lif->rxqcqs[i], derr); } + ionic_xdp_queues_config(lif); + return err; } @@ -2668,11 +2640,151 @@ static void ionic_vf_attr_replay(struct ionic_lif *lif) ionic_vf_start(ionic); } +static void ionic_xdp_unregister_rxq_info(struct ionic_queue *q) +{ + struct xdp_rxq_info *xi; + + if (!q->xdp_rxq_info) + return; + + xi = q->xdp_rxq_info; + q->xdp_rxq_info = NULL; + + xdp_rxq_info_unreg(xi); + kfree(xi); +} + +static int ionic_xdp_register_rxq_info(struct ionic_queue *q, unsigned int napi_id) +{ + struct xdp_rxq_info *rxq_info; + int err; + + rxq_info = kzalloc(sizeof(*rxq_info), GFP_KERNEL); + if (!rxq_info) + return -ENOMEM; + + err = xdp_rxq_info_reg(rxq_info, q->lif->netdev, q->index, napi_id); + if (err) { + dev_err(q->dev, "Queue %d xdp_rxq_info_reg failed, err %d\n", + q->index, err); + goto err_out; + } + + err = xdp_rxq_info_reg_mem_model(rxq_info, MEM_TYPE_PAGE_ORDER0, NULL); + if (err) { + dev_err(q->dev, "Queue %d xdp_rxq_info_reg_mem_model failed, err %d\n", + q->index, err); + xdp_rxq_info_unreg(rxq_info); + goto err_out; + } + + q->xdp_rxq_info = rxq_info; + + return 0; + +err_out: + kfree(rxq_info); + return err; +} + +static int ionic_xdp_queues_config(struct ionic_lif *lif) +{ + unsigned int i; + int err; + + if (!lif->rxqcqs) + return 0; + + /* There's no need to rework memory if not going to/from NULL program. + * If there is no lif->xdp_prog, there should also be no q.xdp_rxq_info + * This way we don't need to keep an *xdp_prog in every queue struct. + */ + if (!lif->xdp_prog == !lif->rxqcqs[0]->q.xdp_rxq_info) + return 0; + + for (i = 0; i < lif->ionic->nrxqs_per_lif && lif->rxqcqs[i]; i++) { + struct ionic_queue *q = &lif->rxqcqs[i]->q; + + if (q->xdp_rxq_info) { + ionic_xdp_unregister_rxq_info(q); + continue; + } + + err = ionic_xdp_register_rxq_info(q, lif->rxqcqs[i]->napi.napi_id); + if (err) { + dev_err(lif->ionic->dev, "failed to register RX queue %d info for XDP, err %d\n", + i, err); + goto err_out; + } + } + + return 0; + +err_out: + for (i = 0; i < lif->ionic->nrxqs_per_lif && lif->rxqcqs[i]; i++) + ionic_xdp_unregister_rxq_info(&lif->rxqcqs[i]->q); + + return err; +} + +static int ionic_xdp_config(struct net_device *netdev, struct netdev_bpf *bpf) +{ + struct ionic_lif *lif = netdev_priv(netdev); + struct bpf_prog *old_prog; + u32 maxfs; + + if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) { +#define XDP_ERR_SPLIT "XDP not available with split Tx/Rx interrupts" + NL_SET_ERR_MSG_MOD(bpf->extack, XDP_ERR_SPLIT); + netdev_info(lif->netdev, XDP_ERR_SPLIT); + return -EOPNOTSUPP; + } + + if (!ionic_xdp_is_valid_mtu(lif, netdev->mtu, bpf->prog)) { +#define XDP_ERR_MTU "MTU is too large for XDP without frags support" + NL_SET_ERR_MSG_MOD(bpf->extack, XDP_ERR_MTU); + netdev_info(lif->netdev, XDP_ERR_MTU); + return -EINVAL; + } + + maxfs = __le32_to_cpu(lif->identity->eth.max_frame_size) - VLAN_ETH_HLEN; + if (bpf->prog && !(bpf->prog->aux && bpf->prog->aux->xdp_has_frags)) + maxfs = min_t(u32, maxfs, IONIC_XDP_MAX_LINEAR_MTU); + netdev->max_mtu = maxfs; + + if (!netif_running(netdev)) { + old_prog = xchg(&lif->xdp_prog, bpf->prog); + } else { + mutex_lock(&lif->queue_lock); + ionic_stop_queues_reconfig(lif); + old_prog = xchg(&lif->xdp_prog, bpf->prog); + ionic_start_queues_reconfig(lif); + mutex_unlock(&lif->queue_lock); + } + + if (old_prog) + bpf_prog_put(old_prog); + + return 0; +} + +static int ionic_xdp(struct net_device *netdev, struct netdev_bpf *bpf) +{ + switch (bpf->command) { + case XDP_SETUP_PROG: + return ionic_xdp_config(netdev, bpf); + default: + return -EINVAL; + } +} + static const struct net_device_ops ionic_netdev_ops = { .ndo_open = ionic_open, .ndo_stop = ionic_stop, .ndo_eth_ioctl = ionic_eth_ioctl, .ndo_start_xmit = ionic_start_xmit, + .ndo_bpf = ionic_xdp, + .ndo_xdp_xmit = ionic_xdp_xmit, .ndo_get_stats64 = ionic_get_stats64, .ndo_set_rx_mode = ionic_ndo_set_rx_mode, .ndo_set_features = ionic_set_features, @@ -2755,6 +2867,8 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b) swap(a->q.base, b->q.base); swap(a->q.base_pa, b->q.base_pa); swap(a->q.info, b->q.info); + swap(a->q.xdp_rxq_info, b->q.xdp_rxq_info); + swap(a->q.partner, b->q.partner); swap(a->q_base, b->q_base); swap(a->q_base_pa, b->q_base_pa); swap(a->q_size, b->q_size); @@ -2770,7 +2884,6 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b) swap(a->cq.desc_size, b->cq.desc_size); swap(a->cq.base, b->cq.base); swap(a->cq.base_pa, b->cq.base_pa); - swap(a->cq.info, b->cq.info); swap(a->cq_base, b->cq_base); swap(a->cq_base_pa, b->cq_base_pa); swap(a->cq_size, b->cq_size); @@ -2834,6 +2947,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif, flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG; err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags, 4, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_tx_desc_info), lif->kern_pid, &lif->txqcqs[i]); if (err) goto err_out; @@ -2842,6 +2956,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif, flags = lif->txqcqs[i]->flags & ~IONIC_QCQ_F_INTR; err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags, num_desc, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_tx_desc_info), lif->kern_pid, &tx_qcqs[i]); if (err) goto err_out; @@ -2863,6 +2978,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif, flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG; err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags, 4, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_rx_desc_info), lif->kern_pid, &lif->rxqcqs[i]); if (err) goto err_out; @@ -2871,6 +2987,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif, flags = lif->rxqcqs[i]->flags & ~IONIC_QCQ_F_INTR; err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags, num_desc, desc_sz, comp_sz, sg_desc_sz, + sizeof(struct ionic_rx_desc_info), lif->kern_pid, &rx_qcqs[i]); if (err) goto err_out; @@ -3445,7 +3562,7 @@ static int ionic_lif_notifyq_init(struct ionic_lif *lif) dev_dbg(dev, "notifyq->hw_index %d\n", q->hw_index); /* preset the callback info */ - q->info[0].cb_arg = lif; + q->admin_info[0].ctx = lif; qcq->flags |= IONIC_QCQ_F_INITED; @@ -3697,6 +3814,7 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif) union ionic_q_identity __iomem *q_ident; struct ionic *ionic = lif->ionic; struct ionic_dev *idev; + u16 max_frags; int qtype; int err; @@ -3764,17 +3882,16 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif) dev_dbg(ionic->dev, " qtype[%d].sg_desc_stride = %d\n", qtype, qti->sg_desc_stride); - if (qti->max_sg_elems >= IONIC_MAX_FRAGS) { - qti->max_sg_elems = IONIC_MAX_FRAGS - 1; - dev_dbg(ionic->dev, "limiting qtype %d max_sg_elems to IONIC_MAX_FRAGS-1 %d\n", - qtype, qti->max_sg_elems); - } + if (qtype == IONIC_QTYPE_TXQ) + max_frags = IONIC_TX_MAX_FRAGS; + else if (qtype == IONIC_QTYPE_RXQ) + max_frags = IONIC_RX_MAX_FRAGS; + else + max_frags = 1; - if (qti->max_sg_elems > MAX_SKB_FRAGS) { - qti->max_sg_elems = MAX_SKB_FRAGS; - dev_dbg(ionic->dev, "limiting qtype %d max_sg_elems to MAX_SKB_FRAGS %d\n", - qtype, qti->max_sg_elems); - } + qti->max_sg_elems = min_t(u16, max_frags - 1, MAX_SKB_FRAGS); + dev_dbg(ionic->dev, "qtype %d max_sg_elems %d\n", + qtype, qti->max_sg_elems); } } -- cgit v1.2.3