diff options
Diffstat (limited to 'package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch')
-rw-r--r-- | package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch | 333 |
1 files changed, 0 insertions, 333 deletions
diff --git a/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch b/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch deleted file mode 100644 index 888ad5b050..0000000000 --- a/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch +++ /dev/null @@ -1,333 +0,0 @@ -From: Franky Lin <frankyl@broadcom.com> -Date: Wed, 17 Feb 2016 11:26:55 +0100 -Subject: [PATCH] brcmfmac: add neighbor discovery offload ip address table - configuration - -Configure ipv6 address for neighbor discovery offload ip table in -firmware obtained through ipv6 address notification callback. - -Reviewed-by: Hante Meuleman <meuleman@broadcom.com> -Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> -Signed-off-by: Franky Lin <frankyl@broadcom.com> -Signed-off-by: Arend van Spriel <arend@broadcom.com> -Signed-off-by: Kalle Valo <kvalo@codeaurora.org> ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -456,7 +456,7 @@ send_key_to_dongle(struct brcmf_if *ifp, - } - - static s32 --brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable) -+brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) - { - s32 err; - u32 mode; -@@ -484,6 +484,15 @@ brcmf_configure_arp_offload(struct brcmf - 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; - } - -@@ -3543,7 +3552,7 @@ static s32 brcmf_cfg80211_resume(struct - brcmf_report_wowl_wakeind(wiphy, ifp); - brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); - brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0); -- brcmf_configure_arp_offload(ifp, true); -+ brcmf_configure_arp_nd_offload(ifp, true); - brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, - cfg->wowl.pre_pmmode); - cfg->wowl.active = false; -@@ -3567,7 +3576,7 @@ static void brcmf_configure_wowl(struct - - brcmf_dbg(TRACE, "Suspend, wowl config.\n"); - -- brcmf_configure_arp_offload(ifp, false); -+ brcmf_configure_arp_nd_offload(ifp, false); - brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode); - brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); - -@@ -4336,7 +4345,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi - - if (!mbss) { - brcmf_set_mpc(ifp, 0); -- brcmf_configure_arp_offload(ifp, false); -+ brcmf_configure_arp_nd_offload(ifp, false); - } - - /* find the RSN_IE */ -@@ -4482,7 +4491,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi - exit: - if ((err) && (!mbss)) { - brcmf_set_mpc(ifp, 1); -- brcmf_configure_arp_offload(ifp, true); -+ brcmf_configure_arp_nd_offload(ifp, true); - } - return err; - } -@@ -4540,7 +4549,7 @@ static int brcmf_cfg80211_stop_ap(struct - brcmf_err("bss_enable config failed %d\n", err); - } - brcmf_set_mpc(ifp, 1); -- brcmf_configure_arp_offload(ifp, true); -+ brcmf_configure_arp_nd_offload(ifp, true); - clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); - brcmf_net_setcarrier(ifp, false); - -@@ -6287,7 +6296,7 @@ static s32 brcmf_config_dongle(struct br - if (err) - goto default_conf_out; - -- brcmf_configure_arp_offload(ifp, true); -+ brcmf_configure_arp_nd_offload(ifp, true); - - cfg->dongle_up = true; - default_conf_out: ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -20,6 +20,8 @@ - #include <linux/inetdevice.h> - #include <net/cfg80211.h> - #include <net/rtnetlink.h> -+#include <net/addrconf.h> -+#include <net/ipv6.h> - #include <brcmu_utils.h> - #include <brcmu_wifi.h> - -@@ -172,6 +174,35 @@ _brcmf_set_mac_address(struct work_struc - } - } - -+#if IS_ENABLED(CONFIG_IPV6) -+static void _brcmf_update_ndtable(struct work_struct *work) -+{ -+ struct brcmf_if *ifp; -+ int i, ret; -+ -+ ifp = container_of(work, struct brcmf_if, ndoffload_work); -+ -+ /* clear the table in firmware */ -+ ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0); -+ if (ret) { -+ brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret); -+ return; -+ } -+ -+ for (i = 0; i < ifp->ipv6addr_idx; i++) { -+ ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip", -+ &ifp->ipv6_addr_tbl[i], -+ sizeof(struct in6_addr)); -+ if (ret) -+ brcmf_err("add nd ip err %d\n", ret); -+ } -+} -+#else -+static void _brcmf_update_ndtable(struct work_struct *work) -+{ -+} -+#endif -+ - static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) - { - struct brcmf_if *ifp = netdev_priv(ndev); -@@ -685,6 +716,7 @@ int brcmf_net_attach(struct brcmf_if *if - - INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); - INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); -+ INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable); - - if (rtnl_locked) - err = register_netdevice(ndev); -@@ -884,6 +916,7 @@ static void brcmf_del_if(struct brcmf_pu - if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { - cancel_work_sync(&ifp->setmacaddr_work); - cancel_work_sync(&ifp->multicast_work); -+ cancel_work_sync(&ifp->ndoffload_work); - } - brcmf_net_detach(ifp->ndev); - } else { -@@ -1025,6 +1058,56 @@ static int brcmf_inetaddr_changed(struct - } - #endif - -+#if IS_ENABLED(CONFIG_IPV6) -+static int brcmf_inet6addr_changed(struct notifier_block *nb, -+ unsigned long action, void *data) -+{ -+ struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub, -+ inet6addr_notifier); -+ struct inet6_ifaddr *ifa = data; -+ struct brcmf_if *ifp; -+ int i; -+ struct in6_addr *table; -+ -+ /* Only handle primary interface */ -+ ifp = drvr->iflist[0]; -+ if (!ifp) -+ return NOTIFY_DONE; -+ if (ifp->ndev != ifa->idev->dev) -+ return NOTIFY_DONE; -+ -+ table = ifp->ipv6_addr_tbl; -+ for (i = 0; i < NDOL_MAX_ENTRIES; i++) -+ if (ipv6_addr_equal(&ifa->addr, &table[i])) -+ break; -+ -+ switch (action) { -+ case NETDEV_UP: -+ if (i == NDOL_MAX_ENTRIES) { -+ if (ifp->ipv6addr_idx < NDOL_MAX_ENTRIES) { -+ table[ifp->ipv6addr_idx++] = ifa->addr; -+ } else { -+ for (i = 0; i < NDOL_MAX_ENTRIES - 1; i++) -+ table[i] = table[i + 1]; -+ table[NDOL_MAX_ENTRIES - 1] = ifa->addr; -+ } -+ } -+ break; -+ case NETDEV_DOWN: -+ if (i < NDOL_MAX_ENTRIES) -+ for (; i < ifp->ipv6addr_idx; i++) -+ table[i] = table[i + 1]; -+ break; -+ default: -+ break; -+ } -+ -+ schedule_work(&ifp->ndoffload_work); -+ -+ return NOTIFY_OK; -+} -+#endif -+ - int brcmf_attach(struct device *dev) - { - struct brcmf_pub *drvr = NULL; -@@ -1164,30 +1247,41 @@ int brcmf_bus_start(struct device *dev) - #ifdef CONFIG_INET - drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed; - ret = register_inetaddr_notifier(&drvr->inetaddr_notifier); -+ if (ret) -+ goto fail; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ drvr->inet6addr_notifier.notifier_call = brcmf_inet6addr_changed; -+ ret = register_inet6addr_notifier(&drvr->inet6addr_notifier); -+ if (ret) { -+ unregister_inetaddr_notifier(&drvr->inetaddr_notifier); -+ goto fail; -+ } - #endif -+#endif /* CONFIG_INET */ -+ -+ return 0; - - fail: -- if (ret < 0) { -- brcmf_err("failed: %d\n", ret); -- if (drvr->config) { -- brcmf_cfg80211_detach(drvr->config); -- drvr->config = NULL; -- } -- if (drvr->fws) { -- brcmf_fws_del_interface(ifp); -- brcmf_fws_deinit(drvr); -- } -- if (ifp) -- brcmf_net_detach(ifp->ndev); -- if (p2p_ifp) -- brcmf_net_detach(p2p_ifp->ndev); -- drvr->iflist[0] = NULL; -- drvr->iflist[1] = NULL; -- if (brcmf_ignoring_probe_fail(drvr)) -- ret = 0; -- return ret; -+ brcmf_err("failed: %d\n", ret); -+ if (drvr->config) { -+ brcmf_cfg80211_detach(drvr->config); -+ drvr->config = NULL; -+ } -+ if (drvr->fws) { -+ brcmf_fws_del_interface(ifp); -+ brcmf_fws_deinit(drvr); - } -- return 0; -+ if (ifp) -+ brcmf_net_detach(ifp->ndev); -+ if (p2p_ifp) -+ brcmf_net_detach(p2p_ifp->ndev); -+ drvr->iflist[0] = NULL; -+ drvr->iflist[1] = NULL; -+ if (brcmf_ignoring_probe_fail(drvr)) -+ ret = 0; -+ -+ return ret; - } - - void brcmf_bus_add_txhdrlen(struct device *dev, uint len) -@@ -1237,6 +1331,10 @@ void brcmf_detach(struct device *dev) - unregister_inetaddr_notifier(&drvr->inetaddr_notifier); - #endif - -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&drvr->inet6addr_notifier); -+#endif -+ - /* stop firmware event handling */ - brcmf_fweh_detach(drvr); - if (drvr->config) ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -48,6 +48,8 @@ - */ - #define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 - -+#define NDOL_MAX_ENTRIES 8 -+ - /** - * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info - * -@@ -143,6 +145,7 @@ struct brcmf_pub { - #endif - - struct notifier_block inetaddr_notifier; -+ struct notifier_block inet6addr_notifier; - struct brcmf_mp_device *settings; - }; - -@@ -175,6 +178,7 @@ enum brcmf_netif_stop_reason { - * @stats: interface specific network statistics. - * @setmacaddr_work: worker object for setting mac address. - * @multicast_work: worker object for multicast provisioning. -+ * @ndoffload_work: worker object for neighbor discovery offload configuration. - * @fws_desc: interface specific firmware-signalling descriptor. - * @ifidx: interface index in device firmware. - * @bsscfgidx: index of bss associated with this interface. -@@ -191,6 +195,7 @@ struct brcmf_if { - struct net_device_stats stats; - struct work_struct setmacaddr_work; - struct work_struct multicast_work; -+ struct work_struct ndoffload_work; - struct brcmf_fws_mac_descriptor *fws_desc; - int ifidx; - s32 bsscfgidx; -@@ -199,6 +204,8 @@ struct brcmf_if { - spinlock_t netif_stop_lock; - atomic_t pend_8021x_cnt; - wait_queue_head_t pend_8021x_wait; -+ struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES]; -+ u8 ipv6addr_idx; - }; - - struct brcmf_skb_reorder_data { |