brcmfmac: Add few features in AP mode
v2 cover brcmfmac: Add few features in AP mode
This patch series add support for AP isolation and forwarding mechanism in AP mode.
changes in v2:
- Remove u32 cast from patch 1/4
- Fix sparse warning in patch 3/4
- Remove the macro from patch 3/4
- Change conditional statements in patch 4/4
Jia-Shyr Chuang (1):
brcmfmac: support the forwarding packet
Ting-Ying Li (2):
brcmfmac: don't allow arp/nd offload to be enabled if ap mode exists
brcmfmac: add a variable for packet forwarding condition
Wright Feng (1):
brcmfmac: add change_bss to support AP isolation
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 65 +++++++++- .../broadcom/brcm80211/brcmfmac/cfg80211.h | 1 + .../broadcom/brcm80211/brcmfmac/core.c | 117 +++++++++++++++++- .../broadcom/brcm80211/brcmfmac/core.h | 18 ++- .../broadcom/brcm80211/brcmfmac/feature.c | 1 + .../broadcom/brcm80211/brcmfmac/feature.h | 3 +- .../broadcom/brcm80211/brcmfmac/msgbuf.c | 31 ++++- 7 files changed, 228 insertions(+), 8 deletions(-)
Signature · 1 line
2.25.0
PATCH v2 1/4 brcmfmac: add change_bss to support AP isolation
Hostap has a parameter "ap_isolate" which is used to prevent low-level bridging of frames between associated stations in the BSS. Regarding driver side, we add cfg80211 ops method change_bss to support setting AP isolation if firmware has ap_isolate feature.
---
v2: Remove u32 cast
--- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 23 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/feature.c | 1 + .../broadcom/brcm80211/brcmfmac/feature.h | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +23 -0
@@ -5466,6 +5466,26 @@ static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,return brcmf_set_pmk (ifp,NULL ,0 ); } +static int +brcmf_cfg80211_change_bss (struct wiphy *wiphy,struct net_device *dev, +struct bss_parameters *params) +{ +struct brcmf_if *ifp; +int ret =0 ; +u32 ap_isolate; + +brcmf_dbg (TRACE ,"Enter\n" ); + ifp =netdev_priv (dev); +if (params->ap_isolate >=0 ) { + ap_isolate = params->ap_isolate; + ret =brcmf_fil_iovar_int_set (ifp,"ap_isolate" , ap_isolate); +if (ret <0 ) +brcmf_err ("ap_isolate iovar failed: ret=%d\n" , ret); + } + +return ret; +} +static struct cfg80211_ops brcmf_cfg80211_ops = { .add_virtual_intf = brcmf_cfg80211_add_iface, .del_virtual_intf = brcmf_cfg80211_del_iface,
@@ -7540,6 +7560,9 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,if (brcmf_feat_is_enabled (ifp,BRCMF_FEAT_WOWL_GTK )) ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;#endif +if (brcmf_feat_is_enabled (ifp,BRCMF_FEAT_AP_ISOLATE )) + ops->change_bss = brcmf_cfg80211_change_bss; + err =wiphy_register (wiphy);if (err <0 ) {bphy_err (drvr,"Could not register wiphy device (%d)\n" , err);
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +1 -0
@@ -279,6 +279,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)brcmf_feat_iovar_int_get (ifp,BRCMF_FEAT_RSDB ,"rsdb_mode" );brcmf_feat_iovar_int_get (ifp,BRCMF_FEAT_TDLS ,"tdls_enable" );brcmf_feat_iovar_int_get (ifp,BRCMF_FEAT_MFP ,"mfp" ); +brcmf_feat_iovar_int_get (ifp,BRCMF_FEAT_AP_ISOLATE ,"ap_isolate" ); pfn_mac.version =BRCMF_PFN_MACADDR_CFG_VER ; err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac,
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +2 -1
@@ -51,7 +51,8 @@ BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \ BRCMF_FEAT_DEF(DOT11H) \ BRCMF_FEAT_DEF(SAE) \ - BRCMF_FEAT_DEF(FWAUTH) + BRCMF_FEAT_DEF(FWAUTH) \ + BRCMF_FEAT_DEF(AP_ISOLATE)/* * Quirks:
Signature · 1 line
2.25.0
Re: [PATCH v2 1/4] brcmfmac: add change_bss to support AP isolation
Quoted 4 lines · Wright Feng
Hostap has a parameter "
ap_isolate" which is used to prevent low-level bridging of frames between associated stations in the BSS. Regarding driver side, we add cfg80211 ops methodchange_bssto support setting AP isolation if firmware hasap_isolatefeature.
Quoted 9 lines
Signed-off-by Wright Feng <[email protected]>Signed-off-by Chi-hsien Lin <[email protected]>---
v2: Remove u32 cast--- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 23 +++++++++++++++++++ .../broadcom/brcm80211/brcmfmac/feature.c | 1 + .../broadcom/brcm80211/brcmfmac/feature.h | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-)
Re: [PATCH v2 1/4] brcmfmac: add change_bss to support AP isolation
In reply to Wright FengQuoted 8 lines · Wright Feng
Hostap has a parameter "
ap_isolate" which is used to prevent low-level bridging of frames between associated stations in the BSS. Regarding driver side, we add cfg80211 ops methodchange_bssto support setting AP isolation if firmware hasap_isolatefeature.Signed-off-by Wright Feng <[email protected]>Signed-off-by Chi-hsien Lin <[email protected]>Reviewed-by Arend van Spriel <[email protected]>
Dropping as no response to Arend's comment.
4 patches set to Changes Requested.
11845611 [v2,1/4] brcmfmac: add change_bss to support AP isolation 11845613 [v2,2/4] brcmfmac: don't allow arp/nd offload to be enabled if ap mode exists 11845615 [v2,3/4] brcmfmac: support the forwarding packet
11845617 [v2,4/4] brcmfmac: add a variable for packet forwarding condition
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
PATCH v2 2/4 brcmfmac: don't allow arp/nd offload to be enabled if ap mode exists
In reply to Wright FengFrom: Ting-Ying Li <[email protected]>
Add a condition to determine whether arp/nd offload enabling request is allowed. If there is any interface acts as ap mode and is operating, then reject the request of arp oflload enabling from cfg80211.
--- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 17 ++++++++++++++++- .../broadcom/brcm80211/brcmfmac/cfg80211.h | 1 + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +16 -1
@@ -769,6 +769,21 @@ void brcmf_set_mpc(struct brcmf_if *ifp, int mpc) } } +bool brcmf_is_apmode_operating (struct wiphy *wiphy) +{ +struct brcmf_cfg80211_info *cfg =wiphy_to_cfg (wiphy); +struct brcmf_cfg80211_vif *vif; +bool ret = false; + +list_for_each_entry (vif, &cfg->vif_list, list) { +if (brcmf_is_apmode (vif) && +test_bit (BRCMF_VIF_STATUS_AP_CREATED , &vif->sme_state)) + ret = true; + } + +return ret; +} +s32 brcmf_notify_escan_complete (struct brcmf_cfg80211_info *cfg,struct brcmf_if *ifp,bool aborted,bool fw_abort)
@@ -4990,8 +5005,8 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)bphy_err (drvr,"bss_enable config failed %d\n" , err); }brcmf_set_mpc (ifp,1 ); -brcmf_configure_arp_nd_offload (ifp, true);clear_bit (BRCMF_VIF_STATUS_AP_CREATED , &ifp->vif->sme_state); +brcmf_configure_arp_nd_offload (ifp, true);brcmf_net_setcarrier (ifp, false);return err;
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +1 -0
@@ -461,5 +461,6 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,void brcmf_set_mpc (struct brcmf_if *ndev,int mpc);void brcmf_abort_scanning (struct brcmf_cfg80211_info *cfg);void brcmf_cfg80211_free_netdev (struct net_device *ndev); +bool brcmf_is_apmode_operating (struct wiphy *wiphy);#endif /* BRCMFMAC_CFG80211_H */
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +5 -0
@@ -96,6 +96,11 @@ void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)s32 err;u32 mode; +if (enable &&brcmf_is_apmode_operating (ifp->drvr->wiphy)) { +brcmf_dbg (TRACE ,"Skip ARP/ND offload enable when soft AP is running\n" ); +return ; + } +if (enable) mode =BRCMF_ARP_OL_AGENT |BRCMF_ARP_OL_PEER_AUTO_REPLY ;else
Signature · 1 line
2.25.0
Re: [PATCH v2 2/4] brcmfmac: don't allow arp/nd offload to be enabled if ap mode exists
Quoted 6 lines · Wright Feng
From: Ting-Ying Li <[email protected]>
Add a condition to determine whether arp/nd offload enabling request is allowed. If there is any interface acts as ap mode and is operating, then reject the request of arp oflload enabling from cfg80211.
Quoted 7 lines
Signed-off-by Ting-Ying Li <[email protected]>Signed-off-by Wright Feng <[email protected]>--- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 17 ++++++++++++++++- .../broadcom/brcm80211/brcmfmac/cfg80211.h | 1 + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-)
PATCH v2 3/4 brcmfmac: support the forwarding packet
In reply to Wright FengFrom: Jia-Shyr Chuang <[email protected]>
Support packet forwarding mechanism for some special usages on PCIE, and observed that packet only send BE when pumping iperf with VI. we need to set priority before forwarding packet.
---
v2: Fix sparse warning and remove the macro from the patch
--- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 12 +- .../broadcom/brcm80211/brcmfmac/core.c | 112 +++++++++++++++++- .../broadcom/brcm80211/brcmfmac/core.h | 17 ++- .../broadcom/brcm80211/brcmfmac/msgbuf.c | 31 ++++- 4 files changed, 166 insertions(+), 6 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +9 -3
@@ -611,7 +611,7 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,return ERR_PTR (err); } -static bool brcmf_is_apmode (struct brcmf_cfg80211_vif *vif) +bool brcmf_is_apmode (struct brcmf_cfg80211_vif *vif) {enum nl80211_iftype iftype;
@@ -4812,7 +4812,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, err = -EINVAL ; goto exit; } -/* Interface specific setup */ if (dev_role ==NL80211_IFTYPE_AP ) {if ((brcmf_feat_is_enabled (ifp,BRCMF_FEAT_MBSS )) && (!mbss))
@@ -4892,7 +4891,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, err); goto exit; } -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);
@@ -6086,6 +6084,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" );
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +111 -1
121 lines not on this page · raw message
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +16 -1
@@ -193,6 +193,18 @@ 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 ]; +}; + +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 +227,8 @@ 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); +bool brcmf_is_apmode (struct brcmf_cfg80211_vif *vif);#endif /* BRCMFMAC_CORE_H */
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +30 -1
@@ -1141,7 +1141,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;
@@ -1190,6 +1191,34 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf)return ; } + eh = (struct ethhdr *)(skb->data); +if (brcmf_is_apmode (ifp->vif)) { +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, false); }
Signature · 1 line
2.25.0
Arend Van Spriel
maintainerRe: [PATCH v2 3/4] brcmfmac: support the forwarding packet
Quoted 5 lines · Wright Feng
From: Jia-Shyr Chuang <[email protected]>
Support packet forwarding mechanism for some special usages on PCIE, and observed that packet only send BE when pumping iperf with VI. we need to set priority before forwarding packet.
I commented on this feature in the previous patch set, but did not see any follow up on that.
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/
Regards,
Arend
PATCH v2 4/4 brcmfmac: add a variable for packet forwarding condition
In reply to Wright FengFrom: Ting-Ying Li <[email protected]>
When the "ap_isolate" function is not set by the host, host-based packet forwarding will be enabled if the packet forwarding mechanism is not offloaded to the lower layer.
---
v4: Change conditional statements
--- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 17 +++++++++++++++-- .../wireless/broadcom/brcm80211/brcmfmac/core.h | 1 + .../broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +15 -2
@@ -5484,8 +5484,8 @@ brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) {struct brcmf_if *ifp; -int ret =0 ; -u32 ap_isolate; +int ret =0 , result =0 ; +u32 ap_isolate, val;brcmf_dbg (TRACE ,"Enter\n" ); ifp =netdev_priv (dev);
@@ -5496,6 +5496,19 @@ brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,brcmf_err ("ap_isolate iovar failed: ret=%d\n" , ret); } +/* Get ap_isolate value from firmware to detemine whether fmac */ +/* driver enables packet forwarding. */ + result =brcmf_fil_iovar_int_get (ifp,"ap_isolate" , &val); +if (result ==0 && + params->ap_isolate ==0 && + val ==1 ) { + ifp->fmac_pkt_fwd_en = true; + }else { +if (result <0 ) +brcmf_err ("get ap_isolate iovar failed: result=%d\n" , result); + ifp->fmac_pkt_fwd_en = false; + } +return ret; }
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +1 -0
@@ -195,6 +195,7 @@ struct brcmf_if {bool fwil_fwerr;struct list_head sta_list;/* sll of associated stations */ spinlock_t sta_list_lock; +bool fmac_pkt_fwd_en; };struct ether_addr {
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +1 -1
@@ -1192,7 +1192,7 @@ brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) } eh = (struct ethhdr *)(skb->data); -if (brcmf_is_apmode (ifp->vif)) { +if (brcmf_is_apmode (ifp->vif) && ifp->fmac_pkt_fwd_en) {skb_set_network_header (skb,sizeof (struct ethhdr )); skb->protocol = eh->h_proto; skb->priority =cfg80211_classify8021d (skb,NULL );
Signature · 1 line
2.25.0