Commit 48fc96b3 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ionic-fw-upgrade-filter-fixes'



Shannon Nelson says:

====================
ionic: fw upgrade filter fixes

With further testing of the fw-upgrade operations we found a
couple of issues that needed to be cleaned up:
 - the filters other than the base MAC address need to be
   reinstated into the device
 - we don't need to remove the station MAC filter if it
   isn't changing from a previous MAC filter
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cb9533d1 216902ae
Loading
Loading
Loading
Loading
+27 −17
Original line number Diff line number Diff line
@@ -2127,6 +2127,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
	if (lif->registered)
		ionic_lif_set_netdev_info(lif);

	ionic_rx_filter_replay(lif);

	if (netif_running(lif->netdev)) {
		err = ionic_txrx_alloc(lif);
		if (err)
@@ -2206,9 +2208,9 @@ static void ionic_lif_deinit(struct ionic_lif *lif)
	if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
		cancel_work_sync(&lif->deferred.work);
		cancel_work_sync(&lif->tx_timeout_work);
		ionic_rx_filters_deinit(lif);
	}

	ionic_rx_filters_deinit(lif);
	if (lif->netdev->features & NETIF_F_RXHASH)
		ionic_lif_rss_deinit(lif);

@@ -2339,10 +2341,12 @@ static int ionic_station_set(struct ionic_lif *lif)
	err = ionic_adminq_post_wait(lif, &ctx);
	if (err)
		return err;

	netdev_dbg(lif->netdev, "found initial MAC addr %pM\n",
		   ctx.comp.lif_getattr.mac);
	if (is_zero_ether_addr(ctx.comp.lif_getattr.mac))
		return 0;

	if (!ether_addr_equal(ctx.comp.lif_getattr.mac, netdev->dev_addr)) {
		memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
		addr.sa_family = AF_INET;
		err = eth_prepare_mac_addr_change(netdev, &addr);
@@ -2352,11 +2356,15 @@ static int ionic_station_set(struct ionic_lif *lif)
			return 0;
		}

		if (!is_zero_ether_addr(netdev->dev_addr)) {
			netdev_dbg(lif->netdev, "deleting station MAC addr %pM\n",
				   netdev->dev_addr);
			ionic_lif_addr(lif, netdev->dev_addr, false);
		}

		eth_commit_mac_addr_change(netdev, &addr);
	}

	netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",
		   netdev->dev_addr);
	ionic_lif_addr(lif, netdev->dev_addr, true);
@@ -2421,9 +2429,11 @@ static int ionic_lif_init(struct ionic_lif *lif)
	if (err)
		goto err_out_notifyq_deinit;

	if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
		err = ionic_rx_filters_init(lif);
		if (err)
			goto err_out_notifyq_deinit;
	}

	err = ionic_station_set(lif);
	if (err)
+42 −10
Original line number Diff line number Diff line
@@ -17,17 +17,49 @@ void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f)
	devm_kfree(dev, f);
}

int ionic_rx_filter_del(struct ionic_lif *lif, struct ionic_rx_filter *f)
void ionic_rx_filter_replay(struct ionic_lif *lif)
{
	struct ionic_admin_ctx ctx = {
		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
		.cmd.rx_filter_del = {
			.opcode = IONIC_CMD_RX_FILTER_DEL,
			.filter_id = cpu_to_le32(f->filter_id),
		},
	};

	return ionic_adminq_post_wait(lif, &ctx);
	struct ionic_rx_filter_add_cmd *ac;
	struct ionic_admin_ctx ctx;
	struct ionic_rx_filter *f;
	struct hlist_head *head;
	struct hlist_node *tmp;
	unsigned int i;
	int err = 0;

	ac = &ctx.cmd.rx_filter_add;

	for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
		head = &lif->rx_filters.by_id[i];
		hlist_for_each_entry_safe(f, tmp, head, by_id) {
			ctx.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work);
			memcpy(ac, &f->cmd, sizeof(f->cmd));
			dev_dbg(&lif->netdev->dev, "replay filter command:\n");
			dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
					 &ctx.cmd, sizeof(ctx.cmd), true);

			err = ionic_adminq_post_wait(lif, &ctx);
			if (err) {
				switch (le16_to_cpu(ac->match)) {
				case IONIC_RX_FILTER_MATCH_VLAN:
					netdev_info(lif->netdev, "Replay failed - %d: vlan %d\n",
						    err,
						    le16_to_cpu(ac->vlan.vlan));
					break;
				case IONIC_RX_FILTER_MATCH_MAC:
					netdev_info(lif->netdev, "Replay failed - %d: mac %pM\n",
						    err, ac->mac.addr);
					break;
				case IONIC_RX_FILTER_MATCH_MAC_VLAN:
					netdev_info(lif->netdev, "Replay failed - %d: vlan %d mac %pM\n",
						    err,
						    le16_to_cpu(ac->vlan.vlan),
						    ac->mac.addr);
					break;
				}
			}
		}
	}
}

int ionic_rx_filters_init(struct ionic_lif *lif)
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ struct ionic_rx_filters {
};

void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f);
int ionic_rx_filter_del(struct ionic_lif *lif, struct ionic_rx_filter *f);
void ionic_rx_filter_replay(struct ionic_lif *lif);
int ionic_rx_filters_init(struct ionic_lif *lif);
void ionic_rx_filters_deinit(struct ionic_lif *lif);
int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index,