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: 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>
This commit is contained in:
parent
a365023a76
commit
ffd2f89ad0
@ -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)
|
|||||||
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)
|
|||||||
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))
|
otx2_do_set_rx_mode(pf);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user