From patchwork Sat Jan 2 08:41:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arend van Spriel X-Patchwork-Id: 7940511 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2B5DA9F387 for ; Sat, 2 Jan 2016 08:42:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3B5C1204AF for ; Sat, 2 Jan 2016 08:42:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1912B20490 for ; Sat, 2 Jan 2016 08:42:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751859AbcABIlz (ORCPT ); Sat, 2 Jan 2016 03:41:55 -0500 Received: from mail-gw2-out.broadcom.com ([216.31.210.63]:4471 "EHLO mail-gw2-out.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751344AbcABIlv (ORCPT ); Sat, 2 Jan 2016 03:41:51 -0500 X-IronPort-AV: E=Sophos;i="5.20,511,1444719600"; d="scan'208";a="84612162" Received: from irvexchcas06.broadcom.com (HELO IRVEXCHCAS06.corp.ad.broadcom.com) ([10.9.208.53]) by mail-gw2-out.broadcom.com with ESMTP; 02 Jan 2016 01:20:49 -0800 Received: from IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) by IRVEXCHCAS06.corp.ad.broadcom.com (10.9.208.53) with Microsoft SMTP Server (TLS) id 14.3.235.1; Sat, 2 Jan 2016 00:41:50 -0800 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP1.corp.ad.broadcom.com (10.9.207.51) with Microsoft SMTP Server id 14.3.235.1; Sat, 2 Jan 2016 00:41:51 -0800 Received: from bld-bun-01.bun.broadcom.com (unknown [10.176.128.83]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id 3837C40FE5; Sat, 2 Jan 2016 00:38:12 -0800 (PST) Received: by bld-bun-01.bun.broadcom.com (Postfix, from userid 25152) id 3309CB00693; Sat, 2 Jan 2016 09:41:49 +0100 (CET) From: Arend van Spriel To: Kalle Valo CC: linux-wireless , Franky Lin , Arend van Spriel Subject: [PATCH V2 1/7] brcmfmac: add arp offload ip address table configuration support Date: Sat, 2 Jan 2016 09:41:36 +0100 Message-ID: <1451724102-21911-2-git-send-email-arend@broadcom.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1451724102-21911-1-git-send-email-arend@broadcom.com> References: <1451724102-21911-1-git-send-email-arend@broadcom.com> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Franky Lin Obtain ipv4 address through inetaddr notification for ARP offload host ip table configuration. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Hante Meuleman Signed-off-by: Franky Lin Signed-off-by: Arend van Spriel --- .../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..4c8f7bf 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -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; + __be32 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_data_set(ifp, "arp_hostip", + &ifa->ifa_address, sizeof(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_data_set(ifp, + "arp_hostip", &addr_table[i], + sizeof(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 */