From 9576a36cc107ba206c182a6ae9fb179db6f32bef Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:39 -0700 Subject: [PATCH 1/8] ionic: contiguous memory for notifyq The event notification queue is set up a little differently in the NIC and so the notifyq q and cq descriptor structures need to be contiguous, which got missed in an earlier patch that separated out the q and cq descriptor allocations. That patch was aimed at making the big tx and rx descriptor queue allocations easier to manage - the notifyq is much smaller and doesn't need to be split. This patch simply adds an if/else and slightly different code for the notifyq descriptor allocation. Fixes: ea5a8b09dc3a ("ionic: reduce contiguous memory allocation requirement") Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_lif.c | 69 +++++++++++++------ 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 1b4d5eb9bbc99..969979b31e93f 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -518,30 +518,55 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, goto err_out_free_cq_info; } - new->q_size = PAGE_SIZE + (num_descs * desc_size); - new->q_base = dma_alloc_coherent(dev, new->q_size, &new->q_base_pa, - GFP_KERNEL); - if (!new->q_base) { - netdev_err(lif->netdev, "Cannot allocate queue DMA memory\n"); - err = -ENOMEM; - goto err_out_free_cq_info; - } - 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); + if (flags & IONIC_QCQ_F_NOTIFYQ) { + int q_size, cq_size; + + /* q & cq need to be contiguous in case of notifyq */ + q_size = ALIGN(num_descs * desc_size, PAGE_SIZE); + cq_size = ALIGN(num_descs * cq_desc_size, PAGE_SIZE); + + new->q_size = PAGE_SIZE + q_size + cq_size; + new->q_base = dma_alloc_coherent(dev, new->q_size, + &new->q_base_pa, GFP_KERNEL); + if (!new->q_base) { + netdev_err(lif->netdev, "Cannot allocate qcq DMA memory\n"); + err = -ENOMEM; + goto err_out_free_cq_info; + } + 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); + } else { + new->q_size = PAGE_SIZE + (num_descs * desc_size); + new->q_base = dma_alloc_coherent(dev, new->q_size, &new->q_base_pa, + GFP_KERNEL); + if (!new->q_base) { + netdev_err(lif->netdev, "Cannot allocate queue DMA memory\n"); + err = -ENOMEM; + goto err_out_free_cq_info; + } + 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->cq_size = PAGE_SIZE + (num_descs * cq_desc_size); - new->cq_base = dma_alloc_coherent(dev, new->cq_size, &new->cq_base_pa, - GFP_KERNEL); - if (!new->cq_base) { - netdev_err(lif->netdev, "Cannot allocate cq DMA memory\n"); - err = -ENOMEM; - goto err_out_free_q; + new->cq_size = PAGE_SIZE + (num_descs * cq_desc_size); + new->cq_base = dma_alloc_coherent(dev, new->cq_size, &new->cq_base_pa, + GFP_KERNEL); + if (!new->cq_base) { + netdev_err(lif->netdev, "Cannot allocate cq DMA memory\n"); + 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); } - 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); if (flags & IONIC_QCQ_F_SG) { new->sg_size = PAGE_SIZE + (num_descs * sg_desc_size); From 52733cff9b6e9fc2868d10fb7171f690dcb8b5a7 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:40 -0700 Subject: [PATCH 2/8] ionic: drain the work queue Check through our work list for additional items. This normally will only have one item, but occasionally may have another job waiting. There really is no need reschedule ourself here. Reported-by: Sebastian Andrzej Siewior Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_lif.c | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 969979b31e93f..53ac0e4402e73 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -62,15 +62,18 @@ static void ionic_lif_deferred_work(struct work_struct *work) struct ionic_deferred *def = &lif->deferred; struct ionic_deferred_work *w = NULL; - spin_lock_bh(&def->lock); - if (!list_empty(&def->list)) { - w = list_first_entry(&def->list, - struct ionic_deferred_work, list); - list_del(&w->list); - } - spin_unlock_bh(&def->lock); + do { + spin_lock_bh(&def->lock); + if (!list_empty(&def->list)) { + w = list_first_entry(&def->list, + struct ionic_deferred_work, list); + list_del(&w->list); + } + spin_unlock_bh(&def->lock); + + if (!w) + break; - if (w) { switch (w->type) { case IONIC_DW_TYPE_RX_MODE: ionic_lif_rx_mode(lif, w->rx_mode); @@ -94,8 +97,8 @@ static void ionic_lif_deferred_work(struct work_struct *work) break; } kfree(w); - schedule_work(&def->work); - } + w = NULL; + } while (true); } void ionic_lif_deferred_enqueue(struct ionic_deferred *def, From 2c580d7783c78c115cea9e50b43477f3eab5076d Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:41 -0700 Subject: [PATCH 3/8] ionic: clear linkcheck bit on alloc fail Clear our link check requested flag on an allocation error. We end up dropping this link check request, but that should be fine as our watchdog will come back a few seconds later and request it again. Reported-by: Sebastian Andrzej Siewior Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 53ac0e4402e73..5906145e45859 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -164,8 +164,10 @@ void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep) if (!can_sleep) { work = kzalloc(sizeof(*work), GFP_ATOMIC); - if (!work) + if (!work) { + clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state); return; + } work->type = IONIC_DW_TYPE_LINK_STATUS; ionic_lif_deferred_enqueue(&lif->deferred, work); From 7c737fc43ca0ab81f92cdb2c448b2bc114d53179 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:42 -0700 Subject: [PATCH 4/8] ionic: check qcq ptr in ionic_qcq_disable There are a couple of error recovery paths that can come through ionic_qcq_disable() without having set up the qcq, so we need to make sure we have a valid qcq pointer before using it. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_lif.c | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 5906145e45859..efffdfe184068 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -266,29 +266,26 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq) static int ionic_qcq_disable(struct ionic_qcq *qcq) { - struct ionic_queue *q = &qcq->q; - struct ionic_lif *lif = q->lif; - struct ionic_dev *idev; - struct device *dev; + struct ionic_queue *q; + struct ionic_lif *lif; struct ionic_admin_ctx ctx = { .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), .cmd.q_control = { .opcode = IONIC_CMD_Q_CONTROL, - .lif_index = cpu_to_le16(lif->index), - .type = q->type, - .index = cpu_to_le32(q->index), .oper = IONIC_Q_DISABLE, }, }; - idev = &lif->ionic->idev; - dev = lif->ionic->dev; + if (!qcq) + return -ENXIO; - dev_dbg(dev, "q_disable.index %d q_disable.qtype %d\n", - ctx.cmd.q_control.index, ctx.cmd.q_control.type); + q = &qcq->q; + lif = q->lif; if (qcq->flags & IONIC_QCQ_F_INTR) { + struct ionic_dev *idev = &lif->ionic->idev; + cancel_work_sync(&qcq->dim.work); ionic_intr_mask(idev->intr_ctrl, qcq->intr.index, IONIC_INTR_MASK_SET); @@ -297,6 +294,12 @@ static int ionic_qcq_disable(struct ionic_qcq *qcq) napi_disable(&qcq->napi); } + ctx.cmd.q_control.lif_index = cpu_to_le16(lif->index); + ctx.cmd.q_control.type = q->type; + ctx.cmd.q_control.index = cpu_to_le32(q->index); + dev_dbg(lif->ionic->dev, "q_disable.index %d q_disable.qtype %d\n", + ctx.cmd.q_control.index, ctx.cmd.q_control.type); + return ionic_adminq_post_wait(lif, &ctx); } @@ -1794,6 +1797,12 @@ static int ionic_txrx_enable(struct ionic_lif *lif) int i, 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); + err = -ENXIO; + goto err_out; + } + ionic_rx_fill(&lif->rxqcqs[i]->q); err = ionic_qcq_enable(lif->rxqcqs[i]); if (err) From ba6ab8aca216d9be1a2eb3c96a7a8686fe9a1619 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:43 -0700 Subject: [PATCH 5/8] ionic: disable all queue napi contexts on timeout Some time ago we short-circuited the queue disables on a timeout error in order to not have to wait on every queue when we already know it will time out. However, this meant that we're not properly stopping all the interrupts and napi contexts. This changes queue disable to always call ionic_qcq_disable() and to give it an argument to know when to not do the adminq request. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_lif.c | 47 +++++++++---------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index efffdfe184068..2b6cd60095b1b 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -264,10 +264,11 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq) return ionic_adminq_post_wait(lif, &ctx); } -static int ionic_qcq_disable(struct ionic_qcq *qcq) +static int ionic_qcq_disable(struct ionic_qcq *qcq, bool send_to_hw) { struct ionic_queue *q; struct ionic_lif *lif; + int err = 0; struct ionic_admin_ctx ctx = { .work = COMPLETION_INITIALIZER_ONSTACK(ctx.work), @@ -294,13 +295,17 @@ static int ionic_qcq_disable(struct ionic_qcq *qcq) napi_disable(&qcq->napi); } - ctx.cmd.q_control.lif_index = cpu_to_le16(lif->index); - ctx.cmd.q_control.type = q->type; - ctx.cmd.q_control.index = cpu_to_le32(q->index); - dev_dbg(lif->ionic->dev, "q_disable.index %d q_disable.qtype %d\n", - ctx.cmd.q_control.index, ctx.cmd.q_control.type); + if (send_to_hw) { + ctx.cmd.q_control.lif_index = cpu_to_le16(lif->index); + ctx.cmd.q_control.type = q->type; + ctx.cmd.q_control.index = cpu_to_le32(q->index); + dev_dbg(lif->ionic->dev, "q_disable.index %d q_disable.qtype %d\n", + ctx.cmd.q_control.index, ctx.cmd.q_control.type); - return ionic_adminq_post_wait(lif, &ctx); + err = ionic_adminq_post_wait(lif, &ctx); + } + + return err; } static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq) @@ -1627,22 +1632,16 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif) static void ionic_txrx_disable(struct ionic_lif *lif) { unsigned int i; - int err; + int err = 0; if (lif->txqcqs) { - for (i = 0; i < lif->nxqs; i++) { - err = ionic_qcq_disable(lif->txqcqs[i]); - if (err == -ETIMEDOUT) - break; - } + for (i = 0; i < lif->nxqs; i++) + err = ionic_qcq_disable(lif->txqcqs[i], (err != -ETIMEDOUT)); } if (lif->rxqcqs) { - for (i = 0; i < lif->nxqs; i++) { - err = ionic_qcq_disable(lif->rxqcqs[i]); - if (err == -ETIMEDOUT) - break; - } + for (i = 0; i < lif->nxqs; i++) + err = ionic_qcq_disable(lif->rxqcqs[i], (err != -ETIMEDOUT)); } } @@ -1794,6 +1793,7 @@ static int ionic_txrx_init(struct ionic_lif *lif) static int ionic_txrx_enable(struct ionic_lif *lif) { + int derr = 0; int i, err; for (i = 0; i < lif->nxqs; i++) { @@ -1810,8 +1810,7 @@ static int ionic_txrx_enable(struct ionic_lif *lif) err = ionic_qcq_enable(lif->txqcqs[i]); if (err) { - if (err != -ETIMEDOUT) - ionic_qcq_disable(lif->rxqcqs[i]); + derr = ionic_qcq_disable(lif->rxqcqs[i], (err != -ETIMEDOUT)); goto err_out; } } @@ -1820,12 +1819,8 @@ static int ionic_txrx_enable(struct ionic_lif *lif) err_out: while (i--) { - err = ionic_qcq_disable(lif->txqcqs[i]); - if (err == -ETIMEDOUT) - break; - err = ionic_qcq_disable(lif->rxqcqs[i]); - if (err == -ETIMEDOUT) - break; + derr = ionic_qcq_disable(lif->txqcqs[i], (derr != -ETIMEDOUT)); + derr = ionic_qcq_disable(lif->rxqcqs[i], (derr != -ETIMEDOUT)); } return err; From a21b5d49e77a2ec732b3dc7c9204c92125b0fa7a Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:44 -0700 Subject: [PATCH 6/8] ionic: refill lif identity after fw_up After we do a fw upgrade and refill the ionic->ident.dev, we also need to update the other identity info. Since the lif identity needs to be updated each time the ionic identity is refreshed, we can pull it into ionic_identify(). The debugfs entry is moved so that it doesn't cause an error message when the data is refreshed after the fw upgrade. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_bus_pci.c | 10 ++-------- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 10 +++++++++- drivers/net/ethernet/pensando/ionic/ionic_main.c | 16 +++++++++++----- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c index 2749ce009ebc1..b0d8499d373bd 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c @@ -266,6 +266,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(dev, "Cannot identify device: %d, aborting\n", err); goto err_out_teardown; } + ionic_debugfs_add_ident(ionic); err = ionic_init(ionic); if (err) { @@ -286,14 +287,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_reset; } - /* Configure LIFs */ - err = ionic_lif_identify(ionic, IONIC_LIF_TYPE_CLASSIC, - &ionic->ident.lif); - if (err) { - dev_err(dev, "Cannot identify LIFs: %d, aborting\n", err); - goto err_out_port_reset; - } - + /* Allocate and init the LIF */ err = ionic_lif_size(ionic); if (err) { dev_err(dev, "Cannot size LIF: %d, aborting\n", err); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 2b6cd60095b1b..fcf5b00d1c331 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -2556,7 +2556,15 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif) dev_info(ionic->dev, "FW Up: restarting LIFs\n"); ionic_init_devinfo(ionic); - ionic_port_init(ionic); + err = ionic_identify(ionic); + if (err) + goto err_out; + err = ionic_port_identify(ionic); + if (err) + goto err_out; + err = ionic_port_init(ionic); + if (err) + goto err_out; err = ionic_qcqs_alloc(lif); if (err) goto err_out; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index c7a67c5cda423..c21195be59e18 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -429,17 +429,23 @@ int ionic_identify(struct ionic *ionic) sz = min(sizeof(ident->dev), sizeof(idev->dev_cmd_regs->data)); memcpy_fromio(&ident->dev, &idev->dev_cmd_regs->data, sz); } - mutex_unlock(&ionic->dev_cmd_lock); - if (err) - goto err_out_unmap; + if (err) { + dev_err(ionic->dev, "Cannot identify ionic: %dn", err); + goto err_out; + } - ionic_debugfs_add_ident(ionic); + err = ionic_lif_identify(ionic, IONIC_LIF_TYPE_CLASSIC, + &ionic->ident.lif); + if (err) { + dev_err(ionic->dev, "Cannot identify LIFs: %d\n", err); + goto err_out; + } return 0; -err_out_unmap: +err_out: return err; } From bb9f80f31d37c8bffd2d957da73fee5ff42a3dc2 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:45 -0700 Subject: [PATCH 7/8] ionic: use lif ident for filter count Use the lif's ident information for the uc and mc filter counts rather than the ionic's version, to be sure we're getting the info that is specific to this lif. While we're thinking about it, add some missing error checking where we get the lif's identity information. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_lif.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index fcf5b00d1c331..d655a7ae3058c 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -1022,7 +1022,6 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr) static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add, bool can_sleep) { - struct ionic *ionic = lif->ionic; struct ionic_deferred_work *work; unsigned int nmfilters; unsigned int nufilters; @@ -1032,8 +1031,8 @@ static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add, * here before checking the need for deferral so that we * can return an overflow error to the stack. */ - nmfilters = le32_to_cpu(ionic->ident.lif.eth.max_mcast_filters); - nufilters = le32_to_cpu(ionic->ident.lif.eth.max_ucast_filters); + nmfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); + nufilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); if ((is_multicast_ether_addr(addr) && lif->nmcast < nmfilters)) lif->nmcast++; @@ -1162,12 +1161,9 @@ static void ionic_dev_uc_sync(struct net_device *netdev, bool from_ndo) static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo) { struct ionic_lif *lif = netdev_priv(netdev); - struct ionic_identity *ident; unsigned int nfilters; unsigned int rx_mode; - ident = &lif->ionic->ident; - rx_mode = IONIC_RX_MODE_F_UNICAST; rx_mode |= (netdev->flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0; rx_mode |= (netdev->flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0; @@ -1182,7 +1178,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo) * to see if we can disable NIC PROMISC */ ionic_dev_uc_sync(netdev, from_ndo); - nfilters = le32_to_cpu(ident->lif.eth.max_ucast_filters); + nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters); if (netdev_uc_count(netdev) + 1 > nfilters) { rx_mode |= IONIC_RX_MODE_F_PROMISC; lif->uc_overflow = true; @@ -1194,7 +1190,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo) /* same for multicast */ ionic_dev_uc_sync(netdev, from_ndo); - nfilters = le32_to_cpu(ident->lif.eth.max_mcast_filters); + nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters); if (netdev_mc_count(netdev) > nfilters) { rx_mode |= IONIC_RX_MODE_F_ALLMULTI; lif->mc_overflow = true; @@ -2425,7 +2421,12 @@ int ionic_lif_alloc(struct ionic *ionic) lif->identity = lid; lif->lif_type = IONIC_LIF_TYPE_CLASSIC; - ionic_lif_identify(ionic, lif->lif_type, lif->identity); + err = ionic_lif_identify(ionic, lif->lif_type, lif->identity); + if (err) { + dev_err(ionic->dev, "Cannot identify type %d: %d\n", + lif->lif_type, err); + goto err_out_free_netdev; + } lif->netdev->min_mtu = max_t(unsigned int, ETH_MIN_MTU, le32_to_cpu(lif->identity->eth.min_frame_size)); lif->netdev->max_mtu = From 9e15410dc7450b8fbc31909efc2c7100f1e9be5e Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Thu, 1 Oct 2020 09:22:46 -0700 Subject: [PATCH 8/8] ionic: add new bad firmware error code If the new firmware image downladed for update is corrupted or is a bad format, the download process will report a status code specifically for that. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic_if.h | 1 + drivers/net/ethernet/pensando/ionic/ionic_main.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_if.h b/drivers/net/ethernet/pensando/ionic/ionic_if.h index 5bb56a27a50d6..31ccfcdc2b0a4 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_if.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_if.h @@ -96,6 +96,7 @@ enum ionic_status_code { IONIC_RC_ERROR = 29, /* Generic error */ IONIC_RC_ERDMA = 30, /* Generic RDMA error */ IONIC_RC_EVFID = 31, /* VF ID does not exist */ + IONIC_RC_EBAD_FW = 32, /* FW file is invalid or corrupted */ }; enum ionic_notifyq_opcode { diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index c21195be59e18..ee0740881af31 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -64,6 +64,8 @@ static const char *ionic_error_to_str(enum ionic_status_code code) return "IONIC_RC_ERROR"; case IONIC_RC_ERDMA: return "IONIC_RC_ERDMA"; + case IONIC_RC_EBAD_FW: + return "IONIC_RC_EBAD_FW"; default: return "IONIC_RC_UNKNOWN"; }