From: Wright Feng <wright.feng@cypress.com>
To: linux-wireless@vger.kernel.org
Cc: wright.feng@cypress.com, brcm80211-dev-list@broadcom.com,
brcm80211-dev-list@cypress.com,
Arend van Spriel <arend.vanspriel@broadcom.com>,
Franky Lin <franky.lin@broadcom.com>,
Hante Meuleman <hante.meuleman@broadcom.com>,
Kalle Valo <kvalo@codeaurora.org>,
chi-hsien.lin@cypress.com,
Jia-Shyr Chuang <joseph.chuang@cypress.com>,
Ting-Ying Li <tingying.li@cypress.com>
Subject: [PATCH 3/4] brcmfmac: support the forwarding packet
Date: Tue, 1 Sep 2020 01:32:36 -0500 [thread overview]
Message-ID: <20200901063237.15549-4-wright.feng@cypress.com> (raw)
In-Reply-To: <20200901063237.15549-1-wright.feng@cypress.com>
From: Jia-Shyr Chuang <joseph.chuang@cypress.com>
Support packet forwarding mechanism for some special usages on PCIE,
and fix BE/VI priority issue when pumping iperf.
Signed-off-by: Jia-Shyr Chuang <joseph.chuang@cypress.com>
Signed-off-by: Ting-Ying Li <tingying.li@cypress.com>
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@cypress.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 13 ++-
.../broadcom/brcm80211/brcmfmac/core.c | 100 +++++++++++++++++-
.../broadcom/brcm80211/brcmfmac/core.h | 18 +++-
.../broadcom/brcm80211/brcmfmac/msgbuf.c | 31 +++++-
4 files changed, 157 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index d6972420d426..8c7941f85715 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -4799,7 +4799,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = -EINVAL;
goto exit;
}
-
+ ifp->isap = false;
/* Interface specific setup */
if (dev_role == NL80211_IFTYPE_AP) {
if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
@@ -4860,7 +4860,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err);
goto exit;
}
-
+ ifp->isap = true;
brcmf_dbg(TRACE, "AP mode configuration complete\n");
} else if (dev_role == NL80211_IFTYPE_P2P_GO) {
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
@@ -4892,6 +4892,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
}
+ ifp->isap = true;
brcmf_dbg(TRACE, "GO mode configuration complete\n");
} else {
WARN_ON(1);
@@ -6045,6 +6046,14 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
}
if (brcmf_is_apmode(ifp->vif)) {
+ if (e->event_code == BRCMF_E_ASSOC_IND ||
+ e->event_code == BRCMF_E_REASSOC_IND) {
+ brcmf_findadd_sta(ifp, e->addr);
+ } else if ((e->event_code == BRCMF_E_DISASSOC_IND) ||
+ (e->event_code == BRCMF_E_DEAUTH_IND) ||
+ (e->event_code == BRCMF_E_DEAUTH)) {
+ brcmf_del_sta(ifp, e->addr);
+ }
err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
} else if (brcmf_is_linkup(ifp->vif, e)) {
brcmf_dbg(CONN, "Linkup\n");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 20c510dca601..3257b784e019 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -62,6 +62,14 @@ struct wlc_d11rxhdr {
s8 rxpwr[4];
} __packed;
+#define BRCMF_IF_STA_LIST_LOCK_INIT(ifp) spin_lock_init(&(ifp)->sta_list_lock)
+#define BRCMF_IF_STA_LIST_LOCK(ifp, flags) \
+ spin_lock_irqsave(&(ifp)->sta_list_lock, (flags))
+#define BRCMF_IF_STA_LIST_UNLOCK(ifp, flags) \
+ spin_unlock_irqrestore(&(ifp)->sta_list_lock, (flags))
+
+#define BRCMF_STA_NULL ((struct brcmf_sta *)NULL)
+
char *brcmf_ifname(struct brcmf_if *ifp)
{
if (!ifp)
@@ -899,7 +907,9 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
init_waitqueue_head(&ifp->pend_8021x_wait);
spin_lock_init(&ifp->netif_stop_lock);
-
+ BRCMF_IF_STA_LIST_LOCK_INIT(ifp);
+ /* Initialize STA info list */
+ INIT_LIST_HEAD(&ifp->sta_list);
if (mac_addr != NULL)
memcpy(ifp->mac_addr, mac_addr, ETH_ALEN);
@@ -1557,3 +1567,91 @@ void __exit brcmf_core_exit(void)
#endif
}
+/** Find STA with MAC address ea in an interface's STA list. */
+struct brcmf_sta *
+brcmf_find_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta;
+ unsigned long flags;
+
+ BRCMF_IF_STA_LIST_LOCK(ifp, flags);
+ list_for_each_entry(sta, &ifp->sta_list, list) {
+ if (!memcmp(sta->ea.octet, ea, ETH_ALEN)) {
+ brcmf_dbg(INFO, "Found STA: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x into sta list\n",
+ sta->ea.octet[0], sta->ea.octet[1],
+ sta->ea.octet[2], sta->ea.octet[3],
+ sta->ea.octet[4], sta->ea.octet[5]);
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+ return sta;
+ }
+ }
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+
+ return BRCMF_STA_NULL;
+}
+
+/** Add STA into the interface's STA list. */
+struct brcmf_sta *
+brcmf_add_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta;
+ unsigned long flags;
+
+ sta = kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (sta == BRCMF_STA_NULL) {
+ brcmf_err("Alloc failed\n");
+ return BRCMF_STA_NULL;
+ }
+ memcpy(sta->ea.octet, ea, ETH_ALEN);
+ brcmf_dbg(INFO, "Add STA: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x into sta list\n",
+ sta->ea.octet[0], sta->ea.octet[1],
+ sta->ea.octet[2], sta->ea.octet[3],
+ sta->ea.octet[4], sta->ea.octet[5]);
+
+ /* link the sta and the dhd interface */
+ sta->ifp = ifp;
+ INIT_LIST_HEAD(&sta->list);
+
+ BRCMF_IF_STA_LIST_LOCK(ifp, flags);
+
+ list_add_tail(&sta->list, &ifp->sta_list);
+
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+ return sta;
+}
+
+/** Delete STA from the interface's STA list. */
+void
+brcmf_del_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta, *next;
+ unsigned long flags;
+
+ BRCMF_IF_STA_LIST_LOCK(ifp, flags);
+ list_for_each_entry_safe(sta, next, &ifp->sta_list, list) {
+ if (!memcmp(sta->ea.octet, ea, ETH_ALEN)) {
+ brcmf_dbg(INFO, "del STA: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x from sta list\n",
+ ea[0], ea[1], ea[2], ea[3],
+ ea[4], ea[5]);
+ list_del(&sta->list);
+ kfree(sta);
+ }
+ }
+
+ BRCMF_IF_STA_LIST_UNLOCK(ifp, flags);
+}
+
+/** Add STA if it doesn't exist. Not reentrant. */
+struct brcmf_sta*
+brcmf_findadd_sta(struct brcmf_if *ifp, const u8 *ea)
+{
+ struct brcmf_sta *sta = NULL;
+
+ sta = brcmf_find_sta(ifp, ea);
+
+ if (!sta) {
+ /* Add entry */
+ sta = brcmf_add_sta(ifp, ea);
+ }
+ return sta;
+}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index 33b2ab3b54b0..3cf0b8c8d7b1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -185,6 +185,7 @@ struct brcmf_if {
struct brcmf_fws_mac_descriptor *fws_desc;
int ifidx;
s32 bsscfgidx;
+ bool isap;
u8 mac_addr[ETH_ALEN];
u8 netif_stop;
spinlock_t netif_stop_lock;
@@ -193,6 +194,19 @@ struct brcmf_if {
struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES];
u8 ipv6addr_idx;
bool fwil_fwerr;
+ struct list_head sta_list; /* sll of associated stations */
+ spinlock_t sta_list_lock;
+};
+
+struct ether_addr {
+ u8 octet[ETH_ALEN];
+};
+
+/** Per STA params. A list of dhd_sta objects are managed in dhd_if */
+struct brcmf_sta {
+ void *ifp; /* associated brcm_if */
+ struct ether_addr ea; /* stations ethernet mac address */
+ struct list_head list; /* link into brcmf_if::sta_list */
};
int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
@@ -215,5 +229,7 @@ int brcmf_net_mon_attach(struct brcmf_if *ifp);
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
int __init brcmf_core_init(void);
void __exit brcmf_core_exit(void);
-
+void brcmf_del_sta(struct brcmf_if *ifp, const u8 *ea);
+struct brcmf_sta *brcmf_find_sta(struct brcmf_if *ifp, const u8 *ea);
+struct brcmf_sta *brcmf_findadd_sta(struct brcmf_if *ifp, const u8 *ea);
#endif /* BRCMFMAC_CORE_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index f1a20db8daab..c53c3cf96f92 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -1140,7 +1140,8 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
{
struct brcmf_pub *drvr = msgbuf->drvr;
struct msgbuf_rx_complete *rx_complete;
- struct sk_buff *skb;
+ struct sk_buff *skb, *cpskb = NULL;
+ struct ethhdr *eh;
u16 data_offset;
u16 buflen;
u16 flags;
@@ -1189,6 +1190,34 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)
return;
}
+ eh = (struct ethhdr *)(skb->data);
+ if (ifp->isap) {
+ skb_set_network_header(skb, sizeof(struct ethhdr));
+ skb->protocol = eh->h_proto;
+ skb->priority = cfg80211_classify8021d(skb, NULL);
+ if (is_unicast_ether_addr(eh->h_dest)) {
+ if (brcmf_find_sta(ifp, eh->h_dest)) {
+ /* determine the priority */
+ if (skb->priority == 0 || skb->priority > 7) {
+ skb->priority =
+ cfg80211_classify8021d(skb,
+ NULL);
+ }
+ brcmf_proto_tx_queue_data(ifp->drvr,
+ ifp->ifidx, skb);
+ return;
+ }
+ } else {
+ cpskb = pskb_copy(skb, GFP_ATOMIC);
+ if (cpskb) {
+ brcmf_proto_tx_queue_data(ifp->drvr,
+ ifp->ifidx,
+ cpskb);
+ } else {
+ brcmf_err("Unable to do skb copy\n");
+ }
+ }
+ }
skb->protocol = eth_type_trans(skb, ifp->ndev);
brcmf_netif_rx(ifp, skb);
}
--
2.25.0
next prev parent reply other threads:[~2020-09-01 6:33 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-01 6:32 [PATCH 0/4] brcmfmac: Add few features in AP mode Wright Feng
2020-09-01 6:32 ` [PATCH 1/4] brcmfmac: add change_bss to support AP isolation Wright Feng
2020-09-07 9:04 ` Kalle Valo
2020-09-07 9:21 ` Arend Van Spriel
2020-09-07 9:49 ` Kalle Valo
2020-09-07 10:09 ` Wright Feng
2020-09-07 15:29 ` Kalle Valo
[not found] ` <01010174692f7c3f-4b7369b2-0665-4324-b1c8-57bd22ac9ce7-000000@us-west-2.amazonses.com>
2020-09-07 15:57 ` Arend Van Spriel
2020-09-08 2:13 ` Wright Feng
2020-09-08 4:29 ` Kalle Valo
2020-09-01 6:32 ` [PATCH 2/4] brcmfmac: don't allow arp/nd offload to be enabled if ap mode exists Wright Feng
2020-09-01 6:32 ` Wright Feng [this message]
2020-09-01 9:39 ` [PATCH 3/4] brcmfmac: support the forwarding packet Arend Van Spriel
2020-09-03 3:30 ` kernel test robot
2020-09-03 3:30 ` [RFC PATCH] brcmfmac: brcmf_add_sta can be static kernel test robot
2020-09-01 6:32 ` [PATCH 4/4] brcmfmac: add a variable for packet forwarding condition Wright Feng
2020-09-07 9:21 ` Kalle Valo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200901063237.15549-4-wright.feng@cypress.com \
--to=wright.feng@cypress.com \
--cc=arend.vanspriel@broadcom.com \
--cc=brcm80211-dev-list@broadcom.com \
--cc=brcm80211-dev-list@cypress.com \
--cc=chi-hsien.lin@cypress.com \
--cc=franky.lin@broadcom.com \
--cc=hante.meuleman@broadcom.com \
--cc=joseph.chuang@cypress.com \
--cc=kvalo@codeaurora.org \
--cc=linux-wireless@vger.kernel.org \
--cc=tingying.li@cypress.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).