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

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
...@@ -1493,6 +1493,44 @@ static void otx2_free_hw_resources(struct otx2_nic *pf) ...@@ -1493,6 +1493,44 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
mutex_unlock(&mbox->lock); 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) int otx2_open(struct net_device *netdev)
{ {
struct otx2_nic *pf = netdev_priv(netdev); struct otx2_nic *pf = netdev_priv(netdev);
...@@ -1646,6 +1684,8 @@ int otx2_open(struct net_device *netdev) ...@@ -1646,6 +1684,8 @@ int otx2_open(struct net_device *netdev)
if (err) if (err)
goto err_tx_stop_queues; goto err_tx_stop_queues;
otx2_do_set_rx_mode(pf);
return 0; return 0;
err_tx_stop_queues: err_tx_stop_queues:
...@@ -1791,43 +1831,11 @@ static void otx2_set_rx_mode(struct net_device *netdev) ...@@ -1791,43 +1831,11 @@ static void otx2_set_rx_mode(struct net_device *netdev)
queue_work(pf->otx2_wq, &pf->rx_mode_work); 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 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 */ otx2_do_set_rx_mode(pf);
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);
} }
static int otx2_set_features(struct net_device *netdev, static int otx2_set_features(struct net_device *netdev,
...@@ -2358,7 +2366,7 @@ static int otx2_wq_init(struct otx2_nic *pf) ...@@ -2358,7 +2366,7 @@ static int otx2_wq_init(struct otx2_nic *pf)
if (!pf->otx2_wq) if (!pf->otx2_wq)
return -ENOMEM; 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); INIT_WORK(&pf->reset_task, otx2_reset_task);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment