This series adds the following:
* query features through firmware command.
* IBSS fixes.
* ARP offload through inet notifier.
* force probe to succeed for debugging.
Arend van Spriel (2):
brcmfmac: obtain feature info using 'cap' firmware command
brcmfmac: introduce module parameter to force successful probe
Franky Lin (1):
brcmfmac: add arp offload ip address table configuration support
Hante Meuleman (4):
brcmfmac: Add get_station support for IBSS
brcmfmac: Add support for scheduled scan mac randomization
brcmfmac: Fix warn trace on module unload while in ibss mode
brcmfmac: Move all module parameters to one place
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 12 +-
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 118 +++++++++++++++---
.../wireless/broadcom/brcm80211/brcmfmac/common.c | 72 +++++++++++
.../wireless/broadcom/brcm80211/brcmfmac/common.h | 56 +++++++++
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 132 +++++++++++++++++++--
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 7 +-
.../wireless/broadcom/brcm80211/brcmfmac/feature.c | 64 +++++-----
.../broadcom/brcm80211/brcmfmac/firmware.c | 16 +--
.../wireless/broadcom/brcm80211/brcmfmac/fwil.h | 1 +
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 34 ++++++
.../broadcom/brcm80211/brcmfmac/fwsignal.c | 9 +-
11 files changed, 439 insertions(+), 82 deletions(-)
--
1.9.1
The module parameter can be used to ensure the probe succeeds thus
claiming the device and allowing post-mortem debugging in case of
firmware crash. It is only available when select CONFIG_BRCMDBG.
Reviewed-by: Hante Meuleman <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 11 ++++++++++-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h | 13 +++++++++++++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 ++
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index bb9e2b3..4265b50 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -67,6 +67,13 @@ static int brcmf_roamoff;
module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
+#ifdef DEBUG
+/* always succeed brcmf_bus_start() */
+static int brcmf_ignore_probe_fail;
+module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
+MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
+#endif
+
struct brcmf_mp_global_t brcmf_mp_global;
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
@@ -232,7 +239,9 @@ int brcmf_mp_device_attach(struct brcmf_pub *drvr)
drvr->settings->feature_disable = brcmf_feature_disable;
drvr->settings->fcmode = brcmf_fcmode;
drvr->settings->roamoff = !!brcmf_roamoff;
-
+#ifdef DEBUG
+ drvr->settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
+#endif
return 0;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index abe3764..3b0a63b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -55,11 +55,24 @@ struct brcmf_mp_device {
int feature_disable;
int fcmode;
bool roamoff;
+ bool ignore_probe_fail;
};
void brcmf_mp_attach(void);
int brcmf_mp_device_attach(struct brcmf_pub *drvr);
void brcmf_mp_device_detach(struct brcmf_pub *drvr);
+#ifdef DEBUG
+static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr)
+{
+ return drvr->settings->ignore_probe_fail;
+}
+#else
+static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr)
+{
+ return false;
+}
+#endif
+
/* Sets dongle media info (drv_version, mac address). */
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 3fa7bc5..7c75b1a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1183,6 +1183,8 @@ fail:
brcmf_net_detach(p2p_ifp->ndev);
drvr->iflist[0] = NULL;
drvr->iflist[1] = NULL;
+ if (brcmf_ignoring_probe_fail(drvr))
+ ret = 0;
return ret;
}
return 0;
--
1.9.1
From: Hante Meuleman <[email protected]>
When get_station is requested for IBSS then an error will be
printed and no information will be returned. This patch adds
IBSS specific get station information function.
Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 51 ++++++++++++++++++++++
.../wireless/broadcom/brcm80211/brcmfmac/fwil.h | 1 +
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 17 ++++++++
3 files changed, 69 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 17658b3..6b9339b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2429,6 +2429,54 @@ static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
}
static s32
+brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
+ struct station_info *sinfo)
+{
+ struct brcmf_scb_val_le scbval;
+ struct brcmf_pktcnt_le pktcnt;
+ s32 err;
+ u32 rate;
+ u32 rssi;
+
+ /* Get the current tx rate */
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
+ if (err < 0) {
+ brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err);
+ return err;
+ }
+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
+ sinfo->txrate.legacy = rate * 5;
+
+ memset(&scbval, 0, sizeof(scbval));
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
+ sizeof(scbval));
+ if (err) {
+ brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err);
+ return err;
+ }
+ rssi = le32_to_cpu(scbval.val);
+ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+ sinfo->signal = rssi;
+
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
+ sizeof(pktcnt));
+ if (err) {
+ brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
+ return err;
+ }
+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
+ BIT(NL80211_STA_INFO_RX_DROP_MISC) |
+ BIT(NL80211_STA_INFO_TX_PACKETS) |
+ BIT(NL80211_STA_INFO_TX_FAILED);
+ sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
+ sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
+ sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
+ sinfo->tx_failed = le32_to_cpu(pktcnt.tx_bad_pkt);
+
+ return 0;
+}
+
+static s32
brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
const u8 *mac, struct station_info *sinfo)
{
@@ -2445,6 +2493,9 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
if (!check_vif_up(ifp->vif))
return -EIO;
+ if (brcmf_is_ibssmode(ifp->vif))
+ return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
+
memset(&sta_info_le, 0, sizeof(sta_info_le));
memcpy(&sta_info_le, mac, ETH_ALEN);
err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
index b20fc0f..6b72df1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
@@ -70,6 +70,7 @@
#define BRCMF_C_SET_WSEC 134
#define BRCMF_C_GET_PHY_NOISE 135
#define BRCMF_C_GET_BSS_INFO 136
+#define BRCMF_C_GET_GET_PKTCNTS 137
#define BRCMF_C_GET_BANDLIST 140
#define BRCMF_C_SET_SCB_TIMEOUT 158
#define BRCMF_C_GET_ASSOCLIST 159
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index 94d34ad..0b1e46d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -751,4 +751,21 @@ struct brcmf_pno_scanresults_le {
__le32 count;
};
+/**
+ * struct brcmf_pktcnt_le - packet counters.
+ *
+ * @rx_good_pkt: packets (MSDUs & MMPDUs) received from this station
+ * @rx_bad_pkt: failed rx packets
+ * @tx_good_pkt: packets (MSDUs & MMPDUs) transmitted to this station
+ * @tx_bad_pkt: failed tx packets
+ * @rx_ocast_good_pkt: unicast packets destined for others
+ */
+struct brcmf_pktcnt_le {
+ __le32 rx_good_pkt;
+ __le32 rx_bad_pkt;
+ __le32 tx_good_pkt;
+ __le32 tx_bad_pkt;
+ __le32 rx_ocast_good_pkt;
+};
+
#endif /* FWIL_TYPES_H_ */
--
1.9.1
From: Hante Meuleman <[email protected]>
When the driver is being unloaded a situation can occur where the
wirelesss core (cfg80211) wants to remove the ibss, but the state
of brcmfmac has already been set to down. When an error is
returned in that situation then that will result in a stack
trace on removal of the wiphy object. This is avoided by
returning 0 when device is down on a leave_ibss call.
Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 5964763..6632e46 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -1448,8 +1448,13 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
struct brcmf_if *ifp = netdev_priv(ndev);
brcmf_dbg(TRACE, "Enter\n");
- if (!check_vif_up(ifp->vif))
- return -EIO;
+ if (!check_vif_up(ifp->vif)) {
+ /* When driver is being unloaded, it can end up here. If an
+ * error is returned then later on a debug trace in the wireless
+ * core module will be printed. To avoid this 0 is returned.
+ */
+ return 0;
+ }
brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
--
1.9.1
Several features in the driver directly map to a firmware feature
listed in response of the 'cap' firmware command. For those features
this response will be examined instead of attempting individual
firmware commands.
Reviewed-by: Hante Meuleman <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
1 file changed, 30 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index d9d1ca4..08b7200 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
};
#undef BRCMF_FEAT_DEF
+struct brcmf_feat_fwcap {
+ enum brcmf_feat_id feature;
+ const char * const fwcap_id;
+};
+
+static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
+ { BRCMF_FEAT_MBSS, "mbss" },
+ { BRCMF_FEAT_MCHAN, "mchan" },
+ { BRCMF_FEAT_P2P, "p2p" },
+};
+
#ifdef DEBUG
/*
* expand quirk list to array of quirk strings.
@@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
}
}
-/**
- * brcmf_feat_iovar_int_set() - determine feature through iovar set.
- *
- * @ifp: interface to query.
- * @id: feature id.
- * @name: iovar name.
- */
-static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
- enum brcmf_feat_id id, char *name, u32 val)
+static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
{
- int err;
-
- err = brcmf_fil_iovar_int_set(ifp, name, val);
- if (err == 0) {
- brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
- ifp->drvr->feat_flags |= BIT(id);
- } else {
- brcmf_dbg(TRACE, "%s feature check failed: %d\n",
- brcmf_feat_names[id], err);
+ char caps[256];
+ enum brcmf_feat_id id;
+ int i;
+
+ brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
+ brcmf_dbg(INFO, "[ %s]\n", caps);
+
+ for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
+ if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
+ id = brcmf_fwcap_map[i].feature;
+ brcmf_dbg(INFO, "enabling feature: %s\n",
+ brcmf_feat_names[id]);
+ ifp->drvr->feat_flags |= BIT(id);
+ }
}
}
@@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
{
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
- brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
+ brcmf_feat_firmware_capabilities(ifp);
+
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
if (drvr->bus_if->wowl_supported)
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
+ /* MBSS does not work for 43362 */
if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
- brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
- brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
+ ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
--
1.9.1
On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]> wrote:
> From: Hante Meuleman <[email protected]>
>
> Scheduled scan be requested to use mac randomization. This patch
> checks the flags and enables the randomization if desired.
The driver also needs to advertise support for this using the
NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR flag, if the firmware
supports it. This can be done in brcmf_setup_wiphy. Otherwise
tools like wpa_supplicant won't use randomization.
Kr,
Mathy
On 29-12-15 21:58, Mathy Vanhoef wrote:
> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]> wrote:
>> Several features in the driver directly map to a firmware feature
>> listed in response of the 'cap' firmware command. For those features
>> this response will be examined instead of attempting individual
>> firmware commands.
>>
>> Reviewed-by: Hante Meuleman <[email protected]>
>> Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
>> Reviewed-by: Pieter-Paul Giesberts <[email protected]>
>> Signed-off-by: Arend van Spriel <[email protected]>
>> ---
>> .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
>> 1 file changed, 30 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> index d9d1ca4..08b7200 100644
>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
>> };
>> #undef BRCMF_FEAT_DEF
>>
>> +struct brcmf_feat_fwcap {
>> + enum brcmf_feat_id feature;
>> + const char * const fwcap_id;
>> +};
>> +
>> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
>> + { BRCMF_FEAT_MBSS, "mbss" },
>> + { BRCMF_FEAT_MCHAN, "mchan" },
>> + { BRCMF_FEAT_P2P, "p2p" },
>> +};
>> +
>> #ifdef DEBUG
>> /*
>> * expand quirk list to array of quirk strings.
>> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
>> }
>> }
>>
>> -/**
>> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
>> - *
>> - * @ifp: interface to query.
>> - * @id: feature id.
>> - * @name: iovar name.
>> - */
>> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
>> - enum brcmf_feat_id id, char *name, u32 val)
>> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
>> {
>> - int err;
>> -
>> - err = brcmf_fil_iovar_int_set(ifp, name, val);
>> - if (err == 0) {
>> - brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
>> - ifp->drvr->feat_flags |= BIT(id);
>> - } else {
>> - brcmf_dbg(TRACE, "%s feature check failed: %d\n",
>> - brcmf_feat_names[id], err);
>> + char caps[256];
>> + enum brcmf_feat_id id;
>> + int i;
>> +
>> + brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
>> + brcmf_dbg(INFO, "[ %s]\n", caps);
>> +
>> + for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
>> + if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
>> + id = brcmf_fwcap_map[i].feature;
>> + brcmf_dbg(INFO, "enabling feature: %s\n",
>> + brcmf_feat_names[id]);
>> + ifp->drvr->feat_flags |= BIT(id);
>> + }
>> }
>> }
>>
>> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
>> {
>> struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>>
>> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
>> + brcmf_feat_firmware_capabilities(ifp);
>> +
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
>> if (drvr->bus_if->wowl_supported)
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
>> + /* MBSS does not work for 43362 */
>> if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
>> - brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
>> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
>> + ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
>
> Missing ~ before the BIT() declaration? If the if-test fails, all bits are
> cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be updated
> to an equals `==` instead of the old inequality. So one would get:
>
> /* clear MBSS feature for the 43362 (does not work) */
> if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
> ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
Geez. You are absolutely right. Apparently my head was already in
christmas mode writing that code.
Thanks,
Arend
> Also, happy holidays!
> Mathy
>
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>>
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
On 29-12-15 21:47, Mathy Vanhoef wrote:
> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]> wrote:
>> From: Hante Meuleman <[email protected]>
>>
>> Scheduled scan be requested to use mac randomization. This patch
>> checks the flags and enables the randomization if desired.
>
> The driver also needs to advertise support for this using the
> NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR flag, if the firmware
> supports it. This can be done in brcmf_setup_wiphy. Otherwise
> tools like wpa_supplicant won't use randomization.
Indeed. Hante found that out later on and we have a follow-up patch for
that.
Kalle,
How do you want to treat this? Should I squash the patches into one and
resubmit or can I just submit follow-up patch.
Regards,
Arend
> Kr,
> Mathy
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
From: Franky Lin <[email protected]>
Obtain ipv4 address through inetaddr notification for ARP offload host
ip table configuration.
Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../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 <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;
+ __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 */
--
1.9.1
From: Hante Meuleman <[email protected]>
Module parameters are defined in several files. Move them in one
place and make them device specific or global. This makes it
easier to override device specific settings by external data like
platform data in the future.
Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 12 ++---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 13 ++---
.../wireless/broadcom/brcm80211/brcmfmac/common.c | 63 ++++++++++++++++++++++
.../wireless/broadcom/brcm80211/brcmfmac/common.h | 43 +++++++++++++++
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 22 ++++----
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 5 +-
.../wireless/broadcom/brcm80211/brcmfmac/feature.c | 13 ++---
.../broadcom/brcm80211/brcmfmac/firmware.c | 16 +++---
.../broadcom/brcm80211/brcmfmac/fwsignal.c | 9 ++--
9 files changed, 144 insertions(+), 52 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 410a664..5363739 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -47,6 +47,8 @@
#include "debug.h"
#include "sdio.h"
#include "of.h"
+#include "core.h"
+#include "common.h"
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
@@ -57,7 +59,6 @@
/* Maximum milliseconds to wait for F2 to come up */
#define SDIO_WAIT_F2RDY 3000
-#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
struct brcmf_sdiod_freezer {
@@ -68,10 +69,6 @@ struct brcmf_sdiod_freezer {
struct completion resumed;
};
-static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
-module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
-MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
-
static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
@@ -890,7 +887,8 @@ static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
if (!sdiodev->sg_support)
return;
- nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
+ nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE,
+ sdiodev->bus_if->drvr->settings->sdiod_txglomsz);
nents += (nents >> 4) + 1;
WARN_ON(nents > sdiodev->max_segment_count);
@@ -902,7 +900,7 @@ static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
sdiodev->sg_support = false;
}
- sdiodev->txglomsz = brcmf_sdiod_txglomsz;
+ sdiodev->txglomsz = sdiodev->bus_if->drvr->settings->sdiod_txglomsz;
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 6632e46..87c0a56 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -236,10 +236,6 @@ struct parsed_vndr_ies {
struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
};
-static int brcmf_roamoff;
-module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
-MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
-
static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
struct cfg80211_chan_def *ch)
@@ -5395,7 +5391,7 @@ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
__le32 roam_delta[2];
/* Configure beacon timeout value based upon roaming setting */
- if (brcmf_roamoff)
+ if (ifp->drvr->settings->roamoff)
bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
else
bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
@@ -5409,8 +5405,9 @@ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
* roaming.
*/
brcmf_dbg(INFO, "Internal Roaming = %s\n",
- brcmf_roamoff ? "Off" : "On");
- err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
+ ifp->drvr->settings->roamoff ? "Off" : "On");
+ err = brcmf_fil_iovar_int_set(ifp, "roam_off",
+ ifp->drvr->settings->roamoff);
if (err) {
brcmf_err("roam_off error (%d)\n", err);
goto roam_setup_done;
@@ -6082,7 +6079,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
- if (!brcmf_roamoff)
+ if (!ifp->drvr->settings->roamoff)
wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
wiphy->mgmt_stypes = brcmf_txrx_stypes;
wiphy->max_remain_on_channel_duration = 5000;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index 474de11..bb9e2b3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -35,6 +35,40 @@ const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
/* boost value for RSSI_DELTA in preferred join selection */
#define BRCMF_JOIN_PREF_RSSI_BOOST 8
+#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
+
+static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
+module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
+MODULE_PARM_DESC(txglomsz, "Maximum tx packet chain size [SDIO]");
+
+/* Debug level configuration. See debug.h for bits, sysfs modifiable */
+int brcmf_msg_level;
+module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(debug, "Level of debug output");
+
+static int brcmf_p2p_enable;
+module_param_named(p2pon, brcmf_p2p_enable, int, 0);
+MODULE_PARM_DESC(p2pon, "Enable legacy p2p management functionality");
+
+static int brcmf_feature_disable;
+module_param_named(feature_disable, brcmf_feature_disable, int, 0);
+MODULE_PARM_DESC(feature_disable, "Disable features");
+
+static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
+module_param_string(alternative_fw_path, brcmf_firmware_path,
+ BRCMF_FW_ALTPATH_LEN, S_IRUSR);
+MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path");
+
+static int brcmf_fcmode;
+module_param_named(fcmode, brcmf_fcmode, int, 0);
+MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
+
+static int brcmf_roamoff;
+module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
+MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
+
+struct brcmf_mp_global_t brcmf_mp_global;
+
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
{
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
@@ -178,3 +212,32 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
va_end(args);
}
#endif
+
+void brcmf_mp_attach(void)
+{
+ strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
+ BRCMF_FW_ALTPATH_LEN);
+}
+
+int brcmf_mp_device_attach(struct brcmf_pub *drvr)
+{
+ drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC);
+ if (!drvr->settings) {
+ brcmf_err("Failed to alloca storage space for settings\n");
+ return -ENOMEM;
+ }
+
+ drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz;
+ drvr->settings->p2p_enable = !!brcmf_p2p_enable;
+ drvr->settings->feature_disable = brcmf_feature_disable;
+ drvr->settings->fcmode = brcmf_fcmode;
+ drvr->settings->roamoff = !!brcmf_roamoff;
+
+ return 0;
+}
+
+void brcmf_mp_device_detach(struct brcmf_pub *drvr)
+{
+ kfree(drvr->settings);
+}
+
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index 21c7488..abe3764 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -17,6 +17,49 @@
extern const u8 ALLFFMAC[ETH_ALEN];
+#define BRCMF_FW_ALTPATH_LEN 256
+
+/* Definitions for the module global and device specific settings are defined
+ * here. Two structs are used for them. brcmf_mp_global_t and brcmf_mp_device.
+ * The mp_global is instantiated once in a global struct and gets initialized
+ * by the common_attach function which should be called before any other
+ * (module) initiliazation takes place. The device specific settings is part
+ * of the drvr struct and should be initialized on every brcmf_attach.
+ */
+
+/**
+ * struct brcmf_mp_global_t - Global module paramaters.
+ *
+ * @firmware_path: Alternative firmware path.
+ */
+struct brcmf_mp_global_t {
+ char firmware_path[BRCMF_FW_ALTPATH_LEN];
+};
+
+extern struct brcmf_mp_global_t brcmf_mp_global;
+
+/**
+ * struct brcmf_mp_device - Device module paramaters.
+ *
+ * @sdiod_txglomsz: SDIO txglom size.
+ * @joinboost_5g_rssi: 5g rssi booost for preferred join selection.
+ * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant).
+ * @feature_disable: Feature_disable bitmask.
+ * @fcmode: FWS flow control.
+ * @roamoff: Firmware roaming off?
+ */
+struct brcmf_mp_device {
+ int sdiod_txglomsz;
+ int joinboost_5g_rssi;
+ bool p2p_enable;
+ int feature_disable;
+ int fcmode;
+ bool roamoff;
+};
+
+void brcmf_mp_attach(void);
+int brcmf_mp_device_attach(struct brcmf_pub *drvr);
+void brcmf_mp_device_detach(struct brcmf_pub *drvr);
/* Sets dongle media info (drv_version, mac address). */
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 4c8f7bf..3fa7bc5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -57,16 +57,6 @@ MODULE_LICENSE("Dual BSD/GPL");
#define BRCMF_BSSIDX_INVALID -1
-/* Error bits */
-int brcmf_msg_level;
-module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR);
-MODULE_PARM_DESC(debug, "level of debug output");
-
-/* P2P0 enable */
-static int brcmf_p2p_enable;
-module_param_named(p2pon, brcmf_p2p_enable, int, 0);
-MODULE_PARM_DESC(p2pon, "enable legacy p2p management functionality");
-
char *brcmf_ifname(struct brcmf_if *ifp)
{
if (!ifp)
@@ -827,7 +817,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
}
}
- if (!brcmf_p2p_enable && is_p2pdev) {
+ if (!drvr->settings->p2p_enable && is_p2pdev) {
/* this is P2P_DEVICE interface */
brcmf_dbg(INFO, "allocate non-netdev interface\n");
ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
@@ -1058,6 +1048,10 @@ int brcmf_attach(struct device *dev)
drvr->bus_if = dev_get_drvdata(dev);
drvr->bus_if->drvr = drvr;
+ /* Initialize device specific settings */
+ if (brcmf_mp_device_attach(drvr))
+ goto fail;
+
/* attach debug facilities */
brcmf_debug_attach(drvr);
@@ -1150,7 +1144,7 @@ int brcmf_bus_start(struct device *dev)
brcmf_fws_add_interface(ifp);
drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
- brcmf_p2p_enable);
+ drvr->settings->p2p_enable);
if (drvr->config == NULL) {
ret = -ENOMEM;
goto fail;
@@ -1158,7 +1152,7 @@ int brcmf_bus_start(struct device *dev)
ret = brcmf_net_attach(ifp, false);
- if ((!ret) && (brcmf_p2p_enable)) {
+ if ((!ret) && (drvr->settings->p2p_enable)) {
p2p_ifp = drvr->iflist[1];
if (p2p_ifp)
ret = brcmf_net_p2p_attach(p2p_ifp);
@@ -1260,6 +1254,8 @@ void brcmf_detach(struct device *dev)
brcmf_proto_detach(drvr);
+ brcmf_mp_device_detach(drvr);
+
brcmf_debug_detach(drvr);
bus_if->drvr = NULL;
kfree(drvr);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index 6018af7..8f39435 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -69,8 +69,8 @@ struct brcmf_ampdu_rx_reorder {
/* Forward decls for struct brcmf_pub (see below) */
struct brcmf_proto; /* device communication protocol info */
-struct brcmf_cfg80211_dev; /* cfg80211 device info */
-struct brcmf_fws_info; /* firmware signalling info */
+struct brcmf_fws_info; /* firmware signalling info */
+struct brcmf_mp_device; /* module paramateres, device specific */
/*
* struct brcmf_rev_info
@@ -143,6 +143,7 @@ struct brcmf_pub {
#endif
struct notifier_block inetaddr_notifier;
+ struct brcmf_mp_device *settings;
};
/* forward declarations */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 08b7200..eb94e00 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -23,13 +23,9 @@
#include "debug.h"
#include "fwil.h"
#include "feature.h"
+#include "common.h"
-/* Module param feature_disable (global for all devices) */
-static int brcmf_feature_disable;
-module_param_named(feature_disable, brcmf_feature_disable, int, 0);
-MODULE_PARM_DESC(feature_disable, "Disable features");
-
/*
* expand feature list to array of feature strings.
*/
@@ -149,10 +145,11 @@ 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");
- if (brcmf_feature_disable) {
+ if (drvr->settings->feature_disable) {
brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n",
- ifp->drvr->feat_flags, brcmf_feature_disable);
- ifp->drvr->feat_flags &= ~brcmf_feature_disable;
+ ifp->drvr->feat_flags,
+ drvr->settings->feature_disable);
+ ifp->drvr->feat_flags &= ~drvr->settings->feature_disable;
}
/* set chip related quirks */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
index 1e4d5f6..1365c12 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -23,15 +23,13 @@
#include "debug.h"
#include "firmware.h"
+#include "core.h"
+#include "common.h"
#define BRCMF_FW_MAX_NVRAM_SIZE 64000
#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */
-static char brcmf_firmware_path[BRCMF_FW_NAME_LEN];
-module_param_string(alternative_fw_path, brcmf_firmware_path,
- BRCMF_FW_NAME_LEN, 0440);
-
enum nvram_parser_state {
IDLE,
KEY,
@@ -559,13 +557,15 @@ int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
}
/* check if firmware path is provided by module parameter */
- if (brcmf_firmware_path[0] != '\0') {
- strlcpy(fw_name, brcmf_firmware_path, BRCMF_FW_NAME_LEN);
+ if (brcmf_mp_global.firmware_path[0] != '\0') {
+ strlcpy(fw_name, brcmf_mp_global.firmware_path,
+ BRCMF_FW_NAME_LEN);
if ((nvram_name) && (mapping_table[i].nvram))
- strlcpy(nvram_name, brcmf_firmware_path,
+ strlcpy(nvram_name, brcmf_mp_global.firmware_path,
BRCMF_FW_NAME_LEN);
- end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
+ end = brcmf_mp_global.firmware_path[
+ strlen(brcmf_mp_global.firmware_path) - 1];
if (end != '/') {
strlcat(fw_name, "/", BRCMF_FW_NAME_LEN);
if ((nvram_name) && (mapping_table[i].nvram))
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
index e5f5fac..f82c9ab 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -36,6 +36,7 @@
#include "p2p.h"
#include "cfg80211.h"
#include "proto.h"
+#include "common.h"
/**
* DOC: Firmware Signalling
@@ -521,10 +522,6 @@ static const int brcmf_fws_prio2fifo[] = {
BRCMF_FWS_FIFO_AC_VO
};
-static int fcmode;
-module_param(fcmode, int, S_IRUSR);
-MODULE_PARM_DESC(fcmode, "mode of firmware signalled flow control");
-
#define BRCMF_FWS_TLV_DEF(name, id, len) \
case BRCMF_FWS_TYPE_ ## name: \
return len;
@@ -2134,10 +2131,10 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
/* set linkage back */
fws->drvr = drvr;
- fws->fcmode = fcmode;
+ fws->fcmode = drvr->settings->fcmode;
if ((drvr->bus_if->always_use_fws_queue == false) &&
- (fcmode == BRCMF_FWS_FCMODE_NONE)) {
+ (fws->fcmode == BRCMF_FWS_FCMODE_NONE)) {
fws->avoid_queueing = true;
brcmf_dbg(INFO, "FWS queueing will be avoided\n");
return 0;
--
1.9.1
From: Hante Meuleman <[email protected]>
Scheduled scan be requested to use mac randomization. This patch
checks the flags and enables the randomization if desired.
Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 45 ++++++++++++++++++----
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 17 ++++++++
2 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 6b9339b..5964763 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3544,9 +3544,14 @@ static int brcmf_dev_pno_clean(struct net_device *ndev)
return ret;
}
-static int brcmf_dev_pno_config(struct net_device *ndev)
+static int brcmf_dev_pno_config(struct brcmf_if *ifp,
+ struct cfg80211_sched_scan_request *request)
{
struct brcmf_pno_param_le pfn_param;
+ struct brcmf_pno_macaddr_le pfn_mac;
+ s32 err;
+ u8 *mac_mask;
+ int i;
memset(&pfn_param, 0, sizeof(pfn_param));
pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
@@ -3559,8 +3564,37 @@ static int brcmf_dev_pno_config(struct net_device *ndev)
/* set up pno scan fr */
pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
- return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
- &pfn_param, sizeof(pfn_param));
+ err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
+ sizeof(pfn_param));
+ if (err) {
+ brcmf_err("pfn_set failed, err=%d\n", err);
+ return err;
+ }
+
+ /* Find out if mac randomization should be turned on */
+ if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
+ return 0;
+
+ pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
+ pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
+
+ memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
+ mac_mask = request->mac_addr_mask;
+ for (i = 0; i < ETH_ALEN; i++) {
+ pfn_mac.mac[i] &= mac_mask[i];
+ pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
+ }
+ /* Clear multi bit */
+ pfn_mac.mac[0] &= 0xFE;
+ /* Set locally administered */
+ pfn_mac.mac[0] |= 0x02;
+
+ err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
+ sizeof(pfn_mac));
+ if (err)
+ brcmf_err("pfn_macaddr failed, err=%d\n", err);
+
+ return err;
}
static int
@@ -3614,11 +3648,8 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
}
/* configure pno */
- ret = brcmf_dev_pno_config(ndev);
- if (ret < 0) {
- brcmf_err("PNO setup failed!! ret=%d\n", ret);
+ if (brcmf_dev_pno_config(ifp, request))
return -EINVAL;
- }
/* configure each match set */
for (i = 0; i < request->n_match_sets; i++) {
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index 0b1e46d..bf2df49 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -128,6 +128,10 @@
#define BRCMF_MAXPMKID 16 /* max # PMKID cache entries */
+#define BRCMF_PFN_MACADDR_CFG_VER 1
+#define BRCMF_PFN_MAC_OUI_ONLY BIT(0)
+#define BRCMF_PFN_SET_MAC_UNASSOC BIT(1)
+
/* join preference types for join_pref iovar */
enum brcmf_join_pref_types {
BRCMF_JOIN_PREF_RSSI = 1,
@@ -752,6 +756,19 @@ struct brcmf_pno_scanresults_le {
};
/**
+ * struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization.
+ *
+ * @version: PNO version identifier.
+ * @flags: Flags defining how mac addrss should be used.
+ * @mac: MAC address.
+ */
+struct brcmf_pno_macaddr_le {
+ u8 version;
+ u8 flags;
+ u8 mac[ETH_ALEN];
+};
+
+/**
* struct brcmf_pktcnt_le - packet counters.
*
* @rx_good_pkt: packets (MSDUs & MMPDUs) received from this station
--
1.9.1
On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]> wrote:
> Several features in the driver directly map to a firmware feature
> listed in response of the 'cap' firmware command. For those features
> this response will be examined instead of attempting individual
> firmware commands.
>
> Reviewed-by: Hante Meuleman <[email protected]>
> Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
> Reviewed-by: Pieter-Paul Giesberts <[email protected]>
> Signed-off-by: Arend van Spriel <[email protected]>
> ---
> .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
> 1 file changed, 30 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
> index d9d1ca4..08b7200 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
> };
> #undef BRCMF_FEAT_DEF
>
> +struct brcmf_feat_fwcap {
> + enum brcmf_feat_id feature;
> + const char * const fwcap_id;
> +};
> +
> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
> + { BRCMF_FEAT_MBSS, "mbss" },
> + { BRCMF_FEAT_MCHAN, "mchan" },
> + { BRCMF_FEAT_P2P, "p2p" },
> +};
> +
> #ifdef DEBUG
> /*
> * expand quirk list to array of quirk strings.
> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
> }
> }
>
> -/**
> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
> - *
> - * @ifp: interface to query.
> - * @id: feature id.
> - * @name: iovar name.
> - */
> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
> - enum brcmf_feat_id id, char *name, u32 val)
> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
> {
> - int err;
> -
> - err = brcmf_fil_iovar_int_set(ifp, name, val);
> - if (err == 0) {
> - brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
> - ifp->drvr->feat_flags |= BIT(id);
> - } else {
> - brcmf_dbg(TRACE, "%s feature check failed: %d\n",
> - brcmf_feat_names[id], err);
> + char caps[256];
> + enum brcmf_feat_id id;
> + int i;
> +
> + brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
> + brcmf_dbg(INFO, "[ %s]\n", caps);
> +
> + for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
> + if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
> + id = brcmf_fwcap_map[i].feature;
> + brcmf_dbg(INFO, "enabling feature: %s\n",
> + brcmf_feat_names[id]);
> + ifp->drvr->feat_flags |= BIT(id);
> + }
> }
> }
>
> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
> {
> struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>
> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
> + brcmf_feat_firmware_capabilities(ifp);
> +
> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
> if (drvr->bus_if->wowl_supported)
> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
> + /* MBSS does not work for 43362 */
> if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
> - brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
> + ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
Missing ~ before the BIT() declaration? If the if-test fails, all bits are
cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be updated
to an equals `==` instead of the old inequality. So one would get:
/* clear MBSS feature for the 43362 (does not work) */
if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
Also, happy holidays!
Mathy
> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Arend van Spriel <[email protected]> writes:
> On 29-12-15 21:47, Mathy Vanhoef wrote:
>> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]> wrote:
>>> From: Hante Meuleman <[email protected]>
>>>
>>> Scheduled scan be requested to use mac randomization. This patch
>>> checks the flags and enables the randomization if desired.
>>
>> The driver also needs to advertise support for this using the
>> NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR flag, if the firmware
>> supports it. This can be done in brcmf_setup_wiphy. Otherwise
>> tools like wpa_supplicant won't use randomization.
>
> Indeed. Hante found that out later on and we have a follow-up patch for
> that.
>
> Kalle,
>
> How do you want to treat this? Should I squash the patches into one and
> resubmit or can I just submit follow-up patch.
I would prefer that you squash the patches and resubmit the whole
series.
--
Kalle Valo
On 01-01-16 11:39, Kalle Valo wrote:
> Arend van Spriel <[email protected]> writes:
>
>> On 29-12-15 21:47, Mathy Vanhoef wrote:
>>> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]> wrote:
>>>> From: Hante Meuleman <[email protected]>
>>>>
>>>> Scheduled scan be requested to use mac randomization. This patch
>>>> checks the flags and enables the randomization if desired.
>>>
>>> The driver also needs to advertise support for this using the
>>> NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR flag, if the firmware
>>> supports it. This can be done in brcmf_setup_wiphy. Otherwise
>>> tools like wpa_supplicant won't use randomization.
>>
>> Indeed. Hante found that out later on and we have a follow-up patch for
>> that.
>>
>> Kalle,
>>
>> How do you want to treat this? Should I squash the patches into one and
>> resubmit or can I just submit follow-up patch.
>
> I would prefer that you squash the patches and resubmit the whole
> series.
Ok, thanks. Prepared that already.
Regards,
Arend
On Fri, Jan 1, 2016 at 8:05 AM, Arend van Spriel <[email protected]> wrote:
> On 12/29/2015 09:58 PM, Mathy Vanhoef wrote:
>>
>> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]>
>> wrote:
>>>
>>> Several features in the driver directly map to a firmware feature
>>> listed in response of the 'cap' firmware command. For those features
>>> this response will be examined instead of attempting individual
>>> firmware commands.
>>>
>>> Reviewed-by: Hante Meuleman <[email protected]>
>>> Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
>>> Reviewed-by: Pieter-Paul Giesberts <[email protected]>
>
>
> Hi Mathy,
>
> Do you want credits, ie. have "Reviewed-by:" tag added?
Sure, glad I could help.
Kr,
Mathy
>
> Regards,
> Arend
>
>
>>> Signed-off-by: Arend van Spriel <[email protected]>
>>> ---
>>> .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51
>>> +++++++++++++---------
>>> 1 file changed, 30 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> index d9d1ca4..08b7200 100644
>>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>>> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
>>> };
>>> #undef BRCMF_FEAT_DEF
>>>
>>> +struct brcmf_feat_fwcap {
>>> + enum brcmf_feat_id feature;
>>> + const char * const fwcap_id;
>>> +};
>>> +
>>> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
>>> + { BRCMF_FEAT_MBSS, "mbss" },
>>> + { BRCMF_FEAT_MCHAN, "mchan" },
>>> + { BRCMF_FEAT_P2P, "p2p" },
>>> +};
>>> +
>>> #ifdef DEBUG
>>> /*
>>> * expand quirk list to array of quirk strings.
>>> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct
>>> brcmf_if *ifp,
>>> }
>>> }
>>>
>>> -/**
>>> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
>>> - *
>>> - * @ifp: interface to query.
>>> - * @id: feature id.
>>> - * @name: iovar name.
>>> - */
>>> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
>>> - enum brcmf_feat_id id, char *name,
>>> u32 val)
>>> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
>>> {
>>> - int err;
>>> -
>>> - err = brcmf_fil_iovar_int_set(ifp, name, val);
>>> - if (err == 0) {
>>> - brcmf_dbg(INFO, "enabling feature: %s\n",
>>> brcmf_feat_names[id]);
>>> - ifp->drvr->feat_flags |= BIT(id);
>>> - } else {
>>> - brcmf_dbg(TRACE, "%s feature check failed: %d\n",
>>> - brcmf_feat_names[id], err);
>>> + char caps[256];
>>> + enum brcmf_feat_id id;
>>> + int i;
>>> +
>>> + brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
>>> + brcmf_dbg(INFO, "[ %s]\n", caps);
>>> +
>>> + for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
>>> + if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id,
>>> sizeof(caps))) {
>>> + id = brcmf_fwcap_map[i].feature;
>>> + brcmf_dbg(INFO, "enabling feature: %s\n",
>>> + brcmf_feat_names[id]);
>>> + ifp->drvr->feat_flags |= BIT(id);
>>> + }
>>> }
>>> }
>>>
>>> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
>>> {
>>> struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>>>
>>> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
>>> + brcmf_feat_firmware_capabilities(ifp);
>>> +
>>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
>>> if (drvr->bus_if->wowl_supported)
>>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
>>> + /* MBSS does not work for 43362 */
>>> if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
>>> - brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss",
>>> 0);
>>> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
>>> + ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
>>
>>
>> Missing ~ before the BIT() declaration? If the if-test fails, all bits are
>> cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be
>> updated
>> to an equals `==` instead of the old inequality. So one would get:
>>
>> /* clear MBSS feature for the 43362 (does not work) */
>> if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
>> ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
>>
>> Also, happy holidays!
>> Mathy
>>
>>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
>>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>>>
>>> --
>>> 1.9.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
>>> in
>>> the body of a message to [email protected]
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
>> in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
On 12/29/2015 09:58 PM, Mathy Vanhoef wrote:
> On Mon, Dec 14, 2015 at 2:39 PM, Arend van Spriel <[email protected]> wrote:
>> Several features in the driver directly map to a firmware feature
>> listed in response of the 'cap' firmware command. For those features
>> this response will be examined instead of attempting individual
>> firmware commands.
>>
>> Reviewed-by: Hante Meuleman <[email protected]>
>> Reviewed-by: Franky (Zhenhui) Lin <[email protected]>
>> Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Hi Mathy,
Do you want credits, ie. have "Reviewed-by:" tag added?
Regards,
Arend
>> Signed-off-by: Arend van Spriel <[email protected]>
>> ---
>> .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 51 +++++++++++++---------
>> 1 file changed, 30 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> index d9d1ca4..08b7200 100644
>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
>> @@ -40,6 +40,17 @@ static const char *brcmf_feat_names[] = {
>> };
>> #undef BRCMF_FEAT_DEF
>>
>> +struct brcmf_feat_fwcap {
>> + enum brcmf_feat_id feature;
>> + const char * const fwcap_id;
>> +};
>> +
>> +static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = {
>> + { BRCMF_FEAT_MBSS, "mbss" },
>> + { BRCMF_FEAT_MCHAN, "mchan" },
>> + { BRCMF_FEAT_P2P, "p2p" },
>> +};
>> +
>> #ifdef DEBUG
>> /*
>> * expand quirk list to array of quirk strings.
>> @@ -104,25 +115,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
>> }
>> }
>>
>> -/**
>> - * brcmf_feat_iovar_int_set() - determine feature through iovar set.
>> - *
>> - * @ifp: interface to query.
>> - * @id: feature id.
>> - * @name: iovar name.
>> - */
>> -static void brcmf_feat_iovar_int_set(struct brcmf_if *ifp,
>> - enum brcmf_feat_id id, char *name, u32 val)
>> +static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
>> {
>> - int err;
>> -
>> - err = brcmf_fil_iovar_int_set(ifp, name, val);
>> - if (err == 0) {
>> - brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
>> - ifp->drvr->feat_flags |= BIT(id);
>> - } else {
>> - brcmf_dbg(TRACE, "%s feature check failed: %d\n",
>> - brcmf_feat_names[id], err);
>> + char caps[256];
>> + enum brcmf_feat_id id;
>> + int i;
>> +
>> + brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps));
>> + brcmf_dbg(INFO, "[ %s]\n", caps);
>> +
>> + for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) {
>> + if (strnstr(caps, brcmf_fwcap_map[i].fwcap_id, sizeof(caps))) {
>> + id = brcmf_fwcap_map[i].feature;
>> + brcmf_dbg(INFO, "enabling feature: %s\n",
>> + brcmf_feat_names[id]);
>> + ifp->drvr->feat_flags |= BIT(id);
>> + }
>> }
>> }
>>
>> @@ -130,13 +138,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
>> {
>> struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
>>
>> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
>> + brcmf_feat_firmware_capabilities(ifp);
>> +
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
>> if (drvr->bus_if->wowl_supported)
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
>> + /* MBSS does not work for 43362 */
>> if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
>> - brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
>> - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
>> + ifp->drvr->feat_flags &= BIT(BRCMF_FEAT_MBSS);
>
> Missing ~ before the BIT() declaration? If the if-test fails, all bits are
> cleared except BRCMF_FEAT_MBSS. I think the if-test also needs to be updated
> to an equals `==` instead of the old inequality. So one would get:
>
> /* clear MBSS feature for the 43362 (does not work) */
> if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
> ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
>
> Also, happy holidays!
> Mathy
>
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
>> brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
>>
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>