octeontx2-pf: Enable promisc/allmulti match MCAM entries.
authorRakesh Babu <rsaladi2@marvell.com>
Tue, 28 Sep 2021 17:43:45 +0000 (23:13 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 Sep 2021 09:27:33 +0000 (10:27 +0100)
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>
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

index 53df7ff..53a3e8d 100644 (file)
@@ -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;
 }