Message ID | 1449751392-32569-14-git-send-email-arend@broadcom.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Kalle Valo |
Headers | show |
On 12/10/2015 01:43 PM, Arend van Spriel wrote: > From: Franky Lin <frankyl@broadcom.com> > > Obtain ipv4 address through inetaddr notification for ARP offload host > ip table configuration. Turns out this patch has a sparse warning, ie. would not work on big-endian system. We have a fix for that. Should I mark this patch as dropped in patchwork? Regards, Arend > Signed-off-by: Franky Lin <frankyl@broadcom.com> > Signed-off-by: Arend van Spriel <arend@broadcom.com> > --- > .../wireless/broadcom/brcm80211/brcmfmac/core.c | 108 +++++++++++++++++++++ > .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 + > 2 files changed, 110 insertions(+) > > diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c > index 3a39192..2631f6f 100644 > --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c > +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c > @@ -17,6 +17,7 @@ > #include <linux/kernel.h> > #include <linux/etherdevice.h> > #include <linux/module.h> > +#include <linux/inetdevice.h> > #include <net/cfg80211.h> > #include <net/rtnetlink.h> > #include <brcmu_utils.h> > @@ -620,6 +621,8 @@ static int brcmf_netdev_stop(struct net_device *ndev) > > brcmf_cfg80211_down(ndev); > > + brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); > + > brcmf_net_setcarrier(ifp, false); > > return 0; > @@ -940,6 +943,98 @@ int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr) > return available ? bsscfgidx : -ENOMEM; > } > > +#ifdef CONFIG_INET > +#define ARPOL_MAX_ENTRIES 8 > +static int brcmf_inetaddr_changed(struct notifier_block *nb, > + unsigned long action, void *data) > +{ > + struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub, > + inetaddr_notifier); > + struct in_ifaddr *ifa = data; > + struct net_device *ndev = ifa->ifa_dev->dev; > + struct brcmf_if *ifp; > + int idx, i, ret; > + u32 val; > + u32 addr_table[ARPOL_MAX_ENTRIES] = {0}; > + > + /* Find out if the notification is meant for us */ > + for (idx = 0; idx < BRCMF_MAX_IFS; idx++) { > + ifp = drvr->iflist[idx]; > + if (ifp && ifp->ndev == ndev) > + break; > + if (idx == BRCMF_MAX_IFS - 1) > + return NOTIFY_DONE; > + } > + > + /* check if arp offload is supported */ > + ret = brcmf_fil_iovar_int_get(ifp, "arpoe", &val); > + if (ret) > + return NOTIFY_OK; > + > + /* old version only support primary index */ > + ret = brcmf_fil_iovar_int_get(ifp, "arp_version", &val); > + if (ret) > + val = 1; > + if (val == 1) > + ifp = drvr->iflist[0]; > + > + /* retrieve the table from firmware */ > + ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table, > + sizeof(addr_table)); > + if (ret) { > + brcmf_err("fail to get arp ip table err:%d\n", ret); > + return NOTIFY_OK; > + } > + > + for (i = 0; i < ARPOL_MAX_ENTRIES; i++) > + if (ifa->ifa_address == addr_table[i]) > + break; > + > + switch (action) { > + case NETDEV_UP: > + if (i == ARPOL_MAX_ENTRIES) { > + brcmf_dbg(TRACE, "add %pI4 to arp table\n", > + &ifa->ifa_address); > + /* set it directly */ > + ret = brcmf_fil_iovar_int_set(ifp, "arp_hostip", > + ifa->ifa_address); > + if (ret) > + brcmf_err("add arp ip err %d\n", ret); > + } > + break; > + case NETDEV_DOWN: > + if (i < ARPOL_MAX_ENTRIES) { > + addr_table[i] = 0; > + brcmf_dbg(TRACE, "remove %pI4 from arp table\n", > + &ifa->ifa_address); > + /* clear the table in firmware */ > + ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", > + NULL, 0); > + if (ret) { > + brcmf_err("fail to clear arp ip table err:%d\n", > + ret); > + return NOTIFY_OK; > + } > + for (i = 0; i < ARPOL_MAX_ENTRIES; i++) { > + if (addr_table[i] != 0) { > + brcmf_fil_iovar_int_set(ifp, > + "arp_hostip", > + addr_table[i]); > + if (ret) > + brcmf_err("add arp ip err %d\n", > + ret); > + } > + } > + } > + break; > + default: > + break; > + } > + > + return NOTIFY_OK; > +} > +#endif > + > int brcmf_attach(struct device *dev) > { > struct brcmf_pub *drvr = NULL; > @@ -1068,6 +1163,15 @@ int brcmf_bus_start(struct device *dev) > if (p2p_ifp) > ret = brcmf_net_p2p_attach(p2p_ifp); > } > + > + if (ret) > + goto fail; > + > +#ifdef CONFIG_INET > + drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed; > + ret = register_inetaddr_notifier(&drvr->inetaddr_notifier); > +#endif > + > fail: > if (ret < 0) { > brcmf_err("failed: %d\n", ret); > @@ -1133,6 +1237,10 @@ void brcmf_detach(struct device *dev) > if (drvr == NULL) > return; > > +#ifdef CONFIG_INET > + unregister_inetaddr_notifier(&drvr->inetaddr_notifier); > +#endif > + > /* stop firmware event handling */ > brcmf_fweh_detach(drvr); > if (drvr->config) > diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h > index 77d8239..6018af7 100644 > --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h > +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h > @@ -141,6 +141,8 @@ struct brcmf_pub { > #ifdef DEBUG > struct dentry *dbgfs_dir; > #endif > + > + struct notifier_block inetaddr_notifier; > }; > > /* forward declarations */ > -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Arend van Spriel <arend@broadcom.com> writes: > On 12/10/2015 01:43 PM, Arend van Spriel wrote: >> From: Franky Lin <frankyl@broadcom.com> >> >> Obtain ipv4 address through inetaddr notification for ARP offload host >> ip table configuration. > > Turns out this patch has a sparse warning, ie. would not work on > big-endian system. We have a fix for that. Should I mark this patch as > dropped in patchwork? Yeah, that's the best way. For example you could use state "Changes Requested" and then it automatically gets dropped from my queue.
On 12/11/2015 10:29 AM, Kalle Valo wrote: > Arend van Spriel <arend@broadcom.com> writes: > >> On 12/10/2015 01:43 PM, Arend van Spriel wrote: >>> From: Franky Lin <frankyl@broadcom.com> >>> >>> Obtain ipv4 address through inetaddr notification for ARP offload host >>> ip table configuration. >> >> Turns out this patch has a sparse warning, ie. would not work on >> big-endian system. We have a fix for that. Should I mark this patch as >> dropped in patchwork? > > Yeah, that's the best way. For example you could use state "Changes > Requested" and then it automatically gets dropped from my queue. will do that. Thanks, Arend -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 3a39192..2631f6f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -17,6 +17,7 @@ #include <linux/kernel.h> #include <linux/etherdevice.h> #include <linux/module.h> +#include <linux/inetdevice.h> #include <net/cfg80211.h> #include <net/rtnetlink.h> #include <brcmu_utils.h> @@ -620,6 +621,8 @@ static int brcmf_netdev_stop(struct net_device *ndev) brcmf_cfg80211_down(ndev); + brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); + brcmf_net_setcarrier(ifp, false); return 0; @@ -940,6 +943,98 @@ int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr) return available ? bsscfgidx : -ENOMEM; } +#ifdef CONFIG_INET +#define ARPOL_MAX_ENTRIES 8 +static int brcmf_inetaddr_changed(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub, + inetaddr_notifier); + struct in_ifaddr *ifa = data; + struct net_device *ndev = ifa->ifa_dev->dev; + struct brcmf_if *ifp; + int idx, i, ret; + u32 val; + u32 addr_table[ARPOL_MAX_ENTRIES] = {0}; + + /* Find out if the notification is meant for us */ + for (idx = 0; idx < BRCMF_MAX_IFS; idx++) { + ifp = drvr->iflist[idx]; + if (ifp && ifp->ndev == ndev) + break; + if (idx == BRCMF_MAX_IFS - 1) + return NOTIFY_DONE; + } + + /* check if arp offload is supported */ + ret = brcmf_fil_iovar_int_get(ifp, "arpoe", &val); + if (ret) + return NOTIFY_OK; + + /* old version only support primary index */ + ret = brcmf_fil_iovar_int_get(ifp, "arp_version", &val); + if (ret) + val = 1; + if (val == 1) + ifp = drvr->iflist[0]; + + /* retrieve the table from firmware */ + ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table, + sizeof(addr_table)); + if (ret) { + brcmf_err("fail to get arp ip table err:%d\n", ret); + return NOTIFY_OK; + } + + for (i = 0; i < ARPOL_MAX_ENTRIES; i++) + if (ifa->ifa_address == addr_table[i]) + break; + + switch (action) { + case NETDEV_UP: + if (i == ARPOL_MAX_ENTRIES) { + brcmf_dbg(TRACE, "add %pI4 to arp table\n", + &ifa->ifa_address); + /* set it directly */ + ret = brcmf_fil_iovar_int_set(ifp, "arp_hostip", + ifa->ifa_address); + if (ret) + brcmf_err("add arp ip err %d\n", ret); + } + break; + case NETDEV_DOWN: + if (i < ARPOL_MAX_ENTRIES) { + addr_table[i] = 0; + brcmf_dbg(TRACE, "remove %pI4 from arp table\n", + &ifa->ifa_address); + /* clear the table in firmware */ + ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", + NULL, 0); + if (ret) { + brcmf_err("fail to clear arp ip table err:%d\n", + ret); + return NOTIFY_OK; + } + for (i = 0; i < ARPOL_MAX_ENTRIES; i++) { + if (addr_table[i] != 0) { + brcmf_fil_iovar_int_set(ifp, + "arp_hostip", + addr_table[i]); + if (ret) + brcmf_err("add arp ip err %d\n", + ret); + } + } + } + break; + default: + break; + } + + return NOTIFY_OK; +} +#endif + int brcmf_attach(struct device *dev) { struct brcmf_pub *drvr = NULL; @@ -1068,6 +1163,15 @@ int brcmf_bus_start(struct device *dev) if (p2p_ifp) ret = brcmf_net_p2p_attach(p2p_ifp); } + + if (ret) + goto fail; + +#ifdef CONFIG_INET + drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed; + ret = register_inetaddr_notifier(&drvr->inetaddr_notifier); +#endif + fail: if (ret < 0) { brcmf_err("failed: %d\n", ret); @@ -1133,6 +1237,10 @@ void brcmf_detach(struct device *dev) if (drvr == NULL) return; +#ifdef CONFIG_INET + unregister_inetaddr_notifier(&drvr->inetaddr_notifier); +#endif + /* stop firmware event handling */ brcmf_fweh_detach(drvr); if (drvr->config) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index 77d8239..6018af7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -141,6 +141,8 @@ struct brcmf_pub { #ifdef DEBUG struct dentry *dbgfs_dir; #endif + + struct notifier_block inetaddr_notifier; }; /* forward declarations */