Skip to content

Commit

Permalink
octeontx2-pf: Enable promisc/allmulti match MCAM entries.
Browse files Browse the repository at this point in the history
[ Upstream commit ffd2f89 ]

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: Rakesh Babu <rsaladi2@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Rakesh Babu authored and gregkh committed Nov 18, 2021
1 parent 26fcf93 commit 1a0e5b1
Showing 1 changed file with 43 additions and 35 deletions.
78 changes: 43 additions & 35 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 1a0e5b1

Please sign in to comment.