mirror of
https://github.com/hak5/wifipineapple-openwrt.git
synced 2025-10-29 16:57:19 +00:00
Merge pull request #105 from wigyori/chaos_calmer
CC: openssl security upgrade, sync updates from git.openwrt.org/chaos_calmer
This commit is contained in:
commit
ca3f1a614a
@ -2,9 +2,9 @@
|
||||
|
||||
LINUX_RELEASE?=1
|
||||
|
||||
LINUX_VERSION-3.18 = .29
|
||||
LINUX_VERSION-3.18 = .36
|
||||
|
||||
LINUX_KERNEL_MD5SUM-3.18.29 = b25737a0bc98e80d12200de93f239c28
|
||||
LINUX_KERNEL_MD5SUM-3.18.36 = 31b1699c1285aeeb81fb25750baa50d9
|
||||
|
||||
ifdef KERNEL_PATCHVER
|
||||
LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER)))
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
From: Arend van Spriel <arend@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:26:50 +0100
|
||||
Subject: [PATCH] brcmfmac: change function name for
|
||||
brcmf_cfg80211_wait_vif_event_timeout()
|
||||
|
||||
Dropping the '_timeout' from the function name as the fact that a timeout
|
||||
value is passed makes it obvious a timeout is used. Also helps to keep code
|
||||
lines a bit shorter and easier to stick to 80 char boundary.
|
||||
|
||||
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -564,8 +564,8 @@ struct wireless_dev *brcmf_ap_add_vif(st
|
||||
}
|
||||
|
||||
/* wait for firmware event */
|
||||
- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
|
||||
- BRCMF_VIF_EVENT_TIMEOUT);
|
||||
+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
|
||||
+ BRCMF_VIF_EVENT_TIMEOUT);
|
||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||
if (!err) {
|
||||
brcmf_err("timeout occurred\n");
|
||||
@@ -6395,8 +6395,9 @@ bool brcmf_cfg80211_vif_event_armed(stru
|
||||
|
||||
return armed;
|
||||
}
|
||||
-int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
|
||||
- u8 action, ulong timeout)
|
||||
+
|
||||
+int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
|
||||
+ u8 action, ulong timeout)
|
||||
{
|
||||
struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -402,8 +402,8 @@ bool brcmf_get_vif_state_any(struct brcm
|
||||
void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
|
||||
struct brcmf_cfg80211_vif *vif);
|
||||
bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
|
||||
-int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
|
||||
- u8 action, ulong timeout);
|
||||
+int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
|
||||
+ u8 action, ulong timeout);
|
||||
s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
|
||||
struct brcmf_if *ifp, bool aborted,
|
||||
bool fw_abort);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -1988,8 +1988,8 @@ int brcmf_p2p_ifchange(struct brcmf_cfg8
|
||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||
return err;
|
||||
}
|
||||
- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_CHANGE,
|
||||
- BRCMF_VIF_EVENT_TIMEOUT);
|
||||
+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_CHANGE,
|
||||
+ BRCMF_VIF_EVENT_TIMEOUT);
|
||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||
if (!err) {
|
||||
brcmf_err("No BRCMF_E_IF_CHANGE event received\n");
|
||||
@@ -2090,8 +2090,8 @@ static struct wireless_dev *brcmf_p2p_cr
|
||||
}
|
||||
|
||||
/* wait for firmware event */
|
||||
- err = brcmf_cfg80211_wait_vif_event_timeout(p2p->cfg, BRCMF_E_IF_ADD,
|
||||
- BRCMF_VIF_EVENT_TIMEOUT);
|
||||
+ err = brcmf_cfg80211_wait_vif_event(p2p->cfg, BRCMF_E_IF_ADD,
|
||||
+ BRCMF_VIF_EVENT_TIMEOUT);
|
||||
brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
|
||||
brcmf_fweh_p2pdev_setup(pri_ifp, false);
|
||||
if (!err) {
|
||||
@@ -2180,8 +2180,8 @@ struct wireless_dev *brcmf_p2p_add_vif(s
|
||||
}
|
||||
|
||||
/* wait for firmware event */
|
||||
- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
|
||||
- BRCMF_VIF_EVENT_TIMEOUT);
|
||||
+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
|
||||
+ BRCMF_VIF_EVENT_TIMEOUT);
|
||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||
if (!err) {
|
||||
brcmf_err("timeout occurred\n");
|
||||
@@ -2274,8 +2274,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
|
||||
}
|
||||
if (!err) {
|
||||
/* wait for firmware event */
|
||||
- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
|
||||
- BRCMF_VIF_EVENT_TIMEOUT);
|
||||
+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
|
||||
+ BRCMF_VIF_EVENT_TIMEOUT);
|
||||
if (!err)
|
||||
err = -EIO;
|
||||
else
|
||||
@ -0,0 +1,127 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:26:51 +0100
|
||||
Subject: [PATCH] brcmfmac: Limit memory allocs to <64K
|
||||
|
||||
Some systems have problems with allocating memory allocation larger
|
||||
then 64K. Often on unload/load or suspend/resume a failure is
|
||||
reported: Could not allocate wiphy device. This patch makes the
|
||||
escan intermediate storage buf dynamically allocated, and smaller
|
||||
than 64K.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -1125,7 +1125,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy
|
||||
|
||||
/* Arm scan timeout timer */
|
||||
mod_timer(&cfg->escan_timeout, jiffies +
|
||||
- WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
|
||||
+ BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3020,7 +3020,7 @@ brcmf_cfg80211_escan_handler(struct brcm
|
||||
|
||||
list = (struct brcmf_scan_results *)
|
||||
cfg->escan_info.escan_buf;
|
||||
- if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
|
||||
+ if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
|
||||
brcmf_err("Buffer is too small: ignoring\n");
|
||||
goto exit;
|
||||
}
|
||||
@@ -3033,8 +3033,8 @@ brcmf_cfg80211_escan_handler(struct brcm
|
||||
bss_info_le))
|
||||
goto exit;
|
||||
}
|
||||
- memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
|
||||
- bss_info_le, bi_length);
|
||||
+ memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
|
||||
+ bi_length);
|
||||
list->version = le32_to_cpu(bss_info_le->version);
|
||||
list->buflen += bi_length;
|
||||
list->count++;
|
||||
@@ -5402,14 +5402,14 @@ static void brcmf_deinit_priv_mem(struct
|
||||
{
|
||||
kfree(cfg->conf);
|
||||
cfg->conf = NULL;
|
||||
- kfree(cfg->escan_ioctl_buf);
|
||||
- cfg->escan_ioctl_buf = NULL;
|
||||
kfree(cfg->extra_buf);
|
||||
cfg->extra_buf = NULL;
|
||||
kfree(cfg->wowl.nd);
|
||||
cfg->wowl.nd = NULL;
|
||||
kfree(cfg->wowl.nd_info);
|
||||
cfg->wowl.nd_info = NULL;
|
||||
+ kfree(cfg->escan_info.escan_buf);
|
||||
+ cfg->escan_info.escan_buf = NULL;
|
||||
}
|
||||
|
||||
static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
|
||||
@@ -5417,9 +5417,6 @@ static s32 brcmf_init_priv_mem(struct br
|
||||
cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
|
||||
if (!cfg->conf)
|
||||
goto init_priv_mem_out;
|
||||
- cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
|
||||
- if (!cfg->escan_ioctl_buf)
|
||||
- goto init_priv_mem_out;
|
||||
cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
|
||||
if (!cfg->extra_buf)
|
||||
goto init_priv_mem_out;
|
||||
@@ -5431,6 +5428,9 @@ static s32 brcmf_init_priv_mem(struct br
|
||||
GFP_KERNEL);
|
||||
if (!cfg->wowl.nd_info)
|
||||
goto init_priv_mem_out;
|
||||
+ cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
|
||||
+ if (!cfg->escan_info.escan_buf)
|
||||
+ goto init_priv_mem_out;
|
||||
|
||||
return 0;
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -28,8 +28,11 @@
|
||||
#define WL_ROAM_TRIGGER_LEVEL -75
|
||||
#define WL_ROAM_DELTA 20
|
||||
|
||||
-#define WL_ESCAN_BUF_SIZE (1024 * 64)
|
||||
-#define WL_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */
|
||||
+/* Keep BRCMF_ESCAN_BUF_SIZE below 64K (65536). Allocing over 64K can be
|
||||
+ * problematic on some systems and should be avoided.
|
||||
+ */
|
||||
+#define BRCMF_ESCAN_BUF_SIZE 65000
|
||||
+#define BRCMF_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */
|
||||
|
||||
#define WL_ESCAN_ACTION_START 1
|
||||
#define WL_ESCAN_ACTION_CONTINUE 2
|
||||
@@ -205,7 +208,7 @@ enum wl_escan_state {
|
||||
|
||||
struct escan_info {
|
||||
u32 escan_state;
|
||||
- u8 escan_buf[WL_ESCAN_BUF_SIZE];
|
||||
+ u8 *escan_buf;
|
||||
struct wiphy *wiphy;
|
||||
struct brcmf_if *ifp;
|
||||
s32 (*run)(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
|
||||
@@ -278,7 +281,6 @@ struct brcmf_cfg80211_wowl {
|
||||
* @escan_info: escan information.
|
||||
* @escan_timeout: Timer for catch scan timeout.
|
||||
* @escan_timeout_work: scan timeout worker.
|
||||
- * @escan_ioctl_buf: dongle command buffer for escan commands.
|
||||
* @vif_list: linked list of vif instances.
|
||||
* @vif_cnt: number of vif instances.
|
||||
* @vif_event: vif event signalling.
|
||||
@@ -309,7 +311,6 @@ struct brcmf_cfg80211_info {
|
||||
struct escan_info escan_info;
|
||||
struct timer_list escan_timeout;
|
||||
struct work_struct escan_timeout_work;
|
||||
- u8 *escan_ioctl_buf;
|
||||
struct list_head vif_list;
|
||||
struct brcmf_cfg80211_vif_event vif_event;
|
||||
struct completion vif_disabled;
|
||||
@ -0,0 +1,29 @@
|
||||
From: Franky Lin <frankyl@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:26:52 +0100
|
||||
Subject: [PATCH] brcmfmac: check for wowl support before enumerating feature
|
||||
flag
|
||||
|
||||
In some cases wiphy->wowlan could be NULL if firmware doesn't have the
|
||||
support. Driver should check for support before walking down the feature
|
||||
flags.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Franky Lin <frankyl@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6594,7 +6594,8 @@ struct brcmf_cfg80211_info *brcmf_cfg802
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
|
||||
wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
|
||||
#ifdef CONFIG_PM
|
||||
- if (wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
|
||||
+ if (wiphy->wowlan &&
|
||||
+ wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
|
||||
wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,214 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:26:53 +0100
|
||||
Subject: [PATCH] brcmfmac: Configure country code using device specific
|
||||
settings
|
||||
|
||||
Country code configuration in a device is a device specific
|
||||
operation. For this the country code as specified by reg notifier
|
||||
(iso3166 alpha2) needs to be translated to a device specific
|
||||
country locale and revision number. This patch adds this
|
||||
translation and puts a placeholder in the device specific settings
|
||||
where the translation table can be stored. Additional patches will
|
||||
be needed to read these tables from for example device platform
|
||||
data.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6405,28 +6405,85 @@ int brcmf_cfg80211_wait_vif_event(struct
|
||||
vif_event_equals(event, action), timeout);
|
||||
}
|
||||
|
||||
+static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
|
||||
+ struct brcmf_fil_country_le *ccreq)
|
||||
+{
|
||||
+ struct cc_translate *country_codes;
|
||||
+ struct cc_entry *cc;
|
||||
+ s32 found_index;
|
||||
+ int i;
|
||||
+
|
||||
+ country_codes = drvr->settings->country_codes;
|
||||
+ if (!country_codes) {
|
||||
+ brcmf_dbg(TRACE, "No country codes configured for device\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if ((alpha2[0] == ccreq->country_abbrev[0]) &&
|
||||
+ (alpha2[1] == ccreq->country_abbrev[1])) {
|
||||
+ brcmf_dbg(TRACE, "Country code already set\n");
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
+
|
||||
+ found_index = -1;
|
||||
+ for (i = 0; i < country_codes->table_size; i++) {
|
||||
+ cc = &country_codes->table[i];
|
||||
+ if ((cc->iso3166[0] == '\0') && (found_index == -1))
|
||||
+ found_index = i;
|
||||
+ if ((cc->iso3166[0] == alpha2[0]) &&
|
||||
+ (cc->iso3166[1] == alpha2[1])) {
|
||||
+ found_index = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (found_index == -1) {
|
||||
+ brcmf_dbg(TRACE, "No country code match found\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ memset(ccreq, 0, sizeof(*ccreq));
|
||||
+ ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
|
||||
+ memcpy(ccreq->ccode, country_codes->table[found_index].cc,
|
||||
+ BRCMF_COUNTRY_BUF_SZ);
|
||||
+ ccreq->country_abbrev[0] = alpha2[0];
|
||||
+ ccreq->country_abbrev[1] = alpha2[1];
|
||||
+ ccreq->country_abbrev[2] = 0;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *req)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
|
||||
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
|
||||
struct brcmf_fil_country_le ccreq;
|
||||
+ s32 err;
|
||||
int i;
|
||||
|
||||
- brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
|
||||
- req->alpha2[0], req->alpha2[1]);
|
||||
-
|
||||
/* ignore non-ISO3166 country codes */
|
||||
for (i = 0; i < sizeof(req->alpha2); i++)
|
||||
if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
|
||||
- brcmf_err("not a ISO3166 code\n");
|
||||
+ brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n",
|
||||
+ req->alpha2[0], req->alpha2[1]);
|
||||
return;
|
||||
}
|
||||
- memset(&ccreq, 0, sizeof(ccreq));
|
||||
- ccreq.rev = cpu_to_le32(-1);
|
||||
- memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
|
||||
- if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
|
||||
- brcmf_err("firmware rejected country setting\n");
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
|
||||
+ req->alpha2[0], req->alpha2[1]);
|
||||
+
|
||||
+ err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
|
||||
+ if (err) {
|
||||
+ brcmf_err("Country code iovar returned err = %d\n", err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
|
||||
+ if (err)
|
||||
+ return;
|
||||
+
|
||||
+ err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
|
||||
+ if (err) {
|
||||
+ brcmf_err("Firmware rejected country setting\n");
|
||||
return;
|
||||
}
|
||||
brcmf_setup_wiphybands(wiphy);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -230,10 +230,8 @@ void brcmf_mp_attach(void)
|
||||
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");
|
||||
+ if (!drvr->settings)
|
||||
return -ENOMEM;
|
||||
- }
|
||||
|
||||
drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz;
|
||||
drvr->settings->p2p_enable = !!brcmf_p2p_enable;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef BRCMFMAC_COMMON_H
|
||||
#define BRCMFMAC_COMMON_H
|
||||
|
||||
+#include "fwil_types.h"
|
||||
+
|
||||
extern const u8 ALLFFMAC[ETH_ALEN];
|
||||
|
||||
#define BRCMF_FW_ALTPATH_LEN 256
|
||||
@@ -39,6 +41,33 @@ struct brcmf_mp_global_t {
|
||||
extern struct brcmf_mp_global_t brcmf_mp_global;
|
||||
|
||||
/**
|
||||
+ * struct cc_entry - Struct for translating user space country code (iso3166) to
|
||||
+ * firmware country code and revision.
|
||||
+ *
|
||||
+ * @iso3166: iso3166 alpha 2 country code string.
|
||||
+ * @cc: firmware country code string.
|
||||
+ * @rev: firmware country code revision.
|
||||
+ */
|
||||
+struct cc_entry {
|
||||
+ char iso3166[BRCMF_COUNTRY_BUF_SZ];
|
||||
+ char cc[BRCMF_COUNTRY_BUF_SZ];
|
||||
+ s32 rev;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct cc_translate - Struct for translating country codes as set by user
|
||||
+ * space to a country code and rev which can be used by
|
||||
+ * firmware.
|
||||
+ *
|
||||
+ * @table_size: number of entries in table (> 0)
|
||||
+ * @table: dynamic array of 1 or more elements with translation information.
|
||||
+ */
|
||||
+struct cc_translate {
|
||||
+ int table_size;
|
||||
+ struct cc_entry table[0];
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* struct brcmf_mp_device - Device module paramaters.
|
||||
*
|
||||
* @sdiod_txglomsz: SDIO txglom size.
|
||||
@@ -47,6 +76,7 @@ extern struct brcmf_mp_global_t brcmf_mp
|
||||
* @feature_disable: Feature_disable bitmask.
|
||||
* @fcmode: FWS flow control.
|
||||
* @roamoff: Firmware roaming off?
|
||||
+ * @country_codes: If available, pointer to struct for translating country codes
|
||||
*/
|
||||
struct brcmf_mp_device {
|
||||
int sdiod_txglomsz;
|
||||
@@ -56,6 +86,7 @@ struct brcmf_mp_device {
|
||||
int fcmode;
|
||||
bool roamoff;
|
||||
bool ignore_probe_fail;
|
||||
+ struct cc_translate *country_codes;
|
||||
};
|
||||
|
||||
void brcmf_mp_attach(void);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
@@ -134,6 +134,8 @@
|
||||
#define BRCMF_PFN_MAC_OUI_ONLY BIT(0)
|
||||
#define BRCMF_PFN_SET_MAC_UNASSOC BIT(1)
|
||||
|
||||
+#define BRCMF_MCSSET_LEN 16
|
||||
+
|
||||
/* join preference types for join_pref iovar */
|
||||
enum brcmf_join_pref_types {
|
||||
BRCMF_JOIN_PREF_RSSI = 1,
|
||||
@@ -279,7 +281,7 @@ struct brcmf_bss_info_le {
|
||||
__le32 reserved32[1]; /* Reserved for expansion of BSS properties */
|
||||
u8 flags; /* flags */
|
||||
u8 reserved[3]; /* Reserved for expansion of BSS properties */
|
||||
- u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
|
||||
+ u8 basic_mcs[BRCMF_MCSSET_LEN]; /* 802.11N BSS required MCS set */
|
||||
|
||||
__le16 ie_offset; /* offset at which IEs start, from beginning */
|
||||
__le32 ie_length; /* byte length of Information Elements */
|
||||
@ -0,0 +1,283 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:26:54 +0100
|
||||
Subject: [PATCH] brcmfmac: Add length checks on firmware events
|
||||
|
||||
Add additional length checks on firmware events to create more
|
||||
robust code.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Reviewed-by: Lei Zhang <leizh@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -3092,6 +3092,11 @@ brcmf_notify_sched_scan_results(struct b
|
||||
|
||||
brcmf_dbg(SCAN, "Enter\n");
|
||||
|
||||
+ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
|
||||
+ brcmf_dbg(SCAN, "Event data to small. Ignore\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (e->event_code == BRCMF_E_PFN_NET_LOST) {
|
||||
brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
|
||||
return 0;
|
||||
@@ -3415,6 +3420,11 @@ brcmf_wowl_nd_results(struct brcmf_if *i
|
||||
|
||||
brcmf_dbg(SCAN, "Enter\n");
|
||||
|
||||
+ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
|
||||
+ brcmf_dbg(SCAN, "Event data to small. Ignore\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
pfn_result = (struct brcmf_pno_scanresults_le *)data;
|
||||
|
||||
if (e->event_code == BRCMF_E_PFN_NET_LOST) {
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
@@ -26,50 +26,6 @@
|
||||
#include "fwil.h"
|
||||
|
||||
/**
|
||||
- * struct brcm_ethhdr - broadcom specific ether header.
|
||||
- *
|
||||
- * @subtype: subtype for this packet.
|
||||
- * @length: TODO: length of appended data.
|
||||
- * @version: version indication.
|
||||
- * @oui: OUI of this packet.
|
||||
- * @usr_subtype: subtype for this OUI.
|
||||
- */
|
||||
-struct brcm_ethhdr {
|
||||
- __be16 subtype;
|
||||
- __be16 length;
|
||||
- u8 version;
|
||||
- u8 oui[3];
|
||||
- __be16 usr_subtype;
|
||||
-} __packed;
|
||||
-
|
||||
-struct brcmf_event_msg_be {
|
||||
- __be16 version;
|
||||
- __be16 flags;
|
||||
- __be32 event_type;
|
||||
- __be32 status;
|
||||
- __be32 reason;
|
||||
- __be32 auth_type;
|
||||
- __be32 datalen;
|
||||
- u8 addr[ETH_ALEN];
|
||||
- char ifname[IFNAMSIZ];
|
||||
- u8 ifidx;
|
||||
- u8 bsscfgidx;
|
||||
-} __packed;
|
||||
-
|
||||
-/**
|
||||
- * struct brcmf_event - contents of broadcom event packet.
|
||||
- *
|
||||
- * @eth: standard ether header.
|
||||
- * @hdr: broadcom specific ether header.
|
||||
- * @msg: common part of the actual event message.
|
||||
- */
|
||||
-struct brcmf_event {
|
||||
- struct ethhdr eth;
|
||||
- struct brcm_ethhdr hdr;
|
||||
- struct brcmf_event_msg_be msg;
|
||||
-} __packed;
|
||||
-
|
||||
-/**
|
||||
* struct brcmf_fweh_queue_item - event item on event queue.
|
||||
*
|
||||
* @q: list element for queuing.
|
||||
@@ -85,6 +41,7 @@ struct brcmf_fweh_queue_item {
|
||||
u8 ifidx;
|
||||
u8 ifaddr[ETH_ALEN];
|
||||
struct brcmf_event_msg_be emsg;
|
||||
+ u32 datalen;
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
@@ -294,6 +251,11 @@ static void brcmf_fweh_event_worker(stru
|
||||
brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
|
||||
min_t(u32, emsg.datalen, 64),
|
||||
"event payload, len=%d\n", emsg.datalen);
|
||||
+ if (emsg.datalen > event->datalen) {
|
||||
+ brcmf_err("event invalid length header=%d, msg=%d\n",
|
||||
+ event->datalen, emsg.datalen);
|
||||
+ goto event_free;
|
||||
+ }
|
||||
|
||||
/* special handling of interface event */
|
||||
if (event->code == BRCMF_E_IF) {
|
||||
@@ -439,7 +401,8 @@ int brcmf_fweh_activate_events(struct br
|
||||
* dispatch the event to a registered handler (using worker).
|
||||
*/
|
||||
void brcmf_fweh_process_event(struct brcmf_pub *drvr,
|
||||
- struct brcmf_event *event_packet)
|
||||
+ struct brcmf_event *event_packet,
|
||||
+ u32 packet_len)
|
||||
{
|
||||
enum brcmf_fweh_event_code code;
|
||||
struct brcmf_fweh_info *fweh = &drvr->fweh;
|
||||
@@ -459,6 +422,9 @@ void brcmf_fweh_process_event(struct brc
|
||||
if (code != BRCMF_E_IF && !fweh->evt_handler[code])
|
||||
return;
|
||||
|
||||
+ if (datalen > BRCMF_DCMD_MAXLEN)
|
||||
+ return;
|
||||
+
|
||||
if (in_interrupt())
|
||||
alloc_flag = GFP_ATOMIC;
|
||||
|
||||
@@ -472,6 +438,7 @@ void brcmf_fweh_process_event(struct brc
|
||||
/* use memcpy to get aligned event message */
|
||||
memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg));
|
||||
memcpy(event->data, data, datalen);
|
||||
+ event->datalen = datalen;
|
||||
memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN);
|
||||
|
||||
brcmf_fweh_queue_event(fweh, event);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
|
||||
@@ -27,7 +27,6 @@
|
||||
struct brcmf_pub;
|
||||
struct brcmf_if;
|
||||
struct brcmf_cfg80211_info;
|
||||
-struct brcmf_event;
|
||||
|
||||
/* list of firmware events */
|
||||
#define BRCMF_FWEH_EVENT_ENUM_DEFLIST \
|
||||
@@ -180,13 +179,55 @@ enum brcmf_fweh_event_code {
|
||||
/**
|
||||
* definitions for event packet validation.
|
||||
*/
|
||||
-#define BRCMF_EVENT_OUI_OFFSET 19
|
||||
-#define BRCM_OUI "\x00\x10\x18"
|
||||
-#define DOT11_OUI_LEN 3
|
||||
-#define BCMILCP_BCM_SUBTYPE_EVENT 1
|
||||
+#define BRCM_OUI "\x00\x10\x18"
|
||||
+#define BCMILCP_BCM_SUBTYPE_EVENT 1
|
||||
|
||||
|
||||
/**
|
||||
+ * struct brcm_ethhdr - broadcom specific ether header.
|
||||
+ *
|
||||
+ * @subtype: subtype for this packet.
|
||||
+ * @length: TODO: length of appended data.
|
||||
+ * @version: version indication.
|
||||
+ * @oui: OUI of this packet.
|
||||
+ * @usr_subtype: subtype for this OUI.
|
||||
+ */
|
||||
+struct brcm_ethhdr {
|
||||
+ __be16 subtype;
|
||||
+ __be16 length;
|
||||
+ u8 version;
|
||||
+ u8 oui[3];
|
||||
+ __be16 usr_subtype;
|
||||
+} __packed;
|
||||
+
|
||||
+struct brcmf_event_msg_be {
|
||||
+ __be16 version;
|
||||
+ __be16 flags;
|
||||
+ __be32 event_type;
|
||||
+ __be32 status;
|
||||
+ __be32 reason;
|
||||
+ __be32 auth_type;
|
||||
+ __be32 datalen;
|
||||
+ u8 addr[ETH_ALEN];
|
||||
+ char ifname[IFNAMSIZ];
|
||||
+ u8 ifidx;
|
||||
+ u8 bsscfgidx;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
+ * struct brcmf_event - contents of broadcom event packet.
|
||||
+ *
|
||||
+ * @eth: standard ether header.
|
||||
+ * @hdr: broadcom specific ether header.
|
||||
+ * @msg: common part of the actual event message.
|
||||
+ */
|
||||
+struct brcmf_event {
|
||||
+ struct ethhdr eth;
|
||||
+ struct brcm_ethhdr hdr;
|
||||
+ struct brcmf_event_msg_be msg;
|
||||
+} __packed;
|
||||
+
|
||||
+/**
|
||||
* struct brcmf_event_msg - firmware event message.
|
||||
*
|
||||
* @version: version information.
|
||||
@@ -256,34 +297,35 @@ void brcmf_fweh_unregister(struct brcmf_
|
||||
enum brcmf_fweh_event_code code);
|
||||
int brcmf_fweh_activate_events(struct brcmf_if *ifp);
|
||||
void brcmf_fweh_process_event(struct brcmf_pub *drvr,
|
||||
- struct brcmf_event *event_packet);
|
||||
+ struct brcmf_event *event_packet,
|
||||
+ u32 packet_len);
|
||||
void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
|
||||
|
||||
static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct brcmf_event *event_packet;
|
||||
- u8 *data;
|
||||
u16 usr_stype;
|
||||
|
||||
/* only process events when protocol matches */
|
||||
if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
|
||||
return;
|
||||
|
||||
+ if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
|
||||
+ return;
|
||||
+
|
||||
/* check for BRCM oui match */
|
||||
event_packet = (struct brcmf_event *)skb_mac_header(skb);
|
||||
- data = (u8 *)event_packet;
|
||||
- data += BRCMF_EVENT_OUI_OFFSET;
|
||||
- if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN))
|
||||
+ if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
|
||||
+ sizeof(event_packet->hdr.oui)))
|
||||
return;
|
||||
|
||||
/* final match on usr_subtype */
|
||||
- data += DOT11_OUI_LEN;
|
||||
- usr_stype = get_unaligned_be16(data);
|
||||
+ usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype);
|
||||
if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
|
||||
return;
|
||||
|
||||
- brcmf_fweh_process_event(drvr, event_packet);
|
||||
+ brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN);
|
||||
}
|
||||
|
||||
#endif /* FWEH_H_ */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -1361,6 +1361,11 @@ int brcmf_p2p_notify_action_frame_rx(str
|
||||
u16 mgmt_type;
|
||||
u8 action;
|
||||
|
||||
+ if (e->datalen < sizeof(*rxframe)) {
|
||||
+ brcmf_dbg(SCAN, "Event data to small. Ignore\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ch.chspec = be16_to_cpu(rxframe->chanspec);
|
||||
cfg->d11inf.decchspec(&ch);
|
||||
/* Check if wpa_supplicant has registered for this frame */
|
||||
@@ -1858,6 +1863,11 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
|
||||
brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code,
|
||||
e->reason);
|
||||
|
||||
+ if (e->datalen < sizeof(*rxframe)) {
|
||||
+ brcmf_dbg(SCAN, "Event data to small. Ignore\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
ch.chspec = be16_to_cpu(rxframe->chanspec);
|
||||
cfg->d11inf.decchspec(&ch);
|
||||
|
||||
@ -0,0 +1,333 @@
|
||||
From: Franky Lin <frankyl@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:26:55 +0100
|
||||
Subject: [PATCH] brcmfmac: add neighbor discovery offload ip address table
|
||||
configuration
|
||||
|
||||
Configure ipv6 address for neighbor discovery offload ip table in
|
||||
firmware obtained through ipv6 address notification callback.
|
||||
|
||||
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Franky Lin <frankyl@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -456,7 +456,7 @@ send_key_to_dongle(struct brcmf_if *ifp,
|
||||
}
|
||||
|
||||
static s32
|
||||
-brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
|
||||
+brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
|
||||
{
|
||||
s32 err;
|
||||
u32 mode;
|
||||
@@ -484,6 +484,15 @@ brcmf_configure_arp_offload(struct brcmf
|
||||
enable, mode);
|
||||
}
|
||||
|
||||
+ err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
|
||||
+ if (err) {
|
||||
+ brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
|
||||
+ enable, err);
|
||||
+ err = 0;
|
||||
+ } else
|
||||
+ brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
|
||||
+ enable, mode);
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -3543,7 +3552,7 @@ static s32 brcmf_cfg80211_resume(struct
|
||||
brcmf_report_wowl_wakeind(wiphy, ifp);
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
|
||||
brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
|
||||
- brcmf_configure_arp_offload(ifp, true);
|
||||
+ brcmf_configure_arp_nd_offload(ifp, true);
|
||||
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
|
||||
cfg->wowl.pre_pmmode);
|
||||
cfg->wowl.active = false;
|
||||
@@ -3567,7 +3576,7 @@ static void brcmf_configure_wowl(struct
|
||||
|
||||
brcmf_dbg(TRACE, "Suspend, wowl config.\n");
|
||||
|
||||
- brcmf_configure_arp_offload(ifp, false);
|
||||
+ brcmf_configure_arp_nd_offload(ifp, false);
|
||||
brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
|
||||
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
|
||||
|
||||
@@ -4336,7 +4345,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
|
||||
if (!mbss) {
|
||||
brcmf_set_mpc(ifp, 0);
|
||||
- brcmf_configure_arp_offload(ifp, false);
|
||||
+ brcmf_configure_arp_nd_offload(ifp, false);
|
||||
}
|
||||
|
||||
/* find the RSN_IE */
|
||||
@@ -4482,7 +4491,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
exit:
|
||||
if ((err) && (!mbss)) {
|
||||
brcmf_set_mpc(ifp, 1);
|
||||
- brcmf_configure_arp_offload(ifp, true);
|
||||
+ brcmf_configure_arp_nd_offload(ifp, true);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@@ -4540,7 +4549,7 @@ static int brcmf_cfg80211_stop_ap(struct
|
||||
brcmf_err("bss_enable config failed %d\n", err);
|
||||
}
|
||||
brcmf_set_mpc(ifp, 1);
|
||||
- brcmf_configure_arp_offload(ifp, true);
|
||||
+ brcmf_configure_arp_nd_offload(ifp, true);
|
||||
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
brcmf_net_setcarrier(ifp, false);
|
||||
|
||||
@@ -6287,7 +6296,7 @@ static s32 brcmf_config_dongle(struct br
|
||||
if (err)
|
||||
goto default_conf_out;
|
||||
|
||||
- brcmf_configure_arp_offload(ifp, true);
|
||||
+ brcmf_configure_arp_nd_offload(ifp, true);
|
||||
|
||||
cfg->dongle_up = true;
|
||||
default_conf_out:
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <linux/inetdevice.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/rtnetlink.h>
|
||||
+#include <net/addrconf.h>
|
||||
+#include <net/ipv6.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
|
||||
@@ -172,6 +174,35 @@ _brcmf_set_mac_address(struct work_struc
|
||||
}
|
||||
}
|
||||
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+static void _brcmf_update_ndtable(struct work_struct *work)
|
||||
+{
|
||||
+ struct brcmf_if *ifp;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ ifp = container_of(work, struct brcmf_if, ndoffload_work);
|
||||
+
|
||||
+ /* clear the table in firmware */
|
||||
+ ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);
|
||||
+ if (ret) {
|
||||
+ brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ifp->ipv6addr_idx; i++) {
|
||||
+ ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip",
|
||||
+ &ifp->ipv6_addr_tbl[i],
|
||||
+ sizeof(struct in6_addr));
|
||||
+ if (ret)
|
||||
+ brcmf_err("add nd ip err %d\n", ret);
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+static void _brcmf_update_ndtable(struct work_struct *work)
|
||||
+{
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
@@ -685,6 +716,7 @@ int brcmf_net_attach(struct brcmf_if *if
|
||||
|
||||
INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
|
||||
INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
|
||||
+ INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);
|
||||
|
||||
if (rtnl_locked)
|
||||
err = register_netdevice(ndev);
|
||||
@@ -884,6 +916,7 @@ static void brcmf_del_if(struct brcmf_pu
|
||||
if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
|
||||
cancel_work_sync(&ifp->setmacaddr_work);
|
||||
cancel_work_sync(&ifp->multicast_work);
|
||||
+ cancel_work_sync(&ifp->ndoffload_work);
|
||||
}
|
||||
brcmf_net_detach(ifp->ndev);
|
||||
} else {
|
||||
@@ -1025,6 +1058,56 @@ static int brcmf_inetaddr_changed(struct
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+static int brcmf_inet6addr_changed(struct notifier_block *nb,
|
||||
+ unsigned long action, void *data)
|
||||
+{
|
||||
+ struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub,
|
||||
+ inet6addr_notifier);
|
||||
+ struct inet6_ifaddr *ifa = data;
|
||||
+ struct brcmf_if *ifp;
|
||||
+ int i;
|
||||
+ struct in6_addr *table;
|
||||
+
|
||||
+ /* Only handle primary interface */
|
||||
+ ifp = drvr->iflist[0];
|
||||
+ if (!ifp)
|
||||
+ return NOTIFY_DONE;
|
||||
+ if (ifp->ndev != ifa->idev->dev)
|
||||
+ return NOTIFY_DONE;
|
||||
+
|
||||
+ table = ifp->ipv6_addr_tbl;
|
||||
+ for (i = 0; i < NDOL_MAX_ENTRIES; i++)
|
||||
+ if (ipv6_addr_equal(&ifa->addr, &table[i]))
|
||||
+ break;
|
||||
+
|
||||
+ switch (action) {
|
||||
+ case NETDEV_UP:
|
||||
+ if (i == NDOL_MAX_ENTRIES) {
|
||||
+ if (ifp->ipv6addr_idx < NDOL_MAX_ENTRIES) {
|
||||
+ table[ifp->ipv6addr_idx++] = ifa->addr;
|
||||
+ } else {
|
||||
+ for (i = 0; i < NDOL_MAX_ENTRIES - 1; i++)
|
||||
+ table[i] = table[i + 1];
|
||||
+ table[NDOL_MAX_ENTRIES - 1] = ifa->addr;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ case NETDEV_DOWN:
|
||||
+ if (i < NDOL_MAX_ENTRIES)
|
||||
+ for (; i < ifp->ipv6addr_idx; i++)
|
||||
+ table[i] = table[i + 1];
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ schedule_work(&ifp->ndoffload_work);
|
||||
+
|
||||
+ return NOTIFY_OK;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
int brcmf_attach(struct device *dev)
|
||||
{
|
||||
struct brcmf_pub *drvr = NULL;
|
||||
@@ -1164,30 +1247,41 @@ int brcmf_bus_start(struct device *dev)
|
||||
#ifdef CONFIG_INET
|
||||
drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed;
|
||||
ret = register_inetaddr_notifier(&drvr->inetaddr_notifier);
|
||||
+ if (ret)
|
||||
+ goto fail;
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+ drvr->inet6addr_notifier.notifier_call = brcmf_inet6addr_changed;
|
||||
+ ret = register_inet6addr_notifier(&drvr->inet6addr_notifier);
|
||||
+ if (ret) {
|
||||
+ unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
|
||||
+ goto fail;
|
||||
+ }
|
||||
#endif
|
||||
+#endif /* CONFIG_INET */
|
||||
+
|
||||
+ return 0;
|
||||
|
||||
fail:
|
||||
- if (ret < 0) {
|
||||
- brcmf_err("failed: %d\n", ret);
|
||||
- if (drvr->config) {
|
||||
- brcmf_cfg80211_detach(drvr->config);
|
||||
- drvr->config = NULL;
|
||||
- }
|
||||
- if (drvr->fws) {
|
||||
- brcmf_fws_del_interface(ifp);
|
||||
- brcmf_fws_deinit(drvr);
|
||||
- }
|
||||
- if (ifp)
|
||||
- brcmf_net_detach(ifp->ndev);
|
||||
- if (p2p_ifp)
|
||||
- brcmf_net_detach(p2p_ifp->ndev);
|
||||
- drvr->iflist[0] = NULL;
|
||||
- drvr->iflist[1] = NULL;
|
||||
- if (brcmf_ignoring_probe_fail(drvr))
|
||||
- ret = 0;
|
||||
- return ret;
|
||||
+ brcmf_err("failed: %d\n", ret);
|
||||
+ if (drvr->config) {
|
||||
+ brcmf_cfg80211_detach(drvr->config);
|
||||
+ drvr->config = NULL;
|
||||
+ }
|
||||
+ if (drvr->fws) {
|
||||
+ brcmf_fws_del_interface(ifp);
|
||||
+ brcmf_fws_deinit(drvr);
|
||||
}
|
||||
- return 0;
|
||||
+ if (ifp)
|
||||
+ brcmf_net_detach(ifp->ndev);
|
||||
+ if (p2p_ifp)
|
||||
+ brcmf_net_detach(p2p_ifp->ndev);
|
||||
+ drvr->iflist[0] = NULL;
|
||||
+ drvr->iflist[1] = NULL;
|
||||
+ if (brcmf_ignoring_probe_fail(drvr))
|
||||
+ ret = 0;
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
|
||||
@@ -1237,6 +1331,10 @@ void brcmf_detach(struct device *dev)
|
||||
unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
|
||||
#endif
|
||||
|
||||
+#if IS_ENABLED(CONFIG_IPV6)
|
||||
+ unregister_inet6addr_notifier(&drvr->inet6addr_notifier);
|
||||
+#endif
|
||||
+
|
||||
/* stop firmware event handling */
|
||||
brcmf_fweh_detach(drvr);
|
||||
if (drvr->config)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -48,6 +48,8 @@
|
||||
*/
|
||||
#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32
|
||||
|
||||
+#define NDOL_MAX_ENTRIES 8
|
||||
+
|
||||
/**
|
||||
* struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info
|
||||
*
|
||||
@@ -143,6 +145,7 @@ struct brcmf_pub {
|
||||
#endif
|
||||
|
||||
struct notifier_block inetaddr_notifier;
|
||||
+ struct notifier_block inet6addr_notifier;
|
||||
struct brcmf_mp_device *settings;
|
||||
};
|
||||
|
||||
@@ -175,6 +178,7 @@ enum brcmf_netif_stop_reason {
|
||||
* @stats: interface specific network statistics.
|
||||
* @setmacaddr_work: worker object for setting mac address.
|
||||
* @multicast_work: worker object for multicast provisioning.
|
||||
+ * @ndoffload_work: worker object for neighbor discovery offload configuration.
|
||||
* @fws_desc: interface specific firmware-signalling descriptor.
|
||||
* @ifidx: interface index in device firmware.
|
||||
* @bsscfgidx: index of bss associated with this interface.
|
||||
@@ -191,6 +195,7 @@ struct brcmf_if {
|
||||
struct net_device_stats stats;
|
||||
struct work_struct setmacaddr_work;
|
||||
struct work_struct multicast_work;
|
||||
+ struct work_struct ndoffload_work;
|
||||
struct brcmf_fws_mac_descriptor *fws_desc;
|
||||
int ifidx;
|
||||
s32 bsscfgidx;
|
||||
@@ -199,6 +204,8 @@ struct brcmf_if {
|
||||
spinlock_t netif_stop_lock;
|
||||
atomic_t pend_8021x_cnt;
|
||||
wait_queue_head_t pend_8021x_wait;
|
||||
+ struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES];
|
||||
+ u8 ipv6addr_idx;
|
||||
};
|
||||
|
||||
struct brcmf_skb_reorder_data {
|
||||
@ -0,0 +1,38 @@
|
||||
From: Franky Lin <frankyl@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:26:56 +0100
|
||||
Subject: [PATCH] brcmfmac: check return for ARP ip setting iovar
|
||||
|
||||
The return value of iovar set function should be saved and checked.
|
||||
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Franky Lin <frankyl@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -1039,14 +1039,14 @@ static int brcmf_inetaddr_changed(struct
|
||||
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);
|
||||
- }
|
||||
+ if (addr_table[i] == 0)
|
||||
+ continue;
|
||||
+ ret = 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;
|
||||
@ -0,0 +1,221 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:00 +0100
|
||||
Subject: [PATCH] brcmfmac: remove pcie gen1 support
|
||||
|
||||
The PCIE bus driver supports older gen1 (v1) chips, but there is no
|
||||
actual device which is using this older pcie core which is supported
|
||||
by brcmfmac. Remove all gen1 related code.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -100,9 +100,6 @@ static struct brcmf_firmware_mapping brc
|
||||
#define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124
|
||||
#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140
|
||||
|
||||
-#define BRCMF_PCIE_GENREV1 1
|
||||
-#define BRCMF_PCIE_GENREV2 2
|
||||
-
|
||||
#define BRCMF_PCIE2_INTA 0x01
|
||||
#define BRCMF_PCIE2_INTB 0x02
|
||||
|
||||
@@ -257,9 +254,7 @@ struct brcmf_pciedev_info {
|
||||
u32 ram_size;
|
||||
struct brcmf_chip *ci;
|
||||
u32 coreid;
|
||||
- u32 generic_corerev;
|
||||
struct brcmf_pcie_shared_info shared;
|
||||
- void (*ringbell)(struct brcmf_pciedev_info *devinfo);
|
||||
wait_queue_head_t mbdata_resp_wait;
|
||||
bool mbdata_completed;
|
||||
bool irq_allocated;
|
||||
@@ -746,68 +741,22 @@ static void brcmf_pcie_bus_console_read(
|
||||
}
|
||||
|
||||
|
||||
-static __used void brcmf_pcie_ringbell_v1(struct brcmf_pciedev_info *devinfo)
|
||||
-{
|
||||
- u32 reg_value;
|
||||
-
|
||||
- brcmf_dbg(PCIE, "RING !\n");
|
||||
- reg_value = brcmf_pcie_read_reg32(devinfo,
|
||||
- BRCMF_PCIE_PCIE2REG_MAILBOXINT);
|
||||
- reg_value |= BRCMF_PCIE2_INTB;
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
|
||||
- reg_value);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static void brcmf_pcie_ringbell_v2(struct brcmf_pciedev_info *devinfo)
|
||||
-{
|
||||
- brcmf_dbg(PCIE, "RING !\n");
|
||||
- /* Any arbitrary value will do, lets use 1 */
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1);
|
||||
-}
|
||||
-
|
||||
-
|
||||
static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1)
|
||||
- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK,
|
||||
- 0);
|
||||
- else
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
|
||||
- 0);
|
||||
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0);
|
||||
}
|
||||
|
||||
|
||||
static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1)
|
||||
- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK,
|
||||
- BRCMF_PCIE_INT_DEF);
|
||||
- else
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
|
||||
- BRCMF_PCIE_MB_INT_D2H_DB |
|
||||
- BRCMF_PCIE_MB_INT_FN0_0 |
|
||||
- BRCMF_PCIE_MB_INT_FN0_1);
|
||||
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
|
||||
+ BRCMF_PCIE_MB_INT_D2H_DB |
|
||||
+ BRCMF_PCIE_MB_INT_FN0_0 |
|
||||
+ BRCMF_PCIE_MB_INT_FN0_1);
|
||||
}
|
||||
|
||||
|
||||
-static irqreturn_t brcmf_pcie_quick_check_isr_v1(int irq, void *arg)
|
||||
-{
|
||||
- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
|
||||
- u32 status;
|
||||
-
|
||||
- status = 0;
|
||||
- pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
|
||||
- if (status) {
|
||||
- brcmf_pcie_intr_disable(devinfo);
|
||||
- brcmf_dbg(PCIE, "Enter\n");
|
||||
- return IRQ_WAKE_THREAD;
|
||||
- }
|
||||
- return IRQ_NONE;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static irqreturn_t brcmf_pcie_quick_check_isr_v2(int irq, void *arg)
|
||||
+static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg)
|
||||
{
|
||||
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
|
||||
|
||||
@@ -820,29 +769,7 @@ static irqreturn_t brcmf_pcie_quick_chec
|
||||
}
|
||||
|
||||
|
||||
-static irqreturn_t brcmf_pcie_isr_thread_v1(int irq, void *arg)
|
||||
-{
|
||||
- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
|
||||
- const struct pci_dev *pdev = devinfo->pdev;
|
||||
- u32 status;
|
||||
-
|
||||
- devinfo->in_irq = true;
|
||||
- status = 0;
|
||||
- pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
|
||||
- brcmf_dbg(PCIE, "Enter %x\n", status);
|
||||
- if (status) {
|
||||
- pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status);
|
||||
- if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
|
||||
- brcmf_proto_msgbuf_rx_trigger(&devinfo->pdev->dev);
|
||||
- }
|
||||
- if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
|
||||
- brcmf_pcie_intr_enable(devinfo);
|
||||
- devinfo->in_irq = false;
|
||||
- return IRQ_HANDLED;
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static irqreturn_t brcmf_pcie_isr_thread_v2(int irq, void *arg)
|
||||
+static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
|
||||
{
|
||||
struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
|
||||
u32 status;
|
||||
@@ -879,28 +806,14 @@ static int brcmf_pcie_request_irq(struct
|
||||
brcmf_pcie_intr_disable(devinfo);
|
||||
|
||||
brcmf_dbg(PCIE, "Enter\n");
|
||||
- /* is it a v1 or v2 implementation */
|
||||
+
|
||||
pci_enable_msi(pdev);
|
||||
- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) {
|
||||
- if (request_threaded_irq(pdev->irq,
|
||||
- brcmf_pcie_quick_check_isr_v1,
|
||||
- brcmf_pcie_isr_thread_v1,
|
||||
- IRQF_SHARED, "brcmf_pcie_intr",
|
||||
- devinfo)) {
|
||||
- pci_disable_msi(pdev);
|
||||
- brcmf_err("Failed to request IRQ %d\n", pdev->irq);
|
||||
- return -EIO;
|
||||
- }
|
||||
- } else {
|
||||
- if (request_threaded_irq(pdev->irq,
|
||||
- brcmf_pcie_quick_check_isr_v2,
|
||||
- brcmf_pcie_isr_thread_v2,
|
||||
- IRQF_SHARED, "brcmf_pcie_intr",
|
||||
- devinfo)) {
|
||||
- pci_disable_msi(pdev);
|
||||
- brcmf_err("Failed to request IRQ %d\n", pdev->irq);
|
||||
- return -EIO;
|
||||
- }
|
||||
+ if (request_threaded_irq(pdev->irq, brcmf_pcie_quick_check_isr,
|
||||
+ brcmf_pcie_isr_thread, IRQF_SHARED,
|
||||
+ "brcmf_pcie_intr", devinfo)) {
|
||||
+ pci_disable_msi(pdev);
|
||||
+ brcmf_err("Failed to request IRQ %d\n", pdev->irq);
|
||||
+ return -EIO;
|
||||
}
|
||||
devinfo->irq_allocated = true;
|
||||
return 0;
|
||||
@@ -931,16 +844,9 @@ static void brcmf_pcie_release_irq(struc
|
||||
if (devinfo->in_irq)
|
||||
brcmf_err("Still in IRQ (processing) !!!\n");
|
||||
|
||||
- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) {
|
||||
- status = 0;
|
||||
- pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
|
||||
- pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status);
|
||||
- } else {
|
||||
- status = brcmf_pcie_read_reg32(devinfo,
|
||||
- BRCMF_PCIE_PCIE2REG_MAILBOXINT);
|
||||
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
|
||||
- status);
|
||||
- }
|
||||
+ status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
|
||||
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status);
|
||||
+
|
||||
devinfo->irq_allocated = false;
|
||||
}
|
||||
|
||||
@@ -989,7 +895,9 @@ static int brcmf_pcie_ring_mb_ring_bell(
|
||||
if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
|
||||
return -EIO;
|
||||
|
||||
- devinfo->ringbell(devinfo);
|
||||
+ brcmf_dbg(PCIE, "RING !\n");
|
||||
+ /* Any arbitrary value will do, lets use 1 */
|
||||
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1503,9 +1411,6 @@ static int brcmf_pcie_download_fw_nvram(
|
||||
u32 address;
|
||||
u32 resetintr;
|
||||
|
||||
- devinfo->ringbell = brcmf_pcie_ringbell_v2;
|
||||
- devinfo->generic_corerev = BRCMF_PCIE_GENREV2;
|
||||
-
|
||||
brcmf_dbg(PCIE, "Halt ARM.\n");
|
||||
err = brcmf_pcie_enter_download_state(devinfo);
|
||||
if (err)
|
||||
@ -19,7 +19,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -40,7 +40,7 @@ MODULE_AUTHOR("Broadcom Corporation");
|
||||
@@ -42,7 +42,7 @@ MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:02 +0100
|
||||
Subject: [PATCH] brcmfmac: move module init and exit to common
|
||||
|
||||
In preparation of module parameters for all devices the module init
|
||||
and exit routines are moved to the common file.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -28,6 +28,10 @@
|
||||
#include "tracepoint.h"
|
||||
#include "common.h"
|
||||
|
||||
+MODULE_AUTHOR("Broadcom Corporation");
|
||||
+MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
+MODULE_LICENSE("Dual BSD/GPL");
|
||||
+
|
||||
const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
|
||||
@@ -221,7 +225,7 @@ void __brcmf_dbg(u32 level, const char *
|
||||
}
|
||||
#endif
|
||||
|
||||
-void brcmf_mp_attach(void)
|
||||
+static void brcmf_mp_attach(void)
|
||||
{
|
||||
strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
|
||||
BRCMF_FW_ALTPATH_LEN);
|
||||
@@ -249,3 +253,33 @@ void brcmf_mp_device_detach(struct brcmf
|
||||
kfree(drvr->settings);
|
||||
}
|
||||
|
||||
+static int __init brcmfmac_module_init(void)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ /* Initialize debug system first */
|
||||
+ brcmf_debugfs_init();
|
||||
+
|
||||
+#ifdef CPTCFG_BRCMFMAC_SDIO
|
||||
+ brcmf_sdio_init();
|
||||
+#endif
|
||||
+ /* Initialize global module paramaters */
|
||||
+ brcmf_mp_attach();
|
||||
+
|
||||
+ /* Continue the initialization by registering the different busses */
|
||||
+ err = brcmf_core_init();
|
||||
+ if (err)
|
||||
+ brcmf_debugfs_exit();
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void __exit brcmfmac_module_exit(void)
|
||||
+{
|
||||
+ brcmf_core_exit();
|
||||
+ brcmf_debugfs_exit();
|
||||
+}
|
||||
+
|
||||
+module_init(brcmfmac_module_init);
|
||||
+module_exit(brcmfmac_module_exit);
|
||||
+
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -89,7 +89,6 @@ struct brcmf_mp_device {
|
||||
struct cc_translate *country_codes;
|
||||
};
|
||||
|
||||
-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
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -38,10 +38,6 @@
|
||||
#include "pcie.h"
|
||||
#include "common.h"
|
||||
|
||||
-MODULE_AUTHOR("Broadcom Corporation");
|
||||
-MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
-MODULE_LICENSE("Dual BSD/GPL");
|
||||
-
|
||||
#define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950)
|
||||
|
||||
/* AMPDU rx reordering definitions */
|
||||
@@ -1422,19 +1418,15 @@ static void brcmf_driver_register(struct
|
||||
}
|
||||
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
|
||||
|
||||
-static int __init brcmfmac_module_init(void)
|
||||
+int __init brcmf_core_init(void)
|
||||
{
|
||||
- brcmf_debugfs_init();
|
||||
-#ifdef CPTCFG_BRCMFMAC_SDIO
|
||||
- brcmf_sdio_init();
|
||||
-#endif
|
||||
if (!schedule_work(&brcmf_driver_work))
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void __exit brcmfmac_module_exit(void)
|
||||
+void __exit brcmf_core_exit(void)
|
||||
{
|
||||
cancel_work_sync(&brcmf_driver_work);
|
||||
|
||||
@@ -1447,8 +1439,5 @@ static void __exit brcmfmac_module_exit(
|
||||
#ifdef CPTCFG_BRCMFMAC_PCIE
|
||||
brcmf_pcie_exit();
|
||||
#endif
|
||||
- brcmf_debugfs_exit();
|
||||
}
|
||||
|
||||
-module_init(brcmfmac_module_init);
|
||||
-module_exit(brcmfmac_module_exit);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -227,5 +227,7 @@ void brcmf_txflowblock_if(struct brcmf_i
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||
+int __init brcmf_core_init(void);
|
||||
+void __exit brcmf_core_exit(void);
|
||||
|
||||
#endif /* BRCMFMAC_CORE_H */
|
||||
@ -0,0 +1,260 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:03 +0100
|
||||
Subject: [PATCH] brcmfmac: add wowl gtk rekeying offload support
|
||||
|
||||
This patch adds support for gtk rekeying offload and for gtk
|
||||
rekeying failure during wowl mode.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -3526,6 +3526,10 @@ static void brcmf_report_wowl_wakeind(st
|
||||
else
|
||||
wakeup_data.net_detect = cfg->wowl.nd_info;
|
||||
}
|
||||
+ if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
|
||||
+ brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
|
||||
+ wakeup_data.gtk_rekey_failure = true;
|
||||
+ }
|
||||
} else {
|
||||
wakeup = NULL;
|
||||
}
|
||||
@@ -3607,6 +3611,8 @@ static void brcmf_configure_wowl(struct
|
||||
brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
|
||||
brcmf_wowl_nd_results);
|
||||
}
|
||||
+ if (wowl->gtk_rekey_failure)
|
||||
+ wowl_config |= BRCMF_WOWL_GTK_FAILURE;
|
||||
if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
|
||||
wowl_config |= BRCMF_WOWL_UNASSOC;
|
||||
|
||||
@@ -4874,7 +4880,32 @@ static int brcmf_cfg80211_tdls_oper(stru
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static struct cfg80211_ops wl_cfg80211_ops = {
|
||||
+#ifdef CONFIG_PM
|
||||
+static int
|
||||
+brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
|
||||
+ struct cfg80211_gtk_rekey_data *gtk)
|
||||
+{
|
||||
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
+ struct brcmf_gtk_keyinfo_le gtk_le;
|
||||
+ int ret;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
|
||||
+
|
||||
+ memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
|
||||
+ memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
|
||||
+ memcpy(gtk_le.replay_counter, gtk->replay_ctr,
|
||||
+ sizeof(gtk_le.replay_counter));
|
||||
+
|
||||
+ ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le,
|
||||
+ sizeof(gtk_le));
|
||||
+ if (ret < 0)
|
||||
+ brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static struct cfg80211_ops brcmf_cfg80211_ops = {
|
||||
.add_virtual_intf = brcmf_cfg80211_add_iface,
|
||||
.del_virtual_intf = brcmf_cfg80211_del_iface,
|
||||
.change_virtual_intf = brcmf_cfg80211_change_iface,
|
||||
@@ -6139,19 +6170,18 @@ static void brcmf_wiphy_wowl_params(stru
|
||||
{
|
||||
#ifdef CONFIG_PM
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
- s32 err;
|
||||
- u32 wowl_cap;
|
||||
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
|
||||
- err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap);
|
||||
- if (!err) {
|
||||
- if (wowl_cap & BRCMF_WOWL_PFN_FOUND) {
|
||||
- brcmf_wowlan_support.flags |=
|
||||
- WIPHY_WOWLAN_NET_DETECT;
|
||||
- init_waitqueue_head(&cfg->wowl.nd_data_wait);
|
||||
- }
|
||||
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
|
||||
+ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
|
||||
+ init_waitqueue_head(&cfg->wowl.nd_data_wait);
|
||||
}
|
||||
}
|
||||
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
|
||||
+ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
|
||||
+ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
|
||||
+ }
|
||||
+
|
||||
wiphy->wowlan = &brcmf_wowlan_support;
|
||||
#endif
|
||||
}
|
||||
@@ -6538,6 +6568,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
|
||||
struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
|
||||
struct brcmf_cfg80211_info *cfg;
|
||||
struct wiphy *wiphy;
|
||||
+ struct cfg80211_ops *ops;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
struct brcmf_if *ifp;
|
||||
s32 err = 0;
|
||||
@@ -6549,8 +6580,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ ops = kzalloc(sizeof(*ops), GFP_KERNEL);
|
||||
+ if (!ops)
|
||||
+ return NULL;
|
||||
+
|
||||
+ memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops));
|
||||
ifp = netdev_priv(ndev);
|
||||
- wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
|
||||
+#ifdef CONFIG_PM
|
||||
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
|
||||
+ ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
|
||||
+#endif
|
||||
+ wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
|
||||
if (!wiphy) {
|
||||
brcmf_err("Could not allocate wiphy device\n");
|
||||
return NULL;
|
||||
@@ -6560,6 +6600,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
|
||||
|
||||
cfg = wiphy_priv(wiphy);
|
||||
cfg->wiphy = wiphy;
|
||||
+ cfg->ops = ops;
|
||||
cfg->pub = drvr;
|
||||
init_vif_event(&cfg->vif_event);
|
||||
INIT_LIST_HEAD(&cfg->vif_list);
|
||||
@@ -6686,6 +6727,7 @@ priv_out:
|
||||
ifp->vif = NULL;
|
||||
wiphy_out:
|
||||
brcmf_free_wiphy(wiphy);
|
||||
+ kfree(ops);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -6696,6 +6738,7 @@ void brcmf_cfg80211_detach(struct brcmf_
|
||||
|
||||
brcmf_btcoex_detach(cfg);
|
||||
wiphy_unregister(cfg->wiphy);
|
||||
+ kfree(cfg->ops);
|
||||
wl_deinit_priv(cfg);
|
||||
brcmf_free_wiphy(cfg->wiphy);
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -256,6 +256,7 @@ struct brcmf_cfg80211_wowl {
|
||||
* struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
|
||||
*
|
||||
* @wiphy: wiphy object for cfg80211 interface.
|
||||
+ * @ops: pointer to copy of ops as registered with wiphy object.
|
||||
* @conf: dongle configuration.
|
||||
* @p2p: peer-to-peer specific information.
|
||||
* @btcoex: Bluetooth coexistence information.
|
||||
@@ -288,6 +289,7 @@ struct brcmf_cfg80211_wowl {
|
||||
*/
|
||||
struct brcmf_cfg80211_info {
|
||||
struct wiphy *wiphy;
|
||||
+ struct cfg80211_ops *ops;
|
||||
struct brcmf_cfg80211_conf *conf;
|
||||
struct brcmf_p2p_info p2p;
|
||||
struct brcmf_btcoex_info *btcoex;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
@@ -136,6 +136,7 @@ void brcmf_feat_attach(struct brcmf_pub
|
||||
{
|
||||
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
|
||||
struct brcmf_pno_macaddr_le pfn_mac;
|
||||
+ u32 wowl_cap;
|
||||
s32 err;
|
||||
|
||||
brcmf_feat_firmware_capabilities(ifp);
|
||||
@@ -143,6 +144,17 @@ void brcmf_feat_attach(struct brcmf_pub
|
||||
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");
|
||||
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) {
|
||||
+ err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap);
|
||||
+ if (!err) {
|
||||
+ if (wowl_cap & BRCMF_WOWL_PFN_FOUND)
|
||||
+ ifp->drvr->feat_flags |=
|
||||
+ BIT(BRCMF_FEAT_WOWL_ND);
|
||||
+ if (wowl_cap & BRCMF_WOWL_GTK_FAILURE)
|
||||
+ ifp->drvr->feat_flags |=
|
||||
+ BIT(BRCMF_FEAT_WOWL_GTK);
|
||||
+ }
|
||||
+ }
|
||||
/* MBSS does not work for 43362 */
|
||||
if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
|
||||
ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
@@ -27,6 +27,8 @@
|
||||
* RSDB: Real Simultaneous Dual Band
|
||||
* TDLS: Tunneled Direct Link Setup
|
||||
* SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan.
|
||||
+ * WOWL_ND: WOWL net detect (PNO)
|
||||
+ * WOWL_GTK: (WOWL) GTK rekeying offload
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MBSS) \
|
||||
@@ -36,7 +38,9 @@
|
||||
BRCMF_FEAT_DEF(P2P) \
|
||||
BRCMF_FEAT_DEF(RSDB) \
|
||||
BRCMF_FEAT_DEF(TDLS) \
|
||||
- BRCMF_FEAT_DEF(SCAN_RANDOM_MAC)
|
||||
+ BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \
|
||||
+ BRCMF_FEAT_DEF(WOWL_ND) \
|
||||
+ BRCMF_FEAT_DEF(WOWL_GTK)
|
||||
|
||||
/*
|
||||
* Quirks:
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
@@ -111,7 +111,9 @@
|
||||
/* Wakeup if received matched secured pattern: */
|
||||
#define BRCMF_WOWL_SECURE (1 << 25)
|
||||
/* Wakeup on finding preferred network */
|
||||
-#define BRCMF_WOWL_PFN_FOUND (1 << 26)
|
||||
+#define BRCMF_WOWL_PFN_FOUND (1 << 27)
|
||||
+/* Wakeup on receiving pairwise key EAP packets: */
|
||||
+#define WIPHY_WOWL_EAP_PK (1 << 28)
|
||||
/* Link Down indication in WoWL mode: */
|
||||
#define BRCMF_WOWL_LINKDOWN (1 << 31)
|
||||
|
||||
@@ -136,6 +138,10 @@
|
||||
|
||||
#define BRCMF_MCSSET_LEN 16
|
||||
|
||||
+#define BRCMF_RSN_KCK_LENGTH 16
|
||||
+#define BRCMF_RSN_KEK_LENGTH 16
|
||||
+#define BRCMF_RSN_REPLAY_LEN 8
|
||||
+
|
||||
/* join preference types for join_pref iovar */
|
||||
enum brcmf_join_pref_types {
|
||||
BRCMF_JOIN_PREF_RSSI = 1,
|
||||
@@ -789,4 +795,17 @@ struct brcmf_pktcnt_le {
|
||||
__le32 rx_ocast_good_pkt;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct brcmf_gtk_keyinfo_le - GTP rekey data
|
||||
+ *
|
||||
+ * @kck: key confirmation key.
|
||||
+ * @kek: key encryption key.
|
||||
+ * @replay_counter: replay counter.
|
||||
+ */
|
||||
+struct brcmf_gtk_keyinfo_le {
|
||||
+ u8 kck[BRCMF_RSN_KCK_LENGTH];
|
||||
+ u8 kek[BRCMF_RSN_KEK_LENGTH];
|
||||
+ u8 replay_counter[BRCMF_RSN_REPLAY_LEN];
|
||||
+};
|
||||
+
|
||||
#endif /* FWIL_TYPES_H_ */
|
||||
@ -0,0 +1,385 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:04 +0100
|
||||
Subject: [PATCH] brcmfmac: move platform data retrieval code to common
|
||||
|
||||
In preparation of module parameters for all devices the module
|
||||
platform data retrieval is moved from sdio to common. It is still
|
||||
only used for sdio devices.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -27,8 +27,6 @@
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
-#include <linux/platform_device.h>
|
||||
-#include <linux/platform_data/brcmfmac-sdio.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/errno.h>
|
||||
@@ -46,7 +44,6 @@
|
||||
#include "bus.h"
|
||||
#include "debug.h"
|
||||
#include "sdio.h"
|
||||
-#include "of.h"
|
||||
#include "core.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -106,18 +103,18 @@ static void brcmf_sdiod_dummy_irqhandler
|
||||
|
||||
int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
+ struct brcmfmac_sdio_platform_data *pdata;
|
||||
int ret = 0;
|
||||
u8 data;
|
||||
u32 addr, gpiocontrol;
|
||||
unsigned long flags;
|
||||
|
||||
- if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
|
||||
+ pdata = sdiodev->pdata;
|
||||
+ if ((pdata) && (pdata->oob_irq_supported)) {
|
||||
brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
|
||||
- sdiodev->pdata->oob_irq_nr);
|
||||
- ret = request_irq(sdiodev->pdata->oob_irq_nr,
|
||||
- brcmf_sdiod_oob_irqhandler,
|
||||
- sdiodev->pdata->oob_irq_flags,
|
||||
- "brcmf_oob_intr",
|
||||
+ pdata->oob_irq_nr);
|
||||
+ ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
|
||||
+ pdata->oob_irq_flags, "brcmf_oob_intr",
|
||||
&sdiodev->func[1]->dev);
|
||||
if (ret != 0) {
|
||||
brcmf_err("request_irq failed %d\n", ret);
|
||||
@@ -129,7 +126,7 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
sdiodev->irq_en = true;
|
||||
spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
|
||||
|
||||
- ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr);
|
||||
+ ret = enable_irq_wake(pdata->oob_irq_nr);
|
||||
if (ret != 0) {
|
||||
brcmf_err("enable_irq_wake failed %d\n", ret);
|
||||
return ret;
|
||||
@@ -158,7 +155,7 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
|
||||
/* redirect, configure and enable io for interrupt signal */
|
||||
data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
|
||||
- if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
|
||||
+ if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
|
||||
data |= SDIO_SEPINT_ACT_HI;
|
||||
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
|
||||
|
||||
@@ -176,9 +173,12 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
|
||||
int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
+ struct brcmfmac_sdio_platform_data *pdata;
|
||||
+
|
||||
brcmf_dbg(SDIO, "Entering\n");
|
||||
|
||||
- if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) {
|
||||
+ pdata = sdiodev->pdata;
|
||||
+ if ((pdata) && (pdata->oob_irq_supported)) {
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
|
||||
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
|
||||
@@ -187,11 +187,10 @@ int brcmf_sdiod_intr_unregister(struct b
|
||||
if (sdiodev->oob_irq_requested) {
|
||||
sdiodev->oob_irq_requested = false;
|
||||
if (sdiodev->irq_wake) {
|
||||
- disable_irq_wake(sdiodev->pdata->oob_irq_nr);
|
||||
+ disable_irq_wake(pdata->oob_irq_nr);
|
||||
sdiodev->irq_wake = false;
|
||||
}
|
||||
- free_irq(sdiodev->pdata->oob_irq_nr,
|
||||
- &sdiodev->func[1]->dev);
|
||||
+ free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
|
||||
sdiodev->irq_en = false;
|
||||
}
|
||||
} else {
|
||||
@@ -1103,8 +1102,6 @@ static const struct sdio_device_id brcmf
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||
|
||||
-static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
|
||||
-
|
||||
|
||||
static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev,
|
||||
int val)
|
||||
@@ -1167,10 +1164,7 @@ static int brcmf_ops_sdio_probe(struct s
|
||||
dev_set_drvdata(&func->dev, bus_if);
|
||||
dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
|
||||
sdiodev->dev = &sdiodev->func[1]->dev;
|
||||
- sdiodev->pdata = brcmfmac_sdio_pdata;
|
||||
-
|
||||
- if (!sdiodev->pdata)
|
||||
- brcmf_of_probe(sdiodev);
|
||||
+ sdiodev->pdata = brcmf_get_module_param(sdiodev->dev);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
|
||||
@@ -1296,7 +1290,7 @@ static const struct dev_pm_ops brcmf_sdi
|
||||
static struct sdio_driver brcmf_sdmmc_driver = {
|
||||
.probe = brcmf_ops_sdio_probe,
|
||||
.remove = brcmf_ops_sdio_remove,
|
||||
- .name = BRCMFMAC_SDIO_PDATA_NAME,
|
||||
+ .name = KBUILD_MODNAME,
|
||||
.id_table = brcmf_sdmmc_ids,
|
||||
.drv = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -1306,37 +1300,6 @@ static struct sdio_driver brcmf_sdmmc_dr
|
||||
},
|
||||
};
|
||||
|
||||
-static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
|
||||
-{
|
||||
- brcmf_dbg(SDIO, "Enter\n");
|
||||
-
|
||||
- brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
|
||||
-
|
||||
- if (brcmfmac_sdio_pdata->power_on)
|
||||
- brcmfmac_sdio_pdata->power_on();
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int brcmf_sdio_pd_remove(struct platform_device *pdev)
|
||||
-{
|
||||
- brcmf_dbg(SDIO, "Enter\n");
|
||||
-
|
||||
- if (brcmfmac_sdio_pdata->power_off)
|
||||
- brcmfmac_sdio_pdata->power_off();
|
||||
-
|
||||
- sdio_unregister_driver(&brcmf_sdmmc_driver);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static struct platform_driver brcmf_sdio_pd = {
|
||||
- .remove = brcmf_sdio_pd_remove,
|
||||
- .driver = {
|
||||
- .name = BRCMFMAC_SDIO_PDATA_NAME,
|
||||
- }
|
||||
-};
|
||||
-
|
||||
void brcmf_sdio_register(void)
|
||||
{
|
||||
int ret;
|
||||
@@ -1350,19 +1313,6 @@ void brcmf_sdio_exit(void)
|
||||
{
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
|
||||
- if (brcmfmac_sdio_pdata)
|
||||
- platform_driver_unregister(&brcmf_sdio_pd);
|
||||
- else
|
||||
- sdio_unregister_driver(&brcmf_sdmmc_driver);
|
||||
+ sdio_unregister_driver(&brcmf_sdmmc_driver);
|
||||
}
|
||||
|
||||
-void __init brcmf_sdio_init(void)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- brcmf_dbg(SDIO, "Enter\n");
|
||||
-
|
||||
- ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
|
||||
- if (ret == -ENODEV)
|
||||
- brcmf_dbg(SDIO, "No platform data available.\n");
|
||||
-}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "fwil_types.h"
|
||||
#include "tracepoint.h"
|
||||
#include "common.h"
|
||||
+#include "of.h"
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
@@ -79,6 +80,7 @@ module_param_named(ignore_probe_fail, br
|
||||
MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
|
||||
#endif
|
||||
|
||||
+static struct brcmfmac_sdio_platform_data *brcmfmac_pdata;
|
||||
struct brcmf_mp_global_t brcmf_mp_global;
|
||||
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
@@ -231,6 +233,13 @@ static void brcmf_mp_attach(void)
|
||||
BRCMF_FW_ALTPATH_LEN);
|
||||
}
|
||||
|
||||
+struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev)
|
||||
+{
|
||||
+ if (!brcmfmac_pdata)
|
||||
+ brcmf_of_probe(dev, &brcmfmac_pdata);
|
||||
+ return brcmfmac_pdata;
|
||||
+}
|
||||
+
|
||||
int brcmf_mp_device_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC);
|
||||
@@ -253,6 +262,35 @@ void brcmf_mp_device_detach(struct brcmf
|
||||
kfree(drvr->settings);
|
||||
}
|
||||
|
||||
+static int __init brcmf_common_pd_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ brcmf_dbg(INFO, "Enter\n");
|
||||
+
|
||||
+ brcmfmac_pdata = dev_get_platdata(&pdev->dev);
|
||||
+
|
||||
+ if (brcmfmac_pdata->power_on)
|
||||
+ brcmfmac_pdata->power_on();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_common_pd_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ brcmf_dbg(INFO, "Enter\n");
|
||||
+
|
||||
+ if (brcmfmac_pdata->power_off)
|
||||
+ brcmfmac_pdata->power_off();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver brcmf_pd = {
|
||||
+ .remove = brcmf_common_pd_remove,
|
||||
+ .driver = {
|
||||
+ .name = BRCMFMAC_SDIO_PDATA_NAME,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
static int __init brcmfmac_module_init(void)
|
||||
{
|
||||
int err;
|
||||
@@ -260,16 +298,21 @@ static int __init brcmfmac_module_init(v
|
||||
/* Initialize debug system first */
|
||||
brcmf_debugfs_init();
|
||||
|
||||
-#ifdef CPTCFG_BRCMFMAC_SDIO
|
||||
- brcmf_sdio_init();
|
||||
-#endif
|
||||
+ /* Get the platform data (if available) for our devices */
|
||||
+ err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe);
|
||||
+ if (err == -ENODEV)
|
||||
+ brcmf_dbg(INFO, "No platform data available.\n");
|
||||
+
|
||||
/* Initialize global module paramaters */
|
||||
brcmf_mp_attach();
|
||||
|
||||
/* Continue the initialization by registering the different busses */
|
||||
err = brcmf_core_init();
|
||||
- if (err)
|
||||
+ if (err) {
|
||||
brcmf_debugfs_exit();
|
||||
+ if (brcmfmac_pdata)
|
||||
+ platform_driver_unregister(&brcmf_pd);
|
||||
+ }
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -277,6 +320,8 @@ static int __init brcmfmac_module_init(v
|
||||
static void __exit brcmfmac_module_exit(void)
|
||||
{
|
||||
brcmf_core_exit();
|
||||
+ if (brcmfmac_pdata)
|
||||
+ platform_driver_unregister(&brcmf_pd);
|
||||
brcmf_debugfs_exit();
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef BRCMFMAC_COMMON_H
|
||||
#define BRCMFMAC_COMMON_H
|
||||
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/platform_data/brcmfmac-sdio.h>
|
||||
#include "fwil_types.h"
|
||||
|
||||
extern const u8 ALLFFMAC[ETH_ALEN];
|
||||
@@ -89,6 +91,7 @@ struct brcmf_mp_device {
|
||||
struct cc_translate *country_codes;
|
||||
};
|
||||
|
||||
+struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev);
|
||||
int brcmf_mp_device_attach(struct brcmf_pub *drvr);
|
||||
void brcmf_mp_device_detach(struct brcmf_pub *drvr);
|
||||
#ifdef DEBUG
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
@@ -16,17 +16,16 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
-#include <linux/mmc/card.h>
|
||||
-#include <linux/platform_data/brcmfmac-sdio.h>
|
||||
-#include <linux/mmc/sdio_func.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include "debug.h"
|
||||
-#include "sdio.h"
|
||||
+#include "core.h"
|
||||
+#include "common.h"
|
||||
+#include "of.h"
|
||||
|
||||
-void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
|
||||
+void
|
||||
+brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio)
|
||||
{
|
||||
- struct device *dev = sdiodev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
int irq;
|
||||
u32 irqf;
|
||||
@@ -35,12 +34,12 @@ void brcmf_of_probe(struct brcmf_sdio_de
|
||||
if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
|
||||
return;
|
||||
|
||||
- sdiodev->pdata = devm_kzalloc(dev, sizeof(*sdiodev->pdata), GFP_KERNEL);
|
||||
- if (!sdiodev->pdata)
|
||||
+ *sdio = devm_kzalloc(dev, sizeof(*sdio), GFP_KERNEL);
|
||||
+ if (!(*sdio))
|
||||
return;
|
||||
|
||||
if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
|
||||
- sdiodev->pdata->drive_strength = val;
|
||||
+ (*sdio)->drive_strength = val;
|
||||
|
||||
/* make sure there are interrupts defined in the node */
|
||||
if (!of_find_property(np, "interrupts", NULL))
|
||||
@@ -53,7 +52,7 @@ void brcmf_of_probe(struct brcmf_sdio_de
|
||||
}
|
||||
irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
|
||||
|
||||
- sdiodev->pdata->oob_irq_supported = true;
|
||||
- sdiodev->pdata->oob_irq_nr = irq;
|
||||
- sdiodev->pdata->oob_irq_flags = irqf;
|
||||
+ (*sdio)->oob_irq_supported = true;
|
||||
+ (*sdio)->oob_irq_nr = irq;
|
||||
+ (*sdio)->oob_irq_flags = irqf;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
|
||||
@@ -14,9 +14,11 @@
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef CONFIG_OF
|
||||
-void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev);
|
||||
+void
|
||||
+brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio);
|
||||
#else
|
||||
-static void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
|
||||
+static void brcmf_of_probe(struct device *dev,
|
||||
+ struct brcmfmac_sdio_platform_data **sdio)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
@ -0,0 +1,69 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:05 +0100
|
||||
Subject: [PATCH] brcmfmac: keep ARP and ND offload enabled during WOWL
|
||||
|
||||
Currently ARP and ND (IPv6 Neigbor Discovery) offload get disabled
|
||||
on entering suspend. However when firmwares support the wowl_cap
|
||||
iovar then these offload routines can be kept enabled as they
|
||||
will work during WOWL as well.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -3556,7 +3556,8 @@ static s32 brcmf_cfg80211_resume(struct
|
||||
brcmf_report_wowl_wakeind(wiphy, ifp);
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
|
||||
brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
|
||||
- brcmf_configure_arp_nd_offload(ifp, true);
|
||||
+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
|
||||
+ brcmf_configure_arp_nd_offload(ifp, true);
|
||||
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
|
||||
cfg->wowl.pre_pmmode);
|
||||
cfg->wowl.active = false;
|
||||
@@ -3580,7 +3581,8 @@ static void brcmf_configure_wowl(struct
|
||||
|
||||
brcmf_dbg(TRACE, "Suspend, wowl config.\n");
|
||||
|
||||
- brcmf_configure_arp_nd_offload(ifp, false);
|
||||
+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
|
||||
+ brcmf_configure_arp_nd_offload(ifp, false);
|
||||
brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
|
||||
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
@@ -147,6 +147,7 @@ void brcmf_feat_attach(struct brcmf_pub
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) {
|
||||
err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap);
|
||||
if (!err) {
|
||||
+ ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_WOWL_ARP_ND);
|
||||
if (wowl_cap & BRCMF_WOWL_PFN_FOUND)
|
||||
ifp->drvr->feat_flags |=
|
||||
BIT(BRCMF_FEAT_WOWL_ND);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
@@ -29,6 +29,7 @@
|
||||
* SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan.
|
||||
* WOWL_ND: WOWL net detect (PNO)
|
||||
* WOWL_GTK: (WOWL) GTK rekeying offload
|
||||
+ * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL.
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MBSS) \
|
||||
@@ -40,7 +41,8 @@
|
||||
BRCMF_FEAT_DEF(TDLS) \
|
||||
BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \
|
||||
BRCMF_FEAT_DEF(WOWL_ND) \
|
||||
- BRCMF_FEAT_DEF(WOWL_GTK)
|
||||
+ BRCMF_FEAT_DEF(WOWL_GTK) \
|
||||
+ BRCMF_FEAT_DEF(WOWL_ARP_ND)
|
||||
|
||||
/*
|
||||
* Quirks:
|
||||
@ -0,0 +1,734 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:07 +0100
|
||||
Subject: [PATCH] brcmfmac: switch to new platform data
|
||||
|
||||
Platform data is only available for sdio. With this patch a new
|
||||
platform data structure is being used which allows for platform
|
||||
data for any device and configurable per device. This patch only
|
||||
switches to the new structure and adds support for SDIO devices.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -103,7 +103,7 @@ static void brcmf_sdiod_dummy_irqhandler
|
||||
|
||||
int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
- struct brcmfmac_sdio_platform_data *pdata;
|
||||
+ struct brcmfmac_sdio_pd *pdata;
|
||||
int ret = 0;
|
||||
u8 data;
|
||||
u32 addr, gpiocontrol;
|
||||
@@ -173,7 +173,7 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
|
||||
int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
- struct brcmfmac_sdio_platform_data *pdata;
|
||||
+ struct brcmfmac_sdio_pd *pdata;
|
||||
|
||||
brcmf_dbg(SDIO, "Entering\n");
|
||||
|
||||
@@ -1164,17 +1164,6 @@ static int brcmf_ops_sdio_probe(struct s
|
||||
dev_set_drvdata(&func->dev, bus_if);
|
||||
dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
|
||||
sdiodev->dev = &sdiodev->func[1]->dev;
|
||||
- sdiodev->pdata = brcmf_get_module_param(sdiodev->dev);
|
||||
-
|
||||
-#ifdef CONFIG_PM_SLEEP
|
||||
- /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
|
||||
- * is true or when platform data OOB irq is true).
|
||||
- */
|
||||
- if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
|
||||
- ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
|
||||
- (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)))
|
||||
- bus_if->wowl_supported = true;
|
||||
-#endif
|
||||
|
||||
brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6459,8 +6459,8 @@ int brcmf_cfg80211_wait_vif_event(struct
|
||||
static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
|
||||
struct brcmf_fil_country_le *ccreq)
|
||||
{
|
||||
- struct cc_translate *country_codes;
|
||||
- struct cc_entry *cc;
|
||||
+ struct brcmfmac_pd_cc *country_codes;
|
||||
+ struct brcmfmac_pd_cc_entry *cc;
|
||||
s32 found_index;
|
||||
int i;
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -80,7 +80,7 @@ module_param_named(ignore_probe_fail, br
|
||||
MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
|
||||
#endif
|
||||
|
||||
-static struct brcmfmac_sdio_platform_data *brcmfmac_pdata;
|
||||
+static struct brcmfmac_platform_data *brcmfmac_pdata;
|
||||
struct brcmf_mp_global_t brcmf_mp_global;
|
||||
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
@@ -229,15 +229,46 @@ void __brcmf_dbg(u32 level, const char *
|
||||
|
||||
static void brcmf_mp_attach(void)
|
||||
{
|
||||
+ /* If module param firmware path is set then this will always be used,
|
||||
+ * if not set then if available use the platform data version. To make
|
||||
+ * sure it gets initialized at all, always copy the module param version
|
||||
+ */
|
||||
strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
|
||||
BRCMF_FW_ALTPATH_LEN);
|
||||
+ if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) &&
|
||||
+ (brcmf_mp_global.firmware_path[0] == '\0')) {
|
||||
+ strlcpy(brcmf_mp_global.firmware_path,
|
||||
+ brcmfmac_pdata->fw_alternative_path,
|
||||
+ BRCMF_FW_ALTPATH_LEN);
|
||||
+ }
|
||||
}
|
||||
|
||||
-struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev)
|
||||
-{
|
||||
- if (!brcmfmac_pdata)
|
||||
- brcmf_of_probe(dev, &brcmfmac_pdata);
|
||||
- return brcmfmac_pdata;
|
||||
+struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev,
|
||||
+ enum brcmf_bus_type bus_type,
|
||||
+ u32 chip, u32 chiprev)
|
||||
+{
|
||||
+ struct brcmfmac_sdio_pd *pdata;
|
||||
+ struct brcmfmac_pd_device *device_pd;
|
||||
+ int i;
|
||||
+
|
||||
+ if (brcmfmac_pdata) {
|
||||
+ for (i = 0; i < brcmfmac_pdata->device_count; i++) {
|
||||
+ device_pd = &brcmfmac_pdata->devices[i];
|
||||
+ if ((device_pd->bus_type == bus_type) &&
|
||||
+ (device_pd->id == chip) &&
|
||||
+ ((device_pd->rev == chiprev) ||
|
||||
+ (device_pd->rev == -1))) {
|
||||
+ brcmf_dbg(INFO, "Platform data for device found\n");
|
||||
+ if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO)
|
||||
+ return &device_pd->bus.sdio;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ pdata = NULL;
|
||||
+ brcmf_of_probe(dev, &pdata);
|
||||
+
|
||||
+ return pdata;
|
||||
}
|
||||
|
||||
int brcmf_mp_device_attach(struct brcmf_pub *drvr)
|
||||
@@ -287,7 +318,7 @@ static int brcmf_common_pd_remove(struct
|
||||
static struct platform_driver brcmf_pd = {
|
||||
.remove = brcmf_common_pd_remove,
|
||||
.driver = {
|
||||
- .name = BRCMFMAC_SDIO_PDATA_NAME,
|
||||
+ .name = BRCMFMAC_PDATA_NAME,
|
||||
}
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -16,7 +16,7 @@
|
||||
#define BRCMFMAC_COMMON_H
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
-#include <linux/platform_data/brcmfmac-sdio.h>
|
||||
+#include <linux/platform_data/brcmfmac.h>
|
||||
#include "fwil_types.h"
|
||||
|
||||
extern const u8 ALLFFMAC[ETH_ALEN];
|
||||
@@ -43,33 +43,6 @@ struct brcmf_mp_global_t {
|
||||
extern struct brcmf_mp_global_t brcmf_mp_global;
|
||||
|
||||
/**
|
||||
- * struct cc_entry - Struct for translating user space country code (iso3166) to
|
||||
- * firmware country code and revision.
|
||||
- *
|
||||
- * @iso3166: iso3166 alpha 2 country code string.
|
||||
- * @cc: firmware country code string.
|
||||
- * @rev: firmware country code revision.
|
||||
- */
|
||||
-struct cc_entry {
|
||||
- char iso3166[BRCMF_COUNTRY_BUF_SZ];
|
||||
- char cc[BRCMF_COUNTRY_BUF_SZ];
|
||||
- s32 rev;
|
||||
-};
|
||||
-
|
||||
-/**
|
||||
- * struct cc_translate - Struct for translating country codes as set by user
|
||||
- * space to a country code and rev which can be used by
|
||||
- * firmware.
|
||||
- *
|
||||
- * @table_size: number of entries in table (> 0)
|
||||
- * @table: dynamic array of 1 or more elements with translation information.
|
||||
- */
|
||||
-struct cc_translate {
|
||||
- int table_size;
|
||||
- struct cc_entry table[0];
|
||||
-};
|
||||
-
|
||||
-/**
|
||||
* struct brcmf_mp_device - Device module paramaters.
|
||||
*
|
||||
* @sdiod_txglomsz: SDIO txglom size.
|
||||
@@ -88,10 +61,12 @@ struct brcmf_mp_device {
|
||||
int fcmode;
|
||||
bool roamoff;
|
||||
bool ignore_probe_fail;
|
||||
- struct cc_translate *country_codes;
|
||||
+ struct brcmfmac_pd_cc *country_codes;
|
||||
};
|
||||
|
||||
-struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev);
|
||||
+struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev,
|
||||
+ enum brcmf_bus_type bus_type,
|
||||
+ u32 chip, u32 chiprev);
|
||||
int brcmf_mp_device_attach(struct brcmf_pub *drvr);
|
||||
void brcmf_mp_device_detach(struct brcmf_pub *drvr);
|
||||
#ifdef DEBUG
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
@@ -23,8 +23,7 @@
|
||||
#include "common.h"
|
||||
#include "of.h"
|
||||
|
||||
-void
|
||||
-brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio)
|
||||
+void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
int irq;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
|
||||
@@ -15,10 +15,9 @@
|
||||
*/
|
||||
#ifdef CONFIG_OF
|
||||
void
|
||||
-brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio);
|
||||
+brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio);
|
||||
#else
|
||||
-static void brcmf_of_probe(struct device *dev,
|
||||
- struct brcmfmac_sdio_platform_data **sdio)
|
||||
+static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -33,8 +33,6 @@
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
-#include <linux/platform_data/brcmfmac-sdio.h>
|
||||
-#include <linux/moduleparam.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <defs.h>
|
||||
#include <brcmu_wifi.h>
|
||||
@@ -44,6 +42,8 @@
|
||||
#include "sdio.h"
|
||||
#include "chip.h"
|
||||
#include "firmware.h"
|
||||
+#include "core.h"
|
||||
+#include "common.h"
|
||||
|
||||
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
|
||||
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
|
||||
@@ -3775,26 +3775,28 @@ static const struct brcmf_buscore_ops br
|
||||
static bool
|
||||
brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
|
||||
{
|
||||
+ struct brcmf_sdio_dev *sdiodev;
|
||||
u8 clkctl = 0;
|
||||
int err = 0;
|
||||
int reg_addr;
|
||||
u32 reg_val;
|
||||
u32 drivestrength;
|
||||
|
||||
- sdio_claim_host(bus->sdiodev->func[1]);
|
||||
+ sdiodev = bus->sdiodev;
|
||||
+ sdio_claim_host(sdiodev->func[1]);
|
||||
|
||||
pr_debug("F1 signature read @0x18000000=0x%4x\n",
|
||||
- brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));
|
||||
+ brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL));
|
||||
|
||||
/*
|
||||
* Force PLL off until brcmf_chip_attach()
|
||||
* programs PLL control regs
|
||||
*/
|
||||
|
||||
- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
BRCMF_INIT_CLKCTL1, &err);
|
||||
if (!err)
|
||||
- clkctl = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
+ clkctl = brcmf_sdiod_regrb(sdiodev,
|
||||
SBSDIO_FUNC1_CHIPCLKCSR, &err);
|
||||
|
||||
if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
|
||||
@@ -3803,50 +3805,77 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops);
|
||||
+ bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops);
|
||||
if (IS_ERR(bus->ci)) {
|
||||
brcmf_err("brcmf_chip_attach failed!\n");
|
||||
bus->ci = NULL;
|
||||
goto fail;
|
||||
}
|
||||
+ sdiodev->pdata = brcmf_get_module_param(sdiodev->dev,
|
||||
+ BRCMF_BUSTYPE_SDIO,
|
||||
+ bus->ci->chip,
|
||||
+ bus->ci->chiprev);
|
||||
+ /* platform specific configuration:
|
||||
+ * alignments must be at least 4 bytes for ADMA
|
||||
+ */
|
||||
+ bus->head_align = ALIGNMENT;
|
||||
+ bus->sgentry_align = ALIGNMENT;
|
||||
+ if (sdiodev->pdata) {
|
||||
+ if (sdiodev->pdata->sd_head_align > ALIGNMENT)
|
||||
+ bus->head_align = sdiodev->pdata->sd_head_align;
|
||||
+ if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
|
||||
+ bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
|
||||
+ }
|
||||
+ /* allocate scatter-gather table. sg support
|
||||
+ * will be disabled upon allocation failure.
|
||||
+ */
|
||||
+ brcmf_sdiod_sgtable_alloc(sdiodev);
|
||||
+
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+ /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
|
||||
+ * is true or when platform data OOB irq is true).
|
||||
+ */
|
||||
+ if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
|
||||
+ ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
|
||||
+ (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)))
|
||||
+ sdiodev->bus_if->wowl_supported = true;
|
||||
+#endif
|
||||
|
||||
if (brcmf_sdio_kso_init(bus)) {
|
||||
brcmf_err("error enabling KSO\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if ((bus->sdiodev->pdata) && (bus->sdiodev->pdata->drive_strength))
|
||||
- drivestrength = bus->sdiodev->pdata->drive_strength;
|
||||
+ if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength))
|
||||
+ drivestrength = sdiodev->pdata->drive_strength;
|
||||
else
|
||||
drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
|
||||
- brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
|
||||
+ brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength);
|
||||
|
||||
/* Set card control so an SDIO card reset does a WLAN backplane reset */
|
||||
- reg_val = brcmf_sdiod_regrb(bus->sdiodev,
|
||||
- SDIO_CCCR_BRCM_CARDCTRL, &err);
|
||||
+ reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET;
|
||||
|
||||
- brcmf_sdiod_regwb(bus->sdiodev,
|
||||
- SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
|
||||
+ brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
/* set PMUControl so a backplane reset does PMU state reload */
|
||||
reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol);
|
||||
- reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err);
|
||||
+ reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
|
||||
|
||||
- brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err);
|
||||
+ brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
- sdio_release_host(bus->sdiodev->func[1]);
|
||||
+ sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
|
||||
|
||||
@@ -3867,7 +3896,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
return true;
|
||||
|
||||
fail:
|
||||
- sdio_release_host(bus->sdiodev->func[1]);
|
||||
+ sdio_release_host(sdiodev->func[1]);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4045,18 +4074,6 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
|
||||
bus->txminmax = BRCMF_TXMINMAX;
|
||||
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
|
||||
|
||||
- /* platform specific configuration:
|
||||
- * alignments must be at least 4 bytes for ADMA
|
||||
- */
|
||||
- bus->head_align = ALIGNMENT;
|
||||
- bus->sgentry_align = ALIGNMENT;
|
||||
- if (sdiodev->pdata) {
|
||||
- if (sdiodev->pdata->sd_head_align > ALIGNMENT)
|
||||
- bus->head_align = sdiodev->pdata->sd_head_align;
|
||||
- if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
|
||||
- bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
|
||||
- }
|
||||
-
|
||||
/* single-threaded workqueue */
|
||||
wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
|
||||
dev_name(&sdiodev->func[1]->dev));
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -184,7 +184,7 @@ struct brcmf_sdio_dev {
|
||||
struct brcmf_sdio *bus;
|
||||
struct device *dev;
|
||||
struct brcmf_bus *bus_if;
|
||||
- struct brcmfmac_sdio_platform_data *pdata;
|
||||
+ struct brcmfmac_sdio_pd *pdata;
|
||||
bool oob_irq_requested;
|
||||
bool irq_en; /* irq enable flags */
|
||||
spinlock_t irq_en_lock;
|
||||
--- a/include/linux/platform_data/brcmfmac-sdio.h
|
||||
+++ /dev/null
|
||||
@@ -1,135 +0,0 @@
|
||||
-/*
|
||||
- * Copyright (c) 2013 Broadcom Corporation
|
||||
- *
|
||||
- * Permission to use, copy, modify, and/or distribute this software for any
|
||||
- * purpose with or without fee is hereby granted, provided that the above
|
||||
- * copyright notice and this permission notice appear in all copies.
|
||||
- *
|
||||
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
- */
|
||||
-
|
||||
-#ifndef _LINUX_BRCMFMAC_PLATFORM_H
|
||||
-#define _LINUX_BRCMFMAC_PLATFORM_H
|
||||
-
|
||||
-/*
|
||||
- * Platform specific driver functions and data. Through the platform specific
|
||||
- * device data functions can be provided to help the brcmfmac driver to
|
||||
- * operate with the device in combination with the used platform.
|
||||
- *
|
||||
- * Use the platform data in the following (similar) way:
|
||||
- *
|
||||
- *
|
||||
-#include <brcmfmac_platform.h>
|
||||
-
|
||||
-
|
||||
-static void brcmfmac_power_on(void)
|
||||
-{
|
||||
-}
|
||||
-
|
||||
-static void brcmfmac_power_off(void)
|
||||
-{
|
||||
-}
|
||||
-
|
||||
-static void brcmfmac_reset(void)
|
||||
-{
|
||||
-}
|
||||
-
|
||||
-static struct brcmfmac_sdio_platform_data brcmfmac_sdio_pdata = {
|
||||
- .power_on = brcmfmac_power_on,
|
||||
- .power_off = brcmfmac_power_off,
|
||||
- .reset = brcmfmac_reset
|
||||
-};
|
||||
-
|
||||
-static struct platform_device brcmfmac_device = {
|
||||
- .name = BRCMFMAC_SDIO_PDATA_NAME,
|
||||
- .id = PLATFORM_DEVID_NONE,
|
||||
- .dev.platform_data = &brcmfmac_sdio_pdata
|
||||
-};
|
||||
-
|
||||
-void __init brcmfmac_init_pdata(void)
|
||||
-{
|
||||
- brcmfmac_sdio_pdata.oob_irq_supported = true;
|
||||
- brcmfmac_sdio_pdata.oob_irq_nr = gpio_to_irq(GPIO_BRCMF_SDIO_OOB);
|
||||
- brcmfmac_sdio_pdata.oob_irq_flags = IORESOURCE_IRQ |
|
||||
- IORESOURCE_IRQ_HIGHLEVEL;
|
||||
- platform_device_register(&brcmfmac_device);
|
||||
-}
|
||||
- *
|
||||
- *
|
||||
- * Note: the brcmfmac can be loaded as module or be statically built-in into
|
||||
- * the kernel. If built-in then do note that it uses module_init (and
|
||||
- * module_exit) routines which equal device_initcall. So if you intend to
|
||||
- * create a module with the platform specific data for the brcmfmac and have
|
||||
- * it built-in to the kernel then use a higher initcall then device_initcall
|
||||
- * (see init.h). If this is not done then brcmfmac will load without problems
|
||||
- * but will not pickup the platform data.
|
||||
- *
|
||||
- * When the driver does not "detect" platform driver data then it will continue
|
||||
- * without reporting anything and just assume there is no data needed. Which is
|
||||
- * probably true for most platforms.
|
||||
- *
|
||||
- * Explanation of the platform_data fields:
|
||||
- *
|
||||
- * drive_strength: is the preferred drive_strength to be used for the SDIO
|
||||
- * pins. If 0 then a default value will be used. This is the target drive
|
||||
- * strength, the exact drive strength which will be used depends on the
|
||||
- * capabilities of the device.
|
||||
- *
|
||||
- * oob_irq_supported: does the board have support for OOB interrupts. SDIO
|
||||
- * in-band interrupts are relatively slow and for having less overhead on
|
||||
- * interrupt processing an out of band interrupt can be used. If the HW
|
||||
- * supports this then enable this by setting this field to true and configure
|
||||
- * the oob related fields.
|
||||
- *
|
||||
- * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are
|
||||
- * used for registering the irq using request_irq function.
|
||||
- *
|
||||
- * broken_sg_support: flag for broken sg list support of SDIO host controller.
|
||||
- * Set this to true if the SDIO host controller has higher align requirement
|
||||
- * than 32 bytes for each scatterlist item.
|
||||
- *
|
||||
- * sd_head_align: alignment requirement for start of data buffer
|
||||
- *
|
||||
- * sd_sgentry_align: length alignment requirement for each sg entry
|
||||
- *
|
||||
- * power_on: This function is called by the brcmfmac when the module gets
|
||||
- * loaded. This can be particularly useful for low power devices. The platform
|
||||
- * spcific routine may for example decide to power up the complete device.
|
||||
- * If there is no use-case for this function then provide NULL.
|
||||
- *
|
||||
- * power_off: This function is called by the brcmfmac when the module gets
|
||||
- * unloaded. At this point the device can be powered down or otherwise be reset.
|
||||
- * So if an actual power_off is not supported but reset is then reset the device
|
||||
- * when this function gets called. This can be particularly useful for low power
|
||||
- * devices. If there is no use-case for this function (either power-down or
|
||||
- * reset) then provide NULL.
|
||||
- *
|
||||
- * reset: This function can get called if the device communication broke down.
|
||||
- * This functionality is particularly useful in case of SDIO type devices. It is
|
||||
- * possible to reset a dongle via sdio data interface, but it requires that
|
||||
- * this is fully functional. This function is chip/module specific and this
|
||||
- * function should return only after the complete reset has completed.
|
||||
- */
|
||||
-
|
||||
-#define BRCMFMAC_SDIO_PDATA_NAME "brcmfmac_sdio"
|
||||
-
|
||||
-struct brcmfmac_sdio_platform_data {
|
||||
- unsigned int drive_strength;
|
||||
- bool oob_irq_supported;
|
||||
- unsigned int oob_irq_nr;
|
||||
- unsigned long oob_irq_flags;
|
||||
- bool broken_sg_support;
|
||||
- unsigned short sd_head_align;
|
||||
- unsigned short sd_sgentry_align;
|
||||
- void (*power_on)(void);
|
||||
- void (*power_off)(void);
|
||||
- void (*reset)(void);
|
||||
-};
|
||||
-
|
||||
-#endif /* _LINUX_BRCMFMAC_PLATFORM_H */
|
||||
--- /dev/null
|
||||
+++ b/include/linux/platform_data/brcmfmac.h
|
||||
@@ -0,0 +1,185 @@
|
||||
+/*
|
||||
+ * Copyright (c) 201 Broadcom Corporation
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LINUX_BRCMFMAC_PLATFORM_H
|
||||
+#define _LINUX_BRCMFMAC_PLATFORM_H
|
||||
+
|
||||
+
|
||||
+#define BRCMFMAC_PDATA_NAME "brcmfmac"
|
||||
+
|
||||
+#define BRCMFMAC_COUNTRY_BUF_SZ 4
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Platform specific driver functions and data. Through the platform specific
|
||||
+ * device data functions and data can be provided to help the brcmfmac driver to
|
||||
+ * operate with the device in combination with the used platform.
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * Note: the brcmfmac can be loaded as module or be statically built-in into
|
||||
+ * the kernel. If built-in then do note that it uses module_init (and
|
||||
+ * module_exit) routines which equal device_initcall. So if you intend to
|
||||
+ * create a module with the platform specific data for the brcmfmac and have
|
||||
+ * it built-in to the kernel then use a higher initcall then device_initcall
|
||||
+ * (see init.h). If this is not done then brcmfmac will load without problems
|
||||
+ * but will not pickup the platform data.
|
||||
+ *
|
||||
+ * When the driver does not "detect" platform driver data then it will continue
|
||||
+ * without reporting anything and just assume there is no data needed. Which is
|
||||
+ * probably true for most platforms.
|
||||
+ */
|
||||
+
|
||||
+/**
|
||||
+ * enum brcmf_bus_type - Bus type identifier. Currently SDIO, USB and PCIE are
|
||||
+ * supported.
|
||||
+ */
|
||||
+enum brcmf_bus_type {
|
||||
+ BRCMF_BUSTYPE_SDIO,
|
||||
+ BRCMF_BUSTYPE_USB,
|
||||
+ BRCMF_BUSTYPE_PCIE
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * struct brcmfmac_sdio_pd - SDIO Device specific platform data.
|
||||
+ *
|
||||
+ * @txglomsz: SDIO txglom size. Use 0 if default of driver is to be
|
||||
+ * used.
|
||||
+ * @drive_strength: is the preferred drive_strength to be used for the SDIO
|
||||
+ * pins. If 0 then a default value will be used. This is
|
||||
+ * the target drive strength, the exact drive strength
|
||||
+ * which will be used depends on the capabilities of the
|
||||
+ * device.
|
||||
+ * @oob_irq_supported: does the board have support for OOB interrupts. SDIO
|
||||
+ * in-band interrupts are relatively slow and for having
|
||||
+ * less overhead on interrupt processing an out of band
|
||||
+ * interrupt can be used. If the HW supports this then
|
||||
+ * enable this by setting this field to true and configure
|
||||
+ * the oob related fields.
|
||||
+ * @oob_irq_nr,
|
||||
+ * @oob_irq_flags: the OOB interrupt information. The values are used for
|
||||
+ * registering the irq using request_irq function.
|
||||
+ * @broken_sg_support: flag for broken sg list support of SDIO host controller.
|
||||
+ * Set this to true if the SDIO host controller has higher
|
||||
+ * align requirement than 32 bytes for each scatterlist
|
||||
+ * item.
|
||||
+ * @sd_head_align: alignment requirement for start of data buffer.
|
||||
+ * @sd_sgentry_align: length alignment requirement for each sg entry.
|
||||
+ * @reset: This function can get called if the device communication
|
||||
+ * broke down. This functionality is particularly useful in
|
||||
+ * case of SDIO type devices. It is possible to reset a
|
||||
+ * dongle via sdio data interface, but it requires that
|
||||
+ * this is fully functional. This function is chip/module
|
||||
+ * specific and this function should return only after the
|
||||
+ * complete reset has completed.
|
||||
+ */
|
||||
+struct brcmfmac_sdio_pd {
|
||||
+ int txglomsz;
|
||||
+ unsigned int drive_strength;
|
||||
+ bool oob_irq_supported;
|
||||
+ unsigned int oob_irq_nr;
|
||||
+ unsigned long oob_irq_flags;
|
||||
+ bool broken_sg_support;
|
||||
+ unsigned short sd_head_align;
|
||||
+ unsigned short sd_sgentry_align;
|
||||
+ void (*reset)(void);
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct brcmfmac_pd_cc_entry - Struct for translating user space country code
|
||||
+ * (iso3166) to firmware country code and
|
||||
+ * revision.
|
||||
+ *
|
||||
+ * @iso3166: iso3166 alpha 2 country code string.
|
||||
+ * @cc: firmware country code string.
|
||||
+ * @rev: firmware country code revision.
|
||||
+ */
|
||||
+struct brcmfmac_pd_cc_entry {
|
||||
+ char iso3166[BRCMFMAC_COUNTRY_BUF_SZ];
|
||||
+ char cc[BRCMFMAC_COUNTRY_BUF_SZ];
|
||||
+ s32 rev;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct brcmfmac_pd_cc - Struct for translating country codes as set by user
|
||||
+ * space to a country code and rev which can be used by
|
||||
+ * firmware.
|
||||
+ *
|
||||
+ * @table_size: number of entries in table (> 0)
|
||||
+ * @table: array of 1 or more elements with translation information.
|
||||
+ */
|
||||
+struct brcmfmac_pd_cc {
|
||||
+ int table_size;
|
||||
+ struct brcmfmac_pd_cc_entry table[0];
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct brcmfmac_pd_device - Device specific platform data. (id/rev/bus_type)
|
||||
+ * is the unique identifier of the device.
|
||||
+ *
|
||||
+ * @id: ID of the device for which this data is. In case of SDIO
|
||||
+ * or PCIE this is the chipid as identified by chip.c In
|
||||
+ * case of USB this is the chipid as identified by the
|
||||
+ * device query.
|
||||
+ * @rev: chip revision, see id.
|
||||
+ * @bus_type: The type of bus. Some chipid/rev exist for different bus
|
||||
+ * types. Each bus type has its own set of settings.
|
||||
+ * @feature_disable: Bitmask of features to disable (override), See feature.c
|
||||
+ * in brcmfmac for details.
|
||||
+ * @country_codes: If available, pointer to struct for translating country
|
||||
+ * codes.
|
||||
+ * @bus: Bus specific (union) device settings. Currently only
|
||||
+ * SDIO.
|
||||
+ */
|
||||
+struct brcmfmac_pd_device {
|
||||
+ unsigned int id;
|
||||
+ unsigned int rev;
|
||||
+ enum brcmf_bus_type bus_type;
|
||||
+ unsigned int feature_disable;
|
||||
+ struct brcmfmac_pd_cc *country_codes;
|
||||
+ union {
|
||||
+ struct brcmfmac_sdio_pd sdio;
|
||||
+ } bus;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct brcmfmac_platform_data - BRCMFMAC specific platform data.
|
||||
+ *
|
||||
+ * @power_on: This function is called by the brcmfmac driver when the module
|
||||
+ * gets loaded. This can be particularly useful for low power
|
||||
+ * devices. The platform spcific routine may for example decide to
|
||||
+ * power up the complete device. If there is no use-case for this
|
||||
+ * function then provide NULL.
|
||||
+ * @power_off: This function is called by the brcmfmac when the module gets
|
||||
+ * unloaded. At this point the devices can be powered down or
|
||||
+ * otherwise be reset. So if an actual power_off is not supported
|
||||
+ * but reset is supported by the devices then reset the devices
|
||||
+ * when this function gets called. This can be particularly useful
|
||||
+ * for low power devices. If there is no use-case for this
|
||||
+ * function then provide NULL.
|
||||
+ */
|
||||
+struct brcmfmac_platform_data {
|
||||
+ void (*power_on)(void);
|
||||
+ void (*power_off)(void);
|
||||
+ char *fw_alternative_path;
|
||||
+ int device_count;
|
||||
+ struct brcmfmac_pd_device devices[0];
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#endif /* _LINUX_BRCMFMAC_PLATFORM_H */
|
||||
@ -0,0 +1,607 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:08 +0100
|
||||
Subject: [PATCH] brcmfmac: merge platform data and module paramaters
|
||||
|
||||
Merge module parameters and platform data in one struct. This is the
|
||||
last step to move to the new platform data per device. Now parameters
|
||||
of platform data will be merged with module parameters per device.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -109,8 +109,8 @@ int brcmf_sdiod_intr_register(struct brc
|
||||
u32 addr, gpiocontrol;
|
||||
unsigned long flags;
|
||||
|
||||
- pdata = sdiodev->pdata;
|
||||
- if ((pdata) && (pdata->oob_irq_supported)) {
|
||||
+ pdata = &sdiodev->settings->bus.sdio;
|
||||
+ if (pdata->oob_irq_supported) {
|
||||
brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
|
||||
pdata->oob_irq_nr);
|
||||
ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
|
||||
@@ -177,8 +177,8 @@ int brcmf_sdiod_intr_unregister(struct b
|
||||
|
||||
brcmf_dbg(SDIO, "Entering\n");
|
||||
|
||||
- pdata = sdiodev->pdata;
|
||||
- if ((pdata) && (pdata->oob_irq_supported)) {
|
||||
+ pdata = &sdiodev->settings->bus.sdio;
|
||||
+ if (pdata->oob_irq_supported) {
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
|
||||
brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
|
||||
@@ -522,7 +522,7 @@ static int brcmf_sdiod_sglist_rw(struct
|
||||
target_list = pktlist;
|
||||
/* for host with broken sg support, prepare a page aligned list */
|
||||
__skb_queue_head_init(&local_list);
|
||||
- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
|
||||
+ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) {
|
||||
req_sz = 0;
|
||||
skb_queue_walk(pktlist, pkt_next)
|
||||
req_sz += pkt_next->len;
|
||||
@@ -629,7 +629,7 @@ static int brcmf_sdiod_sglist_rw(struct
|
||||
}
|
||||
}
|
||||
|
||||
- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
|
||||
+ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) {
|
||||
local_pkt_next = local_list.next;
|
||||
orig_offset = 0;
|
||||
skb_queue_walk(pktlist, pkt_next) {
|
||||
@@ -900,7 +900,7 @@ void brcmf_sdiod_sgtable_alloc(struct br
|
||||
return;
|
||||
|
||||
nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE,
|
||||
- sdiodev->bus_if->drvr->settings->sdiod_txglomsz);
|
||||
+ sdiodev->settings->bus.sdio.txglomsz);
|
||||
nents += (nents >> 4) + 1;
|
||||
|
||||
WARN_ON(nents > sdiodev->max_segment_count);
|
||||
@@ -912,7 +912,7 @@ void brcmf_sdiod_sgtable_alloc(struct br
|
||||
sdiodev->sg_support = false;
|
||||
}
|
||||
|
||||
- sdiodev->txglomsz = sdiodev->bus_if->drvr->settings->sdiod_txglomsz;
|
||||
+ sdiodev->txglomsz = sdiodev->settings->bus.sdio.txglomsz;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -1246,8 +1246,8 @@ static int brcmf_ops_sdio_suspend(struct
|
||||
|
||||
sdio_flags = MMC_PM_KEEP_POWER;
|
||||
if (sdiodev->wowl_enabled) {
|
||||
- if (sdiodev->pdata->oob_irq_supported)
|
||||
- enable_irq_wake(sdiodev->pdata->oob_irq_nr);
|
||||
+ if (sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
+ enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
else
|
||||
sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
@@ -43,6 +43,8 @@ enum brcmf_bus_protocol_type {
|
||||
BRCMF_PROTO_MSGBUF
|
||||
};
|
||||
|
||||
+struct brcmf_mp_device;
|
||||
+
|
||||
struct brcmf_bus_dcmd {
|
||||
char *name;
|
||||
char *param;
|
||||
@@ -217,7 +219,7 @@ bool brcmf_c_prec_enq(struct device *dev
|
||||
void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
|
||||
|
||||
/* Indication from bus module regarding presence/insertion of dongle. */
|
||||
-int brcmf_attach(struct device *dev);
|
||||
+int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
|
||||
/* Indication from bus module regarding removal/absence of dongle */
|
||||
void brcmf_detach(struct device *dev);
|
||||
/* Indication from bus module that dongle should be reset */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -243,14 +243,35 @@ static void brcmf_mp_attach(void)
|
||||
}
|
||||
}
|
||||
|
||||
-struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev,
|
||||
- enum brcmf_bus_type bus_type,
|
||||
- u32 chip, u32 chiprev)
|
||||
+struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
|
||||
+ enum brcmf_bus_type bus_type,
|
||||
+ u32 chip, u32 chiprev)
|
||||
{
|
||||
- struct brcmfmac_sdio_pd *pdata;
|
||||
+ struct brcmf_mp_device *settings;
|
||||
struct brcmfmac_pd_device *device_pd;
|
||||
+ bool found;
|
||||
int i;
|
||||
|
||||
+ brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip,
|
||||
+ chiprev);
|
||||
+ settings = kzalloc(sizeof(*settings), GFP_ATOMIC);
|
||||
+ if (!settings)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* start by using the module paramaters */
|
||||
+ settings->p2p_enable = !!brcmf_p2p_enable;
|
||||
+ settings->feature_disable = brcmf_feature_disable;
|
||||
+ settings->fcmode = brcmf_fcmode;
|
||||
+ settings->roamoff = !!brcmf_roamoff;
|
||||
+#ifdef DEBUG
|
||||
+ settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
|
||||
+#endif
|
||||
+
|
||||
+ if (bus_type == BRCMF_BUSTYPE_SDIO)
|
||||
+ settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz;
|
||||
+
|
||||
+ /* See if there is any device specific platform data configured */
|
||||
+ found = false;
|
||||
if (brcmfmac_pdata) {
|
||||
for (i = 0; i < brcmfmac_pdata->device_count; i++) {
|
||||
device_pd = &brcmfmac_pdata->devices[i];
|
||||
@@ -259,38 +280,29 @@ struct brcmfmac_sdio_pd *brcmf_get_modul
|
||||
((device_pd->rev == chiprev) ||
|
||||
(device_pd->rev == -1))) {
|
||||
brcmf_dbg(INFO, "Platform data for device found\n");
|
||||
+ settings->country_codes =
|
||||
+ device_pd->country_codes;
|
||||
if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO)
|
||||
- return &device_pd->bus.sdio;
|
||||
+ memcpy(&settings->bus.sdio,
|
||||
+ &device_pd->bus.sdio,
|
||||
+ sizeof(settings->bus.sdio));
|
||||
+ found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- pdata = NULL;
|
||||
- brcmf_of_probe(dev, &pdata);
|
||||
-
|
||||
- return pdata;
|
||||
-}
|
||||
-
|
||||
-int brcmf_mp_device_attach(struct brcmf_pub *drvr)
|
||||
-{
|
||||
- drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC);
|
||||
- if (!drvr->settings)
|
||||
- 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;
|
||||
-#ifdef DEBUG
|
||||
- drvr->settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
|
||||
-#endif
|
||||
- return 0;
|
||||
+ if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) {
|
||||
+ /* No platform data for this device. In case of SDIO try OF
|
||||
+ * (Open Firwmare) Device Tree.
|
||||
+ */
|
||||
+ brcmf_of_probe(dev, &settings->bus.sdio);
|
||||
+ }
|
||||
+ return settings;
|
||||
}
|
||||
|
||||
-void brcmf_mp_device_detach(struct brcmf_pub *drvr)
|
||||
+void brcmf_release_module_param(struct brcmf_mp_device *module_param)
|
||||
{
|
||||
- kfree(drvr->settings);
|
||||
+ kfree(module_param);
|
||||
}
|
||||
|
||||
static int __init brcmf_common_pd_probe(struct platform_device *pdev)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
|
||||
@@ -45,41 +45,30 @@ extern struct brcmf_mp_global_t brcmf_mp
|
||||
/**
|
||||
* 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?
|
||||
+ * @ignore_probe_fail: Ignore probe failure.
|
||||
* @country_codes: If available, pointer to struct for translating country codes
|
||||
+ * @bus: Bus specific platform data. Only SDIO at the mmoment.
|
||||
*/
|
||||
struct brcmf_mp_device {
|
||||
- int sdiod_txglomsz;
|
||||
- int joinboost_5g_rssi;
|
||||
- bool p2p_enable;
|
||||
- int feature_disable;
|
||||
- int fcmode;
|
||||
- bool roamoff;
|
||||
- bool ignore_probe_fail;
|
||||
+ bool p2p_enable;
|
||||
+ unsigned int feature_disable;
|
||||
+ int fcmode;
|
||||
+ bool roamoff;
|
||||
+ bool ignore_probe_fail;
|
||||
struct brcmfmac_pd_cc *country_codes;
|
||||
+ union {
|
||||
+ struct brcmfmac_sdio_pd sdio;
|
||||
+ } bus;
|
||||
};
|
||||
|
||||
-struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev,
|
||||
- enum brcmf_bus_type bus_type,
|
||||
- u32 chip, u32 chiprev);
|
||||
-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
|
||||
+struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
|
||||
+ enum brcmf_bus_type bus_type,
|
||||
+ u32 chip, u32 chiprev);
|
||||
+void brcmf_release_module_param(struct brcmf_mp_device *module_param);
|
||||
|
||||
/* Sets dongle media info (drv_version, mac address). */
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -1104,7 +1104,7 @@ static int brcmf_inet6addr_changed(struc
|
||||
}
|
||||
#endif
|
||||
|
||||
-int brcmf_attach(struct device *dev)
|
||||
+int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
|
||||
{
|
||||
struct brcmf_pub *drvr = NULL;
|
||||
int ret = 0;
|
||||
@@ -1126,10 +1126,7 @@ int brcmf_attach(struct device *dev)
|
||||
drvr->hdrlen = 0;
|
||||
drvr->bus_if = dev_get_drvdata(dev);
|
||||
drvr->bus_if->drvr = drvr;
|
||||
-
|
||||
- /* Initialize device specific settings */
|
||||
- if (brcmf_mp_device_attach(drvr))
|
||||
- goto fail;
|
||||
+ drvr->settings = settings;
|
||||
|
||||
/* attach debug facilities */
|
||||
brcmf_debug_attach(drvr);
|
||||
@@ -1274,7 +1271,7 @@ fail:
|
||||
brcmf_net_detach(p2p_ifp->ndev);
|
||||
drvr->iflist[0] = NULL;
|
||||
drvr->iflist[1] = NULL;
|
||||
- if (brcmf_ignoring_probe_fail(drvr))
|
||||
+ if (drvr->settings->ignore_probe_fail)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
@@ -1350,8 +1347,6 @@ 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);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "common.h"
|
||||
#include "of.h"
|
||||
|
||||
-void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio)
|
||||
+void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
int irq;
|
||||
@@ -33,12 +33,8 @@ void brcmf_of_probe(struct device *dev,
|
||||
if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
|
||||
return;
|
||||
|
||||
- *sdio = devm_kzalloc(dev, sizeof(*sdio), GFP_KERNEL);
|
||||
- if (!(*sdio))
|
||||
- return;
|
||||
-
|
||||
if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
|
||||
- (*sdio)->drive_strength = val;
|
||||
+ sdio->drive_strength = val;
|
||||
|
||||
/* make sure there are interrupts defined in the node */
|
||||
if (!of_find_property(np, "interrupts", NULL))
|
||||
@@ -51,7 +47,7 @@ void brcmf_of_probe(struct device *dev,
|
||||
}
|
||||
irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
|
||||
|
||||
- (*sdio)->oob_irq_supported = true;
|
||||
- (*sdio)->oob_irq_nr = irq;
|
||||
- (*sdio)->oob_irq_flags = irqf;
|
||||
+ sdio->oob_irq_supported = true;
|
||||
+ sdio->oob_irq_nr = irq;
|
||||
+ sdio->oob_irq_flags = irqf;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
|
||||
@@ -14,10 +14,9 @@
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef CONFIG_OF
|
||||
-void
|
||||
-brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio);
|
||||
+void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio);
|
||||
#else
|
||||
-static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio)
|
||||
+static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -37,6 +37,8 @@
|
||||
#include "pcie.h"
|
||||
#include "firmware.h"
|
||||
#include "chip.h"
|
||||
+#include "core.h"
|
||||
+#include "common.h"
|
||||
|
||||
|
||||
enum brcmf_pcie_state {
|
||||
@@ -266,6 +268,7 @@ struct brcmf_pciedev_info {
|
||||
u16 (*read_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset);
|
||||
void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
|
||||
u16 value);
|
||||
+ struct brcmf_mp_device *settings;
|
||||
};
|
||||
|
||||
struct brcmf_pcie_ringbuf {
|
||||
@@ -1525,16 +1528,16 @@ static void brcmf_pcie_release_resource(
|
||||
}
|
||||
|
||||
|
||||
-static int brcmf_pcie_attach_bus(struct device *dev)
|
||||
+static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Attach to the common driver interface */
|
||||
- ret = brcmf_attach(dev);
|
||||
+ ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings);
|
||||
if (ret) {
|
||||
brcmf_err("brcmf_attach failed\n");
|
||||
} else {
|
||||
- ret = brcmf_bus_start(dev);
|
||||
+ ret = brcmf_bus_start(&devinfo->pdev->dev);
|
||||
if (ret)
|
||||
brcmf_err("dongle is not responding\n");
|
||||
}
|
||||
@@ -1672,7 +1675,7 @@ static void brcmf_pcie_setup(struct devi
|
||||
init_waitqueue_head(&devinfo->mbdata_resp_wait);
|
||||
|
||||
brcmf_pcie_intr_enable(devinfo);
|
||||
- if (brcmf_pcie_attach_bus(bus->dev) == 0)
|
||||
+ if (brcmf_pcie_attach_bus(devinfo) == 0)
|
||||
return;
|
||||
|
||||
brcmf_pcie_bus_console_read(devinfo);
|
||||
@@ -1716,6 +1719,15 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ devinfo->settings = brcmf_get_module_param(&devinfo->pdev->dev,
|
||||
+ BRCMF_BUSTYPE_PCIE,
|
||||
+ devinfo->ci->chip,
|
||||
+ devinfo->ci->chiprev);
|
||||
+ if (!devinfo->settings) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
|
||||
if (!bus) {
|
||||
ret = -ENOMEM;
|
||||
@@ -1760,6 +1772,8 @@ fail:
|
||||
brcmf_pcie_release_resource(devinfo);
|
||||
if (devinfo->ci)
|
||||
brcmf_chip_detach(devinfo->ci);
|
||||
+ if (devinfo->settings)
|
||||
+ brcmf_release_module_param(devinfo->settings);
|
||||
kfree(pcie_bus_dev);
|
||||
kfree(devinfo);
|
||||
return ret;
|
||||
@@ -1799,6 +1813,8 @@ brcmf_pcie_remove(struct pci_dev *pdev)
|
||||
|
||||
if (devinfo->ci)
|
||||
brcmf_chip_detach(devinfo->ci);
|
||||
+ if (devinfo->settings)
|
||||
+ brcmf_release_module_param(devinfo->settings);
|
||||
|
||||
kfree(devinfo);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -2442,15 +2442,17 @@ static void brcmf_sdio_bus_stop(struct d
|
||||
|
||||
static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus)
|
||||
{
|
||||
+ struct brcmf_sdio_dev *sdiodev;
|
||||
unsigned long flags;
|
||||
|
||||
- if (bus->sdiodev->oob_irq_requested) {
|
||||
- spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags);
|
||||
- if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) {
|
||||
- enable_irq(bus->sdiodev->pdata->oob_irq_nr);
|
||||
- bus->sdiodev->irq_en = true;
|
||||
+ sdiodev = bus->sdiodev;
|
||||
+ if (sdiodev->oob_irq_requested) {
|
||||
+ spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
|
||||
+ if (!sdiodev->irq_en && !atomic_read(&bus->ipend)) {
|
||||
+ enable_irq(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
+ sdiodev->irq_en = true;
|
||||
}
|
||||
- spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags);
|
||||
+ spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3394,9 +3396,7 @@ static int brcmf_sdio_bus_preinit(struct
|
||||
sizeof(u32));
|
||||
} else {
|
||||
/* otherwise, set txglomalign */
|
||||
- value = 4;
|
||||
- if (sdiodev->pdata)
|
||||
- value = sdiodev->pdata->sd_sgentry_align;
|
||||
+ value = sdiodev->settings->bus.sdio.sd_sgentry_align;
|
||||
/* SDIO ADMA requires at least 32 bit alignment */
|
||||
value = max_t(u32, value, 4);
|
||||
err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
|
||||
@@ -3811,21 +3811,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
bus->ci = NULL;
|
||||
goto fail;
|
||||
}
|
||||
- sdiodev->pdata = brcmf_get_module_param(sdiodev->dev,
|
||||
+ sdiodev->settings = brcmf_get_module_param(sdiodev->dev,
|
||||
BRCMF_BUSTYPE_SDIO,
|
||||
bus->ci->chip,
|
||||
bus->ci->chiprev);
|
||||
+ if (!sdiodev->settings) {
|
||||
+ brcmf_err("Failed to get device parameters\n");
|
||||
+ goto fail;
|
||||
+ }
|
||||
/* platform specific configuration:
|
||||
* alignments must be at least 4 bytes for ADMA
|
||||
*/
|
||||
bus->head_align = ALIGNMENT;
|
||||
bus->sgentry_align = ALIGNMENT;
|
||||
- if (sdiodev->pdata) {
|
||||
- if (sdiodev->pdata->sd_head_align > ALIGNMENT)
|
||||
- bus->head_align = sdiodev->pdata->sd_head_align;
|
||||
- if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
|
||||
- bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
|
||||
- }
|
||||
+ if (sdiodev->settings->bus.sdio.sd_head_align > ALIGNMENT)
|
||||
+ bus->head_align = sdiodev->settings->bus.sdio.sd_head_align;
|
||||
+ if (sdiodev->settings->bus.sdio.sd_sgentry_align > ALIGNMENT)
|
||||
+ bus->sgentry_align =
|
||||
+ sdiodev->settings->bus.sdio.sd_sgentry_align;
|
||||
+
|
||||
/* allocate scatter-gather table. sg support
|
||||
* will be disabled upon allocation failure.
|
||||
*/
|
||||
@@ -3837,7 +3841,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
*/
|
||||
if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
|
||||
((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
|
||||
- (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)))
|
||||
+ (sdiodev->settings->bus.sdio.oob_irq_supported)))
|
||||
sdiodev->bus_if->wowl_supported = true;
|
||||
#endif
|
||||
|
||||
@@ -3846,8 +3850,8 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength))
|
||||
- drivestrength = sdiodev->pdata->drive_strength;
|
||||
+ if (sdiodev->settings->bus.sdio.drive_strength)
|
||||
+ drivestrength = sdiodev->settings->bus.sdio.drive_strength;
|
||||
else
|
||||
drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
|
||||
brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength);
|
||||
@@ -4124,7 +4128,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
|
||||
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
|
||||
|
||||
/* Attach to the common layer, reserve hdr space */
|
||||
- ret = brcmf_attach(bus->sdiodev->dev);
|
||||
+ ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings);
|
||||
if (ret != 0) {
|
||||
brcmf_err("brcmf_attach failed\n");
|
||||
goto fail;
|
||||
@@ -4228,6 +4232,8 @@ void brcmf_sdio_remove(struct brcmf_sdio
|
||||
}
|
||||
brcmf_chip_detach(bus->ci);
|
||||
}
|
||||
+ if (bus->sdiodev->settings)
|
||||
+ brcmf_release_module_param(bus->sdiodev->settings);
|
||||
|
||||
kfree(bus->rxbuf);
|
||||
kfree(bus->hdrbuf);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||
@@ -184,7 +184,7 @@ struct brcmf_sdio_dev {
|
||||
struct brcmf_sdio *bus;
|
||||
struct device *dev;
|
||||
struct brcmf_bus *bus_if;
|
||||
- struct brcmfmac_sdio_pd *pdata;
|
||||
+ struct brcmf_mp_device *settings;
|
||||
bool oob_irq_requested;
|
||||
bool irq_en; /* irq enable flags */
|
||||
spinlock_t irq_en_lock;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "debug.h"
|
||||
#include "firmware.h"
|
||||
#include "usb.h"
|
||||
+#include "core.h"
|
||||
+#include "common.h"
|
||||
|
||||
|
||||
#define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
|
||||
@@ -171,6 +173,7 @@ struct brcmf_usbdev_info {
|
||||
struct urb *bulk_urb; /* used for FW download */
|
||||
|
||||
bool wowl_enabled;
|
||||
+ struct brcmf_mp_device *settings;
|
||||
};
|
||||
|
||||
static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
|
||||
@@ -1027,6 +1030,9 @@ static void brcmf_usb_detach(struct brcm
|
||||
|
||||
kfree(devinfo->tx_reqs);
|
||||
kfree(devinfo->rx_reqs);
|
||||
+
|
||||
+ if (devinfo->settings)
|
||||
+ brcmf_release_module_param(devinfo->settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -1136,7 +1142,7 @@ static int brcmf_usb_bus_setup(struct br
|
||||
int ret;
|
||||
|
||||
/* Attach to the common driver interface */
|
||||
- ret = brcmf_attach(devinfo->dev);
|
||||
+ ret = brcmf_attach(devinfo->dev, devinfo->settings);
|
||||
if (ret) {
|
||||
brcmf_err("brcmf_attach failed\n");
|
||||
return ret;
|
||||
@@ -1223,6 +1229,14 @@ static int brcmf_usb_probe_cb(struct brc
|
||||
bus->wowl_supported = true;
|
||||
#endif
|
||||
|
||||
+ devinfo->settings = brcmf_get_module_param(bus->dev, BRCMF_BUSTYPE_USB,
|
||||
+ bus_pub->devid,
|
||||
+ bus_pub->chiprev);
|
||||
+ if (!devinfo->settings) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (!brcmf_usb_dlneeded(devinfo)) {
|
||||
ret = brcmf_usb_bus_setup(devinfo);
|
||||
if (ret)
|
||||
@ -0,0 +1,227 @@
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:09 +0100
|
||||
Subject: [PATCH] brcmfmac: integrate add_keyext in add_key
|
||||
|
||||
brcmf_add_keyext is called when a key is configured for a specific
|
||||
mac address. This function is very similar to the calling function
|
||||
brcmf_add_key. Integrate this function and also use existing del_key
|
||||
function in case key is to be cleared.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.van@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <franky.lin@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2073,84 +2073,34 @@ done:
|
||||
}
|
||||
|
||||
static s32
|
||||
-brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
|
||||
- u8 key_idx, const u8 *mac_addr, struct key_params *params)
|
||||
+brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
+ u8 key_idx, bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct brcmf_wsec_key key;
|
||||
s32 err = 0;
|
||||
- u8 keybuf[8];
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter\n");
|
||||
+ if (!check_vif_up(ifp->vif))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
|
||||
+ /* we ignore this key index in this case */
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
- key.index = (u32) key_idx;
|
||||
- /* Instead of bcast for ea address for default wep keys,
|
||||
- driver needs it to be Null */
|
||||
- if (!is_multicast_ether_addr(mac_addr))
|
||||
- memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
|
||||
- key.len = (u32) params->key_len;
|
||||
- /* check for key index change */
|
||||
- if (key.len == 0) {
|
||||
- /* key delete */
|
||||
- err = send_key_to_dongle(ifp, &key);
|
||||
- if (err)
|
||||
- brcmf_err("key delete error (%d)\n", err);
|
||||
- } else {
|
||||
- if (key.len > sizeof(key.data)) {
|
||||
- brcmf_err("Invalid key length (%d)\n", key.len);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
|
||||
- brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
|
||||
- memcpy(key.data, params->key, key.len);
|
||||
+ key.index = (u32)key_idx;
|
||||
+ key.flags = BRCMF_PRIMARY_KEY;
|
||||
+ key.algo = CRYPTO_ALGO_OFF;
|
||||
|
||||
- if (!brcmf_is_apmode(ifp->vif) &&
|
||||
- (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
|
||||
- brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
|
||||
- memcpy(keybuf, &key.data[24], sizeof(keybuf));
|
||||
- memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
|
||||
- memcpy(&key.data[16], keybuf, sizeof(keybuf));
|
||||
- }
|
||||
+ brcmf_dbg(CONN, "key index (%d)\n", key_idx);
|
||||
|
||||
- /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
|
||||
- if (params->seq && params->seq_len == 6) {
|
||||
- /* rx iv */
|
||||
- u8 *ivptr;
|
||||
- ivptr = (u8 *) params->seq;
|
||||
- key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
|
||||
- (ivptr[3] << 8) | ivptr[2];
|
||||
- key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
|
||||
- key.iv_initialized = true;
|
||||
- }
|
||||
+ /* Set the new key/index */
|
||||
+ err = send_key_to_dongle(ifp, &key);
|
||||
|
||||
- switch (params->cipher) {
|
||||
- case WLAN_CIPHER_SUITE_WEP40:
|
||||
- key.algo = CRYPTO_ALGO_WEP1;
|
||||
- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
|
||||
- break;
|
||||
- case WLAN_CIPHER_SUITE_WEP104:
|
||||
- key.algo = CRYPTO_ALGO_WEP128;
|
||||
- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
|
||||
- break;
|
||||
- case WLAN_CIPHER_SUITE_TKIP:
|
||||
- key.algo = CRYPTO_ALGO_TKIP;
|
||||
- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
|
||||
- break;
|
||||
- case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
- key.algo = CRYPTO_ALGO_AES_CCM;
|
||||
- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
|
||||
- break;
|
||||
- case WLAN_CIPHER_SUITE_CCMP:
|
||||
- key.algo = CRYPTO_ALGO_AES_CCM;
|
||||
- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
|
||||
- break;
|
||||
- default:
|
||||
- brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- err = send_key_to_dongle(ifp, &key);
|
||||
- if (err)
|
||||
- brcmf_err("wsec_key error (%d)\n", err);
|
||||
- }
|
||||
+ brcmf_dbg(TRACE, "Exit\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2163,8 +2113,9 @@ brcmf_cfg80211_add_key(struct wiphy *wip
|
||||
struct brcmf_wsec_key *key;
|
||||
s32 val;
|
||||
s32 wsec;
|
||||
- s32 err = 0;
|
||||
+ s32 err;
|
||||
u8 keybuf[8];
|
||||
+ bool ext_key;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
brcmf_dbg(CONN, "key index (%d)\n", key_idx);
|
||||
@@ -2177,27 +2128,32 @@ brcmf_cfg80211_add_key(struct wiphy *wip
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (mac_addr &&
|
||||
- (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
|
||||
- (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
|
||||
- brcmf_dbg(TRACE, "Exit");
|
||||
- return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
|
||||
- }
|
||||
-
|
||||
- key = &ifp->vif->profile.key[key_idx];
|
||||
- memset(key, 0, sizeof(*key));
|
||||
+ if (params->key_len == 0)
|
||||
+ return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
|
||||
+ mac_addr);
|
||||
|
||||
if (params->key_len > sizeof(key->data)) {
|
||||
brcmf_err("Too long key length (%u)\n", params->key_len);
|
||||
- err = -EINVAL;
|
||||
- goto done;
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ext_key = false;
|
||||
+ if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
|
||||
+ (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
|
||||
+ brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
|
||||
+ ext_key = true;
|
||||
}
|
||||
+
|
||||
+ key = &ifp->vif->profile.key[key_idx];
|
||||
+ memset(key, 0, sizeof(*key));
|
||||
+ if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
|
||||
+ memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
|
||||
key->len = params->key_len;
|
||||
key->index = key_idx;
|
||||
-
|
||||
memcpy(key->data, params->key, key->len);
|
||||
+ if (!ext_key)
|
||||
+ key->flags = BRCMF_PRIMARY_KEY;
|
||||
|
||||
- key->flags = BRCMF_PRIMARY_KEY;
|
||||
switch (params->cipher) {
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
key->algo = CRYPTO_ALGO_WEP1;
|
||||
@@ -2237,7 +2193,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip
|
||||
}
|
||||
|
||||
err = send_key_to_dongle(ifp, key);
|
||||
- if (err)
|
||||
+ if (ext_key || err)
|
||||
goto done;
|
||||
|
||||
err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
|
||||
@@ -2256,38 +2212,6 @@ done:
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
return err;
|
||||
}
|
||||
-
|
||||
-static s32
|
||||
-brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
- u8 key_idx, bool pairwise, const u8 *mac_addr)
|
||||
-{
|
||||
- struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
- struct brcmf_wsec_key key;
|
||||
- s32 err = 0;
|
||||
-
|
||||
- brcmf_dbg(TRACE, "Enter\n");
|
||||
- if (!check_vif_up(ifp->vif))
|
||||
- return -EIO;
|
||||
-
|
||||
- if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
|
||||
- /* we ignore this key index in this case */
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- memset(&key, 0, sizeof(key));
|
||||
-
|
||||
- key.index = (u32) key_idx;
|
||||
- key.flags = BRCMF_PRIMARY_KEY;
|
||||
- key.algo = CRYPTO_ALGO_OFF;
|
||||
-
|
||||
- brcmf_dbg(CONN, "key index (%d)\n", key_idx);
|
||||
-
|
||||
- /* Set the new key/index */
|
||||
- err = send_key_to_dongle(ifp, &key);
|
||||
-
|
||||
- brcmf_dbg(TRACE, "Exit\n");
|
||||
- return err;
|
||||
-}
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
@ -0,0 +1,509 @@
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Wed, 17 Feb 2016 11:27:10 +0100
|
||||
Subject: [PATCH] brcmfmac: add 802.11w management frame protection support
|
||||
|
||||
Add full support for both AP and STA for management frame protection.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.van@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <franky.lin@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -72,8 +72,13 @@
|
||||
#define RSN_AKM_NONE 0 /* None (IBSS) */
|
||||
#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
|
||||
#define RSN_AKM_PSK 2 /* Pre-shared Key */
|
||||
+#define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */
|
||||
+#define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */
|
||||
#define RSN_CAP_LEN 2 /* Length of RSN capabilities */
|
||||
-#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
|
||||
+#define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
|
||||
+#define RSN_CAP_MFPR_MASK BIT(6)
|
||||
+#define RSN_CAP_MFPC_MASK BIT(7)
|
||||
+#define RSN_PMKID_COUNT_LEN 2
|
||||
|
||||
#define VNDR_IE_CMD_LEN 4 /* length of the set command
|
||||
* string :"add", "del" (+ NUL)
|
||||
@@ -211,12 +216,19 @@ static const struct ieee80211_regdomain
|
||||
REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
|
||||
};
|
||||
|
||||
-static const u32 __wl_cipher_suites[] = {
|
||||
+/* Note: brcmf_cipher_suites is an array of int defining which cipher suites
|
||||
+ * are supported. A pointer to this array and the number of entries is passed
|
||||
+ * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
|
||||
+ * So the cipher suite AES_CMAC has to be the last one in the array, and when
|
||||
+ * device does not support MFP then the number of suites will be decreased by 1
|
||||
+ */
|
||||
+static const u32 brcmf_cipher_suites[] = {
|
||||
WLAN_CIPHER_SUITE_WEP40,
|
||||
WLAN_CIPHER_SUITE_WEP104,
|
||||
WLAN_CIPHER_SUITE_TKIP,
|
||||
WLAN_CIPHER_SUITE_CCMP,
|
||||
- WLAN_CIPHER_SUITE_AES_CMAC,
|
||||
+ /* Keep as last entry: */
|
||||
+ WLAN_CIPHER_SUITE_AES_CMAC
|
||||
};
|
||||
|
||||
/* Vendor specific ie. id = 221, oui and type defines exact ie */
|
||||
@@ -1533,7 +1545,7 @@ static s32 brcmf_set_auth_type(struct ne
|
||||
|
||||
static s32
|
||||
brcmf_set_wsec_mode(struct net_device *ndev,
|
||||
- struct cfg80211_connect_params *sme, bool mfp)
|
||||
+ struct cfg80211_connect_params *sme)
|
||||
{
|
||||
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
|
||||
struct brcmf_cfg80211_security *sec;
|
||||
@@ -1592,10 +1604,7 @@ brcmf_set_wsec_mode(struct net_device *n
|
||||
sme->privacy)
|
||||
pval = AES_ENABLED;
|
||||
|
||||
- if (mfp)
|
||||
- wsec = pval | gval | MFP_CAPABLE;
|
||||
- else
|
||||
- wsec = pval | gval;
|
||||
+ wsec = pval | gval;
|
||||
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
|
||||
if (err) {
|
||||
brcmf_err("error (%d)\n", err);
|
||||
@@ -1612,56 +1621,100 @@ brcmf_set_wsec_mode(struct net_device *n
|
||||
static s32
|
||||
brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
|
||||
{
|
||||
- struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
|
||||
- struct brcmf_cfg80211_security *sec;
|
||||
- s32 val = 0;
|
||||
- s32 err = 0;
|
||||
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
+ s32 val;
|
||||
+ s32 err;
|
||||
+ const struct brcmf_tlv *rsn_ie;
|
||||
+ const u8 *ie;
|
||||
+ u32 ie_len;
|
||||
+ u32 offset;
|
||||
+ u16 rsn_cap;
|
||||
+ u32 mfp;
|
||||
+ u16 count;
|
||||
|
||||
- if (sme->crypto.n_akm_suites) {
|
||||
- err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
|
||||
- "wpa_auth", &val);
|
||||
- if (err) {
|
||||
- brcmf_err("could not get wpa_auth (%d)\n", err);
|
||||
- return err;
|
||||
+ if (!sme->crypto.n_akm_suites)
|
||||
+ return 0;
|
||||
+
|
||||
+ err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
|
||||
+ if (err) {
|
||||
+ brcmf_err("could not get wpa_auth (%d)\n", err);
|
||||
+ return err;
|
||||
+ }
|
||||
+ if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
|
||||
+ switch (sme->crypto.akm_suites[0]) {
|
||||
+ case WLAN_AKM_SUITE_8021X:
|
||||
+ val = WPA_AUTH_UNSPECIFIED;
|
||||
+ break;
|
||||
+ case WLAN_AKM_SUITE_PSK:
|
||||
+ val = WPA_AUTH_PSK;
|
||||
+ break;
|
||||
+ default:
|
||||
+ brcmf_err("invalid cipher group (%d)\n",
|
||||
+ sme->crypto.cipher_group);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
- if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
|
||||
- switch (sme->crypto.akm_suites[0]) {
|
||||
- case WLAN_AKM_SUITE_8021X:
|
||||
- val = WPA_AUTH_UNSPECIFIED;
|
||||
- break;
|
||||
- case WLAN_AKM_SUITE_PSK:
|
||||
- val = WPA_AUTH_PSK;
|
||||
- break;
|
||||
- default:
|
||||
- brcmf_err("invalid cipher group (%d)\n",
|
||||
- sme->crypto.cipher_group);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
|
||||
- switch (sme->crypto.akm_suites[0]) {
|
||||
- case WLAN_AKM_SUITE_8021X:
|
||||
- val = WPA2_AUTH_UNSPECIFIED;
|
||||
- break;
|
||||
- case WLAN_AKM_SUITE_PSK:
|
||||
- val = WPA2_AUTH_PSK;
|
||||
- break;
|
||||
- default:
|
||||
- brcmf_err("invalid cipher group (%d)\n",
|
||||
- sme->crypto.cipher_group);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
+ } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
|
||||
+ switch (sme->crypto.akm_suites[0]) {
|
||||
+ case WLAN_AKM_SUITE_8021X:
|
||||
+ val = WPA2_AUTH_UNSPECIFIED;
|
||||
+ break;
|
||||
+ case WLAN_AKM_SUITE_8021X_SHA256:
|
||||
+ val = WPA2_AUTH_1X_SHA256;
|
||||
+ break;
|
||||
+ case WLAN_AKM_SUITE_PSK_SHA256:
|
||||
+ val = WPA2_AUTH_PSK_SHA256;
|
||||
+ break;
|
||||
+ case WLAN_AKM_SUITE_PSK:
|
||||
+ val = WPA2_AUTH_PSK;
|
||||
+ break;
|
||||
+ default:
|
||||
+ brcmf_err("invalid cipher group (%d)\n",
|
||||
+ sme->crypto.cipher_group);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
+ }
|
||||
|
||||
- brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
|
||||
- err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
|
||||
- "wpa_auth", val);
|
||||
- if (err) {
|
||||
- brcmf_err("could not set wpa_auth (%d)\n", err);
|
||||
- return err;
|
||||
- }
|
||||
+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
|
||||
+ goto skip_mfp_config;
|
||||
+ /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
|
||||
+ * IE will not be verified, just a quick search for MFP config
|
||||
+ */
|
||||
+ rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
|
||||
+ WLAN_EID_RSN);
|
||||
+ if (!rsn_ie)
|
||||
+ goto skip_mfp_config;
|
||||
+ ie = (const u8 *)rsn_ie;
|
||||
+ ie_len = rsn_ie->len + TLV_HDR_LEN;
|
||||
+ /* Skip unicast suite */
|
||||
+ offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
|
||||
+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
|
||||
+ goto skip_mfp_config;
|
||||
+ /* Skip multicast suite */
|
||||
+ count = ie[offset] + (ie[offset + 1] << 8);
|
||||
+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
|
||||
+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
|
||||
+ goto skip_mfp_config;
|
||||
+ /* Skip auth key management suite(s) */
|
||||
+ count = ie[offset] + (ie[offset + 1] << 8);
|
||||
+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
|
||||
+ if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
|
||||
+ goto skip_mfp_config;
|
||||
+ /* Ready to read capabilities */
|
||||
+ mfp = BRCMF_MFP_NONE;
|
||||
+ rsn_cap = ie[offset] + (ie[offset + 1] << 8);
|
||||
+ if (rsn_cap & RSN_CAP_MFPR_MASK)
|
||||
+ mfp = BRCMF_MFP_REQUIRED;
|
||||
+ else if (rsn_cap & RSN_CAP_MFPC_MASK)
|
||||
+ mfp = BRCMF_MFP_CAPABLE;
|
||||
+ brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
|
||||
+
|
||||
+skip_mfp_config:
|
||||
+ brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
|
||||
+ err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
|
||||
+ if (err) {
|
||||
+ brcmf_err("could not set wpa_auth (%d)\n", err);
|
||||
+ return err;
|
||||
}
|
||||
- sec = &profile->sec;
|
||||
- sec->wpa_auth = sme->crypto.akm_suites[0];
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -1827,7 +1880,7 @@ brcmf_cfg80211_connect(struct wiphy *wip
|
||||
goto done;
|
||||
}
|
||||
|
||||
- err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
|
||||
+ err = brcmf_set_wsec_mode(ndev, sme);
|
||||
if (err) {
|
||||
brcmf_err("wl_set_set_cipher failed (%d)\n", err);
|
||||
goto done;
|
||||
@@ -2077,10 +2130,12 @@ brcmf_cfg80211_del_key(struct wiphy *wip
|
||||
u8 key_idx, bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
- struct brcmf_wsec_key key;
|
||||
- s32 err = 0;
|
||||
+ struct brcmf_wsec_key *key;
|
||||
+ s32 err;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
+ brcmf_dbg(CONN, "key index (%d)\n", key_idx);
|
||||
+
|
||||
if (!check_vif_up(ifp->vif))
|
||||
return -EIO;
|
||||
|
||||
@@ -2089,16 +2144,19 @@ brcmf_cfg80211_del_key(struct wiphy *wip
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- memset(&key, 0, sizeof(key));
|
||||
+ key = &ifp->vif->profile.key[key_idx];
|
||||
|
||||
- key.index = (u32)key_idx;
|
||||
- key.flags = BRCMF_PRIMARY_KEY;
|
||||
- key.algo = CRYPTO_ALGO_OFF;
|
||||
+ if (key->algo == CRYPTO_ALGO_OFF) {
|
||||
+ brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
- brcmf_dbg(CONN, "key index (%d)\n", key_idx);
|
||||
+ memset(key, 0, sizeof(*key));
|
||||
+ key->index = (u32)key_idx;
|
||||
+ key->flags = BRCMF_PRIMARY_KEY;
|
||||
|
||||
- /* Set the new key/index */
|
||||
- err = send_key_to_dongle(ifp, &key);
|
||||
+ /* Clear the key/index */
|
||||
+ err = send_key_to_dongle(ifp, key);
|
||||
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
return err;
|
||||
@@ -2106,8 +2164,8 @@ brcmf_cfg80211_del_key(struct wiphy *wip
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
- u8 key_idx, bool pairwise, const u8 *mac_addr,
|
||||
- struct key_params *params)
|
||||
+ u8 key_idx, bool pairwise, const u8 *mac_addr,
|
||||
+ struct key_params *params)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct brcmf_wsec_key *key;
|
||||
@@ -2214,9 +2272,10 @@ done:
|
||||
}
|
||||
|
||||
static s32
|
||||
-brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
- u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
|
||||
- void (*callback) (void *cookie, struct key_params * params))
|
||||
+brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
|
||||
+ bool pairwise, const u8 *mac_addr, void *cookie,
|
||||
+ void (*callback)(void *cookie,
|
||||
+ struct key_params *params))
|
||||
{
|
||||
struct key_params params;
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
@@ -2268,8 +2327,15 @@ done:
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
|
||||
- struct net_device *ndev, u8 key_idx)
|
||||
+ struct net_device *ndev, u8 key_idx)
|
||||
{
|
||||
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
|
||||
+
|
||||
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
|
||||
+ return 0;
|
||||
+
|
||||
brcmf_dbg(INFO, "Not supported\n");
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
@@ -3769,7 +3835,7 @@ brcmf_configure_wpaie(struct brcmf_if *i
|
||||
u32 auth = 0; /* d11 open authentication */
|
||||
u16 count;
|
||||
s32 err = 0;
|
||||
- s32 len = 0;
|
||||
+ s32 len;
|
||||
u32 i;
|
||||
u32 wsec;
|
||||
u32 pval = 0;
|
||||
@@ -3779,6 +3845,7 @@ brcmf_configure_wpaie(struct brcmf_if *i
|
||||
u8 *data;
|
||||
u16 rsn_cap;
|
||||
u32 wme_bss_disable;
|
||||
+ u32 mfp;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
if (wpa_ie == NULL)
|
||||
@@ -3893,19 +3960,53 @@ brcmf_configure_wpaie(struct brcmf_if *i
|
||||
is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
|
||||
(wpa_auth |= WPA_AUTH_PSK);
|
||||
break;
|
||||
+ case RSN_AKM_SHA256_PSK:
|
||||
+ brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
|
||||
+ wpa_auth |= WPA2_AUTH_PSK_SHA256;
|
||||
+ break;
|
||||
+ case RSN_AKM_SHA256_1X:
|
||||
+ brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
|
||||
+ wpa_auth |= WPA2_AUTH_1X_SHA256;
|
||||
+ break;
|
||||
default:
|
||||
brcmf_err("Ivalid key mgmt info\n");
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
|
||||
+ mfp = BRCMF_MFP_NONE;
|
||||
if (is_rsn_ie) {
|
||||
wme_bss_disable = 1;
|
||||
if ((offset + RSN_CAP_LEN) <= len) {
|
||||
rsn_cap = data[offset] + (data[offset + 1] << 8);
|
||||
if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
|
||||
wme_bss_disable = 0;
|
||||
+ if (rsn_cap & RSN_CAP_MFPR_MASK) {
|
||||
+ brcmf_dbg(TRACE, "MFP Required\n");
|
||||
+ mfp = BRCMF_MFP_REQUIRED;
|
||||
+ /* Firmware only supports mfp required in
|
||||
+ * combination with WPA2_AUTH_PSK_SHA256 or
|
||||
+ * WPA2_AUTH_1X_SHA256.
|
||||
+ */
|
||||
+ if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
|
||||
+ WPA2_AUTH_1X_SHA256))) {
|
||||
+ err = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ /* Firmware has requirement that WPA2_AUTH_PSK/
|
||||
+ * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
|
||||
+ * is to be included in the rsn ie.
|
||||
+ */
|
||||
+ if (wpa_auth & WPA2_AUTH_PSK_SHA256)
|
||||
+ wpa_auth |= WPA2_AUTH_PSK;
|
||||
+ else if (wpa_auth & WPA2_AUTH_1X_SHA256)
|
||||
+ wpa_auth |= WPA2_AUTH_UNSPECIFIED;
|
||||
+ } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
|
||||
+ brcmf_dbg(TRACE, "MFP Capable\n");
|
||||
+ mfp = BRCMF_MFP_CAPABLE;
|
||||
+ }
|
||||
}
|
||||
+ offset += RSN_CAP_LEN;
|
||||
/* set wme_bss_disable to sync RSN Capabilities */
|
||||
err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
|
||||
wme_bss_disable);
|
||||
@@ -3913,6 +4014,21 @@ brcmf_configure_wpaie(struct brcmf_if *i
|
||||
brcmf_err("wme_bss_disable error %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
+
|
||||
+ /* Skip PMKID cnt as it is know to be 0 for AP. */
|
||||
+ offset += RSN_PMKID_COUNT_LEN;
|
||||
+
|
||||
+ /* See if there is BIP wpa suite left for MFP */
|
||||
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
|
||||
+ ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
|
||||
+ err = brcmf_fil_bsscfg_data_set(ifp, "bip",
|
||||
+ &data[offset],
|
||||
+ WPA_IE_MIN_OUI_LEN);
|
||||
+ if (err < 0) {
|
||||
+ brcmf_err("bip error %d\n", err);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
/* FOR WPS , set SES_OW_ENABLED */
|
||||
wsec = (pval | gval | SES_OW_ENABLED);
|
||||
@@ -3929,6 +4045,16 @@ brcmf_configure_wpaie(struct brcmf_if *i
|
||||
brcmf_err("wsec error %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
+ /* Configure MFP, this needs to go after wsec otherwise the wsec command
|
||||
+ * will overwrite the values set by MFP
|
||||
+ */
|
||||
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
|
||||
+ err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
|
||||
+ if (err < 0) {
|
||||
+ brcmf_err("mfp error %d\n", err);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ }
|
||||
/* set upper-layer auth */
|
||||
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
|
||||
if (err < 0) {
|
||||
@@ -6149,8 +6275,10 @@ static int brcmf_setup_wiphy(struct wiph
|
||||
wiphy->n_addresses = i;
|
||||
|
||||
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
|
||||
- wiphy->cipher_suites = __wl_cipher_suites;
|
||||
- wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
|
||||
+ wiphy->cipher_suites = brcmf_cipher_suites;
|
||||
+ wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
|
||||
+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
|
||||
+ wiphy->n_cipher_suites--;
|
||||
wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
|
||||
WIPHY_FLAG_OFFCHAN_TX |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
#define BRCMF_VNDR_IE_P2PAF_SHIFT 12
|
||||
|
||||
-#define BRCMF_MAX_DEFAULT_KEYS 4
|
||||
+#define BRCMF_MAX_DEFAULT_KEYS 6
|
||||
|
||||
/* beacon loss timeout defaults */
|
||||
#define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2
|
||||
@@ -107,7 +107,6 @@ struct brcmf_cfg80211_security {
|
||||
u32 auth_type;
|
||||
u32 cipher_pairwise;
|
||||
u32 cipher_group;
|
||||
- u32 wpa_auth;
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||
@@ -161,6 +161,7 @@ void brcmf_feat_attach(struct brcmf_pub
|
||||
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");
|
||||
+ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp");
|
||||
|
||||
pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
|
||||
err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac,
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||
@@ -30,6 +30,7 @@
|
||||
* WOWL_ND: WOWL net detect (PNO)
|
||||
* WOWL_GTK: (WOWL) GTK rekeying offload
|
||||
* WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL.
|
||||
+ * MFP: 802.11w Management Frame Protection.
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MBSS) \
|
||||
@@ -42,7 +43,8 @@
|
||||
BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \
|
||||
BRCMF_FEAT_DEF(WOWL_ND) \
|
||||
BRCMF_FEAT_DEF(WOWL_GTK) \
|
||||
- BRCMF_FEAT_DEF(WOWL_ARP_ND)
|
||||
+ BRCMF_FEAT_DEF(WOWL_ARP_ND) \
|
||||
+ BRCMF_FEAT_DEF(MFP)
|
||||
|
||||
/*
|
||||
* Quirks:
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
|
||||
@@ -142,6 +142,10 @@
|
||||
#define BRCMF_RSN_KEK_LENGTH 16
|
||||
#define BRCMF_RSN_REPLAY_LEN 8
|
||||
|
||||
+#define BRCMF_MFP_NONE 0
|
||||
+#define BRCMF_MFP_CAPABLE 1
|
||||
+#define BRCMF_MFP_REQUIRED 2
|
||||
+
|
||||
/* join preference types for join_pref iovar */
|
||||
enum brcmf_join_pref_types {
|
||||
BRCMF_JOIN_PREF_RSSI = 1,
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
|
||||
@@ -236,6 +236,8 @@ static inline bool ac_bitmap_tst(u8 bitm
|
||||
#define WPA2_AUTH_RESERVED3 0x0200
|
||||
#define WPA2_AUTH_RESERVED4 0x0400
|
||||
#define WPA2_AUTH_RESERVED5 0x0800
|
||||
+#define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */
|
||||
+#define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */
|
||||
|
||||
#define DOT11_DEFAULT_RTS_LEN 2347
|
||||
#define DOT11_DEFAULT_FRAG_LEN 2346
|
||||
@ -0,0 +1,54 @@
|
||||
From: Hui Wang <hui.wang@canonical.com>
|
||||
Date: Wed, 9 Mar 2016 15:25:26 +0800
|
||||
Subject: [PATCH] brcmfmac: Remove waitqueue_active check
|
||||
|
||||
We met a problem of pm_suspend when repeated closing/opening the lid
|
||||
on a Lenovo laptop (1/20 reproduce rate), below is the log:
|
||||
|
||||
[ 199.735876] PM: Entering mem sleep
|
||||
[ 199.750516] e1000e: EEE TX LPI TIMER: 00000011
|
||||
[ 199.856638] Trying to free nonexistent resource <000000000000d000-000000000000d0ff>
|
||||
[ 201.753566] brcmfmac: brcmf_pcie_suspend: Timeout on response for entering D3 substate
|
||||
[ 201.753581] pci_legacy_suspend(): brcmf_pcie_suspend+0x0/0x1f0 [brcmfmac] returns -5
|
||||
[ 201.753585] dpm_run_callback(): pci_pm_suspend+0x0/0x160 returns -5
|
||||
[ 201.753589] PM: Device 0000:04:00.0 failed to suspend async: error -5
|
||||
|
||||
Through debugging, we found when problem happens, it is not the device
|
||||
fails to enter D3, but the signal D3_ACK comes too early to pass the
|
||||
waitqueue_active() check.
|
||||
|
||||
Just like this:
|
||||
brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D3_INFORM);
|
||||
// signal is triggered here
|
||||
wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed,
|
||||
BRCMF_PCIE_MBDATA_TIMEOUT);
|
||||
|
||||
So far I think it is safe to remove waitqueue_active check since there
|
||||
is only one place to trigger this signal (sending
|
||||
BRCMF_H2D_HOST_D3_INFORM). And it is not a problem calling wake_up
|
||||
event earlier than calling wait_event.
|
||||
|
||||
Cc: Brett Rudley <brudley@broadcom.com>
|
||||
Cc: Hante Meuleman <meuleman@broadcom.com>
|
||||
Cc: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Cc: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Cc: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Hui Wang <hui.wang@canonical.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
|
||||
@@ -677,10 +677,8 @@ static void brcmf_pcie_handle_mb_data(st
|
||||
brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP EXIT\n");
|
||||
if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK) {
|
||||
brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n");
|
||||
- if (waitqueue_active(&devinfo->mbdata_resp_wait)) {
|
||||
- devinfo->mbdata_completed = true;
|
||||
- wake_up(&devinfo->mbdata_resp_wait);
|
||||
- }
|
||||
+ devinfo->mbdata_completed = true;
|
||||
+ wake_up(&devinfo->mbdata_resp_wait);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Tue, 15 Mar 2016 10:06:10 +0300
|
||||
Subject: [PATCH] brcmfmac: uninitialized "ret" variable
|
||||
|
||||
There is an error path where "ret" isn't initialized.
|
||||
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -250,7 +250,7 @@ static int brcmf_sdiod_request_data(stru
|
||||
u32 addr, u8 regsz, void *data, bool write)
|
||||
{
|
||||
struct sdio_func *func;
|
||||
- int ret;
|
||||
+ int ret = -EINVAL;
|
||||
|
||||
brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
|
||||
write, fn, addr, regsz);
|
||||
@ -0,0 +1,24 @@
|
||||
From: Colin Ian King <colin.king@canonical.com>
|
||||
Date: Sun, 20 Mar 2016 17:34:52 +0000
|
||||
Subject: [PATCH] brcmfmac: sdio: remove unused variable retry_limit
|
||||
|
||||
retry_limit has never been used during the life of this driver, so
|
||||
we may as well remove it as it is redundant.
|
||||
|
||||
Signed-off-by: Colin Ian King <colin.king@canonical.com>
|
||||
Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -535,9 +535,6 @@ static int qcount[NUMPRIO];
|
||||
|
||||
#define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)
|
||||
|
||||
-/* Retry count for register access failures */
|
||||
-static const uint retry_limit = 2;
|
||||
-
|
||||
/* Limit on rounding up frames */
|
||||
static const uint max_roundup = 512;
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
From: Markus Elfring <elfring@users.sourceforge.net>
|
||||
Date: Fri, 18 Mar 2016 13:23:24 +1100
|
||||
Subject: [PATCH] brcmfmac: Delete unnecessary variable initialisation
|
||||
|
||||
In brcmf_sdio_download_firmware(), bcmerror is set by the call to
|
||||
brcmf_sdio_download_code_file(), before it's checked in the following
|
||||
line.
|
||||
|
||||
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
|
||||
Acked-by: Arend van Spriel <arend@broadcom.com>
|
||||
[Rewrote commit message]
|
||||
Signed-off-by: Julian Calaby <julian.calaby@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3258,7 +3258,7 @@ static int brcmf_sdio_download_firmware(
|
||||
const struct firmware *fw,
|
||||
void *nvram, u32 nvlen)
|
||||
{
|
||||
- int bcmerror = -EFAULT;
|
||||
+ int bcmerror;
|
||||
u32 rstvec;
|
||||
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
@ -0,0 +1,27 @@
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 11 Apr 2016 11:35:21 +0200
|
||||
Subject: [PATCH] brcmfmac: clear eventmask array before using it
|
||||
|
||||
When the event_msgs iovar is set an array is used to configure the
|
||||
enabled events. This arrays needs to nulled before configuring
|
||||
otherwise unhandled events will be enabled. This solves a problem
|
||||
where in case of wowl the host got woken by an incorrectly enabled
|
||||
event.
|
||||
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
@@ -371,6 +371,7 @@ int brcmf_fweh_activate_events(struct br
|
||||
int i, err;
|
||||
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
|
||||
|
||||
+ memset(eventmask, 0, sizeof(eventmask));
|
||||
for (i = 0; i < BRCMF_E_LAST; i++) {
|
||||
if (ifp->drvr->fweh.evt_handler[i]) {
|
||||
brcmf_dbg(EVENT, "enable event %s\n",
|
||||
@ -0,0 +1,27 @@
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 11 Apr 2016 11:35:22 +0200
|
||||
Subject: [PATCH] brcmfmac: fix clearing wowl wake indicators
|
||||
|
||||
Newer firmwares require the usage of the wowl wakeind struct as size
|
||||
for the iovar to clear the wake indicators. Older firmwares do not
|
||||
care, so change the used size.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -3608,7 +3608,8 @@ static void brcmf_configure_wowl(struct
|
||||
if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
|
||||
wowl_config |= BRCMF_WOWL_UNASSOC;
|
||||
|
||||
- brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear"));
|
||||
+ brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear",
|
||||
+ sizeof(struct brcmf_wowl_wakeind_le));
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
|
||||
brcmf_bus_wowl_config(cfg->pub->bus_if, true);
|
||||
@ -0,0 +1,29 @@
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 11 Apr 2016 11:35:24 +0200
|
||||
Subject: [PATCH] brcmfmac: fix p2p scan abort null pointer exception
|
||||
|
||||
When p2p connection setup is performed without having ever done an
|
||||
escan a null pointer exception can occur. This is because the ifp
|
||||
to abort scanning is taken from escan struct while it was never
|
||||
initialized. Fix this by using the primary ifp for scan abort. The
|
||||
abort should still be performed and all scan related commands are
|
||||
performed on primary ifp.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -1266,7 +1266,7 @@ static void
|
||||
brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg)
|
||||
{
|
||||
struct brcmf_p2p_info *p2p = &cfg->p2p;
|
||||
- struct brcmf_if *ifp = cfg->escan_info.ifp;
|
||||
+ struct brcmf_if *ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
|
||||
|
||||
if (test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status) &&
|
||||
(test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status) ||
|
||||
@ -0,0 +1,297 @@
|
||||
From: Franky Lin <franky.lin@broadcom.com>
|
||||
Date: Mon, 11 Apr 2016 11:35:25 +0200
|
||||
Subject: [PATCH] brcmfmac: screening firmware event packet
|
||||
|
||||
Firmware uses asynchronized events as a communication method to the
|
||||
host. The event packets are marked as ETH_P_LINK_CTL protocol type. For
|
||||
SDIO and PCIe bus, this kind of packets are delivered through virtual
|
||||
event channel not data channel. This patch adds a screening logic to
|
||||
make sure the event handler only processes the events coming from the
|
||||
correct channel.
|
||||
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
@@ -216,7 +216,9 @@ bool brcmf_c_prec_enq(struct device *dev
|
||||
int prec);
|
||||
|
||||
/* Receive frame for delivery to OS. Callee disposes of rxp. */
|
||||
-void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
|
||||
+void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_evnt);
|
||||
+/* Receive async event packet from firmware. Callee disposes of rxp. */
|
||||
+void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
|
||||
|
||||
/* Indication from bus module regarding presence/insertion of dongle. */
|
||||
int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -311,16 +311,17 @@ void brcmf_txflowblock(struct device *de
|
||||
brcmf_fws_bus_blocked(drvr, state);
|
||||
}
|
||||
|
||||
-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
|
||||
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb,
|
||||
+ bool handle_event)
|
||||
{
|
||||
- skb->dev = ifp->ndev;
|
||||
- skb->protocol = eth_type_trans(skb, skb->dev);
|
||||
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
|
||||
if (skb->pkt_type == PACKET_MULTICAST)
|
||||
ifp->stats.multicast++;
|
||||
|
||||
/* Process special event packets */
|
||||
- brcmf_fweh_process_skb(ifp->drvr, skb);
|
||||
+ if (handle_event)
|
||||
+ brcmf_fweh_process_skb(ifp->drvr, skb);
|
||||
|
||||
if (!(ifp->ndev->flags & IFF_UP)) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
@@ -381,7 +382,7 @@ static void brcmf_rxreorder_process_info
|
||||
/* validate flags and flow id */
|
||||
if (flags == 0xFF) {
|
||||
brcmf_err("invalid flags...so ignore this packet\n");
|
||||
- brcmf_netif_rx(ifp, pkt);
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -393,7 +394,7 @@ static void brcmf_rxreorder_process_info
|
||||
if (rfi == NULL) {
|
||||
brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n",
|
||||
flow_id);
|
||||
- brcmf_netif_rx(ifp, pkt);
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -418,7 +419,7 @@ static void brcmf_rxreorder_process_info
|
||||
rfi = kzalloc(buf_size, GFP_ATOMIC);
|
||||
if (rfi == NULL) {
|
||||
brcmf_err("failed to alloc buffer\n");
|
||||
- brcmf_netif_rx(ifp, pkt);
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -532,11 +533,11 @@ static void brcmf_rxreorder_process_info
|
||||
netif_rx:
|
||||
skb_queue_walk_safe(&reorder_list, pkt, pnext) {
|
||||
__skb_unlink(pkt, &reorder_list);
|
||||
- brcmf_netif_rx(ifp, pkt);
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
}
|
||||
}
|
||||
|
||||
-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb)
|
||||
+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
@@ -560,7 +561,32 @@ void brcmf_rx_frame(struct device *dev,
|
||||
if (rd->reorder)
|
||||
brcmf_rxreorder_process_info(ifp, rd->reorder, skb);
|
||||
else
|
||||
- brcmf_netif_rx(ifp, skb);
|
||||
+ brcmf_netif_rx(ifp, skb, handle_evnt);
|
||||
+}
|
||||
+
|
||||
+void brcmf_rx_event(struct device *dev, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct brcmf_if *ifp;
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_pub *drvr = bus_if->drvr;
|
||||
+ int ret;
|
||||
+
|
||||
+ brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
|
||||
+
|
||||
+ /* process and remove protocol-specific header */
|
||||
+ ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
|
||||
+
|
||||
+ if (ret || !ifp || !ifp->ndev) {
|
||||
+ if (ret != -ENODATA && ifp)
|
||||
+ ifp->stats.rx_errors++;
|
||||
+ brcmu_pkt_buf_free_skb(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
+
|
||||
+ brcmf_fweh_process_skb(ifp->drvr, skb);
|
||||
+ brcmu_pkt_buf_free_skb(skb);
|
||||
}
|
||||
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -225,7 +225,8 @@ int brcmf_get_next_free_bsscfgidx(struct
|
||||
void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
||||
enum brcmf_netif_stop_reason reason, bool state);
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb,
|
||||
+ bool handle_event);
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||
int __init brcmf_core_init(void);
|
||||
void __exit brcmf_core_exit(void);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
@@ -1075,28 +1076,13 @@ static void brcmf_msgbuf_rxbuf_event_pos
|
||||
}
|
||||
|
||||
|
||||
-static void
|
||||
-brcmf_msgbuf_rx_skb(struct brcmf_msgbuf *msgbuf, struct sk_buff *skb,
|
||||
- u8 ifidx)
|
||||
-{
|
||||
- struct brcmf_if *ifp;
|
||||
-
|
||||
- ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
|
||||
- if (!ifp || !ifp->ndev) {
|
||||
- brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
|
||||
- brcmu_pkt_buf_free_skb(skb);
|
||||
- return;
|
||||
- }
|
||||
- brcmf_netif_rx(ifp, skb);
|
||||
-}
|
||||
-
|
||||
-
|
||||
static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
|
||||
{
|
||||
struct msgbuf_rx_event *event;
|
||||
u32 idx;
|
||||
u16 buflen;
|
||||
struct sk_buff *skb;
|
||||
+ struct brcmf_if *ifp;
|
||||
|
||||
event = (struct msgbuf_rx_event *)buf;
|
||||
idx = le32_to_cpu(event->msg.request_id);
|
||||
@@ -1116,7 +1102,19 @@ static void brcmf_msgbuf_process_event(s
|
||||
|
||||
skb_trim(skb, buflen);
|
||||
|
||||
- brcmf_msgbuf_rx_skb(msgbuf, skb, event->msg.ifidx);
|
||||
+ ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx);
|
||||
+ if (!ifp || !ifp->ndev) {
|
||||
+ brcmf_err("Received pkt for invalid ifidx %d\n",
|
||||
+ event->msg.ifidx);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
+
|
||||
+ brcmf_fweh_process_skb(ifp->drvr, skb);
|
||||
+
|
||||
+exit:
|
||||
+ brcmu_pkt_buf_free_skb(skb);
|
||||
}
|
||||
|
||||
|
||||
@@ -1128,6 +1126,7 @@ brcmf_msgbuf_process_rx_complete(struct
|
||||
u16 data_offset;
|
||||
u16 buflen;
|
||||
u32 idx;
|
||||
+ struct brcmf_if *ifp;
|
||||
|
||||
brcmf_msgbuf_update_rxbufpost_count(msgbuf, 1);
|
||||
|
||||
@@ -1148,7 +1147,14 @@ brcmf_msgbuf_process_rx_complete(struct
|
||||
|
||||
skb_trim(skb, buflen);
|
||||
|
||||
- brcmf_msgbuf_rx_skb(msgbuf, skb, rx_complete->msg.ifidx);
|
||||
+ ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx);
|
||||
+ if (!ifp || !ifp->ndev) {
|
||||
+ brcmf_err("Received pkt for invalid ifidx %d\n",
|
||||
+ rx_complete->msg.ifidx);
|
||||
+ brcmu_pkt_buf_free_skb(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+ brcmf_netif_rx(ifp, skb, false);
|
||||
}
|
||||
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -1294,6 +1294,17 @@ static inline u8 brcmf_sdio_getdatoffset
|
||||
return (u8)((hdrvalue & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT);
|
||||
}
|
||||
|
||||
+static inline bool brcmf_sdio_fromevntchan(u8 *swheader)
|
||||
+{
|
||||
+ u32 hdrvalue;
|
||||
+ u8 ret;
|
||||
+
|
||||
+ hdrvalue = *(u32 *)swheader;
|
||||
+ ret = (u8)((hdrvalue & SDPCM_CHANNEL_MASK) >> SDPCM_CHANNEL_SHIFT);
|
||||
+
|
||||
+ return (ret == SDPCM_EVENT_CHANNEL);
|
||||
+}
|
||||
+
|
||||
static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
|
||||
struct brcmf_sdio_hdrinfo *rd,
|
||||
enum brcmf_sdio_frmtype type)
|
||||
@@ -1641,7 +1652,11 @@ static u8 brcmf_sdio_rxglom(struct brcmf
|
||||
pfirst->len, pfirst->next,
|
||||
pfirst->prev);
|
||||
skb_unlink(pfirst, &bus->glom);
|
||||
- brcmf_rx_frame(bus->sdiodev->dev, pfirst);
|
||||
+ if (brcmf_sdio_fromevntchan(pfirst->data))
|
||||
+ brcmf_rx_event(bus->sdiodev->dev, pfirst);
|
||||
+ else
|
||||
+ brcmf_rx_frame(bus->sdiodev->dev, pfirst,
|
||||
+ false);
|
||||
bus->sdcnt.rxglompkts++;
|
||||
}
|
||||
|
||||
@@ -1967,18 +1982,19 @@ static uint brcmf_sdio_readframes(struct
|
||||
__skb_trim(pkt, rd->len);
|
||||
skb_pull(pkt, rd->dat_offset);
|
||||
|
||||
+ if (pkt->len == 0)
|
||||
+ brcmu_pkt_buf_free_skb(pkt);
|
||||
+ else if (rd->channel == SDPCM_EVENT_CHANNEL)
|
||||
+ brcmf_rx_event(bus->sdiodev->dev, pkt);
|
||||
+ else
|
||||
+ brcmf_rx_frame(bus->sdiodev->dev, pkt,
|
||||
+ false);
|
||||
+
|
||||
/* prepare the descriptor for the next read */
|
||||
rd->len = rd->len_nxtfrm << 4;
|
||||
rd->len_nxtfrm = 0;
|
||||
/* treat all packet as event if we don't know */
|
||||
rd->channel = SDPCM_EVENT_CHANNEL;
|
||||
-
|
||||
- if (pkt->len == 0) {
|
||||
- brcmu_pkt_buf_free_skb(pkt);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- brcmf_rx_frame(bus->sdiodev->dev, pkt);
|
||||
}
|
||||
|
||||
rxcount = maxframes - rxleft;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -514,7 +514,7 @@ static void brcmf_usb_rx_complete(struct
|
||||
|
||||
if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {
|
||||
skb_put(skb, urb->actual_length);
|
||||
- brcmf_rx_frame(devinfo->dev, skb);
|
||||
+ brcmf_rx_frame(devinfo->dev, skb, true);
|
||||
brcmf_usb_rx_refill(devinfo, req);
|
||||
} else {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
@ -0,0 +1,585 @@
|
||||
From: Arend van Spriel <arend@broadcom.com>
|
||||
Date: Mon, 11 Apr 2016 11:35:26 +0200
|
||||
Subject: [PATCH] brcmfmac: cleanup ampdu-rx host reorder code
|
||||
|
||||
The code for ampdu-rx host reorder is related to the firmware signalling
|
||||
supported in BCDC protocol. This change moves the code to fwsignal module.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -351,6 +351,12 @@ brcmf_proto_bcdc_add_tdls_peer(struct br
|
||||
{
|
||||
}
|
||||
|
||||
+static void brcmf_proto_bcdc_rxreorder(struct brcmf_if *ifp,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ brcmf_fws_rxreorder(ifp, skb);
|
||||
+}
|
||||
+
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc;
|
||||
@@ -372,6 +378,7 @@ int brcmf_proto_bcdc_attach(struct brcmf
|
||||
drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode;
|
||||
drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer;
|
||||
drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer;
|
||||
+ drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder;
|
||||
drvr->proto->pd = bcdc;
|
||||
|
||||
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -40,19 +40,6 @@
|
||||
|
||||
#define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950)
|
||||
|
||||
-/* AMPDU rx reordering definitions */
|
||||
-#define BRCMF_RXREORDER_FLOWID_OFFSET 0
|
||||
-#define BRCMF_RXREORDER_MAXIDX_OFFSET 2
|
||||
-#define BRCMF_RXREORDER_FLAGS_OFFSET 4
|
||||
-#define BRCMF_RXREORDER_CURIDX_OFFSET 6
|
||||
-#define BRCMF_RXREORDER_EXPIDX_OFFSET 8
|
||||
-
|
||||
-#define BRCMF_RXREORDER_DEL_FLOW 0x01
|
||||
-#define BRCMF_RXREORDER_FLUSH_ALL 0x02
|
||||
-#define BRCMF_RXREORDER_CURIDX_VALID 0x04
|
||||
-#define BRCMF_RXREORDER_EXPIDX_VALID 0x08
|
||||
-#define BRCMF_RXREORDER_NEW_HOLE 0x10
|
||||
-
|
||||
#define BRCMF_BSSIDX_INVALID -1
|
||||
|
||||
char *brcmf_ifname(struct brcmf_if *ifp)
|
||||
@@ -342,207 +329,11 @@ void brcmf_netif_rx(struct brcmf_if *ifp
|
||||
netif_rx_ni(skb);
|
||||
}
|
||||
|
||||
-static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi,
|
||||
- u8 start, u8 end,
|
||||
- struct sk_buff_head *skb_list)
|
||||
-{
|
||||
- /* initialize return list */
|
||||
- __skb_queue_head_init(skb_list);
|
||||
-
|
||||
- if (rfi->pend_pkts == 0) {
|
||||
- brcmf_dbg(INFO, "no packets in reorder queue\n");
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- do {
|
||||
- if (rfi->pktslots[start]) {
|
||||
- __skb_queue_tail(skb_list, rfi->pktslots[start]);
|
||||
- rfi->pktslots[start] = NULL;
|
||||
- }
|
||||
- start++;
|
||||
- if (start > rfi->max_idx)
|
||||
- start = 0;
|
||||
- } while (start != end);
|
||||
- rfi->pend_pkts -= skb_queue_len(skb_list);
|
||||
-}
|
||||
-
|
||||
-static void brcmf_rxreorder_process_info(struct brcmf_if *ifp, u8 *reorder_data,
|
||||
- struct sk_buff *pkt)
|
||||
-{
|
||||
- u8 flow_id, max_idx, cur_idx, exp_idx, end_idx;
|
||||
- struct brcmf_ampdu_rx_reorder *rfi;
|
||||
- struct sk_buff_head reorder_list;
|
||||
- struct sk_buff *pnext;
|
||||
- u8 flags;
|
||||
- u32 buf_size;
|
||||
-
|
||||
- flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET];
|
||||
- flags = reorder_data[BRCMF_RXREORDER_FLAGS_OFFSET];
|
||||
-
|
||||
- /* validate flags and flow id */
|
||||
- if (flags == 0xFF) {
|
||||
- brcmf_err("invalid flags...so ignore this packet\n");
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- rfi = ifp->drvr->reorder_flows[flow_id];
|
||||
- if (flags & BRCMF_RXREORDER_DEL_FLOW) {
|
||||
- brcmf_dbg(INFO, "flow-%d: delete\n",
|
||||
- flow_id);
|
||||
-
|
||||
- if (rfi == NULL) {
|
||||
- brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n",
|
||||
- flow_id);
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, rfi->exp_idx,
|
||||
- &reorder_list);
|
||||
- /* add the last packet */
|
||||
- __skb_queue_tail(&reorder_list, pkt);
|
||||
- kfree(rfi);
|
||||
- ifp->drvr->reorder_flows[flow_id] = NULL;
|
||||
- goto netif_rx;
|
||||
- }
|
||||
- /* from here on we need a flow reorder instance */
|
||||
- if (rfi == NULL) {
|
||||
- buf_size = sizeof(*rfi);
|
||||
- max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET];
|
||||
-
|
||||
- buf_size += (max_idx + 1) * sizeof(pkt);
|
||||
-
|
||||
- /* allocate space for flow reorder info */
|
||||
- brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n",
|
||||
- flow_id, max_idx);
|
||||
- rfi = kzalloc(buf_size, GFP_ATOMIC);
|
||||
- if (rfi == NULL) {
|
||||
- brcmf_err("failed to alloc buffer\n");
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- ifp->drvr->reorder_flows[flow_id] = rfi;
|
||||
- rfi->pktslots = (struct sk_buff **)(rfi+1);
|
||||
- rfi->max_idx = max_idx;
|
||||
- }
|
||||
- if (flags & BRCMF_RXREORDER_NEW_HOLE) {
|
||||
- if (rfi->pend_pkts) {
|
||||
- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx,
|
||||
- rfi->exp_idx,
|
||||
- &reorder_list);
|
||||
- WARN_ON(rfi->pend_pkts);
|
||||
- } else {
|
||||
- __skb_queue_head_init(&reorder_list);
|
||||
- }
|
||||
- rfi->cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET];
|
||||
- rfi->exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET];
|
||||
- rfi->max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET];
|
||||
- rfi->pktslots[rfi->cur_idx] = pkt;
|
||||
- rfi->pend_pkts++;
|
||||
- brcmf_dbg(DATA, "flow-%d: new hole %d (%d), pending %d\n",
|
||||
- flow_id, rfi->cur_idx, rfi->exp_idx, rfi->pend_pkts);
|
||||
- } else if (flags & BRCMF_RXREORDER_CURIDX_VALID) {
|
||||
- cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET];
|
||||
- exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET];
|
||||
-
|
||||
- if ((exp_idx == rfi->exp_idx) && (cur_idx != rfi->exp_idx)) {
|
||||
- /* still in the current hole */
|
||||
- /* enqueue the current on the buffer chain */
|
||||
- if (rfi->pktslots[cur_idx] != NULL) {
|
||||
- brcmf_dbg(INFO, "HOLE: ERROR buffer pending..free it\n");
|
||||
- brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]);
|
||||
- rfi->pktslots[cur_idx] = NULL;
|
||||
- }
|
||||
- rfi->pktslots[cur_idx] = pkt;
|
||||
- rfi->pend_pkts++;
|
||||
- rfi->cur_idx = cur_idx;
|
||||
- brcmf_dbg(DATA, "flow-%d: store pkt %d (%d), pending %d\n",
|
||||
- flow_id, cur_idx, exp_idx, rfi->pend_pkts);
|
||||
-
|
||||
- /* can return now as there is no reorder
|
||||
- * list to process.
|
||||
- */
|
||||
- return;
|
||||
- }
|
||||
- if (rfi->exp_idx == cur_idx) {
|
||||
- if (rfi->pktslots[cur_idx] != NULL) {
|
||||
- brcmf_dbg(INFO, "error buffer pending..free it\n");
|
||||
- brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]);
|
||||
- rfi->pktslots[cur_idx] = NULL;
|
||||
- }
|
||||
- rfi->pktslots[cur_idx] = pkt;
|
||||
- rfi->pend_pkts++;
|
||||
-
|
||||
- /* got the expected one. flush from current to expected
|
||||
- * and update expected
|
||||
- */
|
||||
- brcmf_dbg(DATA, "flow-%d: expected %d (%d), pending %d\n",
|
||||
- flow_id, cur_idx, exp_idx, rfi->pend_pkts);
|
||||
-
|
||||
- rfi->cur_idx = cur_idx;
|
||||
- rfi->exp_idx = exp_idx;
|
||||
-
|
||||
- brcmf_rxreorder_get_skb_list(rfi, cur_idx, exp_idx,
|
||||
- &reorder_list);
|
||||
- brcmf_dbg(DATA, "flow-%d: freeing buffers %d, pending %d\n",
|
||||
- flow_id, skb_queue_len(&reorder_list),
|
||||
- rfi->pend_pkts);
|
||||
- } else {
|
||||
- u8 end_idx;
|
||||
-
|
||||
- brcmf_dbg(DATA, "flow-%d (0x%x): both moved, old %d/%d, new %d/%d\n",
|
||||
- flow_id, flags, rfi->cur_idx, rfi->exp_idx,
|
||||
- cur_idx, exp_idx);
|
||||
- if (flags & BRCMF_RXREORDER_FLUSH_ALL)
|
||||
- end_idx = rfi->exp_idx;
|
||||
- else
|
||||
- end_idx = exp_idx;
|
||||
-
|
||||
- /* flush pkts first */
|
||||
- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx,
|
||||
- &reorder_list);
|
||||
-
|
||||
- if (exp_idx == ((cur_idx + 1) % (rfi->max_idx + 1))) {
|
||||
- __skb_queue_tail(&reorder_list, pkt);
|
||||
- } else {
|
||||
- rfi->pktslots[cur_idx] = pkt;
|
||||
- rfi->pend_pkts++;
|
||||
- }
|
||||
- rfi->exp_idx = exp_idx;
|
||||
- rfi->cur_idx = cur_idx;
|
||||
- }
|
||||
- } else {
|
||||
- /* explicity window move updating the expected index */
|
||||
- exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET];
|
||||
-
|
||||
- brcmf_dbg(DATA, "flow-%d (0x%x): change expected: %d -> %d\n",
|
||||
- flow_id, flags, rfi->exp_idx, exp_idx);
|
||||
- if (flags & BRCMF_RXREORDER_FLUSH_ALL)
|
||||
- end_idx = rfi->exp_idx;
|
||||
- else
|
||||
- end_idx = exp_idx;
|
||||
-
|
||||
- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx,
|
||||
- &reorder_list);
|
||||
- __skb_queue_tail(&reorder_list, pkt);
|
||||
- /* set the new expected idx */
|
||||
- rfi->exp_idx = exp_idx;
|
||||
- }
|
||||
-netif_rx:
|
||||
- skb_queue_walk_safe(&reorder_list, pkt, pnext) {
|
||||
- __skb_unlink(pkt, &reorder_list);
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_pub *drvr = bus_if->drvr;
|
||||
- struct brcmf_skb_reorder_data *rd;
|
||||
int ret;
|
||||
|
||||
brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
|
||||
@@ -557,9 +348,8 @@ void brcmf_rx_frame(struct device *dev,
|
||||
return;
|
||||
}
|
||||
|
||||
- rd = (struct brcmf_skb_reorder_data *)skb->cb;
|
||||
- if (rd->reorder)
|
||||
- brcmf_rxreorder_process_info(ifp, rd->reorder, skb);
|
||||
+ if (brcmf_proto_is_reorder_skb(skb))
|
||||
+ brcmf_proto_rxreorder(ifp, skb);
|
||||
else
|
||||
brcmf_netif_rx(ifp, skb, handle_evnt);
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -208,10 +208,6 @@ struct brcmf_if {
|
||||
u8 ipv6addr_idx;
|
||||
};
|
||||
|
||||
-struct brcmf_skb_reorder_data {
|
||||
- u8 *reorder;
|
||||
-};
|
||||
-
|
||||
int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
|
||||
|
||||
/* Return pointer to interface name */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
@@ -92,6 +92,19 @@ enum brcmf_fws_tlv_len {
|
||||
};
|
||||
#undef BRCMF_FWS_TLV_DEF
|
||||
|
||||
+/* AMPDU rx reordering definitions */
|
||||
+#define BRCMF_RXREORDER_FLOWID_OFFSET 0
|
||||
+#define BRCMF_RXREORDER_MAXIDX_OFFSET 2
|
||||
+#define BRCMF_RXREORDER_FLAGS_OFFSET 4
|
||||
+#define BRCMF_RXREORDER_CURIDX_OFFSET 6
|
||||
+#define BRCMF_RXREORDER_EXPIDX_OFFSET 8
|
||||
+
|
||||
+#define BRCMF_RXREORDER_DEL_FLOW 0x01
|
||||
+#define BRCMF_RXREORDER_FLUSH_ALL 0x02
|
||||
+#define BRCMF_RXREORDER_CURIDX_VALID 0x04
|
||||
+#define BRCMF_RXREORDER_EXPIDX_VALID 0x08
|
||||
+#define BRCMF_RXREORDER_NEW_HOLE 0x10
|
||||
+
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* brcmf_fws_tlv_names - array of tlv names.
|
||||
@@ -1614,6 +1627,202 @@ static int brcmf_fws_notify_bcmc_credit_
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi,
|
||||
+ u8 start, u8 end,
|
||||
+ struct sk_buff_head *skb_list)
|
||||
+{
|
||||
+ /* initialize return list */
|
||||
+ __skb_queue_head_init(skb_list);
|
||||
+
|
||||
+ if (rfi->pend_pkts == 0) {
|
||||
+ brcmf_dbg(INFO, "no packets in reorder queue\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ do {
|
||||
+ if (rfi->pktslots[start]) {
|
||||
+ __skb_queue_tail(skb_list, rfi->pktslots[start]);
|
||||
+ rfi->pktslots[start] = NULL;
|
||||
+ }
|
||||
+ start++;
|
||||
+ if (start > rfi->max_idx)
|
||||
+ start = 0;
|
||||
+ } while (start != end);
|
||||
+ rfi->pend_pkts -= skb_queue_len(skb_list);
|
||||
+}
|
||||
+
|
||||
+void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt)
|
||||
+{
|
||||
+ u8 *reorder_data;
|
||||
+ u8 flow_id, max_idx, cur_idx, exp_idx, end_idx;
|
||||
+ struct brcmf_ampdu_rx_reorder *rfi;
|
||||
+ struct sk_buff_head reorder_list;
|
||||
+ struct sk_buff *pnext;
|
||||
+ u8 flags;
|
||||
+ u32 buf_size;
|
||||
+
|
||||
+ reorder_data = ((struct brcmf_skb_reorder_data *)pkt->cb)->reorder;
|
||||
+ flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET];
|
||||
+ flags = reorder_data[BRCMF_RXREORDER_FLAGS_OFFSET];
|
||||
+
|
||||
+ /* validate flags and flow id */
|
||||
+ if (flags == 0xFF) {
|
||||
+ brcmf_err("invalid flags...so ignore this packet\n");
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ rfi = ifp->drvr->reorder_flows[flow_id];
|
||||
+ if (flags & BRCMF_RXREORDER_DEL_FLOW) {
|
||||
+ brcmf_dbg(INFO, "flow-%d: delete\n",
|
||||
+ flow_id);
|
||||
+
|
||||
+ if (rfi == NULL) {
|
||||
+ brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n",
|
||||
+ flow_id);
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, rfi->exp_idx,
|
||||
+ &reorder_list);
|
||||
+ /* add the last packet */
|
||||
+ __skb_queue_tail(&reorder_list, pkt);
|
||||
+ kfree(rfi);
|
||||
+ ifp->drvr->reorder_flows[flow_id] = NULL;
|
||||
+ goto netif_rx;
|
||||
+ }
|
||||
+ /* from here on we need a flow reorder instance */
|
||||
+ if (rfi == NULL) {
|
||||
+ buf_size = sizeof(*rfi);
|
||||
+ max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET];
|
||||
+
|
||||
+ buf_size += (max_idx + 1) * sizeof(pkt);
|
||||
+
|
||||
+ /* allocate space for flow reorder info */
|
||||
+ brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n",
|
||||
+ flow_id, max_idx);
|
||||
+ rfi = kzalloc(buf_size, GFP_ATOMIC);
|
||||
+ if (rfi == NULL) {
|
||||
+ brcmf_err("failed to alloc buffer\n");
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ifp->drvr->reorder_flows[flow_id] = rfi;
|
||||
+ rfi->pktslots = (struct sk_buff **)(rfi + 1);
|
||||
+ rfi->max_idx = max_idx;
|
||||
+ }
|
||||
+ if (flags & BRCMF_RXREORDER_NEW_HOLE) {
|
||||
+ if (rfi->pend_pkts) {
|
||||
+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx,
|
||||
+ rfi->exp_idx,
|
||||
+ &reorder_list);
|
||||
+ WARN_ON(rfi->pend_pkts);
|
||||
+ } else {
|
||||
+ __skb_queue_head_init(&reorder_list);
|
||||
+ }
|
||||
+ rfi->cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET];
|
||||
+ rfi->exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET];
|
||||
+ rfi->max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET];
|
||||
+ rfi->pktslots[rfi->cur_idx] = pkt;
|
||||
+ rfi->pend_pkts++;
|
||||
+ brcmf_dbg(DATA, "flow-%d: new hole %d (%d), pending %d\n",
|
||||
+ flow_id, rfi->cur_idx, rfi->exp_idx, rfi->pend_pkts);
|
||||
+ } else if (flags & BRCMF_RXREORDER_CURIDX_VALID) {
|
||||
+ cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET];
|
||||
+ exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET];
|
||||
+
|
||||
+ if ((exp_idx == rfi->exp_idx) && (cur_idx != rfi->exp_idx)) {
|
||||
+ /* still in the current hole */
|
||||
+ /* enqueue the current on the buffer chain */
|
||||
+ if (rfi->pktslots[cur_idx] != NULL) {
|
||||
+ brcmf_dbg(INFO, "HOLE: ERROR buffer pending..free it\n");
|
||||
+ brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]);
|
||||
+ rfi->pktslots[cur_idx] = NULL;
|
||||
+ }
|
||||
+ rfi->pktslots[cur_idx] = pkt;
|
||||
+ rfi->pend_pkts++;
|
||||
+ rfi->cur_idx = cur_idx;
|
||||
+ brcmf_dbg(DATA, "flow-%d: store pkt %d (%d), pending %d\n",
|
||||
+ flow_id, cur_idx, exp_idx, rfi->pend_pkts);
|
||||
+
|
||||
+ /* can return now as there is no reorder
|
||||
+ * list to process.
|
||||
+ */
|
||||
+ return;
|
||||
+ }
|
||||
+ if (rfi->exp_idx == cur_idx) {
|
||||
+ if (rfi->pktslots[cur_idx] != NULL) {
|
||||
+ brcmf_dbg(INFO, "error buffer pending..free it\n");
|
||||
+ brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]);
|
||||
+ rfi->pktslots[cur_idx] = NULL;
|
||||
+ }
|
||||
+ rfi->pktslots[cur_idx] = pkt;
|
||||
+ rfi->pend_pkts++;
|
||||
+
|
||||
+ /* got the expected one. flush from current to expected
|
||||
+ * and update expected
|
||||
+ */
|
||||
+ brcmf_dbg(DATA, "flow-%d: expected %d (%d), pending %d\n",
|
||||
+ flow_id, cur_idx, exp_idx, rfi->pend_pkts);
|
||||
+
|
||||
+ rfi->cur_idx = cur_idx;
|
||||
+ rfi->exp_idx = exp_idx;
|
||||
+
|
||||
+ brcmf_rxreorder_get_skb_list(rfi, cur_idx, exp_idx,
|
||||
+ &reorder_list);
|
||||
+ brcmf_dbg(DATA, "flow-%d: freeing buffers %d, pending %d\n",
|
||||
+ flow_id, skb_queue_len(&reorder_list),
|
||||
+ rfi->pend_pkts);
|
||||
+ } else {
|
||||
+ u8 end_idx;
|
||||
+
|
||||
+ brcmf_dbg(DATA, "flow-%d (0x%x): both moved, old %d/%d, new %d/%d\n",
|
||||
+ flow_id, flags, rfi->cur_idx, rfi->exp_idx,
|
||||
+ cur_idx, exp_idx);
|
||||
+ if (flags & BRCMF_RXREORDER_FLUSH_ALL)
|
||||
+ end_idx = rfi->exp_idx;
|
||||
+ else
|
||||
+ end_idx = exp_idx;
|
||||
+
|
||||
+ /* flush pkts first */
|
||||
+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx,
|
||||
+ &reorder_list);
|
||||
+
|
||||
+ if (exp_idx == ((cur_idx + 1) % (rfi->max_idx + 1))) {
|
||||
+ __skb_queue_tail(&reorder_list, pkt);
|
||||
+ } else {
|
||||
+ rfi->pktslots[cur_idx] = pkt;
|
||||
+ rfi->pend_pkts++;
|
||||
+ }
|
||||
+ rfi->exp_idx = exp_idx;
|
||||
+ rfi->cur_idx = cur_idx;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* explicity window move updating the expected index */
|
||||
+ exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET];
|
||||
+
|
||||
+ brcmf_dbg(DATA, "flow-%d (0x%x): change expected: %d -> %d\n",
|
||||
+ flow_id, flags, rfi->exp_idx, exp_idx);
|
||||
+ if (flags & BRCMF_RXREORDER_FLUSH_ALL)
|
||||
+ end_idx = rfi->exp_idx;
|
||||
+ else
|
||||
+ end_idx = exp_idx;
|
||||
+
|
||||
+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx,
|
||||
+ &reorder_list);
|
||||
+ __skb_queue_tail(&reorder_list, pkt);
|
||||
+ /* set the new expected idx */
|
||||
+ rfi->exp_idx = exp_idx;
|
||||
+ }
|
||||
+netif_rx:
|
||||
+ skb_queue_walk_safe(&reorder_list, pkt, pnext) {
|
||||
+ __skb_unlink(pkt, &reorder_list);
|
||||
+ brcmf_netif_rx(ifp, pkt, false);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
|
||||
{
|
||||
struct brcmf_skb_reorder_data *rd;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h
|
||||
@@ -29,5 +29,6 @@ void brcmf_fws_add_interface(struct brcm
|
||||
void brcmf_fws_del_interface(struct brcmf_if *ifp);
|
||||
void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb);
|
||||
void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked);
|
||||
+void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
|
||||
#endif /* FWSIGNAL_H_ */
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
@@ -527,6 +527,9 @@ static int brcmf_msgbuf_hdrpull(struct b
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
+static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb)
|
||||
+{
|
||||
+}
|
||||
|
||||
static void
|
||||
brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf *msgbuf, u16 flowid)
|
||||
@@ -1466,6 +1469,7 @@ int brcmf_proto_msgbuf_attach(struct brc
|
||||
drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode;
|
||||
drvr->proto->delete_peer = brcmf_msgbuf_delete_peer;
|
||||
drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer;
|
||||
+ drvr->proto->rxreorder = brcmf_msgbuf_rxreorder;
|
||||
drvr->proto->pd = msgbuf;
|
||||
|
||||
init_waitqueue_head(&msgbuf->ioctl_resp_wait);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
@@ -22,6 +22,9 @@ enum proto_addr_mode {
|
||||
ADDR_DIRECT
|
||||
};
|
||||
|
||||
+struct brcmf_skb_reorder_data {
|
||||
+ u8 *reorder;
|
||||
+};
|
||||
|
||||
struct brcmf_proto {
|
||||
int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
|
||||
@@ -38,6 +41,7 @@ struct brcmf_proto {
|
||||
u8 peer[ETH_ALEN]);
|
||||
void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx,
|
||||
u8 peer[ETH_ALEN]);
|
||||
+ void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void *pd;
|
||||
};
|
||||
|
||||
@@ -91,6 +95,18 @@ brcmf_proto_add_tdls_peer(struct brcmf_p
|
||||
{
|
||||
drvr->proto->add_tdls_peer(drvr, ifidx, peer);
|
||||
}
|
||||
+static inline bool brcmf_proto_is_reorder_skb(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct brcmf_skb_reorder_data *rd;
|
||||
+
|
||||
+ rd = (struct brcmf_skb_reorder_data *)skb->cb;
|
||||
+ return !!rd->reorder;
|
||||
+}
|
||||
|
||||
+static inline void
|
||||
+brcmf_proto_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb)
|
||||
+{
|
||||
+ ifp->drvr->proto->rxreorder(ifp, skb);
|
||||
+}
|
||||
|
||||
#endif /* BRCMFMAC_PROTO_H */
|
||||
@ -0,0 +1,139 @@
|
||||
From: Arend van Spriel <arend@broadcom.com>
|
||||
Date: Mon, 11 Apr 2016 11:35:27 +0200
|
||||
Subject: [PATCH] brcmfmac: revise handling events in receive path
|
||||
|
||||
Move event handling out of brcmf_netif_rx() avoiding the need
|
||||
to pass a flag. This flag is only ever true for USB hosts as
|
||||
other interface use separate brcmf_rx_event() function.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
@@ -216,7 +216,7 @@ bool brcmf_c_prec_enq(struct device *dev
|
||||
int prec);
|
||||
|
||||
/* Receive frame for delivery to OS. Callee disposes of rxp. */
|
||||
-void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_evnt);
|
||||
+void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
|
||||
/* Receive async event packet from firmware. Callee disposes of rxp. */
|
||||
void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -298,18 +298,11 @@ void brcmf_txflowblock(struct device *de
|
||||
brcmf_fws_bus_blocked(drvr, state);
|
||||
}
|
||||
|
||||
-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb,
|
||||
- bool handle_event)
|
||||
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
|
||||
{
|
||||
- skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
-
|
||||
if (skb->pkt_type == PACKET_MULTICAST)
|
||||
ifp->stats.multicast++;
|
||||
|
||||
- /* Process special event packets */
|
||||
- if (handle_event)
|
||||
- brcmf_fweh_process_skb(ifp->drvr, skb);
|
||||
-
|
||||
if (!(ifp->ndev->flags & IFF_UP)) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
return;
|
||||
@@ -329,7 +322,7 @@ void brcmf_netif_rx(struct brcmf_if *ifp
|
||||
netif_rx_ni(skb);
|
||||
}
|
||||
|
||||
-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt)
|
||||
+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
@@ -348,10 +341,17 @@ void brcmf_rx_frame(struct device *dev,
|
||||
return;
|
||||
}
|
||||
|
||||
- if (brcmf_proto_is_reorder_skb(skb))
|
||||
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
+
|
||||
+ if (brcmf_proto_is_reorder_skb(skb)) {
|
||||
brcmf_proto_rxreorder(ifp, skb);
|
||||
- else
|
||||
- brcmf_netif_rx(ifp, skb, handle_evnt);
|
||||
+ } else {
|
||||
+ /* Process special event packets */
|
||||
+ if (handle_event)
|
||||
+ brcmf_fweh_process_skb(ifp->drvr, skb);
|
||||
+
|
||||
+ brcmf_netif_rx(ifp, skb);
|
||||
+ }
|
||||
}
|
||||
|
||||
void brcmf_rx_event(struct device *dev, struct sk_buff *skb)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -221,8 +221,7 @@ int brcmf_get_next_free_bsscfgidx(struct
|
||||
void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
||||
enum brcmf_netif_stop_reason reason, bool state);
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb,
|
||||
- bool handle_event);
|
||||
+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||
int __init brcmf_core_init(void);
|
||||
void __exit brcmf_core_exit(void);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
@@ -1668,7 +1668,7 @@ void brcmf_fws_rxreorder(struct brcmf_if
|
||||
/* validate flags and flow id */
|
||||
if (flags == 0xFF) {
|
||||
brcmf_err("invalid flags...so ignore this packet\n");
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
+ brcmf_netif_rx(ifp, pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1680,7 +1680,7 @@ void brcmf_fws_rxreorder(struct brcmf_if
|
||||
if (rfi == NULL) {
|
||||
brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n",
|
||||
flow_id);
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
+ brcmf_netif_rx(ifp, pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1705,7 +1705,7 @@ void brcmf_fws_rxreorder(struct brcmf_if
|
||||
rfi = kzalloc(buf_size, GFP_ATOMIC);
|
||||
if (rfi == NULL) {
|
||||
brcmf_err("failed to alloc buffer\n");
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
+ brcmf_netif_rx(ifp, pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1819,7 +1819,7 @@ void brcmf_fws_rxreorder(struct brcmf_if
|
||||
netif_rx:
|
||||
skb_queue_walk_safe(&reorder_list, pkt, pnext) {
|
||||
__skb_unlink(pkt, &reorder_list);
|
||||
- brcmf_netif_rx(ifp, pkt, false);
|
||||
+ brcmf_netif_rx(ifp, pkt);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
@@ -1157,7 +1157,7 @@ brcmf_msgbuf_process_rx_complete(struct
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
return;
|
||||
}
|
||||
- brcmf_netif_rx(ifp, skb, false);
|
||||
+ brcmf_netif_rx(ifp, skb);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
From: Arend van Spriel <arend@broadcom.com>
|
||||
Date: Mon, 11 Apr 2016 11:35:28 +0200
|
||||
Subject: [PATCH] brcmfmac: create common function for handling
|
||||
brcmf_proto_hdrpull()
|
||||
|
||||
In receive path brcmf_proto_hdrpull() needs to be called and handled
|
||||
similar in brcmf_rx_frame() and brcmf_rx_event(). Move that duplicated
|
||||
code in separate function.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -322,26 +322,35 @@ void brcmf_netif_rx(struct brcmf_if *ifp
|
||||
netif_rx_ni(skb);
|
||||
}
|
||||
|
||||
-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
|
||||
+static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,
|
||||
+ struct brcmf_if **ifp)
|
||||
{
|
||||
- struct brcmf_if *ifp;
|
||||
- struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
- struct brcmf_pub *drvr = bus_if->drvr;
|
||||
int ret;
|
||||
|
||||
- brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
|
||||
-
|
||||
/* process and remove protocol-specific header */
|
||||
- ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
|
||||
+ ret = brcmf_proto_hdrpull(drvr, true, skb, ifp);
|
||||
|
||||
- if (ret || !ifp || !ifp->ndev) {
|
||||
+ if (ret || !(*ifp) || !(*ifp)->ndev) {
|
||||
if (ret != -ENODATA && ifp)
|
||||
- ifp->stats.rx_errors++;
|
||||
+ (*ifp)->stats.rx_errors++;
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
- return;
|
||||
+ return -ENODATA;
|
||||
}
|
||||
|
||||
- skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
+ skb->protocol = eth_type_trans(skb, (*ifp)->ndev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
|
||||
+{
|
||||
+ struct brcmf_if *ifp;
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_pub *drvr = bus_if->drvr;
|
||||
+
|
||||
+ brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
|
||||
+
|
||||
+ if (brcmf_rx_hdrpull(drvr, skb, &ifp))
|
||||
+ return;
|
||||
|
||||
if (brcmf_proto_is_reorder_skb(skb)) {
|
||||
brcmf_proto_rxreorder(ifp, skb);
|
||||
@@ -359,21 +368,11 @@ void brcmf_rx_event(struct device *dev,
|
||||
struct brcmf_if *ifp;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_pub *drvr = bus_if->drvr;
|
||||
- int ret;
|
||||
|
||||
brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
|
||||
|
||||
- /* process and remove protocol-specific header */
|
||||
- ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
|
||||
-
|
||||
- if (ret || !ifp || !ifp->ndev) {
|
||||
- if (ret != -ENODATA && ifp)
|
||||
- ifp->stats.rx_errors++;
|
||||
- brcmu_pkt_buf_free_skb(skb);
|
||||
+ if (brcmf_rx_hdrpull(drvr, skb, &ifp))
|
||||
return;
|
||||
- }
|
||||
-
|
||||
- skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
|
||||
brcmf_fweh_process_skb(ifp->drvr, skb);
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
@ -43,7 +43,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -506,6 +506,21 @@ brcmf_cfg80211_update_proto_addr_mode(st
|
||||
@@ -527,6 +527,21 @@ brcmf_cfg80211_update_proto_addr_mode(st
|
||||
ADDR_INDIRECT);
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
|
||||
{
|
||||
struct brcmf_mbss_ssid_le mbss_ssid_le;
|
||||
@@ -513,7 +528,7 @@ static int brcmf_cfg80211_request_ap_if(
|
||||
@@ -534,7 +549,7 @@ static int brcmf_cfg80211_request_ap_if(
|
||||
int err;
|
||||
|
||||
memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
|
||||
@ -76,7 +76,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -909,30 +909,6 @@ void brcmf_remove_interface(struct brcmf
|
||||
@@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf
|
||||
brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
static int brcmf_inetaddr_changed(struct notifier_block *nb,
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -214,7 +214,6 @@ int brcmf_net_attach(struct brcmf_if *if
|
||||
@@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *if
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
bool is_p2pdev, char *name, u8 *mac_addr);
|
||||
void brcmf_remove_interface(struct brcmf_if *ifp);
|
||||
|
||||
@ -27,7 +27,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2690,7 +2690,7 @@ static s32 brcmf_inform_single_bss(struc
|
||||
@@ -2689,7 +2689,7 @@ static s32 brcmf_inform_single_bss(struc
|
||||
if (!bi->ctl_ch) {
|
||||
ch.chspec = le16_to_cpu(bi->chanspec);
|
||||
cfg->d11inf.decchspec(&ch);
|
||||
@ -36,7 +36,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
}
|
||||
channel = bi->ctl_ch;
|
||||
|
||||
@@ -2808,7 +2808,7 @@ static s32 brcmf_inform_ibss(struct brcm
|
||||
@@ -2807,7 +2807,7 @@ static s32 brcmf_inform_ibss(struct brcm
|
||||
else
|
||||
band = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
@ -45,7 +45,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
cfg->channel = freq;
|
||||
notify_channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
||||
@@ -2818,7 +2818,7 @@ static s32 brcmf_inform_ibss(struct brcm
|
||||
@@ -2817,7 +2817,7 @@ static s32 brcmf_inform_ibss(struct brcm
|
||||
notify_ielen = le32_to_cpu(bi->ie_length);
|
||||
notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
|
||||
|
||||
@ -54,7 +54,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
brcmf_dbg(CONN, "capability: %X\n", notify_capability);
|
||||
brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
|
||||
brcmf_dbg(CONN, "signal: %d\n", notify_signal);
|
||||
@@ -5132,7 +5132,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8
|
||||
@@ -5235,7 +5235,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8
|
||||
else
|
||||
band = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
@ -63,7 +63,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
notify_channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
||||
done:
|
||||
@@ -5654,14 +5654,15 @@ static int brcmf_construct_chaninfo(stru
|
||||
@@ -5757,14 +5757,15 @@ static int brcmf_construct_chaninfo(stru
|
||||
channel = band->channels;
|
||||
index = band->n_channels;
|
||||
for (j = 0; j < band->n_channels; j++) {
|
||||
@ -82,7 +82,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
/* assuming the chanspecs order is HT20,
|
||||
* HT40 upper, HT40 lower, and VHT80.
|
||||
@@ -5763,7 +5764,7 @@ static int brcmf_enable_bw40_2g(struct b
|
||||
@@ -5866,7 +5867,7 @@ static int brcmf_enable_bw40_2g(struct b
|
||||
if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
|
||||
continue;
|
||||
for (j = 0; j < band->n_channels; j++) {
|
||||
@ -102,7 +102,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
}
|
||||
afx_hdl->peer_chan = bi->ctl_ch;
|
||||
brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n",
|
||||
@@ -1380,7 +1380,7 @@ int brcmf_p2p_notify_action_frame_rx(str
|
||||
@@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(str
|
||||
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
|
||||
&p2p->status) &&
|
||||
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
|
||||
@ -111,7 +111,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
|
||||
afx_hdl->peer_chan);
|
||||
complete(&afx_hdl->act_frm_scan);
|
||||
@@ -1423,7 +1423,7 @@ int brcmf_p2p_notify_action_frame_rx(str
|
||||
@@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(str
|
||||
memcpy(&mgmt_frame->u, frame, mgmt_frame_len);
|
||||
mgmt_frame_len += offsetof(struct ieee80211_mgmt, u);
|
||||
|
||||
@ -120,7 +120,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
ch.band == BRCMU_CHAN_BAND_2G ?
|
||||
IEEE80211_BAND_2GHZ :
|
||||
IEEE80211_BAND_5GHZ);
|
||||
@@ -1863,7 +1863,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
|
||||
@@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
|
||||
|
||||
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
|
||||
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) {
|
||||
@ -129,7 +129,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
|
||||
afx_hdl->peer_chan);
|
||||
complete(&afx_hdl->act_frm_scan);
|
||||
@@ -1888,7 +1888,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
|
||||
@@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere
|
||||
|
||||
mgmt_frame = (u8 *)(rxframe + 1);
|
||||
mgmt_frame_len = e->datalen - sizeof(*rxframe);
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -4769,6 +4769,68 @@ exit:
|
||||
@@ -4847,6 +4847,68 @@ exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
enum nl80211_crit_proto_id proto,
|
||||
@@ -4906,6 +4968,7 @@ static struct cfg80211_ops wl_cfg80211_o
|
||||
@@ -5009,6 +5071,7 @@ static struct cfg80211_ops brcmf_cfg8021
|
||||
.mgmt_tx = brcmf_cfg80211_mgmt_tx,
|
||||
.remain_on_channel = brcmf_p2p_remain_on_channel,
|
||||
.cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -649,20 +649,24 @@ static struct wireless_dev *brcmf_cfg802
|
||||
@@ -670,20 +670,24 @@ static struct wireless_dev *brcmf_cfg802
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
case NL80211_IFTYPE_AP:
|
||||
wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
|
||||
@ -48,7 +48,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2020,8 +2020,6 @@ static int brcmf_p2p_request_p2p_if(stru
|
||||
@@ -2030,8 +2030,6 @@ static int brcmf_p2p_request_p2p_if(stru
|
||||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request,
|
||||
sizeof(if_request));
|
||||
|
||||
@ -32,7 +32,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -4304,7 +4304,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
@@ -4382,7 +4382,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
struct brcmf_join_params join_params;
|
||||
enum nl80211_iftype dev_role;
|
||||
struct brcmf_fil_bss_enable_le bss_enable;
|
||||
@ -41,7 +41,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
bool mbss;
|
||||
int is_11d;
|
||||
|
||||
@@ -4380,16 +4380,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
@@ -4458,16 +4458,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
|
||||
brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
|
||||
|
||||
@ -59,7 +59,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
if (is_11d != ifp->vif->is_11d) {
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
|
||||
is_11d);
|
||||
@@ -4437,6 +4429,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
@@ -4515,6 +4507,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
@ -68,7 +68,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
if (dev_role == NL80211_IFTYPE_AP) {
|
||||
if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
|
||||
brcmf_fil_iovar_int_set(ifp, "mbss", 1);
|
||||
@@ -4446,6 +4440,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
@@ -4524,6 +4518,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
brcmf_err("setting AP mode failed %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
@ -86,7 +86,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
|
||||
if (err < 0) {
|
||||
brcmf_err("BRCMF_C_UP error (%d)\n", err);
|
||||
@@ -4467,7 +4472,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
@@ -4545,7 +4550,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
goto exit;
|
||||
}
|
||||
brcmf_dbg(TRACE, "AP mode configuration complete\n");
|
||||
@ -101,7 +101,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
|
||||
sizeof(ssid_le));
|
||||
if (err < 0) {
|
||||
@@ -4484,7 +4495,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
@@ -4562,7 +4573,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
}
|
||||
|
||||
brcmf_dbg(TRACE, "GO mode configuration complete\n");
|
||||
|
||||
@ -41,7 +41,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -5269,7 +5269,6 @@ brcmf_notify_connect_status_ap(struct br
|
||||
@@ -5372,7 +5372,6 @@ brcmf_notify_connect_status_ap(struct br
|
||||
struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e, void *data)
|
||||
{
|
||||
@ -49,7 +49,7 @@ Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
static int generation;
|
||||
u32 event = e->event_code;
|
||||
u32 reason = e->reason;
|
||||
@@ -5280,8 +5279,6 @@ brcmf_notify_connect_status_ap(struct br
|
||||
@@ -5383,8 +5382,6 @@ brcmf_notify_connect_status_ap(struct br
|
||||
ndev != cfg_to_ndev(cfg)) {
|
||||
brcmf_dbg(CONN, "AP mode link down\n");
|
||||
complete(&cfg->vif_disabled);
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Mon, 6 Jun 2016 23:03:55 +0200
|
||||
Subject: [PATCH] brcmfmac: drop unused pm_block vif attribute
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This attribute was added 3 years ago by
|
||||
commit 3eacf866559c ("brcmfmac: introduce brcmf_cfg80211_vif structure")
|
||||
but it remains unused since then. It seems we can safely drop it.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -587,7 +587,7 @@ struct wireless_dev *brcmf_ap_add_vif(st
|
||||
|
||||
brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
|
||||
|
||||
- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
|
||||
+ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
|
||||
if (IS_ERR(vif))
|
||||
return (struct wireless_dev *)vif;
|
||||
|
||||
@@ -5098,8 +5098,7 @@ static struct cfg80211_ops brcmf_cfg8021
|
||||
};
|
||||
|
||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
- enum nl80211_iftype type,
|
||||
- bool pm_block)
|
||||
+ enum nl80211_iftype type)
|
||||
{
|
||||
struct brcmf_cfg80211_vif *vif_walk;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
@@ -5114,8 +5113,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v
|
||||
vif->wdev.wiphy = cfg->wiphy;
|
||||
vif->wdev.iftype = type;
|
||||
|
||||
- vif->pm_block = pm_block;
|
||||
-
|
||||
brcmf_init_prof(&vif->profile);
|
||||
|
||||
if (type == NL80211_IFTYPE_AP) {
|
||||
@@ -6754,7 +6751,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
|
||||
init_vif_event(&cfg->vif_event);
|
||||
INIT_LIST_HEAD(&cfg->vif_list);
|
||||
|
||||
- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
|
||||
+ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
|
||||
if (IS_ERR(vif))
|
||||
goto wiphy_out;
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -167,7 +167,6 @@ struct vif_saved_ie {
|
||||
* @wdev: wireless device.
|
||||
* @profile: profile information.
|
||||
* @sme_state: SME state using enum brcmf_vif_status bits.
|
||||
- * @pm_block: power-management blocked.
|
||||
* @list: linked list.
|
||||
* @mgmt_rx_reg: registered rx mgmt frame types.
|
||||
* @mbss: Multiple BSS type, set if not first AP (not relevant for P2P).
|
||||
@@ -177,7 +176,6 @@ struct brcmf_cfg80211_vif {
|
||||
struct wireless_dev wdev;
|
||||
struct brcmf_cfg80211_profile profile;
|
||||
unsigned long sme_state;
|
||||
- bool pm_block;
|
||||
struct vif_saved_ie saved_ie;
|
||||
struct list_head list;
|
||||
u16 mgmt_rx_reg;
|
||||
@@ -388,8 +386,7 @@ s32 brcmf_cfg80211_down(struct net_devic
|
||||
enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
|
||||
|
||||
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
||||
- enum nl80211_iftype type,
|
||||
- bool pm_block);
|
||||
+ enum nl80211_iftype type);
|
||||
void brcmf_free_vif(struct brcmf_cfg80211_vif *vif);
|
||||
|
||||
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2074,8 +2074,7 @@ static struct wireless_dev *brcmf_p2p_cr
|
||||
if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
|
||||
return ERR_PTR(-ENOSPC);
|
||||
|
||||
- p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE,
|
||||
- false);
|
||||
+ p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE);
|
||||
if (IS_ERR(p2p_vif)) {
|
||||
brcmf_err("could not create discovery vif\n");
|
||||
return (struct wireless_dev *)p2p_vif;
|
||||
@@ -2175,7 +2174,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
- vif = brcmf_alloc_vif(cfg, type, false);
|
||||
+ vif = brcmf_alloc_vif(cfg, type);
|
||||
if (IS_ERR(vif))
|
||||
return (struct wireless_dev *)vif;
|
||||
brcmf_cfg80211_arm_vif_event(cfg, vif);
|
||||
@ -0,0 +1,37 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Tue, 7 Jun 2016 08:20:21 +0200
|
||||
Subject: [PATCH] brcmfmac: include required headers in cfg80211.h
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Without this including cfg80211.h in a wrong order could result in:
|
||||
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:122:24: error: array type has incomplete element type
|
||||
struct brcmf_wsec_key key[BRCMF_MAX_DEFAULT_KEYS];
|
||||
^
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:291:24: error: field âp2pâ has incomplete type
|
||||
struct brcmf_p2p_info p2p;
|
||||
^
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:297:27: error: field âpmk_listâ has incomplete type
|
||||
struct brcmf_pmk_list_le pmk_list;
|
||||
^
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:317:28: error: field âassoclistâ has incomplete type
|
||||
struct brcmf_assoclist_le assoclist;
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -20,6 +20,9 @@
|
||||
/* for brcmu_d11inf */
|
||||
#include <brcmu_d11.h>
|
||||
|
||||
+#include "fwil_types.h"
|
||||
+#include "p2p.h"
|
||||
+
|
||||
#define WL_NUM_SCAN_MAX 10
|
||||
#define WL_TLV_INFO_MAX 1024
|
||||
#define WL_BSS_INFO_MAX 2048
|
||||
@ -0,0 +1,108 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Tue, 7 Jun 2016 21:10:18 +0200
|
||||
Subject: [PATCH] brcmfmac: slightly simplify building interface combinations
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This change reorders some operations in brcmf_setup_ifmodes in hope to
|
||||
make it simpler:
|
||||
1) It allocates arrays right before filling them. This way it's easier
|
||||
to follow requested array length as it's immediately followed by
|
||||
code filling it. It's easier to check e.g. why we need 4 entries for
|
||||
P2P. Other than that it deduplicates some checks (e.g. for P2P).
|
||||
2) It reorders code to first prepare limits and then define a new combo.
|
||||
Previously this was mixed (e.g. we were setting num of channels
|
||||
before preparing limits).
|
||||
3) It modifies mbss code to use i variable just like other combos do.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6208,29 +6208,15 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
if (!combo)
|
||||
goto err;
|
||||
|
||||
- c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
|
||||
- if (!c0_limits)
|
||||
- goto err;
|
||||
-
|
||||
- if (p2p) {
|
||||
- p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
|
||||
- if (!p2p_limits)
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
- if (mbss) {
|
||||
- mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
|
||||
- if (!mbss_limits)
|
||||
- goto err;
|
||||
- }
|
||||
-
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_ADHOC) |
|
||||
BIT(NL80211_IFTYPE_AP);
|
||||
|
||||
c = 0;
|
||||
i = 0;
|
||||
- combo[c].num_different_channels = 1;
|
||||
+ c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
|
||||
+ if (!c0_limits)
|
||||
+ goto err;
|
||||
c0_limits[i].max = 1;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
if (p2p) {
|
||||
@@ -6248,6 +6234,7 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
c0_limits[i].max = 1;
|
||||
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
}
|
||||
+ combo[c].num_different_channels = 1;
|
||||
combo[c].max_interfaces = i;
|
||||
combo[c].n_limits = i;
|
||||
combo[c].limits = c0_limits;
|
||||
@@ -6255,7 +6242,9 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
if (p2p) {
|
||||
c++;
|
||||
i = 0;
|
||||
- combo[c].num_different_channels = 1;
|
||||
+ p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
|
||||
+ if (!p2p_limits)
|
||||
+ goto err;
|
||||
p2p_limits[i].max = 1;
|
||||
p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||
p2p_limits[i].max = 1;
|
||||
@@ -6264,6 +6253,7 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
|
||||
p2p_limits[i].max = 1;
|
||||
p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||
+ combo[c].num_different_channels = 1;
|
||||
combo[c].max_interfaces = i;
|
||||
combo[c].n_limits = i;
|
||||
combo[c].limits = p2p_limits;
|
||||
@@ -6271,14 +6261,19 @@ static int brcmf_setup_ifmodes(struct wi
|
||||
|
||||
if (mbss) {
|
||||
c++;
|
||||
+ i = 0;
|
||||
+ mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
|
||||
+ if (!mbss_limits)
|
||||
+ goto err;
|
||||
+ mbss_limits[i].max = 4;
|
||||
+ mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||
combo[c].beacon_int_infra_match = true;
|
||||
combo[c].num_different_channels = 1;
|
||||
- mbss_limits[0].max = 4;
|
||||
- mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
|
||||
combo[c].max_interfaces = 4;
|
||||
- combo[c].n_limits = 1;
|
||||
+ combo[c].n_limits = i;
|
||||
combo[c].limits = mbss_limits;
|
||||
}
|
||||
+
|
||||
wiphy->n_iface_combinations = n_combos;
|
||||
wiphy->iface_combinations = combo;
|
||||
return 0;
|
||||
@ -0,0 +1,160 @@
|
||||
From b50ddfa8530e9b5f52e873fdd6ff04f327a88799 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Fri, 17 Jun 2016 12:29:21 +0200
|
||||
Subject: [PATCH] brcmfmac: fix lockup when removing P2P interface after event
|
||||
timeout
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Removing P2P interface is handled by sending a proper request to the
|
||||
firmware. On success firmware triggers an event and driver's handler
|
||||
removes a matching interface.
|
||||
|
||||
However on event timeout we remove interface directly from the cfg80211
|
||||
callback. Current code doesn't handle this case correctly as it always
|
||||
assumes rtnl to be unlocked.
|
||||
|
||||
Fix it by adding an extra rtnl_locked parameter to functions and calling
|
||||
unregister_netdevice when needed.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 29 +++++++++++++---------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 +-
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/fweh.c | 2 +-
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 4 +--
|
||||
4 files changed, 21 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -548,12 +548,16 @@ fail:
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
-static void brcmf_net_detach(struct net_device *ndev)
|
||||
+static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
|
||||
{
|
||||
- if (ndev->reg_state == NETREG_REGISTERED)
|
||||
- unregister_netdev(ndev);
|
||||
- else
|
||||
+ if (ndev->reg_state == NETREG_REGISTERED) {
|
||||
+ if (rtnl_locked)
|
||||
+ unregister_netdevice(ndev);
|
||||
+ else
|
||||
+ unregister_netdev(ndev);
|
||||
+ } else {
|
||||
brcmf_cfg80211_free_netdev(ndev);
|
||||
+ }
|
||||
}
|
||||
|
||||
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
|
||||
@@ -651,7 +655,7 @@ struct brcmf_if *brcmf_add_if(struct brc
|
||||
brcmf_err("ERROR: netdev:%s already exists\n",
|
||||
ifp->ndev->name);
|
||||
netif_stop_queue(ifp->ndev);
|
||||
- brcmf_net_detach(ifp->ndev);
|
||||
+ brcmf_net_detach(ifp->ndev, false);
|
||||
drvr->iflist[bsscfgidx] = NULL;
|
||||
} else {
|
||||
brcmf_dbg(INFO, "netdev:%s ignore IF event\n",
|
||||
@@ -699,7 +703,8 @@ struct brcmf_if *brcmf_add_if(struct brc
|
||||
return ifp;
|
||||
}
|
||||
|
||||
-static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx)
|
||||
+static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx,
|
||||
+ bool rtnl_locked)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
|
||||
@@ -729,7 +734,7 @@ static void brcmf_del_if(struct brcmf_pu
|
||||
cancel_work_sync(&ifp->multicast_work);
|
||||
cancel_work_sync(&ifp->ndoffload_work);
|
||||
}
|
||||
- brcmf_net_detach(ifp->ndev);
|
||||
+ brcmf_net_detach(ifp->ndev, rtnl_locked);
|
||||
} else {
|
||||
/* Only p2p device interfaces which get dynamically created
|
||||
* end up here. In this case the p2p module should be informed
|
||||
@@ -743,14 +748,14 @@ static void brcmf_del_if(struct brcmf_pu
|
||||
}
|
||||
}
|
||||
|
||||
-void brcmf_remove_interface(struct brcmf_if *ifp)
|
||||
+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked)
|
||||
{
|
||||
if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp))
|
||||
return;
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,
|
||||
ifp->ifidx);
|
||||
brcmf_fws_del_interface(ifp);
|
||||
- brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
|
||||
+ brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INET
|
||||
@@ -1057,9 +1062,9 @@ fail:
|
||||
brcmf_fws_deinit(drvr);
|
||||
}
|
||||
if (ifp)
|
||||
- brcmf_net_detach(ifp->ndev);
|
||||
+ brcmf_net_detach(ifp->ndev, false);
|
||||
if (p2p_ifp)
|
||||
- brcmf_net_detach(p2p_ifp->ndev);
|
||||
+ brcmf_net_detach(p2p_ifp->ndev, false);
|
||||
drvr->iflist[0] = NULL;
|
||||
drvr->iflist[1] = NULL;
|
||||
if (drvr->settings->ignore_probe_fail)
|
||||
@@ -1128,7 +1133,7 @@ void brcmf_detach(struct device *dev)
|
||||
|
||||
/* make sure primary interface removed last */
|
||||
for (i = BRCMF_MAX_IFS-1; i > -1; i--)
|
||||
- brcmf_remove_interface(drvr->iflist[i]);
|
||||
+ brcmf_remove_interface(drvr->iflist[i], false);
|
||||
|
||||
brcmf_cfg80211_detach(drvr->config);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -216,7 +216,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
|
||||
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
bool is_p2pdev, char *name, u8 *mac_addr);
|
||||
-void brcmf_remove_interface(struct brcmf_if *ifp);
|
||||
+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
||||
enum brcmf_netif_stop_reason reason, bool state);
|
||||
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
@@ -183,7 +183,7 @@ static void brcmf_fweh_handle_if_event(s
|
||||
err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
|
||||
|
||||
if (ifp && ifevent->action == BRCMF_E_IF_DEL)
|
||||
- brcmf_remove_interface(ifp);
|
||||
+ brcmf_remove_interface(ifp, false);
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2289,7 +2289,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
|
||||
err = 0;
|
||||
}
|
||||
if (err)
|
||||
- brcmf_remove_interface(vif->ifp);
|
||||
+ brcmf_remove_interface(vif->ifp, true);
|
||||
|
||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||
if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
|
||||
@@ -2395,7 +2395,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i
|
||||
if (vif != NULL) {
|
||||
brcmf_p2p_cancel_remain_on_channel(vif->ifp);
|
||||
brcmf_p2p_deinit_discovery(p2p);
|
||||
- brcmf_remove_interface(vif->ifp);
|
||||
+ brcmf_remove_interface(vif->ifp, false);
|
||||
}
|
||||
/* just set it all to zero */
|
||||
memset(p2p, 0, sizeof(*p2p));
|
||||
@ -0,0 +1,39 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Fri, 17 Jun 2016 12:48:44 +0200
|
||||
Subject: [PATCH] brcmfmac: use const char * for interface name in brcmf_add_if
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This function can work just fine with const pointer, it only calls
|
||||
alloc_netdev which take const as well. Moreover it makes this function
|
||||
more flexible as some cfg80211 callback may provide const char * as
|
||||
well, e.g. add_virtual_intf. This will be needed for more advanced
|
||||
interface management.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -638,7 +638,7 @@ fail:
|
||||
}
|
||||
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
- bool is_p2pdev, char *name, u8 *mac_addr)
|
||||
+ bool is_p2pdev, const char *name, u8 *mac_addr)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
struct net_device *ndev;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -215,7 +215,7 @@ char *brcmf_ifname(struct brcmf_if *ifp)
|
||||
struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
|
||||
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
- bool is_p2pdev, char *name, u8 *mac_addr);
|
||||
+ bool is_p2pdev, const char *name, u8 *mac_addr);
|
||||
void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
||||
enum brcmf_netif_stop_reason reason, bool state);
|
||||
@ -0,0 +1,33 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Sat, 18 Jun 2016 18:49:38 +0200
|
||||
Subject: [PATCH] brcmfmac: include also core.h header in cfg80211.h
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This header provides two inline functions using struct brcmf_if so we
|
||||
need core.h to avoid:
|
||||
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ândev_to_profâ:
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:368:13: error: dereferencing pointer to incomplete type
|
||||
return &ifp->vif->profile;
|
||||
^
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ândev_to_vifâ:
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:374:12: error: dereferencing pointer to incomplete type
|
||||
return ifp->vif;
|
||||
^
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -20,6 +20,7 @@
|
||||
/* for brcmu_d11inf */
|
||||
#include <brcmu_d11.h>
|
||||
|
||||
+#include "core.h"
|
||||
#include "fwil_types.h"
|
||||
#include "p2p.h"
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Sun, 19 Jun 2016 01:55:57 +0200
|
||||
Subject: [PATCH] brcmfmac: add missing break when deleting P2P_DEVICE
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We obviously don't want to fall through in that switch. With this change
|
||||
1) We wait for event (triggered by p2p_disc) as expected
|
||||
2) We remove interface manually on timeout
|
||||
3) We return 0 on success instead of -ENOTSUPP
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2263,6 +2263,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
|
||||
return 0;
|
||||
brcmf_p2p_cancel_remain_on_channel(vif->ifp);
|
||||
brcmf_p2p_deinit_discovery(p2p);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Wed, 29 Jun 2016 21:54:26 +0200
|
||||
Subject: [PATCH] brcmfmac: delete interface directly in code that sent fw
|
||||
request
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
So far when receiving event about in-firmware-interface removal our
|
||||
event worker was notifying listener and afterwards it was removing Linux
|
||||
interface.
|
||||
|
||||
First of all it was resulting in slightly unexpected order. The listener
|
||||
(del_virtual_intf callback) was (usually) returning with success before
|
||||
we even called unregister_netdev(ice).
|
||||
|
||||
Please note this couldn't be simply fixed by changing order of calls in
|
||||
brcmf_fweh_handle_if_event as unregistering interface earlier could free
|
||||
struct brcmf_if.
|
||||
|
||||
Another problem of current implementation are possible lockups. Focus on
|
||||
the time slot between calling event handler and removing Linux
|
||||
interface. During that time original caller may leave (unlocking rtnl
|
||||
semaphore) *and* another call to the same code may be done (locking it
|
||||
again). If that happens our event handler will stuck at removing Linux
|
||||
interface, it won't handle another event and will block process holding
|
||||
rtnl lock.
|
||||
|
||||
This can be simply solved by unregistering interface in a proper
|
||||
callback, right after receiving confirmation event from firmware. This
|
||||
only required modifying worker to don't unregister on its own if there
|
||||
is someone waiting for the event.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "brcmu_wifi.h"
|
||||
#include "brcmu_utils.h"
|
||||
|
||||
+#include "cfg80211.h"
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "tracepoint.h"
|
||||
@@ -182,8 +183,13 @@ static void brcmf_fweh_handle_if_event(s
|
||||
|
||||
err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
|
||||
|
||||
- if (ifp && ifevent->action == BRCMF_E_IF_DEL)
|
||||
- brcmf_remove_interface(ifp, false);
|
||||
+ if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
|
||||
+ bool armed = brcmf_cfg80211_vif_event_armed(drvr->config);
|
||||
+
|
||||
+ /* Default handling in case no-one waits for this event */
|
||||
+ if (!armed)
|
||||
+ brcmf_remove_interface(ifp, false);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2290,8 +2290,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
|
||||
else
|
||||
err = 0;
|
||||
}
|
||||
- if (err)
|
||||
- brcmf_remove_interface(vif->ifp, true);
|
||||
+ brcmf_remove_interface(vif->ifp, true);
|
||||
|
||||
brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||
if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
|
||||
@ -0,0 +1,84 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Wed, 29 Jun 2016 21:54:27 +0200
|
||||
Subject: [PATCH] brcmfmac: support removing AP interfaces with
|
||||
"interface_remove"
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove"
|
||||
for removing interfaces. Try to use this method on cfg80211 request. In
|
||||
case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this
|
||||
will just result in firmware rejecting command and this won't change any
|
||||
behavior.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -771,12 +771,48 @@ s32 brcmf_notify_escan_complete(struct b
|
||||
return err;
|
||||
}
|
||||
|
||||
+static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
|
||||
+ struct wireless_dev *wdev)
|
||||
+{
|
||||
+ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
|
||||
+ struct net_device *ndev = wdev->netdev;
|
||||
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
+ int ret;
|
||||
+ int err;
|
||||
+
|
||||
+ brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
|
||||
+
|
||||
+ err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
|
||||
+ if (err) {
|
||||
+ brcmf_err("interface_remove failed %d\n", err);
|
||||
+ goto err_unarm;
|
||||
+ }
|
||||
+
|
||||
+ /* wait for firmware event */
|
||||
+ ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
|
||||
+ BRCMF_VIF_EVENT_TIMEOUT);
|
||||
+ if (!ret) {
|
||||
+ brcmf_err("timeout occurred\n");
|
||||
+ err = -EIO;
|
||||
+ goto err_unarm;
|
||||
+ }
|
||||
+
|
||||
+ brcmf_remove_interface(ifp, true);
|
||||
+
|
||||
+err_unarm:
|
||||
+ brcmf_cfg80211_arm_vif_event(cfg, NULL);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static
|
||||
int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
|
||||
struct net_device *ndev = wdev->netdev;
|
||||
|
||||
+ if (ndev && ndev == cfg_to_ndev(cfg))
|
||||
+ return -ENOTSUPP;
|
||||
+
|
||||
/* vif event pending in firmware */
|
||||
if (brcmf_cfg80211_vif_event_armed(cfg))
|
||||
return -EBUSY;
|
||||
@@ -793,12 +829,13 @@ int brcmf_cfg80211_del_iface(struct wiph
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
- case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
return -EOPNOTSUPP;
|
||||
+ case NL80211_IFTYPE_AP:
|
||||
+ return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
@ -0,0 +1,43 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Wed, 6 Jul 2016 12:22:54 +0200
|
||||
Subject: [PATCH] brcmfmac: respect hidden_ssid for AP interfaces
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This was succesfully tested with 4366B1. A small workaround is needed
|
||||
for the main interface otherwise it would stuck at the hidden state.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -4586,6 +4586,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
brcmf_err("SET SSID error (%d)\n", err);
|
||||
goto exit;
|
||||
}
|
||||
+
|
||||
+ if (settings->hidden_ssid) {
|
||||
+ err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
|
||||
+ if (err) {
|
||||
+ brcmf_err("closednet error (%d)\n", 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);
|
||||
@@ -4644,6 +4653,10 @@ static int brcmf_cfg80211_stop_ap(struct
|
||||
return err;
|
||||
}
|
||||
|
||||
+ /* First BSS doesn't get a full reset */
|
||||
+ if (ifp->bsscfgidx == 0)
|
||||
+ brcmf_fil_iovar_int_set(ifp, "closednet", 0);
|
||||
+
|
||||
memset(&join_params, 0, sizeof(join_params));
|
||||
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
|
||||
&join_params, sizeof(join_params));
|
||||
@ -0,0 +1,53 @@
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Fri, 15 Jul 2016 12:16:12 +0200
|
||||
Subject: [PATCH] brcmfmac: restore stopping netdev queue when bus clogs up
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When the host-interface bus has hard time handling transmit packets
|
||||
it informs higher layer about this and it would stop the netdev
|
||||
queue when needed. However, since commit 9cd18359d31e ("brcmfmac:
|
||||
Make FWS queueing configurable.") this was broken. With this patch
|
||||
the behaviour is restored.
|
||||
|
||||
Cc: stable@vger.kernel.org # v4.5, v4.6, v4.7
|
||||
Fixes: 9cd18359d31e ("brcmfmac: Make FWS queueing configurable.")
|
||||
Tested-by: Per Förlin <per.forlin@gmail.com>
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
@@ -2469,10 +2469,22 @@ void brcmf_fws_bustxfail(struct brcmf_fw
|
||||
void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked)
|
||||
{
|
||||
struct brcmf_fws_info *fws = drvr->fws;
|
||||
+ struct brcmf_if *ifp;
|
||||
+ int i;
|
||||
|
||||
- fws->bus_flow_blocked = flow_blocked;
|
||||
- if (!flow_blocked)
|
||||
- brcmf_fws_schedule_deq(fws);
|
||||
- else
|
||||
- fws->stats.bus_flow_block++;
|
||||
+ if (fws->avoid_queueing) {
|
||||
+ for (i = 0; i < BRCMF_MAX_IFS; i++) {
|
||||
+ ifp = drvr->iflist[i];
|
||||
+ if (!ifp || !ifp->ndev)
|
||||
+ continue;
|
||||
+ brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW,
|
||||
+ flow_blocked);
|
||||
+ }
|
||||
+ } else {
|
||||
+ fws->bus_flow_blocked = flow_blocked;
|
||||
+ if (!flow_blocked)
|
||||
+ brcmf_fws_schedule_deq(fws);
|
||||
+ else
|
||||
+ fws->stats.bus_flow_block++;
|
||||
+ }
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
From fd3ed33f51c2a586412d35b4f64803f019ab589f Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Fri, 15 Jul 2016 12:39:13 +0200
|
||||
Subject: [PATCH] brcmfmac: defer DPC processing during probe
|
||||
|
||||
The sdio dpc starts processing when in SDIOD_STATE_DATA. This state was
|
||||
entered right after firmware download. This patch moves that transition
|
||||
just before enabling sdio interrupt handling thus avoiding watchdog
|
||||
expiry which would put the bus to sleep while probing.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3304,10 +3304,6 @@ static int brcmf_sdio_download_firmware(
|
||||
goto err;
|
||||
}
|
||||
|
||||
- /* Allow full data communication using DPC from now on. */
|
||||
- brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
|
||||
- bcmerror = 0;
|
||||
-
|
||||
err:
|
||||
brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
@@ -4045,6 +4041,9 @@ static void brcmf_sdio_firmware_callback
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
+ /* Allow full data communication using DPC from now on. */
|
||||
+ brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
|
||||
+
|
||||
err = brcmf_sdiod_intr_register(sdiodev);
|
||||
if (err != 0)
|
||||
brcmf_err("intr register failed:%d\n", err);
|
||||
@ -0,0 +1,32 @@
|
||||
From 3bdae810721b33061d2e541bd78a70f86ca42af3 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Date: Mon, 18 Jul 2016 16:24:34 -0700
|
||||
Subject: [PATCH] brcmfmac: Fix glob_skb leak in brcmf_sdiod_recv_chain
|
||||
|
||||
In case brcmf_sdiod_recv_chain() cannot complete a succeful call to
|
||||
brcmf_sdiod_buffrw, we would be leaking glom_skb and not free it as we
|
||||
should, fix this.
|
||||
|
||||
Reported-by: coverity (CID 1164856)
|
||||
Fixes: a413e39a38573 ("brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support")
|
||||
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -722,8 +722,10 @@ int brcmf_sdiod_recv_chain(struct brcmf_
|
||||
return -ENOMEM;
|
||||
err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
|
||||
glom_skb);
|
||||
- if (err)
|
||||
+ if (err) {
|
||||
+ brcmu_pkt_buf_free_skb(glom_skb);
|
||||
goto done;
|
||||
+ }
|
||||
|
||||
skb_queue_walk(pktq, skb) {
|
||||
memcpy(skb->data, glom_skb->data, skb->len);
|
||||
@ -0,0 +1,34 @@
|
||||
From 938f89e50a41c2d56710805fb019ad7618cef84b Mon Sep 17 00:00:00 2001
|
||||
From: Wolfram Sang <wsa-dev@sang-engineering.com>
|
||||
Date: Thu, 11 Aug 2016 23:05:31 +0200
|
||||
Subject: [PATCH] net: wireless: broadcom: brcm80211: brcmfmac: usb: don't
|
||||
print error when allocating urb fails
|
||||
|
||||
kmalloc will print enough information in case of failure.
|
||||
|
||||
Signed-off-by: Wolfram Sang <wsa-dev@sang-engineering.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -1099,15 +1099,11 @@ struct brcmf_usbdev *brcmf_usb_attach(st
|
||||
devinfo->tx_freecount = ntxq;
|
||||
|
||||
devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
- if (!devinfo->ctl_urb) {
|
||||
- brcmf_err("usb_alloc_urb (ctl) failed\n");
|
||||
+ if (!devinfo->ctl_urb)
|
||||
goto error;
|
||||
- }
|
||||
devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
- if (!devinfo->bulk_urb) {
|
||||
- brcmf_err("usb_alloc_urb (bulk) failed\n");
|
||||
+ if (!devinfo->bulk_urb)
|
||||
goto error;
|
||||
- }
|
||||
|
||||
return &devinfo->bus_pub;
|
||||
|
||||
@ -0,0 +1,111 @@
|
||||
From 15dacf880e49ce3ecee05eb1a0c6b8e363dbacdc Mon Sep 17 00:00:00 2001
|
||||
From: "mhiramat@kernel.org" <mhiramat@kernel.org>
|
||||
Date: Mon, 15 Aug 2016 18:40:57 +0900
|
||||
Subject: [PATCH] brcmfmac: Check rtnl_lock is locked when removing interface
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Check rtnl_lock is locked in brcmf_p2p_ifp_removed() by passing
|
||||
rtnl_locked flag. Actually the caller brcmf_del_if() checks whether
|
||||
the rtnl_lock is locked, but doesn't pass it to brcmf_p2p_ifp_removed().
|
||||
|
||||
Without this fix, wpa_supplicant goes softlockup with rtnl_lock
|
||||
holding (this means all other process using netlink are locked up too)
|
||||
|
||||
e.g.
|
||||
[ 4495.876627] INFO: task wpa_supplicant:7307 blocked for more than 10 seconds.
|
||||
[ 4495.876632] Tainted: G W 4.8.0-rc1+ #8
|
||||
[ 4495.876635] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
|
||||
[ 4495.876638] wpa_supplicant D ffff974c647b39a0 0 7307 1 0x00000000
|
||||
[ 4495.876644] ffff974c647b39a0 0000000000000000 ffff974c00000000 ffff974c7dc59c58
|
||||
[ 4495.876651] ffff974c6b7417c0 ffff974c645017c0 ffff974c647b4000 ffffffff86f16c08
|
||||
[ 4495.876657] ffff974c645017c0 0000000000000246 00000000ffffffff ffff974c647b39b8
|
||||
[ 4495.876664] Call Trace:
|
||||
[ 4495.876671] [<ffffffff868aeccc>] schedule+0x3c/0x90
|
||||
[ 4495.876676] [<ffffffff868af065>] schedule_preempt_disabled+0x15/0x20
|
||||
[ 4495.876682] [<ffffffff868b0996>] mutex_lock_nested+0x176/0x3b0
|
||||
[ 4495.876686] [<ffffffff867a2067>] ? rtnl_lock+0x17/0x20
|
||||
[ 4495.876690] [<ffffffff867a2067>] rtnl_lock+0x17/0x20
|
||||
[ 4495.876720] [<ffffffffc0ae9a5d>] brcmf_p2p_ifp_removed+0x4d/0x70 [brcmfmac]
|
||||
[ 4495.876741] [<ffffffffc0aebde6>] brcmf_remove_interface+0x196/0x1b0 [brcmfmac]
|
||||
[ 4495.876760] [<ffffffffc0ae9901>] brcmf_p2p_del_vif+0x111/0x220 [brcmfmac]
|
||||
[ 4495.876777] [<ffffffffc0adefab>] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac]
|
||||
[ 4495.876820] [<ffffffffc097b39e>] nl80211_del_interface+0xfe/0x3a0 [cfg80211]
|
||||
[ 4495.876825] [<ffffffff867ca335>] genl_family_rcv_msg+0x1b5/0x370
|
||||
[ 4495.876832] [<ffffffff860e5d8d>] ? trace_hardirqs_on+0xd/0x10
|
||||
[ 4495.876836] [<ffffffff867ca56d>] genl_rcv_msg+0x7d/0xb0
|
||||
[ 4495.876839] [<ffffffff867ca4f0>] ? genl_family_rcv_msg+0x370/0x370
|
||||
[ 4495.876846] [<ffffffff867c9a47>] netlink_rcv_skb+0x97/0xb0
|
||||
[ 4495.876849] [<ffffffff867ca168>] genl_rcv+0x28/0x40
|
||||
[ 4495.876854] [<ffffffff867c93c3>] netlink_unicast+0x1d3/0x2f0
|
||||
[ 4495.876860] [<ffffffff867c933b>] ? netlink_unicast+0x14b/0x2f0
|
||||
[ 4495.876866] [<ffffffff867c97cb>] netlink_sendmsg+0x2eb/0x3a0
|
||||
[ 4495.876870] [<ffffffff8676dad8>] sock_sendmsg+0x38/0x50
|
||||
[ 4495.876874] [<ffffffff8676e4df>] ___sys_sendmsg+0x27f/0x290
|
||||
[ 4495.876882] [<ffffffff8628b935>] ? mntput_no_expire+0x5/0x3f0
|
||||
[ 4495.876888] [<ffffffff8628b9be>] ? mntput_no_expire+0x8e/0x3f0
|
||||
[ 4495.876894] [<ffffffff8628b935>] ? mntput_no_expire+0x5/0x3f0
|
||||
[ 4495.876899] [<ffffffff8628bd44>] ? mntput+0x24/0x40
|
||||
[ 4495.876904] [<ffffffff86267830>] ? __fput+0x190/0x200
|
||||
[ 4495.876909] [<ffffffff8676f125>] __sys_sendmsg+0x45/0x80
|
||||
[ 4495.876914] [<ffffffff8676f172>] SyS_sendmsg+0x12/0x20
|
||||
[ 4495.876918] [<ffffffff868b5680>] entry_SYSCALL_64_fastpath+0x23/0xc1
|
||||
[ 4495.876924] [<ffffffff860e2b8f>] ? trace_hardirqs_off_caller+0x1f/0xc0
|
||||
|
||||
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Acked-by: RafaÅ MiÅecki <rafal@milecki.pl>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +-
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 8 +++++---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 2 +-
|
||||
3 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -743,7 +743,7 @@ static void brcmf_del_if(struct brcmf_pu
|
||||
* serious troublesome side effects. The p2p module will clean
|
||||
* up the ifp if needed.
|
||||
*/
|
||||
- brcmf_p2p_ifp_removed(ifp);
|
||||
+ brcmf_p2p_ifp_removed(ifp, rtnl_locked);
|
||||
kfree(ifp);
|
||||
}
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2299,7 +2299,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
|
||||
return err;
|
||||
}
|
||||
|
||||
-void brcmf_p2p_ifp_removed(struct brcmf_if *ifp)
|
||||
+void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
@@ -2308,9 +2308,11 @@ void brcmf_p2p_ifp_removed(struct brcmf_
|
||||
vif = ifp->vif;
|
||||
cfg = wdev_to_cfg(&vif->wdev);
|
||||
cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
|
||||
- rtnl_lock();
|
||||
+ if (!rtnl_locked)
|
||||
+ rtnl_lock();
|
||||
cfg80211_unregister_wdev(&vif->wdev);
|
||||
- rtnl_unlock();
|
||||
+ if (!rtnl_locked)
|
||||
+ rtnl_unlock();
|
||||
brcmf_free_vif(vif);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
|
||||
@@ -155,7 +155,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s
|
||||
int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);
|
||||
int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
|
||||
enum brcmf_fil_p2p_if_types if_type);
|
||||
-void brcmf_p2p_ifp_removed(struct brcmf_if *ifp);
|
||||
+void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev);
|
||||
void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev);
|
||||
int brcmf_p2p_scan_prep(struct wiphy *wiphy,
|
||||
@ -0,0 +1,175 @@
|
||||
From b64abcb7dae6060c67ab0e548da3ef923c49641d Mon Sep 17 00:00:00 2001
|
||||
From: "mhiramat@kernel.org" <mhiramat@kernel.org>
|
||||
Date: Mon, 15 Aug 2016 18:41:12 +0900
|
||||
Subject: [PATCH] brcmfmac: Change vif_event_lock to spinlock
|
||||
|
||||
Change vif_event_lock to spinlock from mutex, since this lock is
|
||||
used in wait_event_timeout() via vif_event_equals(). This caused
|
||||
a warning report as below.
|
||||
|
||||
As far as I can see, this lock protects regions where updating
|
||||
structure members, not function calls. Also, since those
|
||||
regions are not called from interrupt handlers (of course, it
|
||||
was a mutex), spin_lock is used instead of spin_lock_irqsave.
|
||||
|
||||
[ 186.678550] ------------[ cut here ]------------
|
||||
[ 186.678556] WARNING: CPU: 2 PID: 7140 at /home/mhiramat/ksrc/linux/kernel/sched/core.c:7545 __might_sleep+0x7c/0x80
|
||||
[ 186.678560] do not call blocking ops when !TASK_RUNNING; state=2 set at [<ffffffff980d9090>] prepare_to_wait_event+0x60/0x100
|
||||
[ 186.678560] Modules linked in: brcmfmac xt_CHECKSUM rfcomm ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_addrtype br_netfilter xt_tcpudp ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_raw ip6table_security ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_filter ip6_tables iptable_raw iptable_security iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_filter ip_tables x_tables bnep nls_iso8859_1 i2c_designware_platform i2c_designware_core snd_hda_codec_hdmi snd_hda_codec_realtek dcdbas snd_hda_codec_generic snd_hda_intel snd_hda_codec intel_rapl snd_hda_core x86_pkg_temp_thermal intel_powerclamp coretemp
|
||||
[ 186.678594] snd_pcm crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 joydev glue_helper snd_hwdep lrw gf128mul uvcvideo ablk_helper snd_seq_midi cryptd snd_seq_midi_event snd_rawmidi videobuf2_vmalloc videobuf2_memops snd_seq input_leds videobuf2_v4l2 cfg80211 videobuf2_core snd_timer videodev serio_raw btusb snd_seq_device media btrtl rtsx_pci_ms snd mei_me memstick hid_multitouch mei soundcore brcmutil idma64 virt_dma intel_lpss_pci processor_thermal_device intel_soc_dts_iosf hci_uart btbcm btqca btintel bluetooth int3403_thermal dell_smo8800 intel_lpss_acpi intel_lpss int3402_thermal int340x_thermal_zone intel_hid mac_hid int3400_thermal shpchp sparse_keymap acpi_pad acpi_thermal_rel acpi_als kfifo_buf industrialio kvm_intel kvm irqbypass parport_pc ppdev lp parport autofs4 btrfs xor raid6_pq
|
||||
[ 186.678631] usbhid nouveau ttm i915 rtsx_pci_sdmmc mxm_wmi i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops psmouse drm ahci rtsx_pci nvme nvme_core libahci i2c_hid hid pinctrl_sunrisepoint video wmi pinctrl_intel fjes [last unloaded: brcmfmac]
|
||||
[ 186.678646] CPU: 2 PID: 7140 Comm: wpa_supplicant Not tainted 4.8.0-rc1+ #8
|
||||
[ 186.678647] Hardware name: Dell Inc. XPS 15 9550/0N7TVV, BIOS 01.02.00 04/07/2016
|
||||
[ 186.678648] 0000000000000000 ffff9d8c64b5b900 ffffffff98442f23 ffff9d8c64b5b950
|
||||
[ 186.678651] 0000000000000000 ffff9d8c64b5b940 ffffffff9808b22b 00001d790000000d
|
||||
[ 186.678653] ffffffff98c75e78 000000000000026c 0000000000000000 ffff9d8c2706d058
|
||||
[ 186.678655] Call Trace:
|
||||
[ 186.678659] [<ffffffff98442f23>] dump_stack+0x85/0xc2
|
||||
[ 186.678666] [<ffffffff9808b22b>] __warn+0xcb/0xf0
|
||||
[ 186.678668] [<ffffffff9808b29f>] warn_slowpath_fmt+0x4f/0x60
|
||||
[ 186.678671] [<ffffffff980d9090>] ? prepare_to_wait_event+0x60/0x100
|
||||
[ 186.678672] [<ffffffff980d9090>] ? prepare_to_wait_event+0x60/0x100
|
||||
[ 186.678674] [<ffffffff980b922c>] __might_sleep+0x7c/0x80
|
||||
[ 186.678680] [<ffffffff988b0853>] mutex_lock_nested+0x33/0x3b0
|
||||
[ 186.678682] [<ffffffff980e5d8d>] ? trace_hardirqs_on+0xd/0x10
|
||||
[ 186.678689] [<ffffffffc0c57d2d>] brcmf_cfg80211_wait_vif_event+0xcd/0x130 [brcmfmac]
|
||||
[ 186.678691] [<ffffffff980d9190>] ? wake_atomic_t_function+0x60/0x60
|
||||
[ 186.678697] [<ffffffffc0c628e9>] brcmf_p2p_del_vif+0xf9/0x220 [brcmfmac]
|
||||
[ 186.678702] [<ffffffffc0c57fab>] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac]
|
||||
[ 186.678716] [<ffffffffc0b0539e>] nl80211_del_interface+0xfe/0x3a0 [cfg80211]
|
||||
[ 186.678718] [<ffffffff987ca335>] genl_family_rcv_msg+0x1b5/0x370
|
||||
[ 186.678720] [<ffffffff980e5d8d>] ? trace_hardirqs_on+0xd/0x10
|
||||
[ 186.678721] [<ffffffff987ca56d>] genl_rcv_msg+0x7d/0xb0
|
||||
[ 186.678722] [<ffffffff987ca4f0>] ? genl_family_rcv_msg+0x370/0x370
|
||||
[ 186.678724] [<ffffffff987c9a47>] netlink_rcv_skb+0x97/0xb0
|
||||
[ 186.678726] [<ffffffff987ca168>] genl_rcv+0x28/0x40
|
||||
[ 186.678727] [<ffffffff987c93c3>] netlink_unicast+0x1d3/0x2f0
|
||||
[ 186.678729] [<ffffffff987c933b>] ? netlink_unicast+0x14b/0x2f0
|
||||
[ 186.678731] [<ffffffff987c97cb>] netlink_sendmsg+0x2eb/0x3a0
|
||||
[ 186.678733] [<ffffffff9876dad8>] sock_sendmsg+0x38/0x50
|
||||
[ 186.678734] [<ffffffff9876e4df>] ___sys_sendmsg+0x27f/0x290
|
||||
[ 186.678737] [<ffffffff9828b935>] ? mntput_no_expire+0x5/0x3f0
|
||||
[ 186.678739] [<ffffffff9828b9be>] ? mntput_no_expire+0x8e/0x3f0
|
||||
[ 186.678741] [<ffffffff9828b935>] ? mntput_no_expire+0x5/0x3f0
|
||||
[ 186.678743] [<ffffffff9828bd44>] ? mntput+0x24/0x40
|
||||
[ 186.678744] [<ffffffff98267830>] ? __fput+0x190/0x200
|
||||
[ 186.678746] [<ffffffff9876f125>] __sys_sendmsg+0x45/0x80
|
||||
[ 186.678748] [<ffffffff9876f172>] SyS_sendmsg+0x12/0x20
|
||||
[ 186.678749] [<ffffffff988b5680>] entry_SYSCALL_64_fastpath+0x23/0xc1
|
||||
[ 186.678751] [<ffffffff980e2b8f>] ? trace_hardirqs_off_caller+0x1f/0xc0
|
||||
[ 186.678752] ---[ end trace e224d66c5d8408b5 ]---
|
||||
|
||||
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 +++++++++++-----------
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +-
|
||||
2 files changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -5555,7 +5555,7 @@ static s32 brcmf_notify_vif_event(struct
|
||||
ifevent->action, ifevent->flags, ifevent->ifidx,
|
||||
ifevent->bsscfgidx);
|
||||
|
||||
- mutex_lock(&event->vif_event_lock);
|
||||
+ spin_lock(&event->vif_event_lock);
|
||||
event->action = ifevent->action;
|
||||
vif = event->vif;
|
||||
|
||||
@@ -5563,7 +5563,7 @@ static s32 brcmf_notify_vif_event(struct
|
||||
case BRCMF_E_IF_ADD:
|
||||
/* waiting process may have timed out */
|
||||
if (!cfg->vif_event.vif) {
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
@@ -5574,24 +5574,24 @@ static s32 brcmf_notify_vif_event(struct
|
||||
ifp->ndev->ieee80211_ptr = &vif->wdev;
|
||||
SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
|
||||
}
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
wake_up(&event->vif_wq);
|
||||
return 0;
|
||||
|
||||
case BRCMF_E_IF_DEL:
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
/* event may not be upon user request */
|
||||
if (brcmf_cfg80211_vif_event_armed(cfg))
|
||||
wake_up(&event->vif_wq);
|
||||
return 0;
|
||||
|
||||
case BRCMF_E_IF_CHANGE:
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
wake_up(&event->vif_wq);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
@@ -5712,7 +5712,7 @@ static void wl_deinit_priv(struct brcmf_
|
||||
static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
|
||||
{
|
||||
init_waitqueue_head(&event->vif_wq);
|
||||
- mutex_init(&event->vif_event_lock);
|
||||
+ spin_lock_init(&event->vif_event_lock);
|
||||
}
|
||||
|
||||
static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
|
||||
@@ -6607,9 +6607,9 @@ static inline bool vif_event_equals(stru
|
||||
{
|
||||
u8 evt_action;
|
||||
|
||||
- mutex_lock(&event->vif_event_lock);
|
||||
+ spin_lock(&event->vif_event_lock);
|
||||
evt_action = event->action;
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
return evt_action == action;
|
||||
}
|
||||
|
||||
@@ -6618,10 +6618,10 @@ void brcmf_cfg80211_arm_vif_event(struct
|
||||
{
|
||||
struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
|
||||
|
||||
- mutex_lock(&event->vif_event_lock);
|
||||
+ spin_lock(&event->vif_event_lock);
|
||||
event->vif = vif;
|
||||
event->action = 0;
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
}
|
||||
|
||||
bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
|
||||
@@ -6629,9 +6629,9 @@ bool brcmf_cfg80211_vif_event_armed(stru
|
||||
struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
|
||||
bool armed;
|
||||
|
||||
- mutex_lock(&event->vif_event_lock);
|
||||
+ spin_lock(&event->vif_event_lock);
|
||||
armed = event->vif != NULL;
|
||||
- mutex_unlock(&event->vif_event_lock);
|
||||
+ spin_unlock(&event->vif_event_lock);
|
||||
|
||||
return armed;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -227,7 +227,7 @@ struct escan_info {
|
||||
*/
|
||||
struct brcmf_cfg80211_vif_event {
|
||||
wait_queue_head_t vif_wq;
|
||||
- struct mutex vif_event_lock;
|
||||
+ spinlock_t vif_event_lock;
|
||||
u8 action;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
From 8af92af3f2d55db143417a5d401696f4b642009a Mon Sep 17 00:00:00 2001
|
||||
From: Baoyou Xie <baoyou.xie@linaro.org>
|
||||
Date: Mon, 29 Aug 2016 20:39:35 +0800
|
||||
Subject: [PATCH] brcmfmac: add missing header dependencies
|
||||
|
||||
We get 1 warning when building kernel with W=1:
|
||||
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c:23:6: warning: no previous prototype for '__brcmf_err' [-Wmissing-prototypes]
|
||||
|
||||
In fact, this function is declared in brcmfmac/debug.h, so this patch
|
||||
adds missing header dependencies.
|
||||
|
||||
Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
|
||||
Acked-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifndef __CHECKER__
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "tracepoint.h"
|
||||
+#include "debug.h"
|
||||
|
||||
void __brcmf_err(const char *func, const char *fmt, ...)
|
||||
{
|
||||
@ -0,0 +1,51 @@
|
||||
From bccf3ffc8c6d8e0251a15541bb4d12b423c4f729 Mon Sep 17 00:00:00 2001
|
||||
From: Ismael Luceno <ismael@iodev.co.uk>
|
||||
Date: Mon, 22 Aug 2016 19:40:07 -0300
|
||||
Subject: [PATCH] brcmfmac: Add USB ID for Cisco Linksys AE1200
|
||||
|
||||
The AE1200 comes with different revisions of the BCM43235 chipset,
|
||||
but all have the same USB ID. Only revision 3 can be supported.
|
||||
|
||||
Signed-off-by: Ismael Luceno <ismael@iodev.co.uk>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 4 ++++
|
||||
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -1456,11 +1456,15 @@ static int brcmf_usb_reset_resume(struct
|
||||
#define BRCMF_USB_DEVICE(dev_id) \
|
||||
{ USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) }
|
||||
|
||||
+#define LINKSYS_USB_DEVICE(dev_id) \
|
||||
+ { USB_DEVICE(BRCM_USB_VENDOR_ID_LINKSYS, dev_id) }
|
||||
+
|
||||
static struct usb_device_id brcmf_usb_devid_table[] = {
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID),
|
||||
+ LINKSYS_USB_DEVICE(BRCM_USB_43235_LINKSYS_DEVICE_ID),
|
||||
{ USB_DEVICE(BRCM_USB_VENDOR_ID_LG, BRCM_USB_43242_LG_DEVICE_ID) },
|
||||
/* special entry for device with firmware loaded and running */
|
||||
BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
|
||||
#define BRCM_USB_VENDOR_ID_LG 0x043e
|
||||
+#define BRCM_USB_VENDOR_ID_LINKSYS 0x13b1
|
||||
#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
|
||||
|
||||
/* Chipcommon Core Chip IDs */
|
||||
@@ -56,6 +57,7 @@
|
||||
|
||||
/* USB Device IDs */
|
||||
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
|
||||
+#define BRCM_USB_43235_LINKSYS_DEVICE_ID 0x0039
|
||||
#define BRCM_USB_43236_DEVICE_ID 0xbd17
|
||||
#define BRCM_USB_43242_DEVICE_ID 0xbd1f
|
||||
#define BRCM_USB_43242_LG_DEVICE_ID 0x3101
|
||||
@ -0,0 +1,51 @@
|
||||
From 7703773ef1d85b40433902a8da20167331597e4a Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
|
||||
Date: Tue, 23 Aug 2016 11:37:17 +0200
|
||||
Subject: [PATCH] brcmfmac: fix pmksa->bssid usage
|
||||
|
||||
The struct cfg80211_pmksa defines its bssid field as:
|
||||
|
||||
const u8 *bssid;
|
||||
|
||||
contrary to struct brcmf_pmksa, which uses:
|
||||
|
||||
u8 bssid[ETH_ALEN];
|
||||
|
||||
Therefore in brcmf_cfg80211_del_pmksa(), &pmksa->bssid takes the address
|
||||
of this field (of type u8**), not the one of its content (which would be
|
||||
u8*). Remove the & operator to make brcmf_dbg("%pM") and memcmp()
|
||||
behave as expected.
|
||||
|
||||
This bug have been found using a custom static checker (which checks the
|
||||
usage of %p... attributes at build time). It has been introduced in
|
||||
commit 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code"),
|
||||
which replaced pmksa->bssid by &pmksa->bssid while refactoring the code,
|
||||
without modifying struct cfg80211_pmksa definition.
|
||||
|
||||
Replace &pmk[i].bssid with pmk[i].bssid too to make the code clearer,
|
||||
this change does not affect the semantic.
|
||||
|
||||
Fixes: 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -3804,11 +3804,11 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w
|
||||
if (!check_vif_up(ifp->vif))
|
||||
return -EIO;
|
||||
|
||||
- brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid);
|
||||
+ brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
|
||||
|
||||
npmk = le32_to_cpu(cfg->pmk_list.npmk);
|
||||
for (i = 0; i < npmk; i++)
|
||||
- if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN))
|
||||
+ if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
|
||||
break;
|
||||
|
||||
if ((npmk > 0) && (i < npmk)) {
|
||||
@ -0,0 +1,34 @@
|
||||
From ded89912156b1a47d940a0c954c43afbabd0c42c Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 5 Sep 2016 10:45:47 +0100
|
||||
Subject: [PATCH] brcmfmac: avoid potential stack overflow in
|
||||
brcmf_cfg80211_start_ap()
|
||||
|
||||
User-space can choose to omit NL80211_ATTR_SSID and only provide raw
|
||||
IE TLV data. When doing so it can provide SSID IE with length exceeding
|
||||
the allowed size. The driver further processes this IE copying it
|
||||
into a local variable without checking the length. Hence stack can be
|
||||
corrupted and used as exploit.
|
||||
|
||||
Cc: stable@vger.kernel.org # v4.7
|
||||
Reported-by: Daxing Guo <freener.gdx@gmail.com>
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -4447,7 +4447,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
(u8 *)&settings->beacon.head[ie_offset],
|
||||
settings->beacon.head_len - ie_offset,
|
||||
WLAN_EID_SSID);
|
||||
- if (!ssid_ie)
|
||||
+ if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
|
||||
@ -0,0 +1,55 @@
|
||||
From 634faf3686900ccdee87b77e2c56df8b2159912b Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 5 Sep 2016 11:42:12 +0100
|
||||
Subject: [PATCH] brcmfmac: add support for bcm4339 chip with modalias
|
||||
sdio:c00v02D0d4339
|
||||
|
||||
The driver already supports the bcm4339 chipset but only for the variant
|
||||
that shares the same modalias as the bcm4335, ie. sdio:c00v02D0d4335.
|
||||
It turns out that there are also bcm4339 devices out there that have a
|
||||
more distiguishable modalias sdio:c00v02D0d4339.
|
||||
|
||||
Reported-by: Steve deRosier <derosier@gmail.com>
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 ++-
|
||||
include/linux/mmc/sdio_ids.h | 1 +
|
||||
3 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -1097,6 +1097,7 @@ static const struct sdio_device_id brcmf
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
|
||||
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
|
||||
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3756,7 +3756,8 @@ static u32 brcmf_sdio_buscore_read32(voi
|
||||
u32 val, rev;
|
||||
|
||||
val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
|
||||
- if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
|
||||
+ if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
|
||||
+ sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
|
||||
addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
|
||||
rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
|
||||
if (rev >= 2) {
|
||||
--- a/include/linux/mmc/sdio_ids.h
|
||||
+++ b/include/linux/mmc/sdio_ids.h
|
||||
@@ -32,6 +32,7 @@
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43340 0xa94c
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
|
||||
+#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
|
||||
@ -0,0 +1,56 @@
|
||||
From 5251b6be8bb5c5675bdf12347c7b83937a5c91e5 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 5 Sep 2016 11:42:13 +0100
|
||||
Subject: [PATCH] brcmfmac: sdio: shorten retry loop in
|
||||
brcmf_sdio_kso_control()
|
||||
|
||||
In brcmf_sdio_kso_control() there is a retry loop as hardware may take
|
||||
time to settle. However, when the call to brcmf_sdiod_regrb() returns
|
||||
an error it is due to SDIO access failure and it makes no sense to wait
|
||||
for hardware to settle. This patch aborts the loop after a number of
|
||||
subsequent access errors.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -313,6 +313,7 @@ struct rte_console {
|
||||
|
||||
#define KSO_WAIT_US 50
|
||||
#define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US)
|
||||
+#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5
|
||||
|
||||
/*
|
||||
* Conversion of 802.1D priority to precedence level
|
||||
@@ -675,6 +676,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio
|
||||
{
|
||||
u8 wr_val = 0, rd_val, cmp_val, bmask;
|
||||
int err = 0;
|
||||
+ int err_cnt = 0;
|
||||
int try_cnt = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter: on=%d\n", on);
|
||||
@@ -710,9 +712,14 @@ brcmf_sdio_kso_control(struct brcmf_sdio
|
||||
*/
|
||||
rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
&err);
|
||||
- if (((rd_val & bmask) == cmp_val) && !err)
|
||||
+ if (!err) {
|
||||
+ if ((rd_val & bmask) == cmp_val)
|
||||
+ break;
|
||||
+ err_cnt = 0;
|
||||
+ }
|
||||
+ /* bail out upon subsequent access errors */
|
||||
+ if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS))
|
||||
break;
|
||||
-
|
||||
udelay(KSO_WAIT_US);
|
||||
brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
|
||||
wr_val, &err);
|
||||
@ -0,0 +1,84 @@
|
||||
From b3589dfe02123a0d0ea82076a9f8ef84a46852c0 Mon Sep 17 00:00:00 2001
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:51 +0100
|
||||
Subject: [PATCH] brcmfmac: ignore 11d configuration errors
|
||||
|
||||
802.11d is not always supported by firmware anymore. Currently the
|
||||
AP configuration of 11d will cause an abort if the ioctl set is
|
||||
failing. This behavior is not correct and the error should be
|
||||
ignored.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 27 ++++++++++++----------
|
||||
1 file changed, 15 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -4422,6 +4422,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
|
||||
bool mbss;
|
||||
int is_11d;
|
||||
+ bool supports_11d;
|
||||
|
||||
brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
|
||||
settings->chandef.chan->hw_value,
|
||||
@@ -4434,11 +4435,16 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
mbss = ifp->vif->mbss;
|
||||
|
||||
/* store current 11d setting */
|
||||
- brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
|
||||
- country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
|
||||
- settings->beacon.tail_len,
|
||||
- WLAN_EID_COUNTRY);
|
||||
- is_11d = country_ie ? 1 : 0;
|
||||
+ if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
|
||||
+ &ifp->vif->is_11d)) {
|
||||
+ supports_11d = false;
|
||||
+ } else {
|
||||
+ country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
|
||||
+ settings->beacon.tail_len,
|
||||
+ WLAN_EID_COUNTRY);
|
||||
+ is_11d = country_ie ? 1 : 0;
|
||||
+ supports_11d = true;
|
||||
+ }
|
||||
|
||||
memset(&ssid_le, 0, sizeof(ssid_le));
|
||||
if (settings->ssid == NULL || settings->ssid_len == 0) {
|
||||
@@ -4497,7 +4503,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
|
||||
/* Parameters shared by all radio interfaces */
|
||||
if (!mbss) {
|
||||
- if (is_11d != ifp->vif->is_11d) {
|
||||
+ if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
|
||||
is_11d);
|
||||
if (err < 0) {
|
||||
@@ -4539,7 +4545,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
brcmf_err("SET INFRA error %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
- } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
|
||||
+ } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
|
||||
/* Multiple-BSS should use same 11d configuration */
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
@@ -4673,11 +4679,8 @@ static int brcmf_cfg80211_stop_ap(struct
|
||||
brcmf_err("setting INFRA mode failed %d\n", err);
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
|
||||
brcmf_fil_iovar_int_set(ifp, "mbss", 0);
|
||||
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
|
||||
- ifp->vif->is_11d);
|
||||
- if (err < 0)
|
||||
- brcmf_err("restoring REGULATORY setting failed %d\n",
|
||||
- err);
|
||||
+ brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
|
||||
+ ifp->vif->is_11d);
|
||||
/* Bring device back up so it can be used again */
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
|
||||
if (err < 0)
|
||||
@ -0,0 +1,32 @@
|
||||
From 704d1c6b56f4ee2ad6a5f012a72a278d17c1a223 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:52 +0100
|
||||
Subject: [PATCH] brcmfmac: rework pointer trickery in
|
||||
brcmf_proto_bcdc_query_dcmd()
|
||||
|
||||
The variable info is assigned to point to bcdc->msg[1], which is the
|
||||
same as pointing to bcdc->buf. As that is what we want to access
|
||||
make it clear by fixing the assignment. This also avoid out-of-bounds
|
||||
errors from static analyzers are bcdc->msg[1] is not in the structure
|
||||
definition.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -194,7 +194,7 @@ retry:
|
||||
}
|
||||
|
||||
/* Check info buffer */
|
||||
- info = (void *)&msg[1];
|
||||
+ info = (void *)&bcdc->buf[0];
|
||||
|
||||
/* Copy info buffer */
|
||||
if (buf) {
|
||||
@ -0,0 +1,39 @@
|
||||
From bc981641360183990de59da17f9f560f9150b801 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:53 +0100
|
||||
Subject: [PATCH] brcmfmac: fix memory leak in brcmf_flowring_add_tdls_peer()
|
||||
|
||||
In the error paths in brcmf_flowring_add_tdls_peer() the allocated
|
||||
resource should be freed.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
|
||||
@@ -495,14 +495,18 @@ void brcmf_flowring_add_tdls_peer(struct
|
||||
} else {
|
||||
search = flow->tdls_entry;
|
||||
if (memcmp(search->mac, peer, ETH_ALEN) == 0)
|
||||
- return;
|
||||
+ goto free_entry;
|
||||
while (search->next) {
|
||||
search = search->next;
|
||||
if (memcmp(search->mac, peer, ETH_ALEN) == 0)
|
||||
- return;
|
||||
+ goto free_entry;
|
||||
}
|
||||
search->next = tdls_entry;
|
||||
}
|
||||
|
||||
flow->tdls_active = true;
|
||||
+ return;
|
||||
+
|
||||
+free_entry:
|
||||
+ kfree(tdls_entry);
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
From 26305d3d7298d1ddf8fd4ce95a382aa90534f0a3 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:54 +0100
|
||||
Subject: [PATCH] brcmfmac: initialize variable in brcmf_sdiod_regrl()
|
||||
|
||||
In case of an error the variable returned is uninitialized. The caller
|
||||
will probably check the error code before using it, but better assure
|
||||
it is set to zero.
|
||||
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||
@@ -416,7 +416,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d
|
||||
|
||||
u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
|
||||
{
|
||||
- u32 data;
|
||||
+ u32 data = 0;
|
||||
int retval;
|
||||
|
||||
brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
|
||||
@ -0,0 +1,107 @@
|
||||
From 8fa5fdec09cd379c9ecb8972f344f8f308e0ccf3 Mon Sep 17 00:00:00 2001
|
||||
From: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:55 +0100
|
||||
Subject: [PATCH] brcmfmac: remove worker from .ndo_set_mac_address() callback
|
||||
|
||||
As it turns out there is no need to use a worker for the callback
|
||||
because it is not called from atomic context.
|
||||
|
||||
Reported-by: Dan Williams <dcbw@redhat.com>
|
||||
Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 39 ++++++++--------------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 --
|
||||
2 files changed, 13 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -136,27 +136,6 @@ static void _brcmf_set_multicast_list(st
|
||||
err);
|
||||
}
|
||||
|
||||
-static void
|
||||
-_brcmf_set_mac_address(struct work_struct *work)
|
||||
-{
|
||||
- struct brcmf_if *ifp;
|
||||
- s32 err;
|
||||
-
|
||||
- ifp = container_of(work, struct brcmf_if, setmacaddr_work);
|
||||
-
|
||||
- brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
-
|
||||
- err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
|
||||
- ETH_ALEN);
|
||||
- if (err < 0) {
|
||||
- brcmf_err("Setting cur_etheraddr failed, %d\n", err);
|
||||
- } else {
|
||||
- brcmf_dbg(TRACE, "MAC address updated to %pM\n",
|
||||
- ifp->mac_addr);
|
||||
- memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
static void _brcmf_update_ndtable(struct work_struct *work)
|
||||
{
|
||||
@@ -190,10 +169,20 @@ static int brcmf_netdev_set_mac_address(
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct sockaddr *sa = (struct sockaddr *)addr;
|
||||
+ int err;
|
||||
|
||||
- memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN);
|
||||
- schedule_work(&ifp->setmacaddr_work);
|
||||
- return 0;
|
||||
+ brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
+
|
||||
+ err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data,
|
||||
+ ETH_ALEN);
|
||||
+ if (err < 0) {
|
||||
+ brcmf_err("Setting cur_etheraddr failed, %d\n", err);
|
||||
+ } else {
|
||||
+ brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data);
|
||||
+ memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN);
|
||||
+ memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
|
||||
+ }
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
|
||||
@@ -525,7 +514,6 @@ int brcmf_net_attach(struct brcmf_if *if
|
||||
/* set the mac address */
|
||||
memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
|
||||
|
||||
- INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
|
||||
INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
|
||||
INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);
|
||||
|
||||
@@ -730,7 +718,6 @@ static void brcmf_del_if(struct brcmf_pu
|
||||
}
|
||||
|
||||
if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
|
||||
- cancel_work_sync(&ifp->setmacaddr_work);
|
||||
cancel_work_sync(&ifp->multicast_work);
|
||||
cancel_work_sync(&ifp->ndoffload_work);
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -176,7 +176,6 @@ enum brcmf_netif_stop_reason {
|
||||
* @vif: points to cfg80211 specific interface information.
|
||||
* @ndev: associated network device.
|
||||
* @stats: interface specific network statistics.
|
||||
- * @setmacaddr_work: worker object for setting mac address.
|
||||
* @multicast_work: worker object for multicast provisioning.
|
||||
* @ndoffload_work: worker object for neighbor discovery offload configuration.
|
||||
* @fws_desc: interface specific firmware-signalling descriptor.
|
||||
@@ -193,7 +192,6 @@ struct brcmf_if {
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
struct net_device *ndev;
|
||||
struct net_device_stats stats;
|
||||
- struct work_struct setmacaddr_work;
|
||||
struct work_struct multicast_work;
|
||||
struct work_struct ndoffload_work;
|
||||
struct brcmf_fws_mac_descriptor *fws_desc;
|
||||
@ -0,0 +1,31 @@
|
||||
From 835680b82f029818c813324aed3073cdcf63241f Mon Sep 17 00:00:00 2001
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:56 +0100
|
||||
Subject: [PATCH] brcmfmac: remove unnecessary null pointer check
|
||||
|
||||
in the function brcmf_bus_start() in the exception handling a
|
||||
check is made to dermine whether ifp is null, though this is not
|
||||
possible. Removing the unnessary check.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -1048,8 +1048,7 @@ fail:
|
||||
brcmf_fws_del_interface(ifp);
|
||||
brcmf_fws_deinit(drvr);
|
||||
}
|
||||
- if (ifp)
|
||||
- brcmf_net_detach(ifp->ndev, false);
|
||||
+ brcmf_net_detach(ifp->ndev, false);
|
||||
if (p2p_ifp)
|
||||
brcmf_net_detach(p2p_ifp->ndev, false);
|
||||
drvr->iflist[0] = NULL;
|
||||
@ -0,0 +1,37 @@
|
||||
From 2b7425f3629b38c438f890c20c5faeca64b144ff Mon Sep 17 00:00:00 2001
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:57 +0100
|
||||
Subject: [PATCH] brcmfmac: fix clearing entry IPv6 address
|
||||
|
||||
When IPv6 address is to be cleared there is a possible out of
|
||||
bound access. But also the clearing of the last entry and the
|
||||
adjustment of total number of stored IPv6 addresses is not
|
||||
updated. This patch fixes that bug. Bug was found using coverity.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -873,9 +873,12 @@ static int brcmf_inet6addr_changed(struc
|
||||
}
|
||||
break;
|
||||
case NETDEV_DOWN:
|
||||
- if (i < NDOL_MAX_ENTRIES)
|
||||
- for (; i < ifp->ipv6addr_idx; i++)
|
||||
+ if (i < NDOL_MAX_ENTRIES) {
|
||||
+ for (; i < ifp->ipv6addr_idx - 1; i++)
|
||||
table[i] = table[i + 1];
|
||||
+ memset(&table[i], 0, sizeof(table[i]));
|
||||
+ ifp->ipv6addr_idx--;
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -0,0 +1,44 @@
|
||||
From a7ed7828ecda0c2b5e0d7f55dedd4230afd4b583 Mon Sep 17 00:00:00 2001
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:58 +0100
|
||||
Subject: [PATCH] brcmfmac: fix out of bound access on clearing wowl wake
|
||||
indicator
|
||||
|
||||
Clearing the wowl wakeindicator happens with a rather odd
|
||||
construction where the string "clear" is used to set the iovar
|
||||
wowl_wakeind. This was implemented incorrectly as it caused an
|
||||
out of bound access. Use an intermediate variable of correct
|
||||
length and copy string in that. Problem was found using coverity.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -3623,6 +3623,7 @@ static void brcmf_configure_wowl(struct
|
||||
struct cfg80211_wowlan *wowl)
|
||||
{
|
||||
u32 wowl_config;
|
||||
+ struct brcmf_wowl_wakeind_le wowl_wakeind;
|
||||
u32 i;
|
||||
|
||||
brcmf_dbg(TRACE, "Suspend, wowl config.\n");
|
||||
@@ -3664,8 +3665,9 @@ static void brcmf_configure_wowl(struct
|
||||
if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
|
||||
wowl_config |= BRCMF_WOWL_UNASSOC;
|
||||
|
||||
- brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear",
|
||||
- sizeof(struct brcmf_wowl_wakeind_le));
|
||||
+ memcpy(&wowl_wakeind, "clear", 6);
|
||||
+ brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
|
||||
+ sizeof(wowl_wakeind));
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
|
||||
brcmf_bus_wowl_config(cfg->pub->bus_if, true);
|
||||
@ -0,0 +1,39 @@
|
||||
From 92c313604711a0976def79dabb9e8da3cc2cc780 Mon Sep 17 00:00:00 2001
|
||||
From: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Date: Mon, 19 Sep 2016 12:09:59 +0100
|
||||
Subject: [PATCH] brcmfmac: simplify mapping of auth type
|
||||
|
||||
The 802.11 standard only has four valid auth type configurations of which
|
||||
our firmware only supports two, ie. Open System and Shared Key. Simplify
|
||||
the mapping falling back to automatic for other types specified by
|
||||
user-space.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Reviewed-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 +-------
|
||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -1577,15 +1577,9 @@ static s32 brcmf_set_auth_type(struct ne
|
||||
val = 1;
|
||||
brcmf_dbg(CONN, "shared key\n");
|
||||
break;
|
||||
- case NL80211_AUTHTYPE_AUTOMATIC:
|
||||
- val = 2;
|
||||
- brcmf_dbg(CONN, "automatic\n");
|
||||
- break;
|
||||
- case NL80211_AUTHTYPE_NETWORK_EAP:
|
||||
- brcmf_dbg(CONN, "network eap\n");
|
||||
default:
|
||||
val = 2;
|
||||
- brcmf_err("invalid auth type (%d)\n", sme->auth_type);
|
||||
+ brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
From 23e9c128adb2038c27a424a5f91136e7fa3e0dc6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Wed, 21 Sep 2016 08:23:24 +0200
|
||||
Subject: [PATCH] brcmfmac: fix memory leak in brcmf_fill_bss_param
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This function is called from get_station callback which means that every
|
||||
time user space was getting/dumping station(s) we were leaking 2 KiB.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <rafal@milecki.pl>
|
||||
Fixes: 1f0dc59a6de ("brcmfmac: rework .get_station() callback")
|
||||
Cc: stable@vger.kernel.org # 4.2+
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2463,7 +2463,7 @@ static void brcmf_fill_bss_param(struct
|
||||
WL_BSS_INFO_MAX);
|
||||
if (err) {
|
||||
brcmf_err("Failed to get bss info (%d)\n", err);
|
||||
- return;
|
||||
+ goto out_kfree;
|
||||
}
|
||||
si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
|
||||
si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
|
||||
@@ -2475,6 +2475,9 @@ static void brcmf_fill_bss_param(struct
|
||||
si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
|
||||
if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
|
||||
si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
|
||||
+
|
||||
+out_kfree:
|
||||
+ kfree(buf);
|
||||
}
|
||||
|
||||
static s32
|
||||
@ -0,0 +1,60 @@
|
||||
From 2df86ad959c9d1cdbeb2f23a0801857731156692 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Fri, 23 Sep 2016 15:27:46 +0200
|
||||
Subject: [PATCH] brcmfmac: drop unused fields from struct brcmf_pub
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
They seem to be there from the first day. We calculate these values but
|
||||
never use them.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <rafal@milecki.pl>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 4 ----
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 --
|
||||
3 files changed, 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -508,9 +508,6 @@ int brcmf_net_attach(struct brcmf_if *if
|
||||
ndev->hard_header_len += drvr->hdrlen;
|
||||
ndev->ethtool_ops = &brcmf_ethtool_ops;
|
||||
|
||||
- drvr->rxsz = ndev->mtu + ndev->hard_header_len +
|
||||
- drvr->hdrlen;
|
||||
-
|
||||
/* set the mac address */
|
||||
memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -112,15 +112,11 @@ struct brcmf_pub {
|
||||
|
||||
/* Internal brcmf items */
|
||||
uint hdrlen; /* Total BRCMF header length (proto + bus) */
|
||||
- uint rxsz; /* Rx buffer size bus module should use */
|
||||
|
||||
/* Dongle media info */
|
||||
char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN];
|
||||
u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
|
||||
|
||||
- /* Multicast data packets sent to dongle */
|
||||
- unsigned long tx_multicast;
|
||||
-
|
||||
struct mac_address addresses[BRCMF_MAX_IFS];
|
||||
|
||||
struct brcmf_if *iflist[BRCMF_MAX_IFS];
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||
@@ -2104,8 +2104,6 @@ int brcmf_fws_process_skb(struct brcmf_i
|
||||
if (!skb->priority)
|
||||
skb->priority = cfg80211_classify8021d(skb, NULL);
|
||||
|
||||
- drvr->tx_multicast += !!multicast;
|
||||
-
|
||||
if (fws->avoid_queueing) {
|
||||
rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
|
||||
if (rc < 0)
|
||||
@ -0,0 +1,38 @@
|
||||
From 2f0e56fa37cce60a5ac5d451bcadec51cd711436 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Tue, 27 Sep 2016 12:12:24 +0200
|
||||
Subject: [PATCH] brcmfmac: replace WARNING on timeout with a simple error
|
||||
message
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Even with timeout increased to 950 ms we get WARNINGs from time to time.
|
||||
It mostly happens on A-MPDU stalls (e.g. when station goes out of
|
||||
range). It may take up to 5-10 secods for the firmware to recover and
|
||||
for that time it doesn't process packets.
|
||||
|
||||
It's still useful to have a message on time out as it may indicate some
|
||||
firmware problem and incorrect key update. Raising a WARNING however
|
||||
wasn't really that necessary, it doesn't point to any driver bug anymore
|
||||
and backtrace wasn't much useful.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -1155,7 +1155,8 @@ int brcmf_netdev_wait_pend8021x(struct b
|
||||
!brcmf_get_pend_8021x_cnt(ifp),
|
||||
MAX_WAIT_FOR_8021X_TX);
|
||||
|
||||
- WARN_ON(!err);
|
||||
+ if (!err)
|
||||
+ brcmf_err("Timed out waiting for no pending 802.1x packets\n");
|
||||
|
||||
return !err;
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
From 7f00ee2bbc630900ba16fc2690473f3e2db0e264 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Tue, 27 Sep 2016 14:11:04 +0200
|
||||
Subject: [PATCH] brcmfmac: use correct skb freeing helper when deleting
|
||||
flowring
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Flowrings contain skbs waiting for transmission that were passed to us
|
||||
by netif. It means we checked every one of them looking for 802.1x
|
||||
Ethernet type. When deleting flowring we have to use freeing function
|
||||
that will check for 802.1x type as well.
|
||||
|
||||
Freeing skbs without a proper check was leading to counter not being
|
||||
properly decreased. This was triggering a WARNING every time
|
||||
brcmf_netdev_wait_pend8021x was called.
|
||||
|
||||
Signed-off-by: RafaÅ MiÅecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend@broadcom.com>
|
||||
Cc: stable@vger.kernel.org # 4.5+
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
|
||||
@@ -234,13 +234,20 @@ static void brcmf_flowring_block(struct
|
||||
|
||||
void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid)
|
||||
{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
|
||||
struct brcmf_flowring_ring *ring;
|
||||
+ struct brcmf_if *ifp;
|
||||
u16 hash_idx;
|
||||
+ u8 ifidx;
|
||||
struct sk_buff *skb;
|
||||
|
||||
ring = flow->rings[flowid];
|
||||
if (!ring)
|
||||
return;
|
||||
+
|
||||
+ ifidx = brcmf_flowring_ifidx_get(flow, flowid);
|
||||
+ ifp = brcmf_get_ifp(bus_if->drvr, ifidx);
|
||||
+
|
||||
brcmf_flowring_block(flow, flowid, false);
|
||||
hash_idx = ring->hash_id;
|
||||
flow->hash[hash_idx].ifidx = BRCMF_FLOWRING_INVALID_IFIDX;
|
||||
@@ -249,7 +256,7 @@ void brcmf_flowring_delete(struct brcmf_
|
||||
|
||||
skb = skb_dequeue(&ring->skblist);
|
||||
while (skb) {
|
||||
- brcmu_pkt_buf_free_skb(skb);
|
||||
+ brcmf_txfinalize(ifp, skb, false);
|
||||
skb = skb_dequeue(&ring->skblist);
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Subject: [PATCH] brcmfmac: add missing eth_type_trans call
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There are 2 protocols supported by brcmfmac and msgbuf one was missing a
|
||||
proper skb setup before passing it to the netif. This was triggering
|
||||
"NULL pointer dereference".
|
||||
|
||||
Fixes: 9c349892ccc9 ("brcmfmac: revise handling events in receive path")
|
||||
Signed-off-by: RafaÅ MiÅecki <zajec5@gmail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||
@@ -1157,6 +1157,9 @@ brcmf_msgbuf_process_rx_complete(struct
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
+
|
||||
brcmf_netif_rx(ifp, skb);
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -1308,6 +1308,7 @@ static int __init brcmfmac_module_init(v
|
||||
#endif
|
||||
@@ -1200,6 +1200,7 @@ int __init brcmf_core_init(void)
|
||||
{
|
||||
if (!schedule_work(&brcmf_driver_work))
|
||||
return -EBUSY;
|
||||
+ flush_work(&brcmf_driver_work);
|
||||
|
||||
@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -630,9 +630,37 @@ static struct wireless_dev *brcmf_cfg802
|
||||
@@ -651,9 +651,37 @@ static struct wireless_dev *brcmf_cfg802
|
||||
u32 *flags,
|
||||
struct vif_params *params)
|
||||
{
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mwlwifi
|
||||
PKG_VERSION:=10.3.0.16-20160105
|
||||
PKG_VERSION:=10.3.0.18-20160804
|
||||
PKG_RELEASE=1
|
||||
|
||||
PKG_LICENSE:=ISC
|
||||
@ -17,7 +17,7 @@ PKG_LICENSE_FILES:=
|
||||
PKG_SOURCE_URL:=https://github.com/kaloz/mwlwifi
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_SOURCE_VERSION:=99d3879cc72f2a25d44fb4bee96fd84eca028b04
|
||||
PKG_SOURCE_VERSION:=d48847cc83954930fdcd98818bbf33e75707b8e1
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
|
||||
|
||||
PKG_MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
--- a/main.c
|
||||
+++ b/main.c
|
||||
@@ -418,11 +418,7 @@ static void mwl_set_ht_caps(struct mwl_p
|
||||
band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
|
||||
band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
|
||||
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||
- hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
|
||||
-#else
|
||||
ieee80211_hw_set(hw, AMPDU_AGGREGATION);
|
||||
-#endif
|
||||
band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_4;
|
||||
|
||||
@@ -524,29 +520,16 @@ static int mwl_wl_init(struct mwl_priv *
|
||||
hw->queues = SYSADPT_TX_WMM_QUEUES;
|
||||
|
||||
/* Set rssi values to dBm */
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||
- hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
|
||||
-#else
|
||||
ieee80211_hw_set(hw, SIGNAL_DBM);
|
||||
ieee80211_hw_set(hw, HAS_RATE_CONTROL);
|
||||
-#endif
|
||||
|
||||
/* Ask mac80211 not to trigger PS mode
|
||||
* based on PM bit of incoming frames.
|
||||
*/
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||
- hw->flags |= IEEE80211_HW_AP_LINK_PS;
|
||||
-#else
|
||||
ieee80211_hw_set(hw, AP_LINK_PS);
|
||||
-#endif
|
||||
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
|
||||
- hw->flags |= IEEE80211_HW_SUPPORTS_PER_STA_GTK |
|
||||
- IEEE80211_HW_MFP_CAPABLE;
|
||||
-#else
|
||||
ieee80211_hw_set(hw, SUPPORTS_PER_STA_GTK);
|
||||
ieee80211_hw_set(hw, MFP_CAPABLE);
|
||||
-#endif
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
|
||||
--- a/dev.h
|
||||
+++ b/dev.h
|
||||
@@ -484,10 +484,6 @@ static inline struct mwl_sta *mwl_dev_ge
|
||||
return (struct mwl_sta *)&sta->drv_priv;
|
||||
}
|
||||
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
|
||||
-#define ether_addr_copy(dst, src) memcpy(dst, src, ETH_ALEN)
|
||||
-#endif
|
||||
-
|
||||
/* Defined in mac80211.c. */
|
||||
extern const struct ieee80211_ops mwl_mac80211_ops;
|
||||
|
||||
--- a/mac80211.c
|
||||
+++ b/mac80211.c
|
||||
@@ -572,19 +572,11 @@ static int mwl_mac80211_get_survey(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
|
||||
-static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
|
||||
- struct ieee80211_vif *vif,
|
||||
- enum ieee80211_ampdu_mlme_action action,
|
||||
- struct ieee80211_sta *sta,
|
||||
- u16 tid, u16 *ssn, u8 buf_size)
|
||||
-#else
|
||||
static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta,
|
||||
u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
||||
-#endif
|
||||
{
|
||||
int rc = 0;
|
||||
struct mwl_priv *priv = hw->priv;
|
||||
--- a/rx.c
|
||||
+++ b/rx.c
|
||||
@@ -232,10 +232,8 @@ static inline void mwl_rx_prepare_status
|
||||
status->flag |= RX_FLAG_VHT;
|
||||
if (bw == RX_RATE_INFO_HT40)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
-#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 18, 0)
|
||||
if (bw == RX_RATE_INFO_HT80)
|
||||
status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
-#endif
|
||||
if (gi == RX_RATE_INFO_SHORT_INTERVAL)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
status->vht_nss = (nss + 1);
|
||||
@ -1,19 +0,0 @@
|
||||
--- a/mac80211.c
|
||||
+++ b/mac80211.c
|
||||
@@ -597,10 +597,13 @@ static int mwl_mac80211_get_survey(struc
|
||||
|
||||
static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
- enum ieee80211_ampdu_mlme_action action,
|
||||
- struct ieee80211_sta *sta,
|
||||
- u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
||||
+ struct ieee80211_ampdu_params *params)
|
||||
{
|
||||
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
||||
+ struct ieee80211_sta *sta = params->sta;
|
||||
+ u16 tid = params->tid;
|
||||
+ u16 *ssn = ¶ms->ssn;
|
||||
+ u8 buf_size = params->buf_size;
|
||||
int rc = 0;
|
||||
struct mwl_priv *priv = hw->priv;
|
||||
struct mwl_ampdu_stream *stream;
|
||||
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=openssl
|
||||
PKG_BASE:=1.0.2
|
||||
PKG_BUGFIX:=h
|
||||
PKG_BUGFIX:=j
|
||||
PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX)
|
||||
PKG_RELEASE:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
@ -21,7 +21,7 @@ PKG_SOURCE_URL:=http://www.openssl.org/source/ \
|
||||
http://www.openssl.org/source/old/$(PKG_BASE)/ \
|
||||
ftp://ftp.funet.fi/pub/crypt/mirrors/ftp.openssl.org/source \
|
||||
ftp://ftp.sunet.se/pub/security/tools/net/openssl/source/
|
||||
PKG_MD5SUM:=9392e65072ce4b614c1392eefc1f23d0
|
||||
PKG_MD5SUM:=96322138f0b69e61b7212bc53d5e912b
|
||||
|
||||
PKG_LICENSE:=OpenSSL
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@ -8,13 +8,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=rpcd
|
||||
PKG_VERSION:=2016-04-13
|
||||
PKG_VERSION:=2016-06-30
|
||||
PKG_RELEASE=$(PKG_SOURCE_VERSION)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(OPENWRT_GIT)/project/rpcd.git
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)
|
||||
PKG_SOURCE_VERSION:=73aea9b8b621a1ce034bc6ee00c9d058a40c8a3d
|
||||
PKG_SOURCE_VERSION:=23417e94d25570e6d62542bac46edd51e8e0243a
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
|
||||
PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
|
||||
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
From f1ba020af5076172c9d29006a747ccf40027fedc Mon Sep 17 00:00:00 2001
|
||||
Message-Id: <f1ba020af5076172c9d29006a747ccf40027fedc.1458840219.git.mschiffer@universe-factory.net>
|
||||
From: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
Date: Thu, 24 Mar 2016 15:34:05 +0100
|
||||
Subject: [PATCH] MIPS: ath79: make bootconsole wait for both THRE and TEMT
|
||||
|
||||
This makes the ath79 bootconsole behave the same way as the generic 8250
|
||||
bootconsole.
|
||||
|
||||
Also waiting for TEMT (transmit buffer is empty) instead of just THRE
|
||||
(transmit buffer is not full) ensures that all characters have been
|
||||
transmitted before the real serial driver starts reconfiguring the serial
|
||||
controller (which would sometimes result in garbage being transmitted.)
|
||||
This change does not cause a visible performance loss.
|
||||
|
||||
In addition, this seems to fix a hang observed in certain configurations on
|
||||
many AR7xxx/AR9xxx SoCs during autoconfig of the real serial driver.
|
||||
|
||||
A more complete follow-up patch will disable 8250 autoconfig for ath79
|
||||
altogether (the serial controller is detected as a 16550A, which is not
|
||||
fully compatible with the ath79 serial, and the autoconfig may lead to
|
||||
undefined behavior on ath79.)
|
||||
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
---
|
||||
arch/mips/ath79/early_printk.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/mips/ath79/early_printk.c
|
||||
+++ b/arch/mips/ath79/early_printk.c
|
||||
@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(voi
|
||||
} while (1);
|
||||
}
|
||||
|
||||
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
|
||||
+
|
||||
static void prom_putchar_ar71xx(unsigned char ch)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
|
||||
|
||||
- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
|
||||
+ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
|
||||
__raw_writel(ch, base + UART_TX * 4);
|
||||
- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
|
||||
+ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
|
||||
}
|
||||
|
||||
static void prom_putchar_ar933x(unsigned char ch)
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -196,6 +196,17 @@ config ATH79_MACH_F9K1115V2
|
||||
@@ -205,6 +205,17 @@ config ATH79_MACH_F9K1115V2
|
||||
select ATH79_DEV_USB
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
select SOC_QCA955X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -72,6 +72,7 @@ obj-$(CONFIG_ATH79_MACH_EAP300V2) += mac
|
||||
@@ -73,6 +73,7 @@ obj-$(CONFIG_ATH79_MACH_EAP300V2) += mac
|
||||
obj-$(CONFIG_ATH79_MACH_EAP7660D) += mach-eap7660d.o
|
||||
obj-$(CONFIG_ATH79_MACH_EL_M150) += mach-el-m150.o
|
||||
obj-$(CONFIG_ATH79_MACH_EL_MINI) += mach-el-mini.o
|
||||
@ -30,7 +30,7 @@
|
||||
obj-$(CONFIG_ATH79_MACH_GL_INET) += mach-gl-inet.o
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -62,6 +62,7 @@ enum ath79_mach_type {
|
||||
@@ -63,6 +63,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_EL_M150, /* EasyLink EL-M150 */
|
||||
ATH79_MACH_EL_MINI, /* EasyLink EL-MINI */
|
||||
ATH79_MACH_ESR1750, /* EnGenius ESR1750 */
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -590,6 +590,16 @@ config ATH79_MACH_R6100
|
||||
@@ -599,6 +599,16 @@ config ATH79_MACH_R6100
|
||||
select ATH79_DEV_USB
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
select SOC_AR71XX
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -81,6 +81,7 @@ obj-$(CONFIG_ATH79_MACH_HIWIFI_HC6361) +
|
||||
@@ -82,6 +82,7 @@ obj-$(CONFIG_ATH79_MACH_HIWIFI_HC6361) +
|
||||
obj-$(CONFIG_ATH79_MACH_JA76PF) += mach-ja76pf.o
|
||||
obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o
|
||||
obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o
|
||||
@ -29,7 +29,7 @@
|
||||
obj-$(CONFIG_ATH79_MACH_MYNET_N600) += mach-mynet-n600.o
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -121,6 +121,7 @@ enum ath79_mach_type {
|
||||
@@ -122,6 +122,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_TEW_673GRU, /* TRENDnet TEW-673GRU */
|
||||
ATH79_MACH_TEW_712BR, /* TRENDnet TEW-712BR */
|
||||
ATH79_MACH_TEW_732BR, /* TRENDnet TEW-732BR */
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -87,6 +87,7 @@ enum ath79_mach_type {
|
||||
@@ -88,6 +88,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_OM2P_LC, /* OpenMesh OM2P-LC */
|
||||
ATH79_MACH_OM2Pv2, /* OpenMesh OM2Pv2 */
|
||||
ATH79_MACH_OM2P, /* OpenMesh OM2P */
|
||||
@ -10,7 +10,7 @@
|
||||
ATH79_MACH_PB42, /* Atheros PB42 */
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -743,6 +743,7 @@ config ATH79_MACH_OM2P
|
||||
@@ -752,6 +752,7 @@ config ATH79_MACH_OM2P
|
||||
config ATH79_MACH_OM5P
|
||||
bool "OpenMesh OM5P board support"
|
||||
select SOC_AR934X
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -760,6 +760,26 @@ config ATH79_MACH_ONION_OMEGA
|
||||
@@ -769,6 +769,26 @@ config ATH79_MACH_ONION_OMEGA
|
||||
select ATH79_DEV_USB
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
select SOC_AR934X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -82,6 +82,8 @@ obj-$(CONFIG_ATH79_MACH_JA76PF) += mach
|
||||
@@ -83,6 +83,8 @@ obj-$(CONFIG_ATH79_MACH_JA76PF) += mach
|
||||
obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o
|
||||
obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o
|
||||
obj-$(CONFIG_ATH79_MACH_MC_MAC1200R) += mach-mc-mac1200r.o
|
||||
@ -40,7 +40,7 @@
|
||||
obj-$(CONFIG_ATH79_MACH_MYNET_N600) += mach-mynet-n600.o
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -71,6 +71,8 @@ enum ath79_mach_type {
|
||||
@@ -72,6 +72,8 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_JA76PF2, /* jjPlus JA76PF2 */
|
||||
ATH79_MACH_JWAP003, /* jjPlus JWAP003 */
|
||||
ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -65,6 +65,7 @@ enum ath79_mach_type {
|
||||
@@ -66,6 +66,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_EPG5000, /* EnGenius EPG5000 */
|
||||
ATH79_MACH_F9K1115V2, /* Belkin AC1750DB */
|
||||
ATH79_MACH_GL_INET, /* GL-CONNECT GL-INET */
|
||||
@ -10,7 +10,7 @@
|
||||
ATH79_MACH_JA76PF, /* jjPlus JA76PF */
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -522,6 +522,16 @@ config ATH79_MACH_EAP300V2
|
||||
@@ -531,6 +531,16 @@ config ATH79_MACH_EAP300V2
|
||||
select ATH79_DEV_M25P80
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
select SOC_AR933X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -76,6 +76,7 @@ obj-$(CONFIG_ATH79_MACH_EPG5000) += mach
|
||||
@@ -77,6 +77,7 @@ obj-$(CONFIG_ATH79_MACH_EPG5000) += mach
|
||||
obj-$(CONFIG_ATH79_MACH_ESR1750) += mach-esr1750.o
|
||||
obj-$(CONFIG_ATH79_MACH_F9K1115V2) += mach-f9k1115v2.o
|
||||
obj-$(CONFIG_ATH79_MACH_GL_INET) += mach-gl-inet.o
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -635,6 +635,16 @@ config ATH79_MACH_RB91X
|
||||
@@ -644,6 +644,16 @@ config ATH79_MACH_RB91X
|
||||
select ATH79_DEV_USB
|
||||
select ATH79_ROUTERBOOT
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
select SOC_AR934X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -104,6 +104,7 @@ obj-$(CONFIG_ATH79_MACH_R6100) += mach-
|
||||
@@ -105,6 +105,7 @@ obj-$(CONFIG_ATH79_MACH_R6100) += mach-
|
||||
obj-$(CONFIG_ATH79_MACH_RB4XX) += mach-rb4xx.o
|
||||
obj-$(CONFIG_ATH79_MACH_RB750) += mach-rb750.o
|
||||
obj-$(CONFIG_ATH79_MACH_RB91X) += mach-rb91x.o
|
||||
@ -29,7 +29,7 @@
|
||||
obj-$(CONFIG_ATH79_MACH_RBSXTLITE) += mach-rbsxtlite.o
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -111,6 +111,7 @@ enum ath79_mach_type {
|
||||
@@ -112,6 +112,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_RB_750G_R3, /* MikroTik RouterBOARD 750GL */
|
||||
ATH79_MACH_RB_751, /* MikroTik RouterBOARD 751 */
|
||||
ATH79_MACH_RB_751G, /* Mikrotik RouterBOARD 751G */
|
||||
|
||||
@ -263,7 +263,7 @@
|
||||
case IPV6_2292HOPOPTS:
|
||||
--- a/net/ipv6/ip6_gre.c
|
||||
+++ b/net/ipv6/ip6_gre.c
|
||||
@@ -393,7 +393,7 @@ static void ip6gre_err(struct sk_buff *s
|
||||
@@ -394,7 +394,7 @@ static void ip6gre_err(struct sk_buff *s
|
||||
|
||||
t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
|
||||
flags & GRE_KEY ?
|
||||
@ -272,7 +272,7 @@
|
||||
p[1]);
|
||||
if (t == NULL)
|
||||
return;
|
||||
@@ -475,11 +475,11 @@ static int ip6gre_rcv(struct sk_buff *sk
|
||||
@@ -476,11 +476,11 @@ static int ip6gre_rcv(struct sk_buff *sk
|
||||
offset += 4;
|
||||
}
|
||||
if (flags&GRE_KEY) {
|
||||
@ -286,7 +286,7 @@
|
||||
offset += 4;
|
||||
}
|
||||
}
|
||||
@@ -744,7 +744,7 @@ static netdev_tx_t ip6gre_xmit2(struct s
|
||||
@@ -745,7 +745,7 @@ static netdev_tx_t ip6gre_xmit2(struct s
|
||||
|
||||
if (tunnel->parms.o_flags&GRE_SEQ) {
|
||||
++tunnel->o_seqno;
|
||||
@ -295,7 +295,7 @@
|
||||
ptr--;
|
||||
}
|
||||
if (tunnel->parms.o_flags&GRE_KEY) {
|
||||
@@ -840,7 +840,7 @@ static inline int ip6gre_xmit_ipv6(struc
|
||||
@@ -841,7 +841,7 @@ static inline int ip6gre_xmit_ipv6(struc
|
||||
|
||||
dsfield = ipv6_get_dsfield(ipv6h);
|
||||
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -178,6 +178,7 @@ enum ath79_mach_type {
|
||||
@@ -179,6 +179,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */
|
||||
ATH79_MACH_UBNT_NANO_M_XW, /* Ubiquiti NanoStation M XW */
|
||||
ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -21,6 +21,7 @@ enum ath79_mach_type {
|
||||
@@ -22,6 +22,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_ALL0258N, /* Allnet ALL0258N */
|
||||
ATH79_MACH_ALL0305, /* Allnet ALL0305 */
|
||||
ATH79_MACH_ALL0315N, /* Allnet ALL0315N */
|
||||
@ -10,7 +10,7 @@
|
||||
ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -56,6 +56,16 @@ config ATH79_MACH_ALL0315N
|
||||
@@ -65,6 +65,16 @@ config ATH79_MACH_ALL0315N
|
||||
select ATH79_DEV_LEDS_GPIO
|
||||
select ATH79_DEV_M25P80
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
select SOC_AR724X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -42,6 +42,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_AP96) += ma
|
||||
@@ -43,6 +43,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_AP96) += ma
|
||||
obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach-alfa-nx.o
|
||||
obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o
|
||||
obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -66,6 +66,16 @@ config ATH79_MACH_ANTMINER_S1
|
||||
@@ -75,6 +75,16 @@ config ATH79_MACH_ANTMINER_S1
|
||||
select ATH79_DEV_USB
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
select SOC_AR724X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -43,6 +43,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach
|
||||
@@ -44,6 +44,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach
|
||||
obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o
|
||||
obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o
|
||||
obj-$(CONFIG_ATH79_MACH_ANTMINER_S1)+= mach-antminer-s1.o
|
||||
@ -29,7 +29,7 @@
|
||||
obj-$(CONFIG_ATH79_MACH_AP132) += mach-ap132.o
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -22,6 +22,7 @@ enum ath79_mach_type {
|
||||
@@ -23,6 +23,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_ALL0305, /* Allnet ALL0305 */
|
||||
ATH79_MACH_ALL0315N, /* Allnet ALL0315N */
|
||||
ATH79_MACH_ANTMINER_S1, /* Antminer-S1 */
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -887,6 +887,16 @@ config ATH79_MACH_EAP7660D
|
||||
@@ -896,6 +896,16 @@ config ATH79_MACH_EAP7660D
|
||||
select ATH79_DEV_LEDS_GPIO
|
||||
select ATH79_DEV_M25P80
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
select SOC_QCA955X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -54,6 +54,7 @@ obj-$(CONFIG_ATH79_MACH_AP96) += mach-a
|
||||
@@ -55,6 +55,7 @@ obj-$(CONFIG_ATH79_MACH_AP96) += mach-a
|
||||
obj-$(CONFIG_ATH79_MACH_ARCHER_C7) += mach-archer-c7.o
|
||||
obj-$(CONFIG_ATH79_MACH_AW_NR580) += mach-aw-nr580.o
|
||||
obj-$(CONFIG_ATH79_MACH_BHU_BXU2000N2_A)+= mach-bhu-bxu2000n2-a.o
|
||||
@ -29,7 +29,7 @@
|
||||
obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -37,6 +37,7 @@ enum ath79_mach_type {
|
||||
@@ -38,6 +38,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_ARCHER_C7, /* TP-LINK Archer C7 board */
|
||||
ATH79_MACH_AW_NR580, /* AzureWave AW-NR580 */
|
||||
ATH79_MACH_BHU_BXU2000N2_A1, /* BHU BXU2000n-2 A1 */
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -741,7 +741,7 @@ config ATH79_MACH_WNR2000
|
||||
@@ -750,7 +750,7 @@ config ATH79_MACH_WNR2000
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
config ATH79_MACH_WNR2000_V3
|
||||
@ -11,7 +11,7 @@
|
||||
select ATH79_DEV_ETH
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -204,6 +204,7 @@ enum ath79_mach_type {
|
||||
@@ -206,6 +206,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_WNR2200, /* NETGEAR WNR2200 */
|
||||
ATH79_MACH_WNR612_V2, /* NETGEAR WNR612 v2 */
|
||||
ATH79_MACH_WNR1000_V2, /* NETGEAR WNR1000 v2 */
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
--- a/arch/mips/ath79/machtypes.h 2016-04-12 21:08:09.309541276 +0200
|
||||
+++ b/arch/mips/ath79/machtypes.h 2016-04-12 21:08:43.200013377 +0200
|
||||
@@ -152,6 +152,7 @@
|
||||
ATH79_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */
|
||||
ATH79_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */
|
||||
ATH79_MACH_TL_WA901ND_V3, /* TP-LINK TL-WA901ND v3 */
|
||||
--- a/arch/mips/ath79/machtypes.h
|
||||
+++ b/arch/mips/ath79/machtypes.h
|
||||
@@ -152,6 +152,7 @@ enum ath79_mach_type {
|
||||
ATH79_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */
|
||||
ATH79_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */
|
||||
ATH79_MACH_TL_WA901ND_V3, /* TP-LINK TL-WA901ND v3 */
|
||||
+ ATH79_MACH_TL_WA901ND_V4, /* TP-LINK TL-WA901ND v4 */
|
||||
ATH79_MACH_TL_WDR3500, /* TP-LINK TL-WDR3500 */
|
||||
ATH79_MACH_TL_WDR4300, /* TP-LINK TL-WDR4300 */
|
||||
ATH79_MACH_TL_WDR4900_V2, /* TP-LINK TL-WDR4900 v2 */
|
||||
--- a/arch/mips/ath79/Kconfig 2016-04-12 21:00:07.267269819 +0200
|
||||
+++ b/arch/mips/ath79/Kconfig 2016-04-12 21:00:08.803199911 +0200
|
||||
@@ -1023,6 +1023,15 @@
|
||||
select ATH79_DEV_M25P80
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
ATH79_MACH_TL_WDR3500, /* TP-LINK TL-WDR3500 */
|
||||
ATH79_MACH_TL_WDR4300, /* TP-LINK TL-WDR4300 */
|
||||
ATH79_MACH_TL_WDR4900_V2, /* TP-LINK TL-WDR4900 v2 */
|
||||
--- a/arch/mips/ath79/Kconfig
|
||||
+++ b/arch/mips/ath79/Kconfig
|
||||
@@ -1023,6 +1023,15 @@ config ATH79_MACH_TL_WA901ND_V2
|
||||
select ATH79_DEV_M25P80
|
||||
select ATH79_DEV_WMAC
|
||||
|
||||
+config ATH79_MACH_TL_WA901ND_V4
|
||||
+ bool "TP-LINK TL-WA901ND v4 support"
|
||||
+ select SOC_QCA956X
|
||||
@ -24,11 +24,11 @@
|
||||
+ select ATH79_DEV_WMAC
|
||||
+
|
||||
config ATH79_MACH_TL_WDR3500
|
||||
bool "TP-LINK TL-WDR3500 board support"
|
||||
select SOC_AR934X
|
||||
--- a/arch/mips/ath79/Makefile 2016-04-12 21:03:21.974455904 +0200
|
||||
+++ b/arch/mips/ath79/Makefile 2016-04-12 21:02:56.115621524 +0200
|
||||
@@ -128,6 +128,7 @@
|
||||
bool "TP-LINK TL-WDR3500 board support"
|
||||
select SOC_AR934X
|
||||
--- a/arch/mips/ath79/Makefile
|
||||
+++ b/arch/mips/ath79/Makefile
|
||||
@@ -128,6 +128,7 @@ obj-$(CONFIG_ATH79_MACH_TL_WA7210N_V2) +
|
||||
obj-$(CONFIG_ATH79_MACH_TL_WA830RE_V2) += mach-tl-wa830re-v2.o
|
||||
obj-$(CONFIG_ATH79_MACH_TL_WA901ND) += mach-tl-wa901nd.o
|
||||
obj-$(CONFIG_ATH79_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
|
||||
--- a/drivers/pci/probe.c
|
||||
+++ b/drivers/pci/probe.c
|
||||
@@ -2100,7 +2100,10 @@ struct pci_bus *pci_scan_root_bus(struct
|
||||
@@ -2132,7 +2132,10 @@ struct pci_bus *pci_scan_root_bus(struct
|
||||
if (!found)
|
||||
pci_bus_update_busn_res_end(b, max);
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
return UBI_IO_BAD_HDR_EBADMSG;
|
||||
--- a/drivers/mtd/ubi/ubi.h
|
||||
+++ b/drivers/mtd/ubi/ubi.h
|
||||
@@ -743,6 +743,7 @@ extern struct mutex ubi_devices_mutex;
|
||||
@@ -747,6 +747,7 @@ extern struct mutex ubi_devices_mutex;
|
||||
extern struct blocking_notifier_head ubi_notifiers;
|
||||
|
||||
/* attach.c */
|
||||
|
||||
@ -90,5 +90,5 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
+#endif /* CONFIG_ARCH_BCM_5301X */
|
||||
+
|
||||
if (!ret)
|
||||
xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING);
|
||||
|
||||
/* clear state flags. Including dying, halted or removing */
|
||||
xhci->xhc_state = 0;
|
||||
|
||||
@ -19,7 +19,7 @@ Reduces overhead when using X
|
||||
module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
|
||||
MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
|
||||
|
||||
@@ -1079,8 +1079,12 @@ static int usbhid_start(struct hid_devic
|
||||
@@ -1071,8 +1071,12 @@ static int usbhid_start(struct hid_devic
|
||||
}
|
||||
|
||||
/* Change the polling interval of mice. */
|
||||
|
||||
@ -10,7 +10,7 @@ Hub overcurrent messages are more serious than "debug". Increase loglevel.
|
||||
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -4928,7 +4928,7 @@ static void port_event(struct usb_hub *h
|
||||
@@ -4934,7 +4934,7 @@ static void port_event(struct usb_hub *h
|
||||
if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
|
||||
u16 status = 0, unused;
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
||||
|
||||
--- a/fs/jffs2/nodelist.h
|
||||
+++ b/fs/jffs2/nodelist.h
|
||||
@@ -255,7 +255,7 @@ struct jffs2_full_dirent
|
||||
@@ -259,7 +259,7 @@ struct jffs2_full_dirent
|
||||
uint32_t ino; /* == zero for unlink */
|
||||
unsigned int nhash;
|
||||
unsigned char type;
|
||||
|
||||
@ -145,7 +145,7 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi
|
||||
#endif
|
||||
--- a/kernel/module.c
|
||||
+++ b/kernel/module.c
|
||||
@@ -1837,6 +1837,10 @@ void __weak module_arch_cleanup(struct m
|
||||
@@ -1840,6 +1840,10 @@ void __weak module_arch_cleanup(struct m
|
||||
{
|
||||
}
|
||||
|
||||
@ -156,7 +156,7 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi
|
||||
/* Free a module, remove from lists, etc. */
|
||||
static void free_module(struct module *mod)
|
||||
{
|
||||
@@ -1869,6 +1873,7 @@ static void free_module(struct module *m
|
||||
@@ -1872,6 +1876,7 @@ static void free_module(struct module *m
|
||||
|
||||
/* This may be NULL, but that's OK */
|
||||
unset_module_init_ro_nx(mod);
|
||||
@ -164,7 +164,7 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi
|
||||
module_free(mod, mod->module_init);
|
||||
kfree(mod->args);
|
||||
percpu_modfree(mod);
|
||||
@@ -2958,6 +2963,7 @@ static struct module *layout_and_allocat
|
||||
@@ -2978,6 +2983,7 @@ static struct module *layout_and_allocat
|
||||
static void module_deallocate(struct module *mod, struct load_info *info)
|
||||
{
|
||||
percpu_modfree(mod);
|
||||
@ -172,8 +172,8 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi
|
||||
module_free(mod, mod->module_init);
|
||||
module_free(mod, mod->module_core);
|
||||
}
|
||||
@@ -3081,6 +3087,7 @@ static int do_init_module(struct module
|
||||
mod->strtab = mod->core_strtab;
|
||||
@@ -3100,6 +3106,7 @@ static int do_init_module(struct module
|
||||
rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
|
||||
#endif
|
||||
unset_module_init_ro_nx(mod);
|
||||
+ module_arch_freeing_init(mod);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user