Commit ffd2f89a authored by Rakesh Babu's avatar Rakesh Babu Committed by David S. Miller
Browse files

octeontx2-pf: Enable promisc/allmulti match MCAM entries.



Whenever the interface is brought up/down then set_rx_mode
function is called by the stack which enables promisc/allmulti
MCAM entries. But there are cases when driver brings
interface down and then up such as while changing number
of channels. In these cases promisc/allmulti MCAM entries
are left disabled as set_rx_mode callback is not called.
This patch enables these MCAM entries in all such cases.

Signed-off-by: default avatarRakesh Babu <rsaladi2@marvell.com>
Signed-off-by: default avatarSubbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a365023a
Loading
Loading
Loading
Loading
+43 −35
Original line number Diff line number Diff line
@@ -1493,6 +1493,44 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
	mutex_unlock(&mbox->lock);
}

static void otx2_do_set_rx_mode(struct otx2_nic *pf)
{
	struct net_device *netdev = pf->netdev;
	struct nix_rx_mode *req;
	bool promisc = false;

	if (!(netdev->flags & IFF_UP))
		return;

	if ((netdev->flags & IFF_PROMISC) ||
	    (netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) {
		promisc = true;
	}

	/* Write unicast address to mcam entries or del from mcam */
	if (!promisc && netdev->priv_flags & IFF_UNICAST_FLT)
		__dev_uc_sync(netdev, otx2_add_macfilter, otx2_del_macfilter);

	mutex_lock(&pf->mbox.lock);
	req = otx2_mbox_alloc_msg_nix_set_rx_mode(&pf->mbox);
	if (!req) {
		mutex_unlock(&pf->mbox.lock);
		return;
	}

	req->mode = NIX_RX_MODE_UCAST;

	if (promisc)
		req->mode |= NIX_RX_MODE_PROMISC;
	if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST))
		req->mode |= NIX_RX_MODE_ALLMULTI;

	req->mode |= NIX_RX_MODE_USE_MCE;

	otx2_sync_mbox_msg(&pf->mbox);
	mutex_unlock(&pf->mbox.lock);
}

int otx2_open(struct net_device *netdev)
{
	struct otx2_nic *pf = netdev_priv(netdev);
@@ -1646,6 +1684,8 @@ int otx2_open(struct net_device *netdev)
	if (err)
		goto err_tx_stop_queues;

	otx2_do_set_rx_mode(pf);

	return 0;

err_tx_stop_queues:
@@ -1791,43 +1831,11 @@ static void otx2_set_rx_mode(struct net_device *netdev)
	queue_work(pf->otx2_wq, &pf->rx_mode_work);
}

static void otx2_do_set_rx_mode(struct work_struct *work)
static void otx2_rx_mode_wrk_handler(struct work_struct *work)
{
	struct otx2_nic *pf = container_of(work, struct otx2_nic, rx_mode_work);
	struct net_device *netdev = pf->netdev;
	struct nix_rx_mode *req;
	bool promisc = false;

	if (!(netdev->flags & IFF_UP))
		return;

	if ((netdev->flags & IFF_PROMISC) ||
	    (netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) {
		promisc = true;
	}

	/* Write unicast address to mcam entries or del from mcam */
	if (!promisc && netdev->priv_flags & IFF_UNICAST_FLT)
		__dev_uc_sync(netdev, otx2_add_macfilter, otx2_del_macfilter);

	mutex_lock(&pf->mbox.lock);
	req = otx2_mbox_alloc_msg_nix_set_rx_mode(&pf->mbox);
	if (!req) {
		mutex_unlock(&pf->mbox.lock);
		return;
	}

	req->mode = NIX_RX_MODE_UCAST;

	if (promisc)
		req->mode |= NIX_RX_MODE_PROMISC;
	if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST))
		req->mode |= NIX_RX_MODE_ALLMULTI;

	req->mode |= NIX_RX_MODE_USE_MCE;

	otx2_sync_mbox_msg(&pf->mbox);
	mutex_unlock(&pf->mbox.lock);
	otx2_do_set_rx_mode(pf);
}

static int otx2_set_features(struct net_device *netdev,
@@ -2358,7 +2366,7 @@ static int otx2_wq_init(struct otx2_nic *pf)
	if (!pf->otx2_wq)
		return -ENOMEM;

	INIT_WORK(&pf->rx_mode_work, otx2_do_set_rx_mode);
	INIT_WORK(&pf->rx_mode_work, otx2_rx_mode_wrk_handler);
	INIT_WORK(&pf->reset_task, otx2_reset_task);
	return 0;
}