brcmfmac: Disable ARP offloading when promiscuous
authorPhil Elwell <phil@raspberrypi.org>
Thu, 24 Aug 2017 15:16:16 +0000 (16:16 +0100)
committerPhil Elwell <phil@raspberrypi.org>
Wed, 30 Aug 2017 12:36:53 +0000 (13:36 +0100)
This is a test patch for brcmfmac from Franky Lin at Broadcom to disable
ARP offloading when in promiscuous mode, re-enabling the ability to
sniff ARP packets over WiFi.

See: https://github.com/raspberrypi/linux/issues/2171

Signed-off-by: Phil Elwell <phil@raspberrypi.org>
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h

index 11e73bff0f479b6dc1157fe39120b33796acb894..bb5b54b0d508182616c55c48de8c509d2ed06ed3 100644 (file)
@@ -481,47 +481,6 @@ send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
        return err;
 }
 
-static s32
-brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
-{
-       s32 err;
-       u32 mode;
-
-       if (enable)
-               mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
-       else
-               mode = 0;
-
-       /* Try to set and enable ARP offload feature, this may fail, then it  */
-       /* is simply not supported and err 0 will be returned                 */
-       err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
-       if (err) {
-               brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
-                         mode, err);
-               err = 0;
-       } else {
-               err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
-               if (err) {
-                       brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
-                                 enable, err);
-                       err = 0;
-               } else
-                       brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
-                                 enable, mode);
-       }
-
-       err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
-       if (err) {
-               brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
-                         enable, err);
-               err = 0;
-       } else
-               brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
-                         enable, mode);
-
-       return err;
-}
-
 static void
 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
 {
index f877301c9454b2e75715937cd015fbfe87fc271b..ef4085cda90e2975eb474cd39627c578684b0f55 100644 (file)
@@ -71,6 +71,43 @@ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
        return ifp;
 }
 
+void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
+{
+       s32 err;
+       u32 mode;
+
+       if (enable)
+               mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
+       else
+               mode = 0;
+
+       /* Try to set and enable ARP offload feature, this may fail, then it  */
+       /* is simply not supported and err 0 will be returned                 */
+       err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
+       if (err) {
+               brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
+                         mode, err);
+               err = 0;
+       } else {
+               err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
+               if (err) {
+                       brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
+                                 enable, err);
+                       err = 0;
+               } else
+                       brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
+                                 enable, mode);
+       }
+
+       err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
+       if (err)
+               brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
+                         enable, err);
+       else
+               brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
+                         enable, mode);
+}
+
 static void _brcmf_set_multicast_list(struct work_struct *work)
 {
        struct brcmf_if *ifp;
@@ -134,6 +171,8 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
        if (err < 0)
                brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n",
                          err);
+
+       brcmf_configure_arp_nd_offload(ifp, !cmd_value);
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
index c94dcab260d0009bc960e1eef119f66c2187e718..ba699fadd4dc8c5155b8567d330135bdc421b9c4 100644 (file)
@@ -208,6 +208,7 @@ int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
 char *brcmf_ifname(struct brcmf_if *ifp);
 struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
 int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
+void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable);
 struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
                              bool is_p2pdev, const char *name, u8 *mac_addr);
 void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);