mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
233 lines
7.4 KiB
Diff
233 lines
7.4 KiB
Diff
From 36d29fdfdd46ec717b40976214a84089cb6553d6 Mon Sep 17 00:00:00 2001
|
|
From: Wright Feng <wright.feng@cypress.com>
|
|
Date: Wed, 7 Nov 2018 21:27:46 -0600
|
|
Subject: [PATCH 065/179] brcmfmac: support station interface creation version
|
|
1, 2 and 3
|
|
|
|
To create virtual station interface for RSDB and VSDB, we add interface
|
|
creation version 1, 2 and 3 supports
|
|
The structures of each version are different and only version 3 and
|
|
later version are able to get interface creating version from firmware
|
|
side.
|
|
|
|
The patch has been verified two concurrent stations pings test with
|
|
interface create version 1:
|
|
89342(4359b1)-PCIE: 9.40.100
|
|
interface create version 2:
|
|
4373a0-sdio: 13.10.271
|
|
interface create version 3:
|
|
4373a0-sdio: 13.35.48
|
|
|
|
Signed-off-by: Wright Feng <wright.feng@cypress.com>
|
|
Signed-off-by: Chi-hsien Lin <chi-hsien.lin@infineon.com>
|
|
---
|
|
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 148 +++++++++++++++---
|
|
1 file changed, 124 insertions(+), 24 deletions(-)
|
|
|
|
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
index a0d9454664e2..e765f8e3cb1c 100644
|
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
|
@@ -269,17 +269,46 @@ struct parsed_vndr_ies {
|
|
#define WLC_E_IF_ROLE_STA 0 /* Infra STA */
|
|
#define WLC_E_IF_ROLE_AP 1 /* Access Point */
|
|
|
|
+#define WL_INTERFACE_CREATE_VER_1 1
|
|
+#define WL_INTERFACE_CREATE_VER_2 2
|
|
+#define WL_INTERFACE_CREATE_VER_3 3
|
|
+#define WL_INTERFACE_CREATE_VER_MAX WL_INTERFACE_CREATE_VER_3
|
|
+
|
|
#define WL_INTERFACE_MAC_DONT_USE 0x0
|
|
#define WL_INTERFACE_MAC_USE 0x2
|
|
|
|
#define WL_INTERFACE_CREATE_STA 0x0
|
|
#define WL_INTERFACE_CREATE_AP 0x1
|
|
|
|
-struct wl_interface_create {
|
|
- u16 ver;
|
|
- u32 flags;
|
|
- u8 mac_addr[ETH_ALEN];
|
|
- u8 pad[13];
|
|
+struct wl_interface_create_v1 {
|
|
+ u16 ver; /* structure version */
|
|
+ u32 flags; /* flags for operation */
|
|
+ u8 mac_addr[ETH_ALEN]; /* MAC address */
|
|
+ u32 wlc_index; /* optional for wlc index */
|
|
+};
|
|
+
|
|
+struct wl_interface_create_v2 {
|
|
+ u16 ver; /* structure version */
|
|
+ u8 pad1[2];
|
|
+ u32 flags; /* flags for operation */
|
|
+ u8 mac_addr[ETH_ALEN]; /* MAC address */
|
|
+ u8 iftype; /* type of interface created */
|
|
+ u8 pad2;
|
|
+ u32 wlc_index; /* optional for wlc index */
|
|
+};
|
|
+
|
|
+struct wl_interface_create_v3 {
|
|
+ u16 ver; /* structure version */
|
|
+ u16 len; /* length of structure + data */
|
|
+ u16 fixed_len; /* length of structure */
|
|
+ u8 iftype; /* type of interface created */
|
|
+ u8 wlc_index; /* optional for wlc index */
|
|
+ u32 flags; /* flags for operation */
|
|
+ u8 mac_addr[ETH_ALEN]; /* MAC address */
|
|
+ u8 bssid[ETH_ALEN]; /* optional for BSSID */
|
|
+ u8 if_index; /* interface index request */
|
|
+ u8 pad[3];
|
|
+ u8 data[]; /* Optional for specific data */
|
|
};
|
|
|
|
static u8 nl80211_band_to_fwil(enum nl80211_band band)
|
|
@@ -569,16 +598,14 @@ static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
|
|
return -ENOMEM;
|
|
}
|
|
|
|
-static void brcmf_set_sta_iface_macaddr(struct brcmf_if *ifp,
|
|
- struct wl_interface_create *iface)
|
|
+static void brcmf_set_vif_sta_macaddr(struct brcmf_if *ifp, u8 *mac_addr)
|
|
{
|
|
u8 mac_idx = ifp->drvr->sta_mac_idx;
|
|
|
|
/* set difference MAC address with locally administered bit */
|
|
- iface->flags |= WL_INTERFACE_MAC_USE;
|
|
- memcpy(iface->mac_addr, ifp->mac_addr, ETH_ALEN);
|
|
- iface->mac_addr[0] |= 0x02;
|
|
- iface->mac_addr[3] ^= mac_idx ? 0xC0 : 0xA0;
|
|
+ memcpy(mac_addr, ifp->mac_addr, ETH_ALEN);
|
|
+ mac_addr[0] |= 0x02;
|
|
+ mac_addr[3] ^= mac_idx ? 0xC0 : 0xA0;
|
|
mac_idx++;
|
|
mac_idx = mac_idx % 2;
|
|
ifp->drvr->sta_mac_idx = mac_idx;
|
|
@@ -586,23 +613,96 @@ static void brcmf_set_sta_iface_macaddr(struct brcmf_if *ifp,
|
|
|
|
static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
|
|
{
|
|
- struct wl_interface_create iface;
|
|
+ struct wl_interface_create_v1 iface_v1;
|
|
+ struct wl_interface_create_v2 iface_v2;
|
|
+ struct wl_interface_create_v3 iface_v3;
|
|
+ u32 iface_create_ver;
|
|
int err;
|
|
|
|
- memset(&iface, 0, sizeof(iface));
|
|
+ /* interface_create version 1 */
|
|
+ memset(&iface_v1, 0, sizeof(iface_v1));
|
|
+ iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
|
|
+ iface_v1.flags = WL_INTERFACE_CREATE_STA |
|
|
+ WL_INTERFACE_MAC_USE;
|
|
+ if (!is_zero_ether_addr(macaddr))
|
|
+ memcpy(iface_v1.mac_addr, macaddr, ETH_ALEN);
|
|
+ else
|
|
+ brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
|
|
|
|
- iface.ver = 0;
|
|
- iface.flags = WL_INTERFACE_CREATE_STA;
|
|
- if (!is_zero_ether_addr(macaddr)) {
|
|
- /* set MAC address in cfg80211 params */
|
|
- memcpy(iface.mac_addr, macaddr, ETH_ALEN);
|
|
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
|
|
+ &iface_v1,
|
|
+ sizeof(iface_v1));
|
|
+ if (err) {
|
|
+ brcmf_info("failed to create interface(v1), err=%d\n",
|
|
+ err);
|
|
} else {
|
|
- brcmf_set_sta_iface_macaddr(ifp, &iface);
|
|
+ brcmf_dbg(INFO, "interface created(v1)\n");
|
|
+ return 0;
|
|
}
|
|
|
|
- err = brcmf_fil_iovar_data_get(ifp, "interface_create", &iface,
|
|
- sizeof(iface));
|
|
- return err;
|
|
+ /* interface_create version 2 */
|
|
+ memset(&iface_v2, 0, sizeof(iface_v2));
|
|
+ iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
|
|
+ iface_v2.flags = WL_INTERFACE_MAC_USE;
|
|
+ iface_v2.iftype = WL_INTERFACE_CREATE_STA;
|
|
+ if (!is_zero_ether_addr(macaddr))
|
|
+ memcpy(iface_v2.mac_addr, macaddr, ETH_ALEN);
|
|
+ else
|
|
+ brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
|
|
+
|
|
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
|
|
+ &iface_v2,
|
|
+ sizeof(iface_v2));
|
|
+ if (err) {
|
|
+ brcmf_info("failed to create interface(v2), err=%d\n",
|
|
+ err);
|
|
+ } else {
|
|
+ brcmf_dbg(INFO, "interface created(v2)\n");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* interface_create version 3+ */
|
|
+ /* get supported version from firmware side */
|
|
+ iface_create_ver = 0;
|
|
+ err = brcmf_fil_bsscfg_int_get(ifp, "interface_create",
|
|
+ &iface_create_ver);
|
|
+ if (err) {
|
|
+ brcmf_err("fail to get supported version, err=%d\n", err);
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+
|
|
+ switch (iface_create_ver) {
|
|
+ case WL_INTERFACE_CREATE_VER_3:
|
|
+ memset(&iface_v3, 0, sizeof(iface_v3));
|
|
+ iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
|
|
+ iface_v3.flags = WL_INTERFACE_MAC_USE;
|
|
+ iface_v3.iftype = WL_INTERFACE_CREATE_STA;
|
|
+ if (!is_zero_ether_addr(macaddr))
|
|
+ memcpy(iface_v3.mac_addr, macaddr, ETH_ALEN);
|
|
+ else
|
|
+ brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
|
|
+
|
|
+ err = brcmf_fil_iovar_data_get(ifp, "interface_create",
|
|
+ &iface_v3,
|
|
+ sizeof(iface_v3));
|
|
+
|
|
+ if (!err)
|
|
+ brcmf_dbg(INFO, "interface created(v3)\n");
|
|
+ break;
|
|
+ default:
|
|
+ brcmf_err("not support interface create(v%d)\n",
|
|
+ iface_create_ver);
|
|
+ err = -EOPNOTSUPP;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (err) {
|
|
+ brcmf_info("station interface creation failed (%d)\n",
|
|
+ err);
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
}
|
|
|
|
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
|
|
@@ -7301,7 +7401,7 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
|
|
*
|
|
* p2p, mchan, and mbss:
|
|
*
|
|
- * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
|
|
+ * #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
|
|
* #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
|
|
* #AP <= 4, matching BI, channels = 1, 4 total
|
|
*
|
|
@@ -7347,7 +7447,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
|
|
goto err;
|
|
|
|
combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
|
|
- c0_limits[i].max = 1;
|
|
+ c0_limits[i].max = 1 + (p2p && mchan);
|
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
|
if (mon_flag) {
|
|
c0_limits[i].max = 1;
|
|
--
|
|
2.17.1
|
|
|