[PATCH] ath10k: fix possible ps sleep crash
If probing failed pci sleep timer could remain running and trigger after ath10k structures were freed causing invalid pointer dereference: BUG: unable to handle kernel paging request at c90001c80004 IP: [] iowrite32+0x38/0x40 ... Call Trace: [] ? __ath10k_pci_sleep+0x48/0x60 [ath10k_pci] [] ath10k_pci_ps_timer+0x5e/0x80 [ath10k_pci] [] call_timer_fn+0x3e/0x120 [] ? ath10k_pci_wake+0x150/0x150 [ath10k_pci] [] run_timer_softirq+0x201/0x2e0 [] __do_softirq+0xaf/0x290 [] irq_exit+0x95/0xa0 [] smp_apic_timer_interrupt+0x46/0x60 [] apic_timer_interrupt+0x6e/0x80 Fixes: 77258d409ce4 ("ath10k: enable pci soc powersaving") Signed-off-by: Michal Kazior --- drivers/net/wireless/ath/ath10k/pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 17a060e8efa2..f37de77811f6 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2850,6 +2850,7 @@ err_free_pipes: ath10k_pci_free_pipes(ar); err_sleep: + ath10k_pci_sleep_sync(ar); ath10k_pci_release(ar); err_core_destroy: -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct
On 28 May 2015 at 23:24, Arend van Spriel wrote: > On 05/28/15 14:34, Rafał Miłecki wrote: >> >> On 28 May 2015 at 13:54, Arend van Spriel wrote: >>> >>> On 05/28/15 13:37, Rafał Miłecki wrote: As we plan to add support for platform NVRAM we should store direct data pointer without the extra struct firmware layer. This will allow us to support other sources with the only requirement being u8 buffer. Signed-off-by: Rafał Miłecki Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel --- Tested on router with BCM43602-s using /lib/firmware/brcm/brcmfmac43602-pcie.txt I've written this patch from scratch, it's inspired by the dropped: [PATCH 6/6] brcmfmac: Add support for host platform NVRAM loading. >>> >>> >>> >>> Hi Rafał, >>> >>> So what is your goal here. The inspirational patch was dropped so it can >>> be >>> resubmitted when the mips change it relies on has made its way upstream. >>> So >>> I have to rebase the patch over here and your patch will just give me >>> conflicts during that rebase. So can we please wait or do you need this >>> change right now. >> >> >> The dropped patch will require rebasing/rewriting anyway. There were >> few changes to firmware.c already, I've few more planned, you'll have >> to drop some code form your patch (parts that will go into MIPS tree) >> and probably apply few changes as requested in comments. > > > I already did that and submitted the mips part to Ralf. I am sorry to say > this but what annoys me is that since then you started submitting patches > that seem to be taken from the dropped patch. So I have a problem seeing the > bright side. If Ralf takes the mips part it ends up in linux-next and we can > submit the brcmfmac part. This is truly the first patch based on your dropped one. All other 5 patches were addressing problems I noticed by myself. One of them fixed the same issue you /silently/ did in the dropped one, but I wasn't even aware of that until I started rebasing your patch. We simply noticed the same problem and fixed it on our owns. So I think this patch is the only one that could annoy you, but *honestly* my intention was exactly the opposite. As already said, I just wanted to do possible cleanup early and let you maintain 50% of your original patch instead the whole one. I really don't want to have you annoyed because the need of rebasing your patch. What you said about Ralf's tree and linux-next isn't exactly true. I do believe Kalle won't merge linux-next into wireless-driver-next, so we have to wait for 4.2-rc1, then for Dave merging Linus's tree, then Kalle merging Dave's tree. We really shouldn't stop development for weeks because of having some patch prepared for later submitting. I think the only think you can do to make your life easier is to submit cleanup part of your prepared patch. This is exactly what I tried to do for you. -- Rafał -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 16/20] PKCS#7: Add an optional authenticated attribute to hold firmware name [ver #5]
[resending with further gmane screwups fixed] On 05/28/2015 08:48 AM, David Howells wrote: Modify the sign-file program to take a "-F " parameter. The name is a utf8 string that, if given, is inserted in a PKCS#7 authenticated attribute from where it can be extracted by the kernel. Authenticated attributes are added to the signature digest. If the attribute is present, the signature would be assumed to be for firmware and would not be permitted with module signing or kexec. The name associated with the attribute would be compared to the name passed to request_firmware() and the load request would be denied if they didn't match. This is insecure because PKCS#7 authenticated attributes are broken (see RFC2315 section 9.4 note 4). You need to either require that everything have authenticated attributes or require that nothing have authenticated attributes. Maybe this insecurity doesn't matter in practice, but I don't wouldn't want to bet on it. On top of that, this is a ton of code to support something trivial. And it requires an OID to be registered (ick). Earlier you suggested just appending the signature purpose to the thing being signed. What's wrong with that? It's probably much less code, it doesn't require reviewing details of the godawful PKCS#7 spec, and it will continue working if and when someone adds a more sensible signature format. And you could tear out PKCS#7 authenticated attribute support on top of it. P.S. Or you could stop using PKCS#7 if possible. Holy crap, maybe it's a standard, but it's a standard that we don't actually have to follow and it *has trivial collisions by construction*. For Pete's sake, there are already 1262 lines of code just implementing PKCS#7. In contrast, the *entire* tweetnacl library, which uses better crypto and is actually correct (no built-in collisions) fits a complete signature implementation and the underlying crypto in barely half that many lines. This is actually unfair to tweetnacl, as tweetnacl also includes an AEAD, which could be removed to shorten it by a decent amount. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] README: clarify redistribution requirements covering patents
On Tue, May 19, 2015 at 1:22 PM, Luis R. Rodriguez wrote: > This v2 just changes "licence" to "license" as requested by Arend. Please let me know if there is anything else needed. Luis -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct
On 05/28/15 14:34, Rafał Miłecki wrote: On 28 May 2015 at 13:54, Arend van Spriel wrote: On 05/28/15 13:37, Rafał Miłecki wrote: As we plan to add support for platform NVRAM we should store direct data pointer without the extra struct firmware layer. This will allow us to support other sources with the only requirement being u8 buffer. Signed-off-by: Rafał Miłecki Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel --- Tested on router with BCM43602-s using /lib/firmware/brcm/brcmfmac43602-pcie.txt I've written this patch from scratch, it's inspired by the dropped: [PATCH 6/6] brcmfmac: Add support for host platform NVRAM loading. Hi Rafał, So what is your goal here. The inspirational patch was dropped so it can be resubmitted when the mips change it relies on has made its way upstream. So I have to rebase the patch over here and your patch will just give me conflicts during that rebase. So can we please wait or do you need this change right now. The dropped patch will require rebasing/rewriting anyway. There were few changes to firmware.c already, I've few more planned, you'll have to drop some code form your patch (parts that will go into MIPS tree) and probably apply few changes as requested in comments. I already did that and submitted the mips part to Ralf. I am sorry to say this but what annoys me is that since then you started submitting patches that seem to be taken from the dropped patch. So I have a problem seeing the bright side. If Ralf takes the mips part it ends up in linux-next and we can submit the brcmfmac part. Regards, Arend I also don't think it makes much sense to pause any development because of having some out-of-tree patch queued for later submitting. And after all, hey, look at the bright side! :) With this patch you'll have to maintain smaller amount of out-of-tree(-for-now) code :) So my goals are: 1) Have all required cleanups pushed mainline early. 2) Make it easier to main out-of-tree changes. The personal reason behind that is to add OpenWrt support for BCM43602 as early as possible. Having clean backports + tiny NVRAM patch make it much easier to do now, maintain and update in the future. -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/9] drop unneeded goto
These patches drop gotos that jump to a label that is at the next instruction, in the case that the label is not used elsewhere in the function. The complete semantic patch that performs this transformation is as follows: // @r@ position p; identifier l; @@ if (...) goto l@p; l: @script:ocaml s@ p << r.p; nm; @@ nm := (List.hd p).current_element @ok exists@ identifier s.nm,l; position p != r.p; @@ nm(...) { <+... goto l@p; ...+> } @depends on !ok@ identifier s.nm; position r.p; identifier l; @@ nm(...) { <... - if(...) goto l@p; l: ...> } // -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/9] wl1251: drop unneeded goto
From: Julia Lawall Delete jump to a label on the next line, when that label is not used elsewhere. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @r@ identifier l; @@ -if (...) goto l; -l: // Signed-off-by: Julia Lawall --- drivers/net/wireless/ti/wl1251/acx.c |3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c index 5695628..d6fbdda 100644 --- a/drivers/net/wireless/ti/wl1251/acx.c +++ b/drivers/net/wireless/ti/wl1251/acx.c @@ -53,10 +53,7 @@ int wl1251_acx_station_id(struct wl1251 *wl) mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac)); - if (ret < 0) - goto out; -out: kfree(mac); return ret; } -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] ath10k: Ignore the adjacent radio's activity when surveying a channel
The overall goal for a scanning radio is to evaluate the outside radio environment. Some platforms integrate several radios together. When one radio wants to survey the current channel, the adjacent radio's activity will make this survey result inaccurate. the switcher can be used to enable the FW to ignore the survey time slot when the adjacent radio is active, especially for TX. This skipped scan approach will make the survey result more accurate. This technique requires a precondition that the scanning and adjacent radio have some physical connection to make them aware of each other's activity from within the FW layer, and the FW claimed supporting this capability. To enable this feature, execute: echo 2 > /sys/kernel/debug/ieee80211/phyX/ath10k/adjacent_wlan_interfrc Then run the survey scan and dump the stastics: iw dev wifiX survey dump The TX&RX counter showed already deducted the time slot be interfered To check whether the feature is enabled, execute: cat /sys/kernel/debug/ieee80211/phyX/ath10k/adjacent_wlan_interfrc INTERFRC DETECT FOR SURVEY SCAN: Enable/Disable Signed-off-by: Yanbo Li --- drivers/net/wireless/ath/ath10k/core.h | 1 + drivers/net/wireless/ath/ath10k/debug.c | 4 drivers/net/wireless/ath/ath10k/wmi.c | 5 + drivers/net/wireless/ath/ath10k/wmi.h | 7 +++ 4 files changed, 17 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index fb0e8521fc45..164160aaf8a7 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -491,6 +491,7 @@ enum ath10k_cal_mode { enum ath10k_wlan_interfrc_mask { ATH10K_SPECTRAL_INTERFRC= 0x0001, + ATH10K_SURVEY_INTERFRC = 0x0002, }; static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 534dfb8ada95..3051cbaebc74 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -2190,6 +2190,10 @@ static ssize_t ath10k_read_adjacent_wlan_interfrc(struct file *file, interfrc_5g); len += scnprintf(buf + len, buf_len - len, "2G INTERFRC: %d\n", interfrc_2g); + len += scnprintf(buf + len, buf_len - len, +"INTERFRC DETECT FOR SURVEY SCAN: %s\n", +ar->wlan_interfrc_mask & ATH10K_SURVEY_INTERFRC ? +"Enable" : "Disable"); mutex_unlock(&ar->conf_mutex); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 1fb850817589..dbd394422905 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3942,6 +3942,11 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar) ar->wmi.svc_map))) features |= WMI_10_2_ADJ_RADIO_SPECTRAL_INTERFRC; + if ((ar->wlan_interfrc_mask & ATH10K_SURVEY_INTERFRC) && + (test_bit(WMI_SERVICE_ADJ_RADIO_SURVEY_INTERFRC, ar->wmi.svc_map))) + features |= WMI_10_2_ADJ_RADIO_SURVEY_INTERFRC; + + cmd->resource_config.feature_mask = __cpu_to_le32(features); memcpy(&cmd->resource_config.common, &config, sizeof(config)); diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 36bb0768d87f..7cbad1932bf5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -151,6 +151,7 @@ enum wmi_service { WMI_SERVICE_ATF, WMI_SERVICE_COEX_GPIO, WMI_SERVICE_ADJ_RADIO_SPECTRAL_INTERFRC, + WMI_SERVICE_ADJ_RADIO_SURVEY_INTERFRC, /* keep last */ WMI_SERVICE_MAX, @@ -183,6 +184,7 @@ enum wmi_10x_service { WMI_10X_SERVICE_ATF, WMI_10X_SERVICE_COEX_GPIO, WMI_10X_SERVICE_ADJ_RADIO_SPECTRAL_INTERFRC, + WMI_10X_SERVICE_ADJ_RADIO_SURVEY_INTERFRC, }; enum wmi_main_service { @@ -302,6 +304,7 @@ static inline char *wmi_service_name(int service_id) SVCSTR(WMI_SERVICE_ATF); SVCSTR(WMI_SERVICE_COEX_GPIO); SVCSTR(WMI_SERVICE_ADJ_RADIO_SPECTRAL_INTERFRC); + SVCSTR(WMI_SERVICE_ADJ_RADIO_SURVEY_INTERFRC); default: return NULL; @@ -372,6 +375,9 @@ static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out, WMI_SERVICE_COEX_GPIO, len); SVCMAP(WMI_10X_SERVICE_ADJ_RADIO_SPECTRAL_INTERFRC, WMI_SERVICE_ADJ_RADIO_SPECTRAL_INTERFRC, len); + SVCMAP(WMI_10X_SERVICE_ADJ_RADIO_SURVEY_INTERFRC, + WMI_SERVICE_ADJ_RADIO_SURVEY_INTERFRC, len); + } static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out, @@ -1973,6 +1979,7 @@ enum wmi_10_2_feature_mask { WMI_10_2_ATF_CONFIG= BIT(1), WMI_10_2_COEX_GPIO = BIT(3), WMI_1
[PATCH 1/2] ath10k: Add the adjacent wlan radio interference detecting interface
Some platforms integrate several radios together. When one radio wants to spectral scan the currently channel, the adjacent radio's activity will introduce some interference in the spectral scan result. To combat the problem, enable the FW to set a special mark within the spectral scan results. Using such a mark the user who is processing the data can identify whether the data has been introduced to interference by the adjacent radio during that period. The user can interpret more accurate spectral scan results given marks where interference occurred. This technique requires the preconditions that the scanning and adjacent radio have some physical connection to make them aware of each other's activity from within the FW layer, and the FW claimed supporting this capability. To enable this feature, execute: echo 1 > /sys/kernel/debug/ieee80211/phyX/ath10k/adjacent_wlan_interfrc Then run the spectral scan steps. ... To check whether the spectral scan data be interfered, execute: cat /sys/kernel/debug/ieee80211/phyX/ath10k/adjacent_wlan_interfrc INTERFRC DETECT FOR SPEC SCAN: Enable/Disable 5G_interference: X/0 2G_Interference: X/0 X means the interference number in the scan period, 0 means no interference. These counters will be reset when next round spectral scan be triggered Signed-off-by: Yanbo Li --- drivers/net/wireless/ath/ath10k/core.h | 8 drivers/net/wireless/ath/ath10k/debug.c| 65 ++ drivers/net/wireless/ath/ath10k/spectral.c | 14 +++ drivers/net/wireless/ath/ath10k/wmi.c | 6 +++ drivers/net/wireless/ath/ath10k/wmi.h | 10 + 5 files changed, 103 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 4a84e17016c9..fb0e8521fc45 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -489,6 +489,10 @@ enum ath10k_cal_mode { ATH10K_CAL_MODE_DT, }; +enum ath10k_wlan_interfrc_mask { + ATH10K_SPECTRAL_INTERFRC= 0x0001, +}; + static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) { switch (mode) { @@ -709,6 +713,8 @@ struct ath10k { /* spectral_mode and spec_config are protected by conf_mutex */ enum ath10k_spectral_mode mode; struct ath10k_spec_scan config; + u32 interfrc_5g; + u32 interfrc_2g; } spectral; struct { @@ -729,6 +735,8 @@ struct ath10k { } stats; bool btc_feature; + /* Detect the adjacent wifi radio interference */ + enum ath10k_wlan_interfrc_mask wlan_interfrc_mask; struct ath10k_thermal thermal; struct ath10k_wow wow; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 820a12bc0dd8..534dfb8ada95 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -2142,6 +2142,66 @@ static const struct file_operations fops_btc_feature = { .open = simple_open }; +static ssize_t ath10k_write_adjacent_wlan_interfrc(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + u32 flag; + + if (kstrtouint_from_user(ubuf, count, 0, &flag)) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + if (flag != ar->wlan_interfrc_mask) { + ar->wlan_interfrc_mask = flag; + queue_work(ar->workqueue, &ar->restart_work); + } + mutex_unlock(&ar->conf_mutex); + + return count; +} + +#define ATH10K_WLAN_INTFRC_REPORT_SIZE 256 + +static ssize_t ath10k_read_adjacent_wlan_interfrc(struct file *file, + char __user *ubuf, + size_t count, loff_t *ppos) +{ + char buf[ATH10K_WLAN_INTFRC_REPORT_SIZE]; + struct ath10k *ar = file->private_data; + unsigned int len = 0; + unsigned int buf_len = ATH10K_WLAN_INTFRC_REPORT_SIZE; + u32 interfrc_5g, interfrc_2g; + + mutex_lock(&ar->conf_mutex); + + len += scnprintf(buf, buf_len, +"INTERFRC DETECT FOR SPEC SCAN: %s\n", +ar->wlan_interfrc_mask & ATH10K_SPECTRAL_INTERFRC ? +"Enable" : "Disable"); + + spin_lock_bh(&ar->data_lock); + interfrc_5g = ar->spectral.interfrc_5g; + interfrc_2g = ar->spectral.interfrc_2g; + spin_unlock_bh(&ar->data_lock); + + len += scnprintf(buf + len, buf_len - len, "5G INTERFRC: %d\n", +interfrc_5g); + len += scnprintf(buf + len, buf_len - len, "2G INTERFRC: %d\n", +interfrc_2g); + + mutex_unlock(&ar->conf_mutex); + + return simple_read
[PATCH v2] ath10k: Debugfs entry to enable/disable WLAN&Blutooth Coexist feature
As some radio have no connection with BT modules, enable the WLAN/Bluetooth coexist(BTC) feature will has some side effect if the radio's GPIO connect with any other HW modules. Add the control switcher "btc_feature" at debugfs and set the feature as disable by default to avoid such case. To enable this feature, execute: echo 1 > /sys/kernel/debug/ieee80211/phyX/ath10k/btc_feature To disable: echo 0 > /sys/kernel/debug/ieee80211/phyX/ath10k/btc_feature Signed-off-by: Yanbo Li diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 70fcdc9c2758..4a84e17016c9 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -728,6 +728,8 @@ struct ath10k { u32 fw_cold_reset_counter; } stats; + bool btc_feature; + struct ath10k_thermal thermal; struct ath10k_wow wow; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 8fa606a9c4dd..820a12bc0dd8 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -2092,6 +2092,56 @@ static const struct file_operations fops_quiet_period = { .open = simple_open }; +static ssize_t ath10k_write_btc_feature(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + char buf[32]; + size_t buf_size; + bool val; + + buf_size = min(count, (sizeof(buf) - 1)); + if (copy_from_user(buf, ubuf, buf_size)) + return -EFAULT; + + buf[buf_size] = '\0'; + if (strtobool(buf, &val) != 0) { + ath10k_warn(ar, "Wrong BTC feature setting\n"); + return -EINVAL; + } + + mutex_lock(&ar->conf_mutex); + if (val != ar->btc_feature) { + ar->btc_feature = val; + queue_work(ar->workqueue, &ar->restart_work); + } + mutex_unlock(&ar->conf_mutex); + + return count; +} + +static ssize_t ath10k_read_btc_feature(struct file *file, char __user *ubuf, + size_t count, loff_t *ppos) +{ + char buf[32]; + struct ath10k *ar = file->private_data; + int len = 0; + + mutex_lock(&ar->conf_mutex); + len = scnprintf(buf, sizeof(buf) - len, "%d\n", + ar->btc_feature); + mutex_unlock(&ar->conf_mutex); + + return simple_read_from_buffer(ubuf, count, ppos, buf, len); +} + +static const struct file_operations fops_btc_feature = { + .read = ath10k_read_btc_feature, + .write = ath10k_write_btc_feature, + .open = simple_open +}; + int ath10k_debug_create(struct ath10k *ar) { ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); @@ -2195,6 +2245,8 @@ int ath10k_debug_register(struct ath10k *ar) debugfs_create_file("quiet_period", S_IRUGO | S_IWUSR, ar->debug.debugfs_phy, ar, &fops_quiet_period); + debugfs_create_file("btc_feature", S_IRUGO | S_IWUSR, + ar->debug.debugfs_phy, ar, &fops_btc_feature); return 0; } diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 0fabe689179c..e3c880230ee6 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3933,7 +3933,8 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar) cmd = (struct wmi_init_cmd_10_2 *)buf->data; features = WMI_10_2_RX_BATCH_MODE; - if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map)) + if (ar->btc_feature && + test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map)) features |= WMI_10_2_COEX_GPIO; cmd->resource_config.feature_mask = __cpu_to_le32(features); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] brcmfmac: fix invalid access to struct acpi_device fields
On 05/28/15 18:48, Jason Andryuk wrote: On Wed, May 27, 2015 at 1:31 PM, Arend van Spriel wrote: diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index b0d0ff5..71779b9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -1117,6 +1117,18 @@ 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) +{ +#if IS_ENABLED(CONFIG_ACPI) + struct acpi_device *adev; + + adev = ACPI_COMPANION(dev); + if (adev) + adev->flags.power_manageable = 0; Shouldn't this be " = val"? Definitely. The only place where it is called uses 0 for val parameter so there is no big issue, but I will fix it. Thanks for spotting that bit. Regards, Arend -Jason +#endif +} + static int brcmf_ops_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/17] mwifiex: verbose logging for association failure messages
On Thu, 2015-05-28 at 18:27 +0530, Avinash Patil wrote: > This patch adds more logging support for association failure - > reason and states. [] > diff --git a/drivers/net/wireless/mwifiex/fw.h > b/drivers/net/wireless/mwifiex/fw.h [] > @@ -419,8 +419,12 @@ enum P2P_MODES { > #define HS_CFG_COND_MAC_EVENT0x0004 > #define HS_CFG_COND_MULTICAST_DATA 0x0008 > > -#define MWIFIEX_TIMEOUT_FOR_AP_RESP 0xfffc > -#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 > +#define ASSOC_ERR_AUTH_ERR_STA_FAILURE 0xFFFB > +#define ASSOC_ERR_ASSOC_ERR_TIMEOUT 0xFFFC > +#define ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD Is there really value in duplicating ASSOC_ERR_ ASSOC_ERR_ASSOC_ERR_ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: pull request: iwlmvm firmware -13.ucode
and now with linux-wireless :) On Thu, 2015-05-28 at 20:53 +0300, Emmanuel Grumbach wrote: > Signed this time. > > > On Thu, 2015-05-28 at 20:53 +0300, Emmanuel Grumbach wrote: > > Hello, > > > > This is a pull request to include -13.ucode into mainline. > > This firmware can run on 7260, 3160, 7265, 7265D and 3165 which are all > > the devices driven by iwlmvm. > > This firmware is supported starting from kernel 4.1 > > > > Thanks you. > > > > The following changes since commit 8e181320b11de501046cf75c8c30915cd09a1e39: > > > > linux-firmware: Add Realtek Bluetooth HCD firmware (2015-05-08 13:12:23 > > -0400) > > > > are available in the git repository at: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware.git > > > > for you to fetch changes up to 841b151cfd49e03e6531891e8cef0a5f3de83d40: > > > > iwlwifi: add new -13 firmware for 3160 / 7260 / 7265 / 7265D (2015-05-28 > > 19:54:40 +0300) > > > > > > Emmanuel Grumbach (1): > > iwlwifi: add new -13 firmware for 3160 / 7260 / 7265 / 7265D > > > > WHENCE | 12 > > iwlwifi-3160-13.ucode | Bin 0 -> 688616 bytes > > iwlwifi-7260-13.ucode | Bin 0 -> 786920 bytes > > iwlwifi-7265-13.ucode | Bin 0 -> 885224 bytes > > iwlwifi-7265D-13.ucode | Bin 0 -> 1008668 bytes > > 5 files changed, 12 insertions(+) > > create mode 100644 iwlwifi-3160-13.ucode > > create mode 100644 iwlwifi-7260-13.ucode > > create mode 100644 iwlwifi-7265-13.ucode > > create mode 100644 iwlwifi-7265D-13.ucode > > > > diff --git a/WHENCE b/WHENCE > > index e544914..06da22a 100644 > > --- a/WHENCE > > +++ b/WHENCE > > @@ -834,6 +834,9 @@ Version: 23.15.10.0 > > File: iwlwifi-7260-12.ucode > > Version: 25.17.12.0 > > > > +File: iwlwifi-7260-13.ucode > > +Version: 25.27.13.0 > > + > > File: iwlwifi-3160-7.ucode > > Version: 22.1.7.0 > > > > @@ -849,6 +852,9 @@ Version: 23.15.10.0 > > File: iwlwifi-3160-12.ucode > > Version: 25.17.12.0 > > > > +File: iwlwifi-3160-13.ucode > > +Version: 25.27.13.0 > > + > > File: iwlwifi-7265-8.ucode > > Version: 22.24.8.0 > > > > @@ -861,12 +867,18 @@ Version: 23.15.10.0 > > File: iwlwifi-7265-12.ucode > > Version: 25.17.12.0 > > > > +File: iwlwifi-7265-13.ucode > > +Version: 25.27.13.0 > > + > > File: iwlwifi-7265D-10.ucode > > Version: 23.15.10.0 > > > > File: iwlwifi-7265D-12.ucode > > Version: 25.17.12.0 > > > > +File: iwlwifi-7265D-13.ucode > > +Version: 25.27.13.0 > > + > > Licence: Redistributable. See LICENCE.iwlwifi_firmware for details > > > > Also available from > > http://wireless.kernel.org/en/users/Drivers/iwlwifi#Firmware > > diff --git a/iwlwifi-3160-13.ucode b/iwlwifi-3160-13.ucode > > new file mode 100644 > > index 000..a5fb7b7 > > Binary files /dev/null and b/iwlwifi-3160-13.ucode differ > > diff --git a/iwlwifi-7260-13.ucode b/iwlwifi-7260-13.ucode > > new file mode 100644 > > index 000..a12dd50 > > Binary files /dev/null and b/iwlwifi-7260-13.ucode differ > > diff --git a/iwlwifi-7265-13.ucode b/iwlwifi-7265-13.ucode > > new file mode 100644 > > index 000..53f5134 > > Binary files /dev/null and b/iwlwifi-7265-13.ucode differ > > diff --git a/iwlwifi-7265D-13.ucode b/iwlwifi-7265D-13.ucode > > new file mode 100644 > > index 000..df4307e > > Binary files /dev/null and b/iwlwifi-7265D-13.ucode differ >
Re: [PATCH] brcmfmac: fix invalid access to struct acpi_device fields
On Wed, May 27, 2015 at 1:31 PM, Arend van Spriel wrote: > diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c > b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c > index b0d0ff5..71779b9 100644 > --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c > +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c > @@ -1117,6 +1117,18 @@ 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) > +{ > +#if IS_ENABLED(CONFIG_ACPI) > + struct acpi_device *adev; > + > + adev = ACPI_COMPANION(dev); > + if (adev) > + adev->flags.power_manageable = 0; Shouldn't this be " = val"? -Jason > +#endif > +} > + > static int brcmf_ops_sdio_probe(struct sdio_func *func, > const struct sdio_device_id *id) > { -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/20] MODSIGN: Extract the blob PKCS#7 signature verifier from module signing [ver #5]
Extract the function that drives the PKCS#7 signature verification given a data blob and a PKCS#7 blob out from the module signing code and lump it with the system keyring code as it's generic. This makes it independent of module config options and opens it to use by the firmware loader. Signed-off-by: David Howells Cc: Luis R. Rodriguez Cc: Rusty Russell Cc: Ming Lei Cc: Seth Forshee Cc: Kyle McMartin --- include/keys/system_keyring.h |5 init/Kconfig | 29 kernel/module_signing.c | 44 +--- kernel/system_keyring.c | 50 + 4 files changed, 75 insertions(+), 53 deletions(-) diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index 72665eb80692..9791c907cdb7 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -28,4 +28,9 @@ static inline struct key *get_system_trusted_keyring(void) } #endif +#ifdef CONFIG_SYSTEM_DATA_VERIFICATION +extern int system_verify_data(const void *data, unsigned long len, + const void *raw_pkcs7, size_t pkcs7_len); +#endif + #endif /* _KEYS_SYSTEM_KEYRING_H */ diff --git a/init/Kconfig b/init/Kconfig index fb98cba069c1..c05afd6594f2 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1758,6 +1758,24 @@ config SYSTEM_TRUSTED_KEYRING Keys in this keyring are used by module signature checking. +config SYSTEM_DATA_VERIFICATION + def_bool n + select SYSTEM_TRUSTED_KEYRING + select KEYS + select CRYPTO + select ASYMMETRIC_KEY_TYPE + select ASYMMETRIC_PUBLIC_KEY_SUBTYPE + select PUBLIC_KEY_ALGO_RSA + select ASN1 + select OID_REGISTRY + select X509_CERTIFICATE_PARSER + select PKCS7_MESSAGE_PARSER + help + Provide PKCS#7 message verification using the contents of the system + trusted keyring to provide public keys. This then can be used for + module verification, kexec image verification and firmware blob + verification. + config PROFILING bool "Profiling support" help @@ -1866,16 +1884,7 @@ config MODULE_SRCVERSION_ALL config MODULE_SIG bool "Module signature verification" depends on MODULES - select SYSTEM_TRUSTED_KEYRING - select KEYS - select CRYPTO - select ASYMMETRIC_KEY_TYPE - select ASYMMETRIC_PUBLIC_KEY_SUBTYPE - select PUBLIC_KEY_ALGO_RSA - select ASN1 - select OID_REGISTRY - select X509_CERTIFICATE_PARSER - select PKCS7_MESSAGE_PARSER + select SYSTEM_DATA_VERIFICATION help Check modules for valid signatures upon load: the signature is simply appended to the module. For more information see diff --git a/kernel/module_signing.c b/kernel/module_signing.c index 8eb20cc66b39..70ad463f6df0 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -10,10 +10,8 @@ */ #include -#include #include #include -#include #include "module-internal.h" /* @@ -37,46 +35,6 @@ struct module_signature { }; /* - * Verify a PKCS#7-based signature on a module. - */ -static int mod_verify_pkcs7(const void *mod, unsigned long modlen, - const void *raw_pkcs7, size_t pkcs7_len) -{ - struct pkcs7_message *pkcs7; - bool trusted; - int ret; - - pkcs7 = pkcs7_parse_message(raw_pkcs7, pkcs7_len); - if (IS_ERR(pkcs7)) - return PTR_ERR(pkcs7); - - /* The data should be detached - so we need to supply it. */ - if (pkcs7_supply_detached_data(pkcs7, mod, modlen) < 0) { - pr_err("PKCS#7 signature with non-detached data\n"); - ret = -EBADMSG; - goto error; - } - - ret = pkcs7_verify(pkcs7); - if (ret < 0) - goto error; - - ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted); - if (ret < 0) - goto error; - - if (!trusted) { - pr_err("PKCS#7 signature not signed with a trusted key\n"); - ret = -ENOKEY; - } - -error: - pkcs7_free_message(pkcs7); - pr_devel("<==%s() = %d\n", __func__, ret); - return ret; -} - -/* * Verify the signature on a module. */ int mod_verify_sig(const void *mod, unsigned long *_modlen) @@ -114,5 +72,5 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen) return -EBADMSG; } - return mod_verify_pkcs7(mod, modlen, mod + modlen, sig_len); + return system_verify_data(mod, modlen, mod + modlen, sig_len); } diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c index 4cda71ee51c7..95f2dcbc7616 100644 --- a/kernel/system_keyring.c +++ b/kernel/system_keyring.c @@ -16,6 +16,7 @@ #include #include #include +#include struct key *system_trusted_keyring; EXPORT_SYMBOL_GPL(system_trusted_k
Re: [PATCH 00/20] MODSIGN: Use PKCS#7 for module signatures [ver #5]
David Howells wrote: > Additionally, the last four patches are provisionally added to support > firmware The last five, that is. David -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/20] modsign: Allow signing key to be PKCS#11 [ver #5]
From: David Woodhouse This is only the key; the corresponding *cert* still needs to be in $(topdir)/signing_key.x509. And there's no way to actually use this from the build system yet. Signed-off-by: David Woodhouse Signed-off-by: David Howells --- scripts/sign-file.c | 29 - 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 720b9bc933ae..ad0aa21bd3ac 100755 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -22,6 +22,7 @@ #include #include #include +#include struct module_signature { uint8_t algo; /* Public-key crypto algorithm [0] */ @@ -154,11 +155,29 @@ int main(int argc, char **argv) /* Read the private key and the X.509 cert the PKCS#7 message * will point to. */ - b = BIO_new_file(private_key_name, "rb"); - ERR(!b, "%s", private_key_name); - private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, NULL); - ERR(!private_key, "%s", private_key_name); - BIO_free(b); + if (!strncmp(private_key_name, "pkcs11:", 7)) { + ENGINE *e; + + ENGINE_load_builtin_engines(); + drain_openssl_errors(); + e = ENGINE_by_id("pkcs11"); + ERR(!e, "Load PKCS#11 ENGINE"); + if (ENGINE_init(e)) + drain_openssl_errors(); + else + ERR(1, "ENGINE_init"); + if (key_pass) + ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN"); + private_key = ENGINE_load_private_key(e, private_key_name, NULL, + NULL); + ERR(!private_key, "%s", private_key_name); + } else { + b = BIO_new_file(private_key_name, "rb"); + ERR(!b, "%s", private_key_name); + private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, NULL); + ERR(!private_key, "%s", private_key_name); + BIO_free(b); + } b = BIO_new_file(x509_name, "rb"); ERR(!b, "%s", x509_name); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/20] MODSIGN: Use PKCS#7 messages as module signatures [ver #5]
Move to using PKCS#7 messages as module signatures because: (1) We have to be able to support the use of X.509 certificates that don't have a subjKeyId set. We're currently relying on this to look up the X.509 certificate in the trusted keyring list. (2) PKCS#7 message signed information blocks have a field that supplies the data required to match with the X.509 certificate that signed it. (3) The PKCS#7 certificate carries fields that specify the digest algorithm used to generate the signature in a standardised way and the X.509 certificates specify the public key algorithm in a standardised way - so we don't need our own methods of specifying these. (4) We now have PKCS#7 message support in the kernel for signed kexec purposes and we can make use of this. To make this work, the old sign-file script has been replaced with a program that needs compiling in a previous patch. The rules to build it are added here. Signed-off-by: David Howells Tested-by: Vivek Goyal --- Makefile|2 init/Kconfig|1 kernel/module_signing.c | 220 + scripts/Makefile|2 scripts/sign-file | 421 --- 5 files changed, 48 insertions(+), 598 deletions(-) delete mode 100755 scripts/sign-file diff --git a/Makefile b/Makefile index eae539d69bf3..ad27fc9fa02b 100644 --- a/Makefile +++ b/Makefile @@ -875,7 +875,7 @@ ifdef CONFIG_MODULE_SIG_ALL MODSECKEY = ./signing_key.priv MODPUBKEY = ./signing_key.x509 export MODPUBKEY -mod_sign_cmd = perl $(srctree)/scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY) +mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY) else mod_sign_cmd = true endif diff --git a/init/Kconfig b/init/Kconfig index dc24dec60232..fb98cba069c1 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1875,6 +1875,7 @@ config MODULE_SIG select ASN1 select OID_REGISTRY select X509_CERTIFICATE_PARSER + select PKCS7_MESSAGE_PARSER help Check modules for valid signatures upon load: the signature is simply appended to the module. For more information see diff --git a/kernel/module_signing.c b/kernel/module_signing.c index be5b8fac4bd0..8eb20cc66b39 100644 --- a/kernel/module_signing.c +++ b/kernel/module_signing.c @@ -11,10 +11,9 @@ #include #include -#include -#include -#include #include +#include +#include #include "module-internal.h" /* @@ -28,157 +27,53 @@ * - Information block */ struct module_signature { - u8 algo; /* Public-key crypto algorithm [enum pkey_algo] */ - u8 hash; /* Digest algorithm [enum hash_algo] */ - u8 id_type;/* Key identifier type [enum pkey_id_type] */ - u8 signer_len; /* Length of signer's name */ - u8 key_id_len; /* Length of key identifier */ + u8 algo; /* Public-key crypto algorithm [0] */ + u8 hash; /* Digest algorithm [0] */ + u8 id_type;/* Key identifier type [PKEY_ID_PKCS7] */ + u8 signer_len; /* Length of signer's name [0] */ + u8 key_id_len; /* Length of key identifier [0] */ u8 __pad[3]; __be32 sig_len;/* Length of signature data */ }; /* - * Digest the module contents. + * Verify a PKCS#7-based signature on a module. */ -static struct public_key_signature *mod_make_digest(enum hash_algo hash, - const void *mod, - unsigned long modlen) +static int mod_verify_pkcs7(const void *mod, unsigned long modlen, + const void *raw_pkcs7, size_t pkcs7_len) { - struct public_key_signature *pks; - struct crypto_shash *tfm; - struct shash_desc *desc; - size_t digest_size, desc_size; + struct pkcs7_message *pkcs7; + bool trusted; int ret; - pr_devel("==>%s()\n", __func__); - - /* Allocate the hashing algorithm we're going to need and find out how -* big the hash operational data will be. -*/ - tfm = crypto_alloc_shash(hash_algo_name[hash], 0, 0); - if (IS_ERR(tfm)) - return (PTR_ERR(tfm) == -ENOENT) ? ERR_PTR(-ENOPKG) : ERR_CAST(tfm); - - desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); - digest_size = crypto_shash_digestsize(tfm); - - /* We allocate the hash operational data storage on the end of our -* context data and the digest output buffer on the end of that. -*/ - ret = -ENOMEM; - pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL); - if (!pks) - goto error_no_pks; - - pks->pkey_hash_algo = hash; - pks->digest = (u8 *)pks + sizeof(*pks)
Re: [PATCH 00/20] MODSIGN: Use PKCS#7 for module signatures [ver #5]
On Thu, 2015-05-28 at 16:46 +0100, David Howells wrote: > > Additionally, the last four patches are provisionally added to support > firmware > signing, but will need further modification (ie. registration of OIDs) before > they can be committed, but are included for comment: I'd quite like to see a way for a given driver to specify the key with which its firmware needs to be signed. Perhaps an extra argument to the request_firmware() call giving the X509v3 Subject Key Identifier of the cert to be trusted? -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/20] modsign: Allow password to be specified for signing key [ver #5]
From: David Woodhouse We don't want this in the Kconfig since it might then get exposed in /proc/config.gz. So make it a parameter to Kbuild instead. This also means we don't have to jump through hoops to strip quotes from it, as we would if it was a config option. Signed-off-by: David Woodhouse Signed-off-by: David Howells Reviewed-by: Mimi Zohar --- Documentation/kbuild/kbuild.txt |5 + Documentation/module-signing.txt |3 +++ scripts/sign-file.c | 27 ++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index 6466704d47b5..0ff6a466a05b 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -174,6 +174,11 @@ The output directory is often set using "O=..." on the commandline. The value can be overridden in which case the default value is ignored. +KBUILD_SIGN_PIN +-- +This variable allows a passphrase or PIN to be passed to the sign-file +utility when signing kernel modules, if the private key requires such. + KBUILD_MODPOST_WARN -- KBUILD_MODPOST_WARN can be set to avoid errors in case of undefined diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt index c72702ec1ded..faaa6ea002f7 100644 --- a/Documentation/module-signing.txt +++ b/Documentation/module-signing.txt @@ -194,6 +194,9 @@ The hash algorithm used does not have to match the one configured, but if it doesn't, you should make sure that hash algorithm is either built into the kernel or can be loaded without requiring itself. +If the private key requires a passphrase or PIN, it can be provided in the +$KBUILD_SIGN_PIN environment variable. + SIGNED MODULES AND STRIPPING diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 39aaabe89388..720b9bc933ae 100755 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -80,6 +80,27 @@ static void drain_openssl_errors(void) } \ } while(0) +static const char *key_pass; + +static int pem_pw_cb(char *buf, int len, int w, void *v) +{ + int pwlen; + + if (!key_pass) + return -1; + + pwlen = strlen(key_pass); + if (pwlen >= len) + return -1; + + strcpy(buf, key_pass); + + /* If it's wrong, don't keep trying it. */ + key_pass = NULL; + + return pwlen; +} + int main(int argc, char **argv) { struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 }; @@ -96,9 +117,12 @@ int main(int argc, char **argv) BIO *b, *bd = NULL, *bm; int opt, n; + OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); ERR_clear_error(); + key_pass = getenv("KBUILD_SIGN_PIN"); + do { opt = getopt(argc, argv, "dp"); switch (opt) { @@ -132,7 +156,8 @@ int main(int argc, char **argv) */ b = BIO_new_file(private_key_name, "rb"); ERR(!b, "%s", private_key_name); -private_key = PEM_read_bio_PrivateKey(b, NULL, NULL, NULL); + private_key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, NULL); + ERR(!private_key, "%s", private_key_name); BIO_free(b); b = BIO_new_file(x509_name, "rb"); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/20] sign-file: Add option to only create signature file [ver #5]
From: Luis R. Rodriguez Make the -d option (which currently isn't actually wired to anything) write out the PKCS#7 message as per the -p option and then exit without either modifying the source or writing out a compound file of the source, signature and metadata. This will be useful when firmware signature support is added upstream as firmware will be left intact, and we'll only require the signature file. The descriptor is implicit by file extension and the file's own size. Signed-off-by: Luis R. Rodriguez Signed-off-by: David Howells --- scripts/sign-file.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 5b8a6dda3235..39aaabe89388 100755 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -86,13 +86,14 @@ int main(int argc, char **argv) char *hash_algo = NULL; char *private_key_name, *x509_name, *module_name, *dest_name; bool save_pkcs7 = false, replace_orig; + bool sign_only = false; unsigned char buf[4096]; unsigned long module_size, pkcs7_size; const EVP_MD *digest_algo; EVP_PKEY *private_key; PKCS7 *pkcs7; X509 *x509; - BIO *b, *bd, *bm; + BIO *b, *bd = NULL, *bm; int opt, n; ERR_load_crypto_strings(); @@ -102,6 +103,7 @@ int main(int argc, char **argv) opt = getopt(argc, argv, "dp"); switch (opt) { case 'p': save_pkcs7 = true; break; + case 'd': sign_only = true; save_pkcs7 = true; break; case -1: break; default: format(); } @@ -148,8 +150,10 @@ int main(int argc, char **argv) /* Open the destination file now so that we can shovel the module data * across as we read it. */ - bd = BIO_new_file(dest_name, "wb"); - ERR(!bd, "%s", dest_name); + if (!sign_only) { + bd = BIO_new_file(dest_name, "wb"); + ERR(!bd, "%s", dest_name); + } /* Digest the module data. */ OpenSSL_add_all_digests(); @@ -180,6 +184,9 @@ int main(int argc, char **argv) BIO_free(b); } + if (sign_only) + return 0; + /* Append the marker and the PKCS#7 message to the destination file */ ERR(BIO_reset(bm) < 0, "%s", module_name); while ((n = BIO_read(bm, buf, sizeof(buf))), -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/20] PKCS#7: Allow detached data to be supplied for signature checking purposes [ver #5]
It is possible for a PKCS#7 message to have detached data. However, to verify the signatures on a PKCS#7 message, we have to be able to digest the data. Provide a function to supply that data. An error is given if the PKCS#7 message included embedded data. This is used in a subsequent patch to supply the data to module signing where the signature is in the form of a PKCS#7 message with detached data, whereby the detached data is the module content that is signed. Signed-off-by: David Howells Tested-by: Vivek Goyal --- crypto/asymmetric_keys/pkcs7_verify.c | 25 + include/crypto/pkcs7.h|3 +++ 2 files changed, 28 insertions(+) diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index 42bfc9de0d79..404f89a0f852 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -382,3 +382,28 @@ int pkcs7_verify(struct pkcs7_message *pkcs7) return enopkg; } EXPORT_SYMBOL_GPL(pkcs7_verify); + +/** + * pkcs7_supply_detached_data - Supply the data needed to verify a PKCS#7 message + * @pkcs7: The PKCS#7 message + * @data: The data to be verified + * @datalen: The amount of data + * + * Supply the detached data needed to verify a PKCS#7 message. Note that no + * attempt to retain/pin the data is made. That is left to the caller. The + * data will not be modified by pkcs7_verify() and will not be freed when the + * PKCS#7 message is freed. + * + * Returns -EINVAL if data is already supplied in the message, 0 otherwise. + */ +int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7, + const void *data, size_t datalen) +{ + if (pkcs7->data) { + pr_debug("Data already supplied\n"); + return -EINVAL; + } + pkcs7->data = data; + pkcs7->data_len = datalen; + return 0; +} diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h index 691c79172a26..e235ab4957ee 100644 --- a/include/crypto/pkcs7.h +++ b/include/crypto/pkcs7.h @@ -34,3 +34,6 @@ extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, * pkcs7_verify.c */ extern int pkcs7_verify(struct pkcs7_message *pkcs7); + +extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7, + const void *data, size_t datalen); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/20] MODSIGN: Use PKCS#7 for module signatures [ver #5]
Here's a set of patches that does the following: (1) Extracts both parts of an X.509 AuthorityKeyIdentifier (AKID) extension. We already extract the bit that can match the subjectKeyIdentifier (SKID) of the parent X.509 cert, but we currently ignore the bits that can match the issuer and serialNumber. Looks up an X.509 cert by issuer and serialNumber if those are provided in the AKID. If the keyIdentifier is also provided, checks that the subjectKeyIdentifier of the cert found matches that also. If no issuer and serialNumber are provided in the AKID, looks up an X.509 cert by SKID using the AKID keyIdentifier. This allows module signing to be done with certificates that don't have an SKID by which they can be looked up. (2) Makes use of the PKCS#7 facility to provide module signatures. sign-file is replaced with a program that generates a PKCS#7 message that has no X.509 certs embedded and that has detached data (the module content) and adds it onto the message with magic string and descriptor. (3) The PKCS#7 message supplies all the information that is needed to select the X.509 cert to be used to verify the signature by standard means (including selection of digest algorithm and public key algorithm). No kernel-specific magic values are required. (4) Makes it possible to get sign-file to just write out a file containing the PKCS#7 signature blob. This can be used for debugging and potentially for firmware signing. (5) Extracts the function that does PKCS#7 signature verification on a blob from the module signing code and put it somewhere more general so that other things, such as firmware signing, can make use of it without depending on module config options. (6) Provides support for providing a password/pin for an encrypted private key to sign-file. (7) Makes it possible to use PKCS#11 with sign-file, thus allowing the use of cryptographic hardware. (8) Overhauls the way the module signing key is handled. If the name in CONFIG_MODULE_SIG_KEY is "signing_key.priv" then a key will be automatically generated and placed in the build directory. If the name is different, autogeneration is suppressed and the file is presumed to be a PEM file containing both the private key and X.509 certificate. (9) Overhauls the way auxiliary trusted keys are added to the kernel. Files matching the pattern "*.x509" are no longer just gathered up and cat'd together. Now CONFIG_SYSTEM_TRUSTED_KEYS must be set to point to a single PEM file containing a set of X.509 certs cat'd together if this facility is desired. Note that the revised sign-file program no longer supports the "-s " option to add an externally generated signature. This is deprecated in favour of using PKCS#11. Note also that the format of the signature file that would be passed to -s has changed. David Woodhouse also has stated an intention to overhaul the makefile magic he added to deal with quotes and quoting encountered when using CONFIG_* option strings in the makefile. The patches can be found here also: http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=modsign-pkcs7 and are tagged with: modsign-pkcs7-20150526 Additionally, the last four patches are provisionally added to support firmware signing, but will need further modification (ie. registration of OIDs) before they can be committed, but are included for comment: (10) Add a PKCS#7 authenticated attribute to hold the name of the firmware blob passed to request_key() so that this can be checked prior to permitting the load. (11) Add usage restriction markers to the extendedKeyUsage field of an X.509 certificate to indicate what may be checked with it. (12) Parse the keyUsage extension of an X.509 certificate to detect CA keys that are used for key signing. (13) Implement a key usage restrictions. For instance, a keys specifically restricted to module signature checking may not be used to verify firmware blobs and a key specifically restricted to kexec image signature checking may not be used for checking the signature on an X.509 certificate. I have allowed that keys that have no restrictions noted can be used for anything other than firmware, but possibly this should be restricted further. They can be found here also: http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=fwsign-pkcs7 David --- David Howells (11): X.509: Extract both parts of the AuthorityKeyIdentifier X.509: Support X.509 lookup by Issuer+Serial form AuthorityKeyIdentifier PKCS#7: Allow detached data to be supplied for signature checking purposes MODSIGN: Provide a utility to append a PKCS#7 signature to a module MODSIGN: Use PKCS#7 messages as module signatures system_keyring.c doesn't
[PATCH 02/20] X.509: Support X.509 lookup by Issuer+Serial form AuthorityKeyIdentifier [ver #5]
If an X.509 certificate has an AuthorityKeyIdentifier extension that provides an issuer and serialNumber, then make it so that these are used in preference to the keyIdentifier field also held therein for searching for the signing certificate. If both the issuer+serialNumber and the keyIdentifier are supplied, then the certificate is looked up by the former but the latter is checked as well. If the latter doesn't match the subjectKeyIdentifier of the parent certificate, EKEYREJECTED is returned. This makes it possible to chain X.509 certificates based on the issuer and serialNumber fields rather than on subjectKeyIdentifier. This is necessary as we are having to deal with keys that are represented by X.509 certificates that lack a subjectKeyIdentifier. Signed-off-by: David Howells Tested-by: Vivek Goyal --- crypto/asymmetric_keys/pkcs7_trust.c | 10 +++- crypto/asymmetric_keys/pkcs7_verify.c| 47 + crypto/asymmetric_keys/x509_public_key.c | 84 +- include/crypto/public_key.h |3 + 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 0f6463b6692b..90d6d47965b0 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -54,7 +54,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, /* Look to see if this certificate is present in the trusted * keys. */ - key = x509_request_asymmetric_key(trust_keyring, x509->id, + key = x509_request_asymmetric_key(trust_keyring, + x509->id, x509->skid, false); if (!IS_ERR(key)) { /* One of the X.509 certificates in the PKCS#7 message @@ -85,8 +86,10 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, /* No match - see if the root certificate has a signer amongst the * trusted keys. */ - if (last && last->akid_skid) { - key = x509_request_asymmetric_key(trust_keyring, last->akid_skid, + if (last && (last->akid_id || last->akid_skid)) { + key = x509_request_asymmetric_key(trust_keyring, + last->akid_id, + last->akid_skid, false); if (!IS_ERR(key)) { x509 = last; @@ -103,6 +106,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, */ key = x509_request_asymmetric_key(trust_keyring, sinfo->signing_cert_id, + NULL, false); if (!IS_ERR(key)) { pr_devel("sinfo %u: Direct signer is key %x\n", diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index a4d083f7e9e1..42bfc9de0d79 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -170,6 +170,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, struct pkcs7_signed_info *sinfo) { struct x509_certificate *x509 = sinfo->signer, *p; + struct asymmetric_key_id *auth; int ret; kenter(""); @@ -187,11 +188,14 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, goto maybe_missing_crypto_in_x509; pr_debug("- issuer %s\n", x509->issuer); + if (x509->akid_id) + pr_debug("- authkeyid.id %*phN\n", +x509->akid_id->len, x509->akid_id->data); if (x509->akid_skid) - pr_debug("- authkeyid %*phN\n", + pr_debug("- authkeyid.skid %*phN\n", x509->akid_skid->len, x509->akid_skid->data); - if (!x509->akid_skid || + if ((!x509->akid_id && !x509->akid_skid) || strcmp(x509->subject, x509->issuer) == 0) { /* If there's no authority certificate specified, then * the certificate must be self-signed and is the root @@ -215,21 +219,42 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, /* Look through the X.509 certificates in the PKCS#7 message's * list to see if the next one is there. */ - pr_debug("- want %*phN\n", -x509->akid_skid->len, x509->akid_skid->data); - for (p = pkcs7->certs; p; p = p->next) { - if (!p->skid) - continue; -
[PATCH 13/20] modsign: Extract signing cert from CONFIG_MODULE_SIG_KEY if needed [ver #5]
From: David Woodhouse Where an external PEM file or PKCS#11 URI is given, we can get the cert from it for ourselves instead of making the user drop signing_key.x509 in place for us. Signed-off-by: David Woodhouse Signed-off-by: David Howells --- Documentation/module-signing.txt | 11 +-- init/Kconfig |8 +- kernel/Makefile | 38 +++ scripts/Makefile |3 + scripts/extract-cert.c | 132 ++ 5 files changed, 181 insertions(+), 11 deletions(-) create mode 100644 scripts/extract-cert.c diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt index 84597c7ea175..693001920890 100644 --- a/Documentation/module-signing.txt +++ b/Documentation/module-signing.txt @@ -93,17 +93,16 @@ This has a number of options available: Setting this option to something other than its default of "signing_key.priv" will disable the autogeneration of signing keys and allow the kernel modules to be signed with a key of your choosing. - The string provided should identify a file containing a private key - in PEM form, or — on systems where the OpenSSL ENGINE_pkcs11 is - appropriately installed — a PKCS#11 URI as defined by RFC7512. + The string provided should identify a file containing both a private + key and its corresponding X.509 certificate in PEM form, or — on + systems where the OpenSSL ENGINE_pkcs11 is functional — a PKCS#11 URI + as defined by RFC7512. In the latter case, the PKCS#11 URI should + reference both a certificate and a private key. If the PEM file containing the private key is encrypted, or if the PKCS#11 token requries a PIN, this can be provided at build time by means of the KBUILD_SIGN_PIN variable. - The corresponding X.509 certificate in DER form should still be placed - in a file named signing_key.x509 in the top-level build directory. - === GENERATING SIGNING KEYS diff --git a/init/Kconfig b/init/Kconfig index 385181546f6a..a4b4f390d8f2 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1959,10 +1959,10 @@ config MODULE_SIG_KEY default "signing_key.priv" depends on MODULE_SIG help - Provide the file name of a private key in PKCS#8 PEM format, or - a PKCS#11 URI according to RFC7512. The corresponding X.509 - certificate in DER form should be present in signing_key.x509 - in the top-level build directory. + Provide the file name of a private key/certificate in PEM format, + or a PKCS#11 URI according to RFC7512. The file should contain, or + the URI should identify, both the certificate and its corresponding + private key. If this option is unchanged from its default "signing_key.priv", then the kernel will automatically generate the private key and diff --git a/kernel/Makefile b/kernel/Makefile index 050a55eca566..9fb259d0383c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -210,5 +210,43 @@ x509.genkey: @echo >>x509.genkey "keyUsage=digitalSignature" @echo >>x509.genkey "subjectKeyIdentifier=hash" @echo >>x509.genkey "authorityKeyIdentifier=keyid" +else +# For external (PKCS#11 or PEM) key, we need to obtain the certificate from +# CONFIG_MODULE_SIG_KEY automatically. +quiet_cmd_extract_der = CERT_DER $(2) + cmd_extract_der = scripts/extract-cert "$(2)" signing_key.x509 + +# CONFIG_MODULE_SIG_KEY is either a PKCS#11 URI or a filename. It is +# surrounded by quotes, and may contain spaces. To strip the quotes +# with $(patsubst) we need to turn the spaces into something else. +# And if it's a filename, those spaces need to be escaped as '\ ' in +# order to use it in dependencies or $(wildcard). +space := +space += +space_escape := %%%SPACE%%% +X509_SOURCE_temp := $(subst $(space),$(space_escape),$(CONFIG_MODULE_SIG_KEY)) +# We need this to check for absolute paths or PKCS#11 URIs. +X509_SOURCE_ONEWORD := $(patsubst "%",%,$(X509_SOURCE_temp)) +# This is the actual source filename/URI without the quotes +X509_SOURCE := $(subst $(space_escape),$(space),$(X509_SOURCE_ONEWORD)) +# This\ version\ with\ spaces\ escaped\ for\ $(wildcard)\ and\ dependencies +X509_SOURCE_ESCAPED := $(subst $(space_escape),\$(space),$(X509_SOURCE_ONEWORD)) + +ifeq ($(patsubst pkcs11:%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD)) +# If it's a filename, depend on it. +X509_DEP := $(X509_SOURCE_ESCAPED) +ifeq ($(patsubst /%,%,$(X509_SOURCE_ONEWORD)),$(X509_SOURCE_ONEWORD)) +ifeq ($(wildcard $(X509_SOURCE_ESCAPED)),) +ifneq ($(wildcard $(srctree)/$(X509_SOURCE_ESCAPED)),) +# Non-absolute filename, found in source tree and not build tree +X509_SOURCE := $(srctree)/$(X509_SOURCE) +X509_DEP := $(srctree)/$(X509_SOURCE_ESCAPED) +endif +endif +endif +endif + +signing_key.x509: scripts/extract-cert include/config/module/sig/key.h $(X509_DEP) +
[PATCH 18/20] X.509: Parse the keyUsage extension to detect key-signing keys [ver #5]
Parse the keyUsage extension to detect keys for which the purpose is key signing and to restrict their use only to the verification of signatures on keys. Not-yet-signed-off-by: David Howells --- crypto/asymmetric_keys/x509_cert_parser.c | 45 - 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 4d9e9a7f8fd2..82b869de1759 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -457,9 +457,51 @@ int x509_process_extension(void *context, size_t hdrlen, struct x509_parse_context *ctx = context; struct asymmetric_key_id *kid; const unsigned char *v = value; + u32 shift, tmp; pr_debug("Extension: %u\n", ctx->last_oid); + if (ctx->last_oid == OID_keyUsage) { + /* There's a bitstring inside the content that we want to get +* at. This bitstring is shuffled up so that the most +* significant set bit is the MSB of the second byte. The +* first byte tells us how far we have to shift the string back +* to put bit string bit 0 on a byte bit 0. +*/ + if (vlen < 3) + return -EBADMSG; + if (v[0] != ASN1_BTS || v[1] != vlen - 2) + return -EBADMSG; + shift = v[2]; + if (shift > 7) + return -EBADMSG; + v += 3; + vlen -= 3; + if (vlen > 2) { + /* We only care about the least significant 9 bits, but +* they will be spread over up to two bytes (leading 0s +* aren't stored). +*/ + v += vlen - 2; + vlen = 2; + } + + tmp = 0; + if (vlen == 2) { + tmp = (u32)*v << 8; + v++; + } + if (vlen >= 1) + tmp |= *v; + tmp >>= shift; + pr_debug("keyUsage %x\n", tmp); + /* check for keyCertSign */ + if (tmp & (1 << 5)) + ctx->cert->pub->usage_restriction = + PKEY_RESTRICTED_TO_KEY_SIGNING; + return 0; + } + if (ctx->last_oid == OID_subjectKeyIdentifier) { /* Get hold of the key fingerprint */ if (ctx->cert->skid || vlen < 3) @@ -492,7 +534,8 @@ int x509_process_extension(void *context, size_t hdrlen, /* Get hold of the extended key usage information */ ctx->raw_extusage = v; ctx->raw_extusage_size = vlen; - ctx->cert->pub->usage_restriction = PKEY_RESTRICTED_USAGE; + if (ctx->cert->pub->usage_restriction == PKEY_USAGE_NOT_SPECIFIED) + ctx->cert->pub->usage_restriction = PKEY_RESTRICTED_USAGE; return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 19/20] KEYS: Restrict signature verification to keys appropriate to the purpose [ver #5]
Restrict the verification of X.509 certificates such that a certificate can only be verified if either: (1) A certificate is signed with the key it holds. (2) A certificate is signed with a key that has keyCertSign set in its keyUsage extension and has no purpose restriction set. Restrict the verification of PKCS#7 messages such that a signature can only be verified by a matching key if the key does not have keyCertSign set and either of the following is true: (1) The key has no purpose restriction and the PKCS#7 is not a firmware signature. (2) The key has a recognised purpose restriction that matches the use to which the PKCS#7 signature is being put. In the event that a restriction mismatch occurs, EKEYREJECTED will be returned and an error similar to one of the following will be logged to dmesg: PKEY: Firmware signed with non-firmware key (module sig) PKEY: Restricted usage key (module sig) used for wrong purpose (kexec sig) The PKCS#7 test key type is given the usage to specify in a module parameter. For example: echo 1 >/sys/module/pkcs7_test_key/parameters/usage keyctl padd pkcs7_test foo @s --- crypto/asymmetric_keys/asymmetric_type.c |9 + crypto/asymmetric_keys/pkcs7_key_type.c | 19 +- crypto/asymmetric_keys/pkcs7_trust.c | 14 +--- crypto/asymmetric_keys/pkcs7_verify.c| 21 --- crypto/asymmetric_keys/public_key.c | 55 -- crypto/asymmetric_keys/public_key.h |3 +- crypto/asymmetric_keys/signature.c |6 ++- crypto/asymmetric_keys/x509_parser.h |3 +- crypto/asymmetric_keys/x509_public_key.c | 15 +--- include/crypto/pkcs7.h |4 ++ include/crypto/public_key.h |3 +- include/keys/asymmetric-subtype.h|3 +- include/keys/asymmetric-type.h | 13 +++ include/keys/system_keyring.h|2 + kernel/module_signing.c |3 +- kernel/system_keyring.c |7 +++- 16 files changed, 148 insertions(+), 32 deletions(-) diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index 9047175fe818..6367d3734533 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -20,6 +20,15 @@ MODULE_LICENSE("GPL"); +const char *const asymmetric_key_verification_names[NR__ASYMMETRIC_KEY_VERIFICATION] = { + [KEY_VERIFYING_MODULE_SIGNATURE]= "mod sig", + [KEY_VERIFYING_FIRMWARE_SIGNATURE] = "firmware sig", + [KEY_VERIFYING_KEXEC_SIGNATURE] = "kexec sig", + [KEY_VERIFYING_KEY_SIGNATURE] = "key sig", + [KEY_VERIFYING_KEY_SELF_SIGNATURE] = "key self sig", +}; +EXPORT_SYMBOL_GPL(asymmetric_key_verification_names); + static LIST_HEAD(asymmetric_key_parsers); static DECLARE_RWSEM(asymmetric_key_parsers_sem); diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c index 751f8fd7335d..ce5eb0346d83 100644 --- a/crypto/asymmetric_keys/pkcs7_key_type.c +++ b/crypto/asymmetric_keys/pkcs7_key_type.c @@ -12,17 +12,24 @@ #define pr_fmt(fmt) "PKCS7key: "fmt #include #include -#include +#include +#include #include #include #include #include "pkcs7_parser.h" +unsigned pkcs7_usage; +module_param_named(usage, pkcs7_usage, uint, S_IWUSR | S_IRUGO); +MODULE_PARM_DESC(pkcs7_usage, +"Usage to specify when verifying the PKCS#7 message"); + /* * Preparse a PKCS#7 wrapped and validated data blob. */ static int pkcs7_preparse(struct key_preparsed_payload *prep) { + enum asymmetric_key_verification usage = pkcs7_usage; struct pkcs7_message *pkcs7; const void *data, *saved_prep_data; size_t datalen, saved_prep_datalen; @@ -31,6 +38,11 @@ static int pkcs7_preparse(struct key_preparsed_payload *prep) kenter(""); + if (usage >= NR__ASYMMETRIC_KEY_VERIFICATION) { + pr_err("Invalid usage type %d\n", usage); + return -EINVAL; + } + saved_prep_data = prep->data; saved_prep_datalen = prep->datalen; pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen); @@ -39,11 +51,12 @@ static int pkcs7_preparse(struct key_preparsed_payload *prep) goto error; } - ret = pkcs7_verify(pkcs7); + ret = pkcs7_verify(pkcs7, usage); if (ret < 0) goto error_free; - ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted); + ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, usage, + &trusted); if (ret < 0) goto error_free; if (!trusted) diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 90d6d47965b0..bbe3dc9755e4 100644 --- a/crypto/asymmetric_keys
[PATCH 14/20] modsign: Use single PEM file for autogenerated key [ver #5]
From: David Woodhouse The current rule for generating signing_key.priv and signing_key.x509 is a classic example of a bad rule which has a tendency to break parallel make. When invoked to create *either* target, it generates the other target as a side-effect that make didn't predict. So let's switch to using a single file signing_key.pem which contains both key and certificate. That matches what we do in the case of an external key specified by CONFIG_MODULE_SIG_KEY anyway, so it's also slightly cleaner. Signed-off-by: David Woodhouse Signed-off-by: David Howells --- .gitignore |1 + Documentation/module-signing.txt |9 - Makefile |4 ++-- init/Kconfig |4 ++-- kernel/Makefile | 15 +++ 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 4ad4a98b884b..17fa24dd7e46 100644 --- a/.gitignore +++ b/.gitignore @@ -97,6 +97,7 @@ GTAGS # Leavings from module signing # extra_certificates +signing_key.pem signing_key.priv signing_key.x509 x509.genkey diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt index 693001920890..5d5e4e32dc26 100644 --- a/Documentation/module-signing.txt +++ b/Documentation/module-signing.txt @@ -91,7 +91,7 @@ This has a number of options available: (4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY) Setting this option to something other than its default of - "signing_key.priv" will disable the autogeneration of signing keys and + "signing_key.pem" will disable the autogeneration of signing keys and allow the kernel modules to be signed with a key of your choosing. The string provided should identify a file containing both a private key and its corresponding X.509 certificate in PEM form, or — on @@ -116,11 +116,10 @@ kernel so that it can be used to check the signatures as the modules are loaded. Under normal conditions, when CONFIG_MODULE_SIG_KEY is unchanged from its -default of "signing_key.priv", the kernel build will automatically generate -a new keypair using openssl if one does not exist in the files: +default, the kernel build will automatically generate a new keypair using +openssl if one does not exist in the file: - signing_key.priv - signing_key.x509 + signing_key.pem during the building of vmlinux (the public part of the key needs to be built into vmlinux) using parameters in the: diff --git a/Makefile b/Makefile index 9590e67c2094..ce2f4682a37a 100644 --- a/Makefile +++ b/Makefile @@ -1175,8 +1175,8 @@ MRPROPER_DIRS += include/config usr/include include/generated \ arch/*/include/generated .tmp_objdiff MRPROPER_FILES += .config .config.old .version .old_version \ Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \ - signing_key.priv signing_key.x509 x509.genkey \ - extra_certificates signing_key.x509.keyid \ + signing_key.pem signing_key.priv signing_key.x509 \ + x509.genkey extra_certificates signing_key.x509.keyid \ signing_key.x509.signer vmlinux-gdb.py # clean - Delete most, but leave enough to build external modules diff --git a/init/Kconfig b/init/Kconfig index a4b4f390d8f2..a52935338419 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1956,7 +1956,7 @@ config MODULE_SIG_HASH config MODULE_SIG_KEY string "File name or PKCS#11 URI of module signing key" - default "signing_key.priv" + default "signing_key.pem" depends on MODULE_SIG help Provide the file name of a private key/certificate in PEM format, @@ -1964,7 +1964,7 @@ config MODULE_SIG_KEY the URI should identify, both the certificate and its corresponding private key. - If this option is unchanged from its default "signing_key.priv", + If this option is unchanged from its default "signing_key.pem", then the kernel will automatically generate the private key and certificate as described in Documentation/module-signing.txt diff --git a/kernel/Makefile b/kernel/Makefile index 9fb259d0383c..541e1e89e90c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -173,8 +173,8 @@ endif # We do it this way rather than having a boolean option for enabling an # external private key, because 'make randconfig' might enable such a # boolean option and we unfortunately can't make it depend on !RANDCONFIG. -ifeq ($(CONFIG_MODULE_SIG_KEY),"signing_key.priv") -signing_key.priv signing_key.x509: x509.genkey +ifeq ($(CONFIG_MODULE_SIG_KEY),"signing_key.pem") +signing_key.pem: x509.genkey @echo "###" @echo "### Now generating an X.509 key pair to be used for signing modules." @echo "###" @@ -185,8 +185,8 @@ signing_key.priv signing_key.x509: x509.genke
[PATCH 17/20] X.509: Restrict the usage of a key based on information in X.509 certificate [ver #5]
Use X.509 extendedKeyUsage extension [RFC5280 4.2.1.12] to hold restriction information as to the purpose of the key. The following changes are made: (1) The kernel's X.509 parser is modified to extract this information and stash it in the public_key struct. (2) The kernel indicates in /proc/keys the restriction if one is found. (3) Autogenerated module signing key certificates are marked with a module signing only restriction. The extendedKeyUsage extension takes a sequence of OIDs to indicate the set of restricted cases. To this end, I have temporarily used three unassigned OIDs from RH OID space. These will need to be replaced with real assigned OIDs: 1.3.6.1.4.1.2312.99.2 Key is restricted to firmware signing 1.3.6.1.4.1.2312.99.3 Key is restricted to module signing 1.3.6.1.4.1.2312.99.4 Key is restricted to kexecable image signing I would propose a fourth, key signing, but that should perhaps be handled through the keyUsage extension [RFC5280 4.2.1.3] setting keyCertSign. I am treating these as mutually exclusive. A key with a restriction is rejected if it also gives a second restriction. To mark a key as being for firmware signing only, for example, the "openssl req" command can be given an extension specifier to mark the X.509 certificate. Assuming a config script is used, this would be done by including the following in the extension list: extendedKeyUsage=critical,1.3.6.1.4.1.2312.99.2 This adds it to the extendedKeyUsage extension. Another, perhaps more convenient way to do it would be to add our own extension type, eg: 1.3.6.1.4.1.2312.99.2=critical,ASN1:NULL This would easier to deal with since we examine all the extensions anyway, and we could parameterise it, but the first option is probably the correct way. Also, do we need to break the firmware restriction space down by class or manufacturer? Or will one restriction do? Not-yet-signed-off-by: David Howells --- crypto/asymmetric_keys/Makefile |4 ++ crypto/asymmetric_keys/asymmetric_type.c |3 + crypto/asymmetric_keys/public_key.c | 23 + crypto/asymmetric_keys/x509_cert_parser.c | 72 + crypto/asymmetric_keys/x509_extusage.asn1 |3 + include/crypto/public_key.h | 12 + include/keys/asymmetric-subtype.h |3 + include/linux/oid_registry.h |3 + kernel/Makefile |1 lib/oid_registry.c|1 10 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 crypto/asymmetric_keys/x509_extusage.asn1 diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index cd1406f9b14a..ac18b7f64a77 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o x509_key_parser-y := \ x509-asn1.o \ x509_akid-asn1.o \ + x509_extusage-asn1.o \ x509_rsakey-asn1.o \ x509_cert_parser.o \ x509_public_key.o @@ -23,13 +24,16 @@ x509_key_parser-y := \ $(obj)/x509_cert_parser.o: \ $(obj)/x509-asn1.h \ $(obj)/x509_akid-asn1.h \ + $(obj)/x509_extusage-asn1.h \ $(obj)/x509_rsakey-asn1.h $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h $(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h +$(obj)/x509_extusage-asn1.o: $(obj)/x509_extusage-asn1.c $(obj)/x509_extusage-asn1.h $(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h clean-files+= x509-asn1.c x509-asn1.h clean-files+= x509_akid-asn1.c x509_akid-asn1.h +clean-files+= x509_extusage-asn1.c x509_extusage-asn1.h clean-files+= x509_rsakey-asn1.c x509_rsakey-asn1.h # diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index bcbbbd794e1d..9047175fe818 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -246,7 +246,8 @@ static void asymmetric_key_describe(const struct key *key, struct seq_file *m) } seq_puts(m, " ["); - /* put something here to indicate the key's capabilities */ + if (subtype->describe_caps) + subtype->describe_caps(key, m); seq_putc(m, ']'); } } diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 2f6e4fb1a1ea..7790f58d00bf 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -42,6 +42,16 @@ const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = { }; EXPORT_SYMBOL_GPL(pkey_id_type_name); +static const char *const public_key_restrictions[NR__PKEY_USAGE_RESTRICTION] = { + [PKEY_USAGE_NOT_SPECIFIED] = "unrestricted", + [PKEY_RESTRICTED_USAGE] =
[PATCH 15/20] modsign: Add explicit CONFIG_SYSTEM_TRUSTED_KEYS option [ver #5]
From: David Woodhouse Let the user explicitly provide a file containing trusted keys, instead of just automatically finding files matching *.x509 in the build tree and trusting whatever we find. This really ought to be an *explicit* configuration, and the build rules for dealing with the files were fairly painful too. Signed-off-by: David Woodhouse Signed-off-by: David Howells --- Documentation/module-signing.txt | 15 +++-- init/Kconfig | 13 kernel/Makefile | 125 -- 3 files changed, 89 insertions(+), 64 deletions(-) diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt index 5d5e4e32dc26..4e62bc29666e 100644 --- a/Documentation/module-signing.txt +++ b/Documentation/module-signing.txt @@ -88,6 +88,7 @@ This has a number of options available: than being a module) so that modules signed with that algorithm can have their signatures checked without causing a dependency loop. + (4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY) Setting this option to something other than its default of @@ -104,6 +105,13 @@ This has a number of options available: means of the KBUILD_SIGN_PIN variable. + (5) "Additional X.509 keys for default system keyring" (CONFIG_SYSTEM_TRUSTED_KEYS) + + This option can be set to the filename of a PEM-encoded file containing + additional certificates which will be included in the system keyring by + default. + + === GENERATING SIGNING KEYS === @@ -171,10 +179,9 @@ in a keyring called ".system_keyring" that can be seen by: 302d2d52 I-- 1 perm 1f01 0 0 asymmetri Fedora kernel signing key: d69a84e6bce3d216b979e9505b3e3ef9a7118079: X509.RSA a7118079 [] ... -Beyond the public key generated specifically for module signing, any file -placed in the kernel source root directory or the kernel build root directory -whose name is suffixed with ".x509" will be assumed to be an X.509 public key -and will be added to the keyring. +Beyond the public key generated specifically for module signing, additional +trusted certificates can be provided in a PEM-encoded file referenced by the +CONFIG_SYSTEM_TRUSTED_KEYS configuration option. Further, the architecture code may take public keys from a hardware store and add those in also (e.g. from the UEFI key database). diff --git a/init/Kconfig b/init/Kconfig index a52935338419..b46c19525074 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1758,6 +1758,19 @@ config SYSTEM_TRUSTED_KEYRING Keys in this keyring are used by module signature checking. +config SYSTEM_TRUSTED_KEYS + string "Additional X.509 keys for default system keyring" + depends on SYSTEM_TRUSTED_KEYRING + help + If set, this option should be the filename of a PEM-formatted file + containing trusted X.509 certificates to be included in the default + system keyring. Any certificate used for module signing is implicitly + also trusted. + + NOTE: If you previously provided keys for the system keyring in the + form of DER-encoded *.x509 files in the top-level build directory, + those are no longer used. You will need to set this option instead. + config SYSTEM_DATA_VERIFICATION def_bool n select SYSTEM_TRUSTED_KEYRING diff --git a/kernel/Makefile b/kernel/Makefile index 541e1e89e90c..2d03e870ba8d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -114,46 +114,75 @@ $(obj)/config_data.h: $(obj)/config_data.gz FORCE ### # -# Roll all the X.509 certificates that we can find together and pull them into -# the kernel so that they get loaded into the system trusted keyring during -# boot. +# When a Kconfig string contains a filename, it is suitable for +# passing to shell commands. It is surrounded by double-quotes, and +# any double-quotes or backslashes within it are escaped by +# backslashes. # -# We look in the source root and the build root for all files whose name ends -# in ".x509". Unfortunately, this will generate duplicate filenames, so we -# have make canonicalise the pathnames and then sort them to discard the -# duplicates. +# This is no use for dependencies or $(wildcard). We need to strip the +# surrounding quotes and the escaping from quotes and backslashes, and +# we *do* need to escape any spaces in the string. So, for example: +# +# Usage: $(eval $(call config_filename,FOO)) +# +# Defines FOO_FILENAME based on the contents of the CONFIG_FOO option, +# transformed as described above to be suitable for use within the +# makefile. +# +# Also, if the filename is a relative filename and exists in the source +# tree but not the build tree, define FOO_SRCPREFIX as $(srctree)/ to +# be prefixed to *both* command invocation and dependencies.
[PATCH 16/20] PKCS#7: Add an optional authenticated attribute to hold firmware name [ver #5]
Modify the sign-file program to take a "-F " parameter. The name is a utf8 string that, if given, is inserted in a PKCS#7 authenticated attribute from where it can be extracted by the kernel. Authenticated attributes are added to the signature digest. If the attribute is present, the signature would be assumed to be for firmware and would not be permitted with module signing or kexec. The name associated with the attribute would be compared to the name passed to request_firmware() and the load request would be denied if they didn't match. If not present, the signature would be rejected if used for firmware. One oddity is that the attribute is per-signature, so if a second signature was added (which PKCS#7 supports), it would have to have the attribute added separately to that signature also. Note that the OID I have selected is an unregistered element of the Red Hat OID space to serve as an example. An OID would need to be allocated for this purpose. The kernel then parses this out, saves the string and makes sure the same string (or lack thereof) is present from all signers. Then when system_verify_data() is called, it is passed a NULL if the attribute is expected not to be present and the name from request_firmware() if it is expected to be present. Verification is rejected if there's a mismatch. MARKING KEYS FOR PURPOSE To mark a key as being for firmware signing only, for example, the openssl req command can be given an extension specifier to mark the X.509 certificate. Assuming a config script is used, this could be done in one of a couple of ways: (1) Add an OID indicating this to the list in the x509v3 extendedKeyUsage extension, eg: extendedKeyUsage=critical,1.3.6.1.4.1.2312.99.2 (2) Add our own extension type with our own OID, eg: 1.3.6.1.4.1.2312.99.2=critical,ASN1:NULL Option (2) is easier to deal with since we examine all the extensions anyway, but option (1) is probably the correct way. Note I'm using an unregistered Red Hat space OID here as an example. We would need to decide how we want to break down the usage space and register appropriate OIDs. If we went with option (2), we could parameterise the thing and use that to select either driver class or driver. It's possible that just declaring that a key is used for firmware signing or anything but and then including the firmware name in the signature is sufficient for our purposes, rather than breaking it down per driver class or per driver. Not-yet-signed-off-by: David Howells --- crypto/asymmetric_keys/pkcs7_parser.c | 77 + crypto/asymmetric_keys/pkcs7_parser.h |1 include/crypto/pkcs7.h|1 include/keys/system_keyring.h |3 + include/linux/oid_registry.h |3 + kernel/module_signing.c |2 - kernel/system_keyring.c | 26 +++ scripts/sign-file.c | 36 ++- 8 files changed, 142 insertions(+), 7 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 3bd5a1e4c493..381e3d8bcc8d 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "public_key.h" #include "pkcs7_parser.h" #include "pkcs7-asn1.h" @@ -29,6 +30,13 @@ struct pkcs7_parse_context { enum OIDlast_oid; /* Last OID encountered */ unsignedx509_index; unsignedsinfo_index; + unsignedfirmware_name_len; + enum { + maybe_firmware_sig, + is_firmware_sig, + isnt_firmware_sig + } firmware_sig_state : 8; + boolsigner_has_firmware_name; const void *raw_serial; unsignedraw_serial_size; unsignedraw_issuer_size; @@ -73,6 +81,7 @@ void pkcs7_free_message(struct pkcs7_message *pkcs7) pkcs7->signed_infos = sinfo->next; pkcs7_free_signed_info(sinfo); } + kfree(pkcs7->firmware_name); kfree(pkcs7); } } @@ -310,6 +319,8 @@ int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen, const void *value, size_t vlen) { struct pkcs7_parse_context *ctx = context; + char *p; + int i; pr_devel("AuthAttr: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value); @@ -320,6 +331,45 @@ int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen, ctx->sinfo->msgdigest = value; ctx->sinfo->msgdigest_len = vlen; return 0; + + case OID_firmwareName: + if (tag != ASN1_UTF8STR || vlen == 0) + return -EBADMSG; + + /* If there's m
[PATCH 20/20] sign-file: use .p7s instead of .pkcs7 file extension [ver #5]
From: Luis R. Rodriguez The file extension .p7s is much more common, use that. Cc: Kyle McMartin Cc: David Woodhouse Signed-off-by: Luis R. Rodriguez Signed-off-by: David Howells --- scripts/sign-file.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 94109c9e8ce6..cf9eb7f79868 100755 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -249,7 +249,7 @@ int main(int argc, char **argv) if (save_pkcs7) { char *pkcs7_name; - ERR(asprintf(&pkcs7_name, "%s.pkcs7", module_name) < 0, "asprintf"); + ERR(asprintf(&pkcs7_name, "%s.p7s", module_name) < 0, "asprintf"); b = BIO_new_file(pkcs7_name, "wb"); ERR(!b, "%s", pkcs7_name); ERR(i2d_PKCS7_bio_stream(b, pkcs7, NULL, 0) < 0, "%s", pkcs7_name); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/20] modsign: Allow external signing key to be specified [ver #5]
From: David Woodhouse Signed-off-by: David Woodhouse Signed-off-by: David Howells --- Documentation/module-signing.txt | 31 ++- Makefile |2 +- init/Kconfig | 14 ++ kernel/Makefile |5 + 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Documentation/module-signing.txt b/Documentation/module-signing.txt index faaa6ea002f7..84597c7ea175 100644 --- a/Documentation/module-signing.txt +++ b/Documentation/module-signing.txt @@ -88,6 +88,22 @@ This has a number of options available: than being a module) so that modules signed with that algorithm can have their signatures checked without causing a dependency loop. + (4) "File name or PKCS#11 URI of module signing key" (CONFIG_MODULE_SIG_KEY) + + Setting this option to something other than its default of + "signing_key.priv" will disable the autogeneration of signing keys and + allow the kernel modules to be signed with a key of your choosing. + The string provided should identify a file containing a private key + in PEM form, or — on systems where the OpenSSL ENGINE_pkcs11 is + appropriately installed — a PKCS#11 URI as defined by RFC7512. + + If the PEM file containing the private key is encrypted, or if the + PKCS#11 token requries a PIN, this can be provided at build time by + means of the KBUILD_SIGN_PIN variable. + + The corresponding X.509 certificate in DER form should still be placed + in a file named signing_key.x509 in the top-level build directory. + === GENERATING SIGNING KEYS @@ -100,8 +116,9 @@ it can be deleted or stored securely. The public key gets built into the kernel so that it can be used to check the signatures as the modules are loaded. -Under normal conditions, the kernel build will automatically generate a new -keypair using openssl if one does not exist in the files: +Under normal conditions, when CONFIG_MODULE_SIG_KEY is unchanged from its +default of "signing_key.priv", the kernel build will automatically generate +a new keypair using openssl if one does not exist in the files: signing_key.priv signing_key.x509 @@ -135,8 +152,12 @@ kernel sources tree and the openssl command. The following is an example to generate the public/private key files: openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \ - -config x509.genkey -outform DER -out signing_key.x509 \ - -keyout signing_key.priv + -config x509.genkey -outform PEM -out kernel_key.pem \ + -keyout kernel_key.pem + +The full pathname for the resulting kernel_key.pem file can then be specified +in the CONFIG_MODULE_SIG_KEY option, and the certificate and key therein will +be used instead of an autogenerated keypair. = @@ -181,7 +202,7 @@ To manually sign a module, use the scripts/sign-file tool available in the Linux kernel source tree. The script requires 4 arguments: 1. The hash algorithm (e.g., sha256) - 2. The private key filename + 2. The private key filename or PKCS#11 URI 3. The public key filename 4. The kernel module to be signed diff --git a/Makefile b/Makefile index ad27fc9fa02b..9590e67c2094 100644 --- a/Makefile +++ b/Makefile @@ -872,7 +872,7 @@ INITRD_COMPRESS-$(CONFIG_RD_LZ4) := lz4 # export INITRD_COMPRESS := $(INITRD_COMPRESS-y) ifdef CONFIG_MODULE_SIG_ALL -MODSECKEY = ./signing_key.priv +MODSECKEY = $(CONFIG_MODULE_SIG_KEY) MODPUBKEY = ./signing_key.x509 export MODPUBKEY mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY) diff --git a/init/Kconfig b/init/Kconfig index c05afd6594f2..385181546f6a 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1954,6 +1954,20 @@ config MODULE_SIG_HASH default "sha384" if MODULE_SIG_SHA384 default "sha512" if MODULE_SIG_SHA512 +config MODULE_SIG_KEY + string "File name or PKCS#11 URI of module signing key" + default "signing_key.priv" + depends on MODULE_SIG + help + Provide the file name of a private key in PKCS#8 PEM format, or + a PKCS#11 URI according to RFC7512. The corresponding X.509 + certificate in DER form should be present in signing_key.x509 + in the top-level build directory. + + If this option is unchanged from its default "signing_key.priv", + then the kernel will automatically generate the private key and + certificate as described in Documentation/module-signing.txt + config MODULE_COMPRESS bool "Compress modules on installation" depends on MODULES diff --git a/kernel/Makefile b/kernel/Makefile index 60c302cfb4d3..050a55eca566 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -170,6 +170,10 @@ ifndef CONFIG_MODULE_SIG_HASH $(error Could not determine digest type to use from kernel confi
[PATCH 09/20] modsign: Abort modules_install when signing fails [ver #5]
From: David Woodhouse Signed-off-by: David Woodhouse Signed-off-by: David Howells --- scripts/Makefile.modinst |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst index e48a4e9d8868..07650eeaaf06 100644 --- a/scripts/Makefile.modinst +++ b/scripts/Makefile.modinst @@ -22,7 +22,7 @@ quiet_cmd_modules_install = INSTALL $@ mkdir -p $(2) ; \ cp $@ $(2) ; \ $(mod_strip_cmd) $(2)/$(notdir $@) ; \ -$(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) ; \ +$(mod_sign_cmd) $(2)/$(notdir $@) $(patsubst %,|| true,$(KBUILD_EXTMOD)) && \ $(mod_compress_cmd) $(2)/$(notdir $@) # Modules built outside the kernel source tree go into extra by default -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/20] MODSIGN: Provide a utility to append a PKCS#7 signature to a module [ver #5]
Provide a utility that: (1) Digests a module using the specified hash algorithm (typically sha256). [The digest can be dumped into a file by passing the '-d' flag] (2) Generates a PKCS#7 message that: (a) Has detached data (ie. the module content). (b) Is signed with the specified private key. (c) Refers to the specified X.509 certificate. (d) Has an empty X.509 certificate list. [The PKCS#7 message can be dumped into a file by passing the '-p' flag] (3) Generates a signed module by concatenating the old module, the PKCS#7 message, a descriptor and a magic string. The descriptor contains the size of the PKCS#7 message and indicates the id_type as PKEY_ID_PKCS7. (4) Either writes the signed module to the specified destination or renames it over the source module. This allows module signing to reuse the PKCS#7 handling code that was added for PE file parsing for signed kexec. Note that the utility is written in C and must be linked against the OpenSSL crypto library. Note further that I have temporarily dropped support for handling externally created signatures until we can work out the best way to do those. Hopefully, whoever creates the signature can give me a PKCS#7 certificate. Signed-off-by: David Howells Tested-by: Vivek Goyal --- include/crypto/public_key.h |1 scripts/sign-file.c | 205 +++ 2 files changed, 206 insertions(+) create mode 100755 scripts/sign-file.c diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index b6f27a240856..fda097e079a4 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -33,6 +33,7 @@ extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST]; enum pkey_id_type { PKEY_ID_PGP,/* OpenPGP generated key ID */ PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */ + PKEY_ID_PKCS7, /* Signature in PKCS#7 message */ PKEY_ID_TYPE__LAST }; diff --git a/scripts/sign-file.c b/scripts/sign-file.c new file mode 100755 index ..5b8a6dda3235 --- /dev/null +++ b/scripts/sign-file.c @@ -0,0 +1,205 @@ +/* Sign a module file using the given key. + * + * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowe...@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct module_signature { + uint8_t algo; /* Public-key crypto algorithm [0] */ + uint8_t hash; /* Digest algorithm [0] */ + uint8_t id_type;/* Key identifier type [PKEY_ID_PKCS7] */ + uint8_t signer_len; /* Length of signer's name [0] */ + uint8_t key_id_len; /* Length of key identifier [0] */ + uint8_t __pad[3]; + uint32_tsig_len;/* Length of signature data */ +}; + +#define PKEY_ID_PKCS7 2 + +static char magic_number[] = "~Module signature appended~\n"; + +static __attribute__((noreturn)) +void format(void) +{ + fprintf(stderr, + "Usage: scripts/sign-file [-dp] []\n"); + exit(2); +} + +static void display_openssl_errors(int l) +{ + const char *file; + char buf[120]; + int e, line; + + if (ERR_peek_error() == 0) + return; + fprintf(stderr, "At main.c:%d:\n", l); + + while ((e = ERR_get_error_line(&file, &line))) { + ERR_error_string(e, buf); + fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line); + } +} + +static void drain_openssl_errors(void) +{ + const char *file; + int line; + + if (ERR_peek_error() == 0) + return; + while (ERR_get_error_line(&file, &line)) {} +} + +#define ERR(cond, fmt, ...)\ + do {\ + bool __cond = (cond); \ + display_openssl_errors(__LINE__); \ + if (__cond) { \ + err(1, fmt, ## __VA_ARGS__);\ + } \ + } while(0) + +int main(int argc, char **argv) +{ + struct module_signature sig_info = { .id_type = PKEY_ID_PKCS7 }; + char *hash_algo = NULL; + char *private_key_name, *x509_name, *module_name, *dest_name; + bool save_pkcs7 = false, replace_orig; + unsigned char buf[4096]; + unsigned long module_size, pkcs7_size; + const EVP_MD *digest_algo; + EVP_PKE
[PATCH 07/20] system_keyring.c doesn't need to #include module-internal.h [ver #5]
system_keyring.c doesn't need to #include module-internal.h as it doesn't use the one thing that exports. Remove the inclusion. Signed-off-by: David Howells --- kernel/system_keyring.c |1 - 1 file changed, 1 deletion(-) diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c index 875f64e8935b..4cda71ee51c7 100644 --- a/kernel/system_keyring.c +++ b/kernel/system_keyring.c @@ -16,7 +16,6 @@ #include #include #include -#include "module-internal.h" struct key *system_trusted_keyring; EXPORT_SYMBOL_GPL(system_trusted_keyring); -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/20] X.509: Extract both parts of the AuthorityKeyIdentifier [ver #5]
Extract both parts of the AuthorityKeyIdentifier, not just the keyIdentifier, as the second part can be used to match X.509 certificates by issuer and serialNumber. Signed-off-by: David Howells Tested-by: Vivek Goyal --- crypto/asymmetric_keys/Makefile |8 +- crypto/asymmetric_keys/pkcs7_trust.c |4 - crypto/asymmetric_keys/pkcs7_verify.c | 12 +- crypto/asymmetric_keys/x509_akid.asn1 | 35 +++ crypto/asymmetric_keys/x509_cert_parser.c | 142 ++--- crypto/asymmetric_keys/x509_parser.h |5 + crypto/asymmetric_keys/x509_public_key.c |8 +- 7 files changed, 145 insertions(+), 69 deletions(-) create mode 100644 crypto/asymmetric_keys/x509_akid.asn1 diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index e47fcd9ac5e8..cd1406f9b14a 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -15,15 +15,21 @@ obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o x509_key_parser-y := \ x509-asn1.o \ + x509_akid-asn1.o \ x509_rsakey-asn1.o \ x509_cert_parser.o \ x509_public_key.o -$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h +$(obj)/x509_cert_parser.o: \ + $(obj)/x509-asn1.h \ + $(obj)/x509_akid-asn1.h \ + $(obj)/x509_rsakey-asn1.h $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h +$(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h $(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h clean-files+= x509-asn1.c x509-asn1.h +clean-files+= x509_akid-asn1.c x509_akid-asn1.h clean-files+= x509_rsakey-asn1.c x509_rsakey-asn1.h # diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 1d29376072da..0f6463b6692b 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -85,8 +85,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, /* No match - see if the root certificate has a signer amongst the * trusted keys. */ - if (last && last->authority) { - key = x509_request_asymmetric_key(trust_keyring, last->authority, + if (last && last->akid_skid) { + key = x509_request_asymmetric_key(trust_keyring, last->akid_skid, false); if (!IS_ERR(key)) { x509 = last; diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index cd455450b069..a4d083f7e9e1 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -187,11 +187,11 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, goto maybe_missing_crypto_in_x509; pr_debug("- issuer %s\n", x509->issuer); - if (x509->authority) + if (x509->akid_skid) pr_debug("- authkeyid %*phN\n", -x509->authority->len, x509->authority->data); +x509->akid_skid->len, x509->akid_skid->data); - if (!x509->authority || + if (!x509->akid_skid || strcmp(x509->subject, x509->issuer) == 0) { /* If there's no authority certificate specified, then * the certificate must be self-signed and is the root @@ -216,13 +216,13 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, * list to see if the next one is there. */ pr_debug("- want %*phN\n", -x509->authority->len, x509->authority->data); +x509->akid_skid->len, x509->akid_skid->data); for (p = pkcs7->certs; p; p = p->next) { if (!p->skid) continue; pr_debug("- cmp [%u] %*phN\n", p->index, p->skid->len, p->skid->data); - if (asymmetric_key_id_same(p->skid, x509->authority)) + if (asymmetric_key_id_same(p->skid, x509->akid_skid)) goto found_issuer; } @@ -338,8 +338,6 @@ int pkcs7_verify(struct pkcs7_message *pkcs7) ret = x509_get_sig_params(x509); if (ret < 0) return ret; - pr_debug("X.509[%u] %*phN\n", -n, x509->authority->len, x509->authority->data); } for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { diff --git a/crypto/asymmetric_keys/x509_akid.asn1 b/crypto/asymmetric_keys/x509_akid.asn1 new file mode 100644 index ..1a33231a75a8 --- /dev/null +++ b/crypto/asymmetric_
[PATCHv2 03/17] mwifiex: support AP reset after bss_stop
This would enable clearing of FW bss data structures when AP operations are stopped. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c| 7 +++ drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/fw.h | 1 + drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 ++ drivers/net/wireless/mwifiex/uap_cmd.c | 10 -- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 3a14d3a..d47799a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1725,6 +1725,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) return -1; } + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "Failed to reset BSS\n"); + return -1; + } + return 0; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a1de83f..b5033d1 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -574,6 +574,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: case HostCmd_CMD_UAP_STA_DEAUTH: + case HOST_CMD_APCMD_SYS_RESET: ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, cmd_oid, data_buf, cmd_ptr); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6a062dd..124120d 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -330,6 +330,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RSSI_INFO 0x00a4 #define HostCmd_CMD_FUNC_INIT 0x00a9 #define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa +#define HOST_CMD_APCMD_SYS_RESET 0x00af #define HostCmd_CMD_UAP_SYS_CONFIG0x00b0 #define HostCmd_CMD_UAP_BSS_START 0x00b1 #define HostCmd_CMD_UAP_BSS_STOP 0x00b2 diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index aa5b9a3..f20a09e 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -1159,6 +1159,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case HostCmd_CMD_UAP_STA_DEAUTH: break; + case HOST_CMD_APCMD_SYS_RESET: + break; case HostCmd_CMD_MEF_CFG: break; case HostCmd_CMD_COALESCE_CFG: diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index a4ae283..0a3297e 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -754,6 +754,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, break; case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: + case HOST_CMD_APCMD_SYS_RESET: cmd->command = cpu_to_le16(cmd_no); cmd->size = cpu_to_le16(S_DS_GEN); break; @@ -811,8 +812,13 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL, true)) { - mwifiex_dbg(priv->adapter, ERROR, - "Failed to stop the BSS\n"); + mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n"); + return -1; + } + + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n"); return -1; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 05/17] mwifiex: reset 11h active flag when chandef does not require dfs
This patch fixes an issue where we were still setting 11h_active flag to true for channel defs where DFS is not required. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index d47799a..fb93e13 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1820,7 +1820,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, "Failed to disable 11h extensions!!"); return -1; } - priv->state_11h.is_11h_active = true; + priv->state_11h.is_11h_active = false; } if (mwifiex_config_start_uap(priv, bss_cfg)) { -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 17/17] mwifiex: do not decrease tx_pending for AMSDU packet once more
From: Xinming Hu Negative adapter->tx_pending is observed while running data traffic, because tx_pending is decreased once more for AMSDU packet. since tx_pending have been decreased for all the source MSDU packets, we don't need to update once more for AMSDU packet. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/txrx.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index c4c7d8d..5ed9b79 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -319,11 +319,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, priv->stats.tx_errors++; } - if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) { + if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) atomic_dec_return(&adapter->pending_bridged_pkts); - if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) - goto done; - } + + if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) + goto done; if (aggr) /* For skb_aggr, do not wake up tx queue */ -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 15/17] mwifiex: update AP WMM settings from BSS_START event
This was missing and would cause issue in WMM handling. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/uap_event.c | 63 1 file changed, 63 insertions(+) diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index 06ce3fe..fee05f5 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c @@ -21,8 +21,70 @@ #include "main.h" #include "11n.h" +#define MWIFIEX_BSS_START_EVT_FIX_SIZE12 +static int mwifiex_check_uap_capabilties(struct mwifiex_private *priv, +struct sk_buff *event) +{ + int evt_len; + u8 *curr; + u16 tlv_len; + struct mwifiex_ie_types_data *tlv_hdr; + struct ieee_types_wmm_parameter *wmm_param_ie = NULL; + int mask = IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK; + + priv->wmm_enabled = false; + skb_pull(event, MWIFIEX_BSS_START_EVT_FIX_SIZE); + evt_len = event->len; + curr = event->data; + + mwifiex_dbg_dump(priv->adapter, EVT_D, "uap capabilties:", +event->data, event->len); + + while ((evt_len >= sizeof(tlv_hdr->header))) { + tlv_hdr = (struct mwifiex_ie_types_data *)curr; + tlv_len = le16_to_cpu(tlv_hdr->header.len); + + if (evt_len < tlv_len + sizeof(tlv_hdr->header)) + break; + + switch (le16_to_cpu(tlv_hdr->header.type)) { + case WLAN_EID_HT_CAPABILITY: + priv->ap_11n_enabled = true; + break; + + case WLAN_EID_VHT_CAPABILITY: + priv->ap_11ac_enabled = true; + break; + case WLAN_EID_VENDOR_SPECIFIC: + /* Point the regular IEEE IE 2 bytes into the Marvell IE +* and setup the IEEE IE type and length byte fields +*/ + wmm_param_ie = (void *)(curr + 2); + wmm_param_ie->vend_hdr.len = (u8)tlv_len; + wmm_param_ie->vend_hdr.element_id = + WLAN_EID_VENDOR_SPECIFIC; + mwifiex_dbg(priv->adapter, EVENT, + "info: check uap capabilities:\t" + "wmm parameter set count: %d\n", + wmm_param_ie->qos_info_bitmap & mask); + + mwifiex_wmm_setup_ac_downgrade(priv); + priv->wmm_enabled = true; + mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie); + break; + + default: + break; + } + + curr += (tlv_len + sizeof(tlv_hdr->header)); + evt_len -= (tlv_len + sizeof(tlv_hdr->header)); + } + + return 0; +} /* * This function handles AP interface specific events generated by firmware. @@ -134,6 +196,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) ETH_ALEN); if (priv->hist_data) mwifiex_hist_data_reset(priv); + mwifiex_check_uap_capabilties(priv, adapter->event_skb); break; case EVENT_UAP_MIC_COUNTERMEASURES: /* For future development */ -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 16/17] mwifiex: using right tid for addressing ra_list
From: Xinming Hu This patch fixes issue with the accessing correct ra_list by downgrading corresponding tid number. Alternatively, ra lists are created in mwifiex_wmm_add_buf_txqueue using downgraded tid number. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/11n.c | 11 --- drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 - 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 8422986..4d8ef49 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -156,7 +156,7 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { - int tid; + int tid, tid_down; struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; struct mwifiex_ra_list_tbl *ra_list; @@ -167,7 +167,9 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK) >> BLOCKACKPARAM_TID_POS; - ra_list = mwifiex_wmm_get_ralist_node(priv, tid, add_ba_rsp-> + + tid_down = mwifiex_wmm_downgrade_tid(priv, tid); + ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, add_ba_rsp-> peer_mac_addr); if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) { if (ra_list) { @@ -530,13 +532,16 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, struct mwifiex_tx_ba_stream_tbl *new_node; struct mwifiex_ra_list_tbl *ra_list; unsigned long flags; + int tid_down; if (!mwifiex_get_ba_tbl(priv, tid, ra)) { new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), GFP_ATOMIC); if (!new_node) return; - ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra); + + tid_down = mwifiex_wmm_downgrade_tid(priv, tid); + ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, ra); if (ra_list) { ra_list->ba_status = ba_status; ra_list->amsdu_in_ampdu = false; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 39d7a95..64401a7 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -663,6 +663,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, struct mwifiex_ra_list_tbl *ra_list; u8 cleanup_rx_reorder_tbl; unsigned long flags; + int tid_down; if (type == TYPE_DELBA_RECEIVE) cleanup_rx_reorder_tbl = (initiator) ? true : false; @@ -688,7 +689,9 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, "event: TID, RA not found in table\n"); return; } - ra_list = mwifiex_wmm_get_ralist_node(priv, tid, peer_mac); + + tid_down = mwifiex_wmm_downgrade_tid(priv, tid); + ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, peer_mac); if (ra_list) { ra_list->amsdu_in_ampdu = false; ra_list->ba_status = BA_SETUP_NONE; -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 14/17] mwifiex: advertise PS ON by default support to cfg80211
This would enable driver to enter powersave as soon as connected. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cfg80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 1226555..3d3794f 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -3685,7 +3685,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_HAS_CHANNEL_SWITCH; + WIPHY_FLAG_HAS_CHANNEL_SWITCH | + WIPHY_FLAG_PS_ON_BY_DEFAULT; if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 12/17] mwifiex: support downloading IEs from tail
Earlier only RSN, WPA and channel switch IEs from tail buffer would be downloaded to FW. This patch adds support for downloading more IEs from tail buffer. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/ie.c | 102 ++ 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c index f3b6ed2..0ba8945 100644 --- a/drivers/net/wireless/mwifiex/ie.c +++ b/drivers/net/wireless/mwifiex/ie.c @@ -320,63 +320,81 @@ done: /* This function parses head and tail IEs, from cfg80211_beacon_data and sets * these IE to FW. */ -static int mwifiex_uap_set_head_tail_ies(struct mwifiex_private *priv, -struct cfg80211_beacon_data *info) +static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, + struct cfg80211_beacon_data *info) { struct mwifiex_ie *gen_ie; - struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL; - struct ieee_types_header *chsw_ie = NULL; + struct ieee_types_header *hdr; + struct ieee80211_vendor_ie *vendorhdr; u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; - const u8 *vendor_ie; + int left_len, parsed_len = 0; + + if (!info->tail || !info->tail_len) + return 0; gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL); if (!gen_ie) return -ENOMEM; - gen_ie->ie_index = cpu_to_le16(gen_idx); - gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON | - MGMT_MASK_PROBE_RESP | - MGMT_MASK_ASSOC_RESP); - if (info->tail && info->tail_len) { - rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, - info->tail, info->tail_len); - if (rsn_ie) { - memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2); - ie_len = rsn_ie->len + 2; - gen_ie->ie_length = cpu_to_le16(ie_len); + left_len = info->tail_len; + + /* Many IEs are generated in FW by parsing bss configuration. +* Let's not add them here; else we may end up duplicating these IEs +*/ + while (left_len > sizeof(struct ieee_types_header)) { + hdr = (void *)(info->tail + parsed_len); + switch (hdr->element_id) { + case WLAN_EID_SSID: + case WLAN_EID_SUPP_RATES: + case WLAN_EID_COUNTRY: + case WLAN_EID_PWR_CONSTRAINT: + case WLAN_EID_EXT_SUPP_RATES: + case WLAN_EID_HT_CAPABILITY: + case WLAN_EID_HT_OPERATION: + case WLAN_EID_VHT_CAPABILITY: + case WLAN_EID_VHT_OPERATION: + case WLAN_EID_VENDOR_SPECIFIC: + break; + default: + memcpy(gen_ie->ie_buffer + ie_len, hdr, + hdr->len + sizeof(struct ieee_types_header)); + ie_len += hdr->len + sizeof(struct ieee_types_header); + break; } + left_len -= hdr->len + sizeof(struct ieee_types_header); + parsed_len += hdr->len + sizeof(struct ieee_types_header); + } - vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + /* parse only WPA vendor IE from tail, WMM IE is configured by +* bss_config command +*/ + vendorhdr = (void *)cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, WLAN_OUI_TYPE_MICROSOFT_WPA, - info->tail, - info->tail_len); - if (vendor_ie) { - wpa_ie = (struct ieee_types_header *)vendor_ie; - memcpy(gen_ie->ie_buffer + ie_len, - wpa_ie, wpa_ie->len + 2); - ie_len += wpa_ie->len + 2; - gen_ie->ie_length = cpu_to_le16(ie_len); - } + info->tail, info->tail_len); + if (vendorhdr) { + memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, + vendorhdr->len + sizeof(struct ieee_types_header)); + ie_len += vendorhdr->len + sizeof(struct ieee_types_header); + } - chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH, - info->tail, info->tail_len); - if (chsw_ie) { - memcpy(gen_ie->ie_buffer + ie_len, - chsw_ie, chsw_ie->len + 2); - ie_len += chsw_ie->len + 2; - ge
[PATCHv2 13/17] mwifiex: drop block-ack action frames
We often see ADDBA request packets coming to driver because driver has registered for action frame subtype. We dont process BA action frames in host. Drop such frames. Signed-off-by: Avinash Patil Signed-off-by: Xinmin Hu Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/util.c | 43 + 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 2e3dc07..790e619 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -329,7 +329,7 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len, struct rxpd *rx_pd) { u16 stype; - u8 category, action_code; + u8 category, action_code, *addr2; struct ieee80211_hdr *ieee_hdr = (void *)payload; stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE); @@ -337,21 +337,35 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len, switch (stype) { case IEEE80211_STYPE_ACTION: category = *(payload + sizeof(struct ieee80211_hdr)); - action_code = *(payload + sizeof(struct ieee80211_hdr) + 1); - if (category == WLAN_CATEGORY_PUBLIC && - action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { + switch (category) { + case WLAN_CATEGORY_PUBLIC: + action_code = *(payload + sizeof(struct ieee80211_hdr) + + 1); + if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { + addr2 = ieee_hdr->addr2; + mwifiex_dbg(priv->adapter, INFO, + "TDLS discovery response %pM nf=%d, snr=%d\n", + addr2, rx_pd->nf, rx_pd->snr); + mwifiex_auto_tdls_update_peer_signal(priv, +addr2, +rx_pd->snr, +rx_pd->nf); + } + break; + case WLAN_CATEGORY_BACK: + /*we dont indicate BACK action frames to cfg80211*/ + mwifiex_dbg(priv->adapter, INFO, + "drop BACK action frames"); + return -1; + default: mwifiex_dbg(priv->adapter, INFO, - "TDLS discovery response %pM nf=%d, snr=%d\n", - ieee_hdr->addr2, rx_pd->nf, rx_pd->snr); - mwifiex_auto_tdls_update_peer_signal(priv, -ieee_hdr->addr2, -rx_pd->snr, -rx_pd->nf); + "unknown public action frame category %d\n", + category); } - break; default: mwifiex_dbg(priv->adapter, INFO, - "unknown mgmt frame subtype %#x\n", stype); + "unknown mgmt frame subtype %#x\n", stype); + return 0; } return 0; @@ -387,8 +401,9 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, ieee_hdr = (void *)skb->data; if (ieee80211_is_mgmt(ieee_hdr->frame_control)) { - mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr, - pkt_len, rx_pd); + if (mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr, + pkt_len, rx_pd)) + return -1; } /* Remove address4 */ memmove(skb->data + sizeof(struct ieee80211_hdr_3addr), -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 11/17] mwifiex: parse power constraint IE from Tail
This patch adds support to parse power constraint IEs from Tail buffer. This power constraint is then set to FW during bss_config download. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cfg80211.c | 3 +++ drivers/net/wireless/mwifiex/fw.h | 6 ++ drivers/net/wireless/mwifiex/ioctl.h| 1 + drivers/net/wireless/mwifiex/main.h | 3 +++ drivers/net/wireless/mwifiex/uap_cmd.c | 27 +++ 5 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 16528c1..1226555 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1867,6 +1867,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, mwifiex_set_wmm_params(priv, bss_cfg, params); + if (mwifiex_is_11h_active(priv)) + mwifiex_set_tpc_params(priv, bss_cfg, params); + if (mwifiex_is_11h_active(priv) && !cfg80211_chandef_dfs_required(wiphy, ¶ms->chandef, priv->bss_mode)) { diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 72e471b..f9dc715 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -128,6 +128,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_UAP_SSID 0x #define TLV_TYPE_UAP_RATES 0x0001 +#define TLV_TYPE_PWR_CONSTRAINT0x0020 #define PROPRIETARY_TLV_BASE_ID 0x0100 #define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) @@ -1780,6 +1781,11 @@ struct host_cmd_tlv_ageout_timer { __le32 sta_ao_timer; } __packed; +struct host_cmd_tlv_power_constraint { + struct mwifiex_ie_types_header header; + u8 constraint; +} __packed; + struct host_cmd_ds_version_ext { u8 version_str_sel; char version_str[128]; diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 6f11a25..4f0174c 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -113,6 +113,7 @@ struct mwifiex_uap_bss_param { u32 sta_ao_timer; u32 ps_sta_ao_timer; u8 qos_info; + u8 power_constraint; struct mwifiex_types_wmm_info wmm_info; }; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 837e610..d92c527 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1149,6 +1149,9 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv, void mwifiex_set_vht_params(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_ap_settings *params); +void mwifiex_set_tpc_params(struct mwifiex_private *priv, + struct mwifiex_uap_bss_param *bss_cfg, + struct cfg80211_ap_settings *params); void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_ap_settings *params); void mwifiex_set_vht_width(struct mwifiex_private *priv, diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 865b363..61e8bf3 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -222,6 +222,23 @@ void mwifiex_set_vht_params(struct mwifiex_private *priv, return; } +/* This function updates 11ac related parameters from IE + * and sets them into bss_config structure. + */ +void mwifiex_set_tpc_params(struct mwifiex_private *priv, + struct mwifiex_uap_bss_param *bss_cfg, + struct cfg80211_ap_settings *params) +{ + const u8 *tpc_ie; + + tpc_ie = cfg80211_find_ie(WLAN_EID_TPC_REQUEST, params->beacon.tail, + params->beacon.tail_len); + if (tpc_ie) + bss_cfg->power_constraint = *(tpc_ie + 2); + else + bss_cfg->power_constraint = 0; +} + /* Enable VHT only when cfg80211_ap_settings has VHT IE. * Otherwise disable VHT. */ @@ -466,6 +483,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_auth_type *auth_type; struct host_cmd_tlv_rates *tlv_rates; struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer; + struct host_cmd_tlv_power_constraint *pwr_ct; struct mwifiex_ie_types_htcap *htcap; struct mwifiex_ie_types_wmmcap *wmm_cap; struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; @@ -644,6 +662,15 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) tlv += sizeof(*ao_timer); } + if (bss_cfg->power_constraint) { + pwr_ct = (void *)tlv; +
[PATCHv2 06/17] mwifiex: disable CAC upon radar detection event
This patch adds support to disable ongoing CAC in FW upon detecting radar during CAC period. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/11h.c | 30 ++ drivers/net/wireless/mwifiex/main.h | 2 ++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c index 65cd461..bb2ffd9 100644 --- a/drivers/net/wireless/mwifiex/11h.c +++ b/drivers/net/wireless/mwifiex/11h.c @@ -161,19 +161,38 @@ int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv, cr_req->chan_desc.chan_width = radar_params->chandef->width; cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms); - mwifiex_dbg(priv->adapter, MSG, - "11h: issuing DFS Radar check for channel=%d\n", - radar_params->chandef->chan->hw_value); + if (radar_params->cac_time_ms) + mwifiex_dbg(priv->adapter, MSG, + "11h: issuing DFS Radar check for channel=%d\n", + radar_params->chandef->chan->hw_value); + else + mwifiex_dbg(priv->adapter, MSG, "cancelling CAC\n"); return 0; } +int mwifiex_stop_radar_detection(struct mwifiex_private *priv, +struct cfg80211_chan_def *chandef) +{ + struct mwifiex_radar_params radar_params; + + memset(&radar_params, 0, sizeof(struct mwifiex_radar_params)); + radar_params.chandef = chandef; + radar_params.cac_time_ms = 0; + + return mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST, + HostCmd_ACT_GEN_SET, 0, &radar_params, true); +} + /* This function is to abort ongoing CAC upon stopping AP operations * or during unload. */ void mwifiex_abort_cac(struct mwifiex_private *priv) { if (priv->wdev.cac_started) { + if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef)) + mwifiex_dbg(priv->adapter, ERROR, + "failed to stop CAC in FW\n"); mwifiex_dbg(priv->adapter, MSG, "Aborting delayed work for CAC.\n"); cancel_delayed_work_sync(&priv->dfs_cac_work); @@ -245,6 +264,9 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv, if (le32_to_cpu(rdr_event->passed)) { mwifiex_dbg(priv->adapter, MSG, "radar detected; indicating kernel\n"); + if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef)) + mwifiex_dbg(priv->adapter, ERROR, + "Failed to stop CAC in FW\n"); cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef, GFP_KERNEL); mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n", @@ -252,7 +274,7 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv, mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n", rdr_event->det_type); } else { - mwifiex_dbg(priv->adapter, ERROR, + mwifiex_dbg(priv->adapter, MSG, "false radar detection event!\n"); } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 5a6c1c7..3ac18c6 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1473,6 +1473,8 @@ mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, void mwifiex_dfs_cac_work_queue(struct work_struct *work); void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work); void mwifiex_abort_cac(struct mwifiex_private *priv); +int mwifiex_stop_radar_detection(struct mwifiex_private *priv, +struct cfg80211_chan_def *chandef); int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv, struct sk_buff *skb); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 07/17] mwifiex: add cfg80211 get_channel handler
From: Xinming Hu This patch add cfg80211 get_channel handler for mwifiex. The handler will be used to report current channel to upper layer utility. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/11h.c | 2 +- drivers/net/wireless/mwifiex/cfg80211.c | 58 - drivers/net/wireless/mwifiex/main.h | 5 ++- drivers/net/wireless/mwifiex/uap_cmd.c | 5 ++- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c index bb2ffd9..71a1b58 100644 --- a/drivers/net/wireless/mwifiex/11h.c +++ b/drivers/net/wireless/mwifiex/11h.c @@ -305,7 +305,7 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work) return; } - mwifiex_uap_set_channel(bss_cfg, priv->dfs_chandef); + mwifiex_uap_set_channel(priv, bss_cfg, priv->dfs_chandef); if (mwifiex_config_start_uap(priv, bss_cfg)) { mwifiex_dbg(priv->adapter, ERROR, diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index fb93e13..ddeb919 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -67,6 +67,22 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type) } } +/* This function maps IEEE HT secondary channel type to NL80211 channel type + */ +u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset) +{ + switch (second_chan_offset) { + case IEEE80211_HT_PARAM_CHA_SEC_NONE: + return NL80211_CHAN_HT20; + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + return NL80211_CHAN_HT40PLUS; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + return NL80211_CHAN_HT40MINUS; + default: + return NL80211_CHAN_HT20; + } +} + /* * This function checks whether WEP is set. */ @@ -1785,7 +1801,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, return -EINVAL; } - mwifiex_uap_set_channel(bss_cfg, params->chandef); + mwifiex_uap_set_channel(priv, bss_cfg, params->chandef); mwifiex_set_uap_rates(bss_cfg, params); if (mwifiex_set_secure_params(priv, bss_cfg, params)) { @@ -3373,6 +3389,45 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, return 0; } +static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_chan_def *chandef) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); + struct mwifiex_bssdescriptor *curr_bss; + struct ieee80211_channel *chan; + u8 second_chan_offset; + enum nl80211_channel_type chan_type; + enum ieee80211_band band; + int freq; + int ret = -ENODATA; + + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP && + cfg80211_chandef_valid(&priv->bss_chandef)) { + *chandef = priv->bss_chandef; + ret = 0; + } else if (priv->media_connected) { + curr_bss = &priv->curr_bss_params.bss_descriptor; + band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); + freq = ieee80211_channel_to_frequency(curr_bss->channel, band); + chan = ieee80211_get_channel(wiphy, freq); + + if (curr_bss->bcn_ht_oper) { + second_chan_offset = curr_bss->bcn_ht_oper->ht_param & + IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + chan_type = mwifiex_sec_chan_offset_to_chan_type + (second_chan_offset); + cfg80211_chandef_create(chandef, chan, chan_type); + } else { + cfg80211_chandef_create(chandef, chan, + NL80211_CHAN_NO_HT); + } + ret = 0; + } + + return ret; +} + static int mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy, struct net_device *dev, @@ -3478,6 +3533,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .tdls_oper = mwifiex_cfg80211_tdls_oper, .add_station = mwifiex_cfg80211_add_station, .change_station = mwifiex_cfg80211_change_station, + .get_channel = mwifiex_cfg80211_get_channel, .start_radar_detection = mwifiex_cfg80211_start_radar_detection, .channel_switch = mwifiex_cfg80211_channel_switch, }; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3ac18c6..88d3779 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -642,6 +642,7 @@ struct mwifiex_private {
[PATCHv2 10/17] mwifiex: dump station support in uap mode
From: Xinming Hu This patch extend cfg80211 dump_station handler, support for dump stations associated to mwifiex micro AP. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cfg80211.c | 51 + 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ddeb919..16528c1 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1229,6 +1229,7 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo, */ static int mwifiex_dump_station_info(struct mwifiex_private *priv, + struct mwifiex_sta_node *node, struct station_info *sinfo) { u32 rate; @@ -1238,6 +1239,30 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, BIT(NL80211_STA_INFO_TX_BITRATE) | BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG); + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { + if (!node) + return -ENOENT; + + sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME) | + BIT(NL80211_STA_INFO_TX_FAILED); + sinfo->inactive_time = + jiffies_to_msecs(jiffies - node->stats.last_rx); + + sinfo->signal = node->stats.rssi; + sinfo->signal_avg = node->stats.rssi; + sinfo->rx_bytes = node->stats.rx_bytes; + sinfo->tx_bytes = node->stats.tx_bytes; + sinfo->rx_packets = node->stats.rx_packets; + sinfo->tx_packets = node->stats.tx_packets; + sinfo->tx_failed = node->stats.tx_failed; + + mwifiex_parse_htinfo(priv, node->stats.last_tx_htinfo, +&sinfo->txrate); + sinfo->txrate.legacy = node->stats.last_tx_rate * 5; + + return 0; + } + /* Get signal information from the firmware */ if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, HostCmd_ACT_GEN_GET, 0, NULL, true)) { @@ -1304,7 +1329,7 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) return -ENOENT; - return mwifiex_dump_station_info(priv, sinfo); + return mwifiex_dump_station_info(priv, NULL, sinfo); } /* @@ -1315,13 +1340,29 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + static struct mwifiex_sta_node *node; - if (!priv->media_connected || idx) - return -ENOENT; + if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && + priv->media_connected && idx == 0) { + ether_addr_copy(mac, priv->cfg_bssid); + return mwifiex_dump_station_info(priv, NULL, sinfo); + } else if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { + mwifiex_send_cmd(priv, HOSTCMD_CMD_UAP_STA_LIST, +HostCmd_ACT_GEN_GET, 0, NULL, true); + + if (node && (&node->list == &priv->sta_list)) { + node = NULL; + return -ENOENT; + } - memcpy(mac, priv->cfg_bssid, ETH_ALEN); + node = list_prepare_entry(node, &priv->sta_list, list); + list_for_each_entry_continue(node, &priv->sta_list, list) { + ether_addr_copy(mac, node->mac_addr); + return mwifiex_dump_station_info(priv, node, sinfo); + } + } - return mwifiex_dump_station_info(priv, sinfo); + return -ENOENT; } static int -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 09/17] mwifiex: add sta_list firmware command
From: Xinming Hu This patch add sta_list firmware command, which can be used to get power status and rssi for the stations associated to mwifiex micro AP. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/fw.h | 14 ++ drivers/net/wireless/mwifiex/sta_cmdresp.c | 24 drivers/net/wireless/mwifiex/uap_cmd.c | 1 + 4 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index b5033d1..b8f6aa1 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -575,6 +575,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_STOP: case HostCmd_CMD_UAP_STA_DEAUTH: case HOST_CMD_APCMD_SYS_RESET: + case HOSTCMD_CMD_UAP_STA_LIST: ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, cmd_oid, data_buf, cmd_ptr); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 1a87188..72e471b 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -334,6 +334,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_UAP_SYS_CONFIG0x00b0 #define HostCmd_CMD_UAP_BSS_START 0x00b1 #define HostCmd_CMD_UAP_BSS_STOP 0x00b2 +#define HOSTCMD_CMD_UAP_STA_LIST 0x00b3 #define HostCmd_CMD_UAP_STA_DEAUTH0x00b5 #define HostCmd_CMD_11N_CFG 0x00cd #define HostCmd_CMD_11N_ADDBA_REQ 0x00ce @@ -1465,6 +1466,18 @@ struct host_cmd_ds_sta_deauth { __le16 reason; } __packed; +struct mwifiex_ie_types_sta_info { + struct mwifiex_ie_types_header header; + u8 mac[ETH_ALEN]; + u8 power_mfg_status; + s8 rssi; +}; + +struct host_cmd_ds_sta_list { + u16 sta_count; + u8 tlv[0]; +} __packed; + struct mwifiex_ie_types_pwr_capability { struct mwifiex_ie_types_header header; s8 min_pwr; @@ -1994,6 +2007,7 @@ struct host_cmd_ds_command { struct host_cmd_ds_802_11_subsc_evt subsc_evt; struct host_cmd_ds_sys_config uap_sys_config; struct host_cmd_ds_sta_deauth sta_deauth; + struct host_cmd_ds_sta_list sta_list; struct host_cmd_11ac_vht_cfg vht_cfg; struct host_cmd_ds_coalesce_cfg coalesce_cfg; struct host_cmd_ds_tdls_oper tdls_oper; diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index f20a09e..166e7de 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -958,6 +958,27 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv, return 0; } +static int mwifiex_ret_uap_sta_list(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_sta_list *sta_list = + &resp->params.sta_list; + struct mwifiex_ie_types_sta_info *sta_info = (void *)&sta_list->tlv; + int i; + struct mwifiex_sta_node *sta_node; + + for (i = 0; i < sta_list->sta_count; i++) { + sta_node = mwifiex_get_sta_entry(priv, sta_info->mac); + if (unlikely(!sta_node)) + continue; + + sta_node->stats.rssi = sta_info->rssi; + sta_info++; + } + + return 0; +} + /* This function handles the command response of set_cfg_data */ static int mwifiex_ret_cfg_data(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) @@ -1148,6 +1169,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case HostCmd_CMD_UAP_SYS_CONFIG: break; + case HOSTCMD_CMD_UAP_STA_LIST: + ret = mwifiex_ret_uap_sta_list(priv, resp); + break; case HostCmd_CMD_UAP_BSS_START: adapter->tx_lock_flag = false; adapter->pps_uapsd_mode = false; diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 68fbdf6..865b363 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -755,6 +755,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: case HOST_CMD_APCMD_SYS_RESET: + case HOSTCMD_CMD_UAP_STA_LIST: cmd->command = cpu_to_le16(cmd_no);
[PATCHv2 08/17] mwifiex: maintain station statistic in uap mode
From: Xinming Hu This patch maintain statistic information for the stations associated to the mwifiex micro AP, include tx/rx bytes/packets, signal strength, tx bitrate. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/fw.h | 7 ++- drivers/net/wireless/mwifiex/main.h | 13 + drivers/net/wireless/mwifiex/txrx.c | 13 +++-- drivers/net/wireless/mwifiex/uap_txrx.c | 18 +- drivers/net/wireless/mwifiex/util.c | 13 + 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 124120d..1a87188 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -632,7 +632,12 @@ struct uap_rxpd { __le16 rx_pkt_type; __le16 seq_num; u8 priority; - u8 reserved1; + u8 rx_rate; + s8 snr; + s8 nf; + u8 ht_info; + u8 reserved[3]; + u8 flags; }; struct mwifiex_fw_chan_stats { diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 88d3779..837e610 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -741,6 +741,18 @@ struct mwifiex_tdls_capab { struct ieee80211_vht_operation vhtoper; }; +struct mwifiex_station_stats { + u64 last_rx; + s8 rssi; + u64 rx_bytes; + u64 tx_bytes; + u32 rx_packets; + u32 tx_packets; + u32 tx_failed; + u8 last_tx_rate; + u8 last_tx_htinfo; +}; + /* This is AP/TDLS specific structure which stores information * about associated/peer STA */ @@ -755,6 +767,7 @@ struct mwifiex_sta_node { u16 max_amsdu; u8 tdls_status; struct mwifiex_tdls_capab tdls_cap; + struct mwifiex_station_stats stats; }; struct mwifiex_auto_tdls_peer { diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 28dcc84..c4c7d8d 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -88,13 +88,22 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, struct mwifiex_adapter *adapter = priv->adapter; u8 *head_ptr; struct txpd *local_tx_pd = NULL; + struct mwifiex_sta_node *dest_node; + struct ethhdr *hdr = (void *)skb->data; hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN; - if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) + if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) { + dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest); + if (dest_node) { + dest_node->stats.tx_bytes += skb->len; + dest_node->stats.tx_packets++; + } + head_ptr = mwifiex_process_uap_txpd(priv, skb); - else + } else { head_ptr = mwifiex_process_sta_txpd(priv, skb); + } if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) { skb_queue_tail(&adapter->tx_data_q, skb); diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c index 61c52fd..8766741 100644 --- a/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/mwifiex/uap_txrx.c @@ -97,6 +97,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, struct mwifiex_txinfo *tx_info; int hdr_chop; struct ethhdr *p_ethhdr; + struct mwifiex_sta_node *src_node; uap_rx_pd = (struct uap_rxpd *)(skb->data); rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); @@ -180,6 +181,15 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, tx_info->bss_type = priv->bss_type; tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT; + src_node = mwifiex_get_sta_entry(priv, rx_pkt_hdr->eth803_hdr.h_source); + if (src_node) { + src_node->stats.last_rx = jiffies; + src_node->stats.rx_bytes += skb->len; + src_node->stats.rx_packets++; + src_node->stats.last_tx_rate = uap_rx_pd->rx_rate; + src_node->stats.last_tx_htinfo = uap_rx_pd->ht_info; + } + if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) { /* Update bridge packet statistics as the * packet is not going to kernel/upper layer. @@ -275,6 +285,8 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); + ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source); + if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) + le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16) skb->len) { mwifi
[PATCHv2 04/17] mwifiex: enable 11d after bss reset
BSS reset would reset all state information in FW. Issue 11d config command after reset to enabled 11d in FW. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/uap_cmd.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 0a3297e..56a4768 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -806,6 +806,8 @@ void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg, int mwifiex_config_start_uap(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg) { + enum state_11d_t state_11d; + if (mwifiex_del_mgmt_ies(priv)) mwifiex_dbg(priv->adapter, ERROR, "Failed to delete mgmt IEs!\n"); @@ -830,6 +832,16 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, return -1; } + /* Send cmd to FW to enable 11D function */ + state_11d = ENABLE_11D; + if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, +HostCmd_ACT_GEN_SET, DOT11D_I, +&state_11d, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "11D: failed to enable 11D\n"); + return -1; + } + if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START, HostCmd_ACT_GEN_SET, 0, NULL, false)) { mwifiex_dbg(priv->adapter, ERROR, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 00/17] mwifiex patches
This patch series mainly adds enhancements for mwifiex AP. With this series, we support verbose information in station dump command also inforamation about AP link. Another important enhancement is related to parsing IEs from Tail of beacon_data. Few issues seen during DFS testing are also fixed in this series. Patch series also includes some other misc patches. Avinash Patil (11): mwifiex: verbose logging for association failure messages mwifiex: correct bss_type assignment mwifiex: support AP reset after bss_stop mwifiex: enable 11d after bss reset mwifiex: reset 11h active flag when chandef does not require dfs mwifiex: disable CAC upon radar detection event mwifiex: parse power constraint IE from Tail mwifiex: support downloading IEs from tail mwifiex: drop block-ack action frames mwifiex: advertise PS ON by default support to cfg80211 mwifiex: update AP WMM settings from BSS_START event Xinming Hu (6): mwifiex: add cfg80211 get_channel handler mwifiex: maintain station statistic in uap mode mwifiex: add sta_list firmware command mwifiex: dump station support in uap mode mwifiex: using right tid for addressing ra_list mwifiex: do not decrease tx_pending for AMSDU packet once more drivers/net/wireless/mwifiex/11h.c | 32 +-- drivers/net/wireless/mwifiex/11n.c | 11 ++- drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 +- drivers/net/wireless/mwifiex/cfg80211.c | 130 --- drivers/net/wireless/mwifiex/cmdevt.c| 2 + drivers/net/wireless/mwifiex/fw.h| 43 - drivers/net/wireless/mwifiex/ie.c| 102 - drivers/net/wireless/mwifiex/ioctl.h | 1 + drivers/net/wireless/mwifiex/join.c | 30 ++- drivers/net/wireless/mwifiex/main.h | 23 - drivers/net/wireless/mwifiex/sta_cmdresp.c | 26 ++ drivers/net/wireless/mwifiex/txrx.c | 21 +++-- drivers/net/wireless/mwifiex/uap_cmd.c | 55 +++- drivers/net/wireless/mwifiex/uap_event.c | 63 + drivers/net/wireless/mwifiex/uap_txrx.c | 18 +++- drivers/net/wireless/mwifiex/util.c | 56 +--- 16 files changed, 525 insertions(+), 93 deletions(-) -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 02/17] mwifiex: correct bss_type assignment
Correct bss_type assignment in add_virtual_interface. This would ensure correct operation in multiple station scenarios. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4eeceda..3a14d3a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2518,7 +2518,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.sta_intf; break; case NL80211_IFTYPE_AP: @@ -2544,7 +2544,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_UAP; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.uap_intf; priv->bss_mode = type; break; @@ -2580,7 +2580,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = MWIFIEX_BSS_ROLE_STA; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.p2p_intf; if (mwifiex_cfg80211_init_p2p_client(priv)) { memset(&priv->wdev, 0, sizeof(priv->wdev)); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 01/17] mwifiex: verbose logging for association failure messages
This patch adds more logging support for association failure - reason and states. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 15 +-- drivers/net/wireless/mwifiex/join.c | 30 +++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c404390..6a062dd 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -419,8 +419,12 @@ enum P2P_MODES { #define HS_CFG_COND_MAC_EVENT 0x0004 #define HS_CFG_COND_MULTICAST_DATA 0x0008 -#define MWIFIEX_TIMEOUT_FOR_AP_RESP0xfffc -#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 +#define ASSOC_ERR_AUTH_ERR_STA_FAILURE 0xFFFB +#define ASSOC_ERR_ASSOC_ERR_TIMEOUT0xFFFC +#define ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD +#define ASSOC_ERR_AUTH_MSG_UNHANDLED 0xFFFE +#define ASSOC_ERR_STA_FAILURE 0x + #define CMD_F_HOSTCMD (1 << 0) #define CMD_F_CANCELED (1 << 1) @@ -1151,6 +1155,13 @@ enum SNMP_MIB_INDEX { DOT11H_I = 10, }; +enum mwifiex_assocmd_failurepoint { + MWIFIEX_ASSOC_CMD_SUCCESS = 0, + MWIFIEX_ASSOC_CMD_FAILURE_ASSOC, + MWIFIEX_ASSOC_CMD_FAILURE_AUTH, + MWIFIEX_ASSOC_CMD_FAILURE_JOIN +}; + #define MAX_SNMP_BUF_SIZE 128 struct host_cmd_ds_802_11_snmp_mib { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 6208ef1..69a44bb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return 0; } +static const char *assoc_failure_reason_to_str(u16 cap_info) +{ + switch (cap_info) { + case ASSOC_ERR_AUTH_ERR_STA_FAILURE: + return "ASSOC_ERR_AUTH_ERR_STA_FAILURE"; + case ASSOC_ERR_AUTH_MSG_UNHANDLED: + return "ASSOC_ERR_AUTH_MSG_UNHANDLED"; + case ASSOC_ERR_ASSOC_ERR_TIMEOUT: + return "ASSOC_ERR_ASSOC_ERR_TIMEOUT"; + case ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED: + return "ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED"; + case ASSOC_ERR_STA_FAILURE: + return "ASSOC_ERR_STA_FAILURE"; + } + + return "Unknown failure"; +} /* * Association firmware command response handler * @@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, status_code, cap_info, le16_to_cpu(assoc_rsp->a_id)); - if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { - if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) + mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n", + assoc_failure_reason_to_str(cap_info)); + if (cap_info == ASSOC_ERR_ASSOC_ERR_TIMEOUT) { + if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) { ret = WLAN_STATUS_AUTH_TIMEOUT; - else + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: AUTH timeout\n"); + } else { ret = WLAN_STATUS_UNSPECIFIED_FAILURE; + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: UNSPECIFIED failure\n"); + } } else { ret = status_code; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 03/17] mwifiex: support AP reset after bss_stop
Hi Kalle, Please ignore this series. Looks like some of the patches are duplicated because of email client issue. I will resend v2. Thanks, Avinash From: Avinash Patil Sent: Thursday, May 28, 2015 6:22 PM To: linux-wireless@vger.kernel.org Cc: Amitkumar Karwar; Cathy Luo; Xinming Hu; Avinash Patil Subject: [PATCH 03/17] mwifiex: support AP reset after bss_stop This would enable clearing of FW bss data structures when AP operations are stopped. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c| 7 +++ drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/fw.h | 1 + drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 ++ drivers/net/wireless/mwifiex/uap_cmd.c | 10 -- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 3a14d3a..d47799a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1725,6 +1725,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) return -1; } + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "Failed to reset BSS\n"); + return -1; + } + return 0; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a1de83f..b5033d1 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -574,6 +574,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: case HostCmd_CMD_UAP_STA_DEAUTH: + case HOST_CMD_APCMD_SYS_RESET: ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, cmd_oid, data_buf, cmd_ptr); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6a062dd..124120d 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -330,6 +330,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RSSI_INFO 0x00a4 #define HostCmd_CMD_FUNC_INIT 0x00a9 #define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa +#define HOST_CMD_APCMD_SYS_RESET 0x00af #define HostCmd_CMD_UAP_SYS_CONFIG0x00b0 #define HostCmd_CMD_UAP_BSS_START 0x00b1 #define HostCmd_CMD_UAP_BSS_STOP 0x00b2 diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index aa5b9a3..f20a09e 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -1159,6 +1159,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case HostCmd_CMD_UAP_STA_DEAUTH: break; + case HOST_CMD_APCMD_SYS_RESET: + break; case HostCmd_CMD_MEF_CFG: break; case HostCmd_CMD_COALESCE_CFG: diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index a4ae283..0a3297e 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -754,6 +754,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, break; case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: + case HOST_CMD_APCMD_SYS_RESET: cmd->command = cpu_to_le16(cmd_no); cmd->size = cpu_to_le16(S_DS_GEN); break; @@ -811,8 +812,13 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL, true)) { - mwifiex_dbg(priv->adapter, ERROR, - "Failed to stop the BSS\n"); + mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n"); + return -1; + } + + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n"); return -1; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/17] mwifiex: verbose logging for association failure messages
This patch adds more logging support for association failure - reason and states. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 15 +-- drivers/net/wireless/mwifiex/join.c | 30 +++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c404390..6a062dd 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -419,8 +419,12 @@ enum P2P_MODES { #define HS_CFG_COND_MAC_EVENT 0x0004 #define HS_CFG_COND_MULTICAST_DATA 0x0008 -#define MWIFIEX_TIMEOUT_FOR_AP_RESP0xfffc -#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 +#define ASSOC_ERR_AUTH_ERR_STA_FAILURE 0xFFFB +#define ASSOC_ERR_ASSOC_ERR_TIMEOUT0xFFFC +#define ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD +#define ASSOC_ERR_AUTH_MSG_UNHANDLED 0xFFFE +#define ASSOC_ERR_STA_FAILURE 0x + #define CMD_F_HOSTCMD (1 << 0) #define CMD_F_CANCELED (1 << 1) @@ -1151,6 +1155,13 @@ enum SNMP_MIB_INDEX { DOT11H_I = 10, }; +enum mwifiex_assocmd_failurepoint { + MWIFIEX_ASSOC_CMD_SUCCESS = 0, + MWIFIEX_ASSOC_CMD_FAILURE_ASSOC, + MWIFIEX_ASSOC_CMD_FAILURE_AUTH, + MWIFIEX_ASSOC_CMD_FAILURE_JOIN +}; + #define MAX_SNMP_BUF_SIZE 128 struct host_cmd_ds_802_11_snmp_mib { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 6208ef1..69a44bb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return 0; } +static const char *assoc_failure_reason_to_str(u16 cap_info) +{ + switch (cap_info) { + case ASSOC_ERR_AUTH_ERR_STA_FAILURE: + return "ASSOC_ERR_AUTH_ERR_STA_FAILURE"; + case ASSOC_ERR_AUTH_MSG_UNHANDLED: + return "ASSOC_ERR_AUTH_MSG_UNHANDLED"; + case ASSOC_ERR_ASSOC_ERR_TIMEOUT: + return "ASSOC_ERR_ASSOC_ERR_TIMEOUT"; + case ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED: + return "ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED"; + case ASSOC_ERR_STA_FAILURE: + return "ASSOC_ERR_STA_FAILURE"; + } + + return "Unknown failure"; +} /* * Association firmware command response handler * @@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, status_code, cap_info, le16_to_cpu(assoc_rsp->a_id)); - if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { - if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) + mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n", + assoc_failure_reason_to_str(cap_info)); + if (cap_info == ASSOC_ERR_ASSOC_ERR_TIMEOUT) { + if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) { ret = WLAN_STATUS_AUTH_TIMEOUT; - else + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: AUTH timeout\n"); + } else { ret = WLAN_STATUS_UNSPECIFIED_FAILURE; + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: UNSPECIFIED failure\n"); + } } else { ret = status_code; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/17] mwifiex: enable 11d after bss reset
BSS reset would reset all state information in FW. Issue 11d config command after reset to enabled 11d in FW. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/uap_cmd.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 0a3297e..56a4768 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -806,6 +806,8 @@ void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg, int mwifiex_config_start_uap(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg) { + enum state_11d_t state_11d; + if (mwifiex_del_mgmt_ies(priv)) mwifiex_dbg(priv->adapter, ERROR, "Failed to delete mgmt IEs!\n"); @@ -830,6 +832,16 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, return -1; } + /* Send cmd to FW to enable 11D function */ + state_11d = ENABLE_11D; + if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, +HostCmd_ACT_GEN_SET, DOT11D_I, +&state_11d, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "11D: failed to enable 11D\n"); + return -1; + } + if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START, HostCmd_ACT_GEN_SET, 0, NULL, false)) { mwifiex_dbg(priv->adapter, ERROR, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/17] mwifiex: verbose logging for association failure messages
This patch adds more logging support for association failure - reason and states. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 15 +-- drivers/net/wireless/mwifiex/join.c | 30 +++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c404390..6a062dd 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -419,8 +419,12 @@ enum P2P_MODES { #define HS_CFG_COND_MAC_EVENT 0x0004 #define HS_CFG_COND_MULTICAST_DATA 0x0008 -#define MWIFIEX_TIMEOUT_FOR_AP_RESP0xfffc -#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 +#define ASSOC_ERR_AUTH_ERR_STA_FAILURE 0xFFFB +#define ASSOC_ERR_ASSOC_ERR_TIMEOUT0xFFFC +#define ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD +#define ASSOC_ERR_AUTH_MSG_UNHANDLED 0xFFFE +#define ASSOC_ERR_STA_FAILURE 0x + #define CMD_F_HOSTCMD (1 << 0) #define CMD_F_CANCELED (1 << 1) @@ -1151,6 +1155,13 @@ enum SNMP_MIB_INDEX { DOT11H_I = 10, }; +enum mwifiex_assocmd_failurepoint { + MWIFIEX_ASSOC_CMD_SUCCESS = 0, + MWIFIEX_ASSOC_CMD_FAILURE_ASSOC, + MWIFIEX_ASSOC_CMD_FAILURE_AUTH, + MWIFIEX_ASSOC_CMD_FAILURE_JOIN +}; + #define MAX_SNMP_BUF_SIZE 128 struct host_cmd_ds_802_11_snmp_mib { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 6208ef1..69a44bb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return 0; } +static const char *assoc_failure_reason_to_str(u16 cap_info) +{ + switch (cap_info) { + case ASSOC_ERR_AUTH_ERR_STA_FAILURE: + return "ASSOC_ERR_AUTH_ERR_STA_FAILURE"; + case ASSOC_ERR_AUTH_MSG_UNHANDLED: + return "ASSOC_ERR_AUTH_MSG_UNHANDLED"; + case ASSOC_ERR_ASSOC_ERR_TIMEOUT: + return "ASSOC_ERR_ASSOC_ERR_TIMEOUT"; + case ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED: + return "ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED"; + case ASSOC_ERR_STA_FAILURE: + return "ASSOC_ERR_STA_FAILURE"; + } + + return "Unknown failure"; +} /* * Association firmware command response handler * @@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, status_code, cap_info, le16_to_cpu(assoc_rsp->a_id)); - if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { - if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) + mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n", + assoc_failure_reason_to_str(cap_info)); + if (cap_info == ASSOC_ERR_ASSOC_ERR_TIMEOUT) { + if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) { ret = WLAN_STATUS_AUTH_TIMEOUT; - else + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: AUTH timeout\n"); + } else { ret = WLAN_STATUS_UNSPECIFIED_FAILURE; + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: UNSPECIFIED failure\n"); + } } else { ret = status_code; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/17] mwifiex: support AP reset after bss_stop
This would enable clearing of FW bss data structures when AP operations are stopped. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c| 7 +++ drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/fw.h | 1 + drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 ++ drivers/net/wireless/mwifiex/uap_cmd.c | 10 -- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 3a14d3a..d47799a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1725,6 +1725,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) return -1; } + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "Failed to reset BSS\n"); + return -1; + } + return 0; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a1de83f..b5033d1 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -574,6 +574,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: case HostCmd_CMD_UAP_STA_DEAUTH: + case HOST_CMD_APCMD_SYS_RESET: ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, cmd_oid, data_buf, cmd_ptr); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6a062dd..124120d 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -330,6 +330,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RSSI_INFO 0x00a4 #define HostCmd_CMD_FUNC_INIT 0x00a9 #define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa +#define HOST_CMD_APCMD_SYS_RESET 0x00af #define HostCmd_CMD_UAP_SYS_CONFIG0x00b0 #define HostCmd_CMD_UAP_BSS_START 0x00b1 #define HostCmd_CMD_UAP_BSS_STOP 0x00b2 diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index aa5b9a3..f20a09e 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -1159,6 +1159,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case HostCmd_CMD_UAP_STA_DEAUTH: break; + case HOST_CMD_APCMD_SYS_RESET: + break; case HostCmd_CMD_MEF_CFG: break; case HostCmd_CMD_COALESCE_CFG: diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index a4ae283..0a3297e 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -754,6 +754,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, break; case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: + case HOST_CMD_APCMD_SYS_RESET: cmd->command = cpu_to_le16(cmd_no); cmd->size = cpu_to_le16(S_DS_GEN); break; @@ -811,8 +812,13 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL, true)) { - mwifiex_dbg(priv->adapter, ERROR, - "Failed to stop the BSS\n"); + mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n"); + return -1; + } + + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n"); return -1; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/17] mwifiex: support AP reset after bss_stop
This would enable clearing of FW bss data structures when AP operations are stopped. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c| 7 +++ drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/fw.h | 1 + drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 ++ drivers/net/wireless/mwifiex/uap_cmd.c | 10 -- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 3a14d3a..d47799a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1725,6 +1725,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) return -1; } + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "Failed to reset BSS\n"); + return -1; + } + return 0; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a1de83f..b5033d1 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -574,6 +574,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: case HostCmd_CMD_UAP_STA_DEAUTH: + case HOST_CMD_APCMD_SYS_RESET: ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, cmd_oid, data_buf, cmd_ptr); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6a062dd..124120d 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -330,6 +330,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RSSI_INFO 0x00a4 #define HostCmd_CMD_FUNC_INIT 0x00a9 #define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa +#define HOST_CMD_APCMD_SYS_RESET 0x00af #define HostCmd_CMD_UAP_SYS_CONFIG0x00b0 #define HostCmd_CMD_UAP_BSS_START 0x00b1 #define HostCmd_CMD_UAP_BSS_STOP 0x00b2 diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index aa5b9a3..f20a09e 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -1159,6 +1159,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case HostCmd_CMD_UAP_STA_DEAUTH: break; + case HOST_CMD_APCMD_SYS_RESET: + break; case HostCmd_CMD_MEF_CFG: break; case HostCmd_CMD_COALESCE_CFG: diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index a4ae283..0a3297e 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -754,6 +754,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, break; case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: + case HOST_CMD_APCMD_SYS_RESET: cmd->command = cpu_to_le16(cmd_no); cmd->size = cpu_to_le16(S_DS_GEN); break; @@ -811,8 +812,13 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL, true)) { - mwifiex_dbg(priv->adapter, ERROR, - "Failed to stop the BSS\n"); + mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n"); + return -1; + } + + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n"); return -1; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/17] mwifiex: verbose logging for association failure messages
This patch adds more logging support for association failure - reason and states. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 15 +-- drivers/net/wireless/mwifiex/join.c | 30 +++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c404390..6a062dd 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -419,8 +419,12 @@ enum P2P_MODES { #define HS_CFG_COND_MAC_EVENT 0x0004 #define HS_CFG_COND_MULTICAST_DATA 0x0008 -#define MWIFIEX_TIMEOUT_FOR_AP_RESP0xfffc -#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 +#define ASSOC_ERR_AUTH_ERR_STA_FAILURE 0xFFFB +#define ASSOC_ERR_ASSOC_ERR_TIMEOUT0xFFFC +#define ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD +#define ASSOC_ERR_AUTH_MSG_UNHANDLED 0xFFFE +#define ASSOC_ERR_STA_FAILURE 0x + #define CMD_F_HOSTCMD (1 << 0) #define CMD_F_CANCELED (1 << 1) @@ -1151,6 +1155,13 @@ enum SNMP_MIB_INDEX { DOT11H_I = 10, }; +enum mwifiex_assocmd_failurepoint { + MWIFIEX_ASSOC_CMD_SUCCESS = 0, + MWIFIEX_ASSOC_CMD_FAILURE_ASSOC, + MWIFIEX_ASSOC_CMD_FAILURE_AUTH, + MWIFIEX_ASSOC_CMD_FAILURE_JOIN +}; + #define MAX_SNMP_BUF_SIZE 128 struct host_cmd_ds_802_11_snmp_mib { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 6208ef1..69a44bb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return 0; } +static const char *assoc_failure_reason_to_str(u16 cap_info) +{ + switch (cap_info) { + case ASSOC_ERR_AUTH_ERR_STA_FAILURE: + return "ASSOC_ERR_AUTH_ERR_STA_FAILURE"; + case ASSOC_ERR_AUTH_MSG_UNHANDLED: + return "ASSOC_ERR_AUTH_MSG_UNHANDLED"; + case ASSOC_ERR_ASSOC_ERR_TIMEOUT: + return "ASSOC_ERR_ASSOC_ERR_TIMEOUT"; + case ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED: + return "ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED"; + case ASSOC_ERR_STA_FAILURE: + return "ASSOC_ERR_STA_FAILURE"; + } + + return "Unknown failure"; +} /* * Association firmware command response handler * @@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, status_code, cap_info, le16_to_cpu(assoc_rsp->a_id)); - if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { - if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) + mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n", + assoc_failure_reason_to_str(cap_info)); + if (cap_info == ASSOC_ERR_ASSOC_ERR_TIMEOUT) { + if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) { ret = WLAN_STATUS_AUTH_TIMEOUT; - else + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: AUTH timeout\n"); + } else { ret = WLAN_STATUS_UNSPECIFIED_FAILURE; + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: UNSPECIFIED failure\n"); + } } else { ret = status_code; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/17] mwifiex: correct bss_type assignment
Correct bss_type assignment in add_virtual_interface. This would ensure correct operation in multiple station scenarios. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4eeceda..3a14d3a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2518,7 +2518,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.sta_intf; break; case NL80211_IFTYPE_AP: @@ -2544,7 +2544,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_UAP; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.uap_intf; priv->bss_mode = type; break; @@ -2580,7 +2580,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = MWIFIEX_BSS_ROLE_STA; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.p2p_intf; if (mwifiex_cfg80211_init_p2p_client(priv)) { memset(&priv->wdev, 0, sizeof(priv->wdev)); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/17] mwifiex: correct bss_type assignment
Correct bss_type assignment in add_virtual_interface. This would ensure correct operation in multiple station scenarios. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4eeceda..3a14d3a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2518,7 +2518,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.sta_intf; break; case NL80211_IFTYPE_AP: @@ -2544,7 +2544,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_UAP; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.uap_intf; priv->bss_mode = type; break; @@ -2580,7 +2580,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = MWIFIEX_BSS_ROLE_STA; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.p2p_intf; if (mwifiex_cfg80211_init_p2p_client(priv)) { memset(&priv->wdev, 0, sizeof(priv->wdev)); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/17] mwifiex: verbose logging for association failure messages
This patch adds more logging support for association failure - reason and states. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 15 +-- drivers/net/wireless/mwifiex/join.c | 30 +++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c404390..6a062dd 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -419,8 +419,12 @@ enum P2P_MODES { #define HS_CFG_COND_MAC_EVENT 0x0004 #define HS_CFG_COND_MULTICAST_DATA 0x0008 -#define MWIFIEX_TIMEOUT_FOR_AP_RESP0xfffc -#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 +#define ASSOC_ERR_AUTH_ERR_STA_FAILURE 0xFFFB +#define ASSOC_ERR_ASSOC_ERR_TIMEOUT0xFFFC +#define ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD +#define ASSOC_ERR_AUTH_MSG_UNHANDLED 0xFFFE +#define ASSOC_ERR_STA_FAILURE 0x + #define CMD_F_HOSTCMD (1 << 0) #define CMD_F_CANCELED (1 << 1) @@ -1151,6 +1155,13 @@ enum SNMP_MIB_INDEX { DOT11H_I = 10, }; +enum mwifiex_assocmd_failurepoint { + MWIFIEX_ASSOC_CMD_SUCCESS = 0, + MWIFIEX_ASSOC_CMD_FAILURE_ASSOC, + MWIFIEX_ASSOC_CMD_FAILURE_AUTH, + MWIFIEX_ASSOC_CMD_FAILURE_JOIN +}; + #define MAX_SNMP_BUF_SIZE 128 struct host_cmd_ds_802_11_snmp_mib { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 6208ef1..69a44bb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return 0; } +static const char *assoc_failure_reason_to_str(u16 cap_info) +{ + switch (cap_info) { + case ASSOC_ERR_AUTH_ERR_STA_FAILURE: + return "ASSOC_ERR_AUTH_ERR_STA_FAILURE"; + case ASSOC_ERR_AUTH_MSG_UNHANDLED: + return "ASSOC_ERR_AUTH_MSG_UNHANDLED"; + case ASSOC_ERR_ASSOC_ERR_TIMEOUT: + return "ASSOC_ERR_ASSOC_ERR_TIMEOUT"; + case ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED: + return "ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED"; + case ASSOC_ERR_STA_FAILURE: + return "ASSOC_ERR_STA_FAILURE"; + } + + return "Unknown failure"; +} /* * Association firmware command response handler * @@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, status_code, cap_info, le16_to_cpu(assoc_rsp->a_id)); - if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { - if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) + mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n", + assoc_failure_reason_to_str(cap_info)); + if (cap_info == ASSOC_ERR_ASSOC_ERR_TIMEOUT) { + if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) { ret = WLAN_STATUS_AUTH_TIMEOUT; - else + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: AUTH timeout\n"); + } else { ret = WLAN_STATUS_UNSPECIFIED_FAILURE; + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: UNSPECIFIED failure\n"); + } } else { ret = status_code; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/17] mwifiex: correct bss_type assignment
Correct bss_type assignment in add_virtual_interface. This would ensure correct operation in multiple station scenarios. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4eeceda..3a14d3a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2518,7 +2518,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.sta_intf; break; case NL80211_IFTYPE_AP: @@ -2544,7 +2544,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_UAP; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.uap_intf; priv->bss_mode = type; break; @@ -2580,7 +2580,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = MWIFIEX_BSS_ROLE_STA; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.p2p_intf; if (mwifiex_cfg80211_init_p2p_client(priv)) { memset(&priv->wdev, 0, sizeof(priv->wdev)); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/17] mwifiex: correct bss_type assignment
Correct bss_type assignment in add_virtual_interface. This would ensure correct operation in multiple station scenarios. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4eeceda..3a14d3a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2518,7 +2518,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.sta_intf; break; case NL80211_IFTYPE_AP: @@ -2544,7 +2544,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_UAP; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.uap_intf; priv->bss_mode = type; break; @@ -2580,7 +2580,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = MWIFIEX_BSS_ROLE_STA; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.p2p_intf; if (mwifiex_cfg80211_init_p2p_client(priv)) { memset(&priv->wdev, 0, sizeof(priv->wdev)); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: pull request: iwlwifi 2015-05-28
"Grumbach, Emmanuel" writes: > as we talked, here is the pull request for 4.1. > Thanks. > > The following changes since commit 292208914d8ca5a41cf68c2f1d2810a2ea2044e9: > > iwlwifi: mvm: avoid use-after-free on iwl_mvm_d0i3_enable_tx() (2015-05-21 > 22:36:46 +0300) > > are available in the git repository at: > > https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git > tags/iwlwifi-for-kalle-2015-05-28 Thanks, pulled. -- Kalle Valo -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/2] nl80211: Add support to configure low ack threshold
On Thu, 2015-05-28 at 11:55 +0530, Rajkumar Manoharan wrote: > @@ -837,6 +839,7 @@ struct station_parameters { > u8 supported_oper_classes_len; > u8 opmode_notif; > bool opmode_notif_used; > + u16 low_ack_threshold; This cannot work, it leaves no way to detect "no change"; you need to add that, document it and also implement it in the mac80211 patch. johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/17] mwifiex: do not decrease tx_pending for AMSDU packet once more
From: Xinming Hu Negative adapter->tx_pending is observed while running data traffic, because tx_pending is decreased once more for AMSDU packet. since tx_pending have been decreased for all the source MSDU packets, we don't need to update once more for AMSDU packet. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/txrx.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index c4c7d8d..5ed9b79 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -319,11 +319,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, priv->stats.tx_errors++; } - if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) { + if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) atomic_dec_return(&adapter->pending_bridged_pkts); - if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) - goto done; - } + + if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT) + goto done; if (aggr) /* For skb_aggr, do not wake up tx queue */ -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 16/17] mwifiex: using right tid for addressing ra_list
From: Xinming Hu This patch fixes issue with the accessing correct ra_list by downgrading corresponding tid number. Alternatively, ra lists are created in mwifiex_wmm_add_buf_txqueue using downgraded tid number. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/11n.c | 11 --- drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 - 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 8422986..4d8ef49 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -156,7 +156,7 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { - int tid; + int tid, tid_down; struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; struct mwifiex_ra_list_tbl *ra_list; @@ -167,7 +167,9 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK) >> BLOCKACKPARAM_TID_POS; - ra_list = mwifiex_wmm_get_ralist_node(priv, tid, add_ba_rsp-> + + tid_down = mwifiex_wmm_downgrade_tid(priv, tid); + ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, add_ba_rsp-> peer_mac_addr); if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) { if (ra_list) { @@ -530,13 +532,16 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, struct mwifiex_tx_ba_stream_tbl *new_node; struct mwifiex_ra_list_tbl *ra_list; unsigned long flags; + int tid_down; if (!mwifiex_get_ba_tbl(priv, tid, ra)) { new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), GFP_ATOMIC); if (!new_node) return; - ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra); + + tid_down = mwifiex_wmm_downgrade_tid(priv, tid); + ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, ra); if (ra_list) { ra_list->ba_status = ba_status; ra_list->amsdu_in_ampdu = false; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 39d7a95..64401a7 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -663,6 +663,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, struct mwifiex_ra_list_tbl *ra_list; u8 cleanup_rx_reorder_tbl; unsigned long flags; + int tid_down; if (type == TYPE_DELBA_RECEIVE) cleanup_rx_reorder_tbl = (initiator) ? true : false; @@ -688,7 +689,9 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, "event: TID, RA not found in table\n"); return; } - ra_list = mwifiex_wmm_get_ralist_node(priv, tid, peer_mac); + + tid_down = mwifiex_wmm_downgrade_tid(priv, tid); + ra_list = mwifiex_wmm_get_ralist_node(priv, tid_down, peer_mac); if (ra_list) { ra_list->amsdu_in_ampdu = false; ra_list->ba_status = BA_SETUP_NONE; -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/17] mwifiex: update AP WMM settings from BSS_START event
This was missing and would cause issue in WMM handling. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/uap_event.c | 63 1 file changed, 63 insertions(+) diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index 06ce3fe..fee05f5 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c @@ -21,8 +21,70 @@ #include "main.h" #include "11n.h" +#define MWIFIEX_BSS_START_EVT_FIX_SIZE12 +static int mwifiex_check_uap_capabilties(struct mwifiex_private *priv, +struct sk_buff *event) +{ + int evt_len; + u8 *curr; + u16 tlv_len; + struct mwifiex_ie_types_data *tlv_hdr; + struct ieee_types_wmm_parameter *wmm_param_ie = NULL; + int mask = IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK; + + priv->wmm_enabled = false; + skb_pull(event, MWIFIEX_BSS_START_EVT_FIX_SIZE); + evt_len = event->len; + curr = event->data; + + mwifiex_dbg_dump(priv->adapter, EVT_D, "uap capabilties:", +event->data, event->len); + + while ((evt_len >= sizeof(tlv_hdr->header))) { + tlv_hdr = (struct mwifiex_ie_types_data *)curr; + tlv_len = le16_to_cpu(tlv_hdr->header.len); + + if (evt_len < tlv_len + sizeof(tlv_hdr->header)) + break; + + switch (le16_to_cpu(tlv_hdr->header.type)) { + case WLAN_EID_HT_CAPABILITY: + priv->ap_11n_enabled = true; + break; + + case WLAN_EID_VHT_CAPABILITY: + priv->ap_11ac_enabled = true; + break; + case WLAN_EID_VENDOR_SPECIFIC: + /* Point the regular IEEE IE 2 bytes into the Marvell IE +* and setup the IEEE IE type and length byte fields +*/ + wmm_param_ie = (void *)(curr + 2); + wmm_param_ie->vend_hdr.len = (u8)tlv_len; + wmm_param_ie->vend_hdr.element_id = + WLAN_EID_VENDOR_SPECIFIC; + mwifiex_dbg(priv->adapter, EVENT, + "info: check uap capabilities:\t" + "wmm parameter set count: %d\n", + wmm_param_ie->qos_info_bitmap & mask); + + mwifiex_wmm_setup_ac_downgrade(priv); + priv->wmm_enabled = true; + mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie); + break; + + default: + break; + } + + curr += (tlv_len + sizeof(tlv_hdr->header)); + evt_len -= (tlv_len + sizeof(tlv_hdr->header)); + } + + return 0; +} /* * This function handles AP interface specific events generated by firmware. @@ -134,6 +196,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) ETH_ALEN); if (priv->hist_data) mwifiex_hist_data_reset(priv); + mwifiex_check_uap_capabilties(priv, adapter->event_skb); break; case EVENT_UAP_MIC_COUNTERMEASURES: /* For future development */ -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/17] mwifiex: advertise PS ON by default support to cfg80211
This would enable driver to enter powersave as soon as connected. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cfg80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 1226555..3d3794f 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -3685,7 +3685,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_HAS_CHANNEL_SWITCH; + WIPHY_FLAG_HAS_CHANNEL_SWITCH | + WIPHY_FLAG_PS_ON_BY_DEFAULT; if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/17] mwifiex: add cfg80211 get_channel handler
From: Xinming Hu This patch add cfg80211 get_channel handler for mwifiex. The handler will be used to report current channel to upper layer utility. Signed-off-by: Xinming Hu Signed-off-by: Cathy Luo Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/11h.c | 2 +- drivers/net/wireless/mwifiex/cfg80211.c | 58 - drivers/net/wireless/mwifiex/main.h | 5 ++- drivers/net/wireless/mwifiex/uap_cmd.c | 5 ++- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c index bb2ffd9..71a1b58 100644 --- a/drivers/net/wireless/mwifiex/11h.c +++ b/drivers/net/wireless/mwifiex/11h.c @@ -305,7 +305,7 @@ void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work) return; } - mwifiex_uap_set_channel(bss_cfg, priv->dfs_chandef); + mwifiex_uap_set_channel(priv, bss_cfg, priv->dfs_chandef); if (mwifiex_config_start_uap(priv, bss_cfg)) { mwifiex_dbg(priv->adapter, ERROR, diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index fb93e13..ddeb919 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -67,6 +67,22 @@ u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type) } } +/* This function maps IEEE HT secondary channel type to NL80211 channel type + */ +u8 mwifiex_sec_chan_offset_to_chan_type(u8 second_chan_offset) +{ + switch (second_chan_offset) { + case IEEE80211_HT_PARAM_CHA_SEC_NONE: + return NL80211_CHAN_HT20; + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + return NL80211_CHAN_HT40PLUS; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + return NL80211_CHAN_HT40MINUS; + default: + return NL80211_CHAN_HT20; + } +} + /* * This function checks whether WEP is set. */ @@ -1785,7 +1801,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, return -EINVAL; } - mwifiex_uap_set_channel(bss_cfg, params->chandef); + mwifiex_uap_set_channel(priv, bss_cfg, params->chandef); mwifiex_set_uap_rates(bss_cfg, params); if (mwifiex_set_secure_params(priv, bss_cfg, params)) { @@ -3373,6 +3389,45 @@ mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, return 0; } +static int mwifiex_cfg80211_get_channel(struct wiphy *wiphy, + struct wireless_dev *wdev, + struct cfg80211_chan_def *chandef) +{ + struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); + struct mwifiex_bssdescriptor *curr_bss; + struct ieee80211_channel *chan; + u8 second_chan_offset; + enum nl80211_channel_type chan_type; + enum ieee80211_band band; + int freq; + int ret = -ENODATA; + + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP && + cfg80211_chandef_valid(&priv->bss_chandef)) { + *chandef = priv->bss_chandef; + ret = 0; + } else if (priv->media_connected) { + curr_bss = &priv->curr_bss_params.bss_descriptor; + band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); + freq = ieee80211_channel_to_frequency(curr_bss->channel, band); + chan = ieee80211_get_channel(wiphy, freq); + + if (curr_bss->bcn_ht_oper) { + second_chan_offset = curr_bss->bcn_ht_oper->ht_param & + IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + chan_type = mwifiex_sec_chan_offset_to_chan_type + (second_chan_offset); + cfg80211_chandef_create(chandef, chan, chan_type); + } else { + cfg80211_chandef_create(chandef, chan, + NL80211_CHAN_NO_HT); + } + ret = 0; + } + + return ret; +} + static int mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy, struct net_device *dev, @@ -3478,6 +3533,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = { .tdls_oper = mwifiex_cfg80211_tdls_oper, .add_station = mwifiex_cfg80211_add_station, .change_station = mwifiex_cfg80211_change_station, + .get_channel = mwifiex_cfg80211_get_channel, .start_radar_detection = mwifiex_cfg80211_start_radar_detection, .channel_switch = mwifiex_cfg80211_channel_switch, }; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3ac18c6..88d3779 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -642,6 +642,7 @@ struct mwifiex_private {
[PATCH 12/17] mwifiex: support downloading IEs from tail
Earlier only RSN, WPA and channel switch IEs from tail buffer would be downloaded to FW. This patch adds support for downloading more IEs from tail buffer. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/ie.c | 102 ++ 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c index f3b6ed2..0ba8945 100644 --- a/drivers/net/wireless/mwifiex/ie.c +++ b/drivers/net/wireless/mwifiex/ie.c @@ -320,63 +320,81 @@ done: /* This function parses head and tail IEs, from cfg80211_beacon_data and sets * these IE to FW. */ -static int mwifiex_uap_set_head_tail_ies(struct mwifiex_private *priv, -struct cfg80211_beacon_data *info) +static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, + struct cfg80211_beacon_data *info) { struct mwifiex_ie *gen_ie; - struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL; - struct ieee_types_header *chsw_ie = NULL; + struct ieee_types_header *hdr; + struct ieee80211_vendor_ie *vendorhdr; u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; - const u8 *vendor_ie; + int left_len, parsed_len = 0; + + if (!info->tail || !info->tail_len) + return 0; gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL); if (!gen_ie) return -ENOMEM; - gen_ie->ie_index = cpu_to_le16(gen_idx); - gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON | - MGMT_MASK_PROBE_RESP | - MGMT_MASK_ASSOC_RESP); - if (info->tail && info->tail_len) { - rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, - info->tail, info->tail_len); - if (rsn_ie) { - memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2); - ie_len = rsn_ie->len + 2; - gen_ie->ie_length = cpu_to_le16(ie_len); + left_len = info->tail_len; + + /* Many IEs are generated in FW by parsing bss configuration. +* Let's not add them here; else we may end up duplicating these IEs +*/ + while (left_len > sizeof(struct ieee_types_header)) { + hdr = (void *)(info->tail + parsed_len); + switch (hdr->element_id) { + case WLAN_EID_SSID: + case WLAN_EID_SUPP_RATES: + case WLAN_EID_COUNTRY: + case WLAN_EID_PWR_CONSTRAINT: + case WLAN_EID_EXT_SUPP_RATES: + case WLAN_EID_HT_CAPABILITY: + case WLAN_EID_HT_OPERATION: + case WLAN_EID_VHT_CAPABILITY: + case WLAN_EID_VHT_OPERATION: + case WLAN_EID_VENDOR_SPECIFIC: + break; + default: + memcpy(gen_ie->ie_buffer + ie_len, hdr, + hdr->len + sizeof(struct ieee_types_header)); + ie_len += hdr->len + sizeof(struct ieee_types_header); + break; } + left_len -= hdr->len + sizeof(struct ieee_types_header); + parsed_len += hdr->len + sizeof(struct ieee_types_header); + } - vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, + /* parse only WPA vendor IE from tail, WMM IE is configured by +* bss_config command +*/ + vendorhdr = (void *)cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, WLAN_OUI_TYPE_MICROSOFT_WPA, - info->tail, - info->tail_len); - if (vendor_ie) { - wpa_ie = (struct ieee_types_header *)vendor_ie; - memcpy(gen_ie->ie_buffer + ie_len, - wpa_ie, wpa_ie->len + 2); - ie_len += wpa_ie->len + 2; - gen_ie->ie_length = cpu_to_le16(ie_len); - } + info->tail, info->tail_len); + if (vendorhdr) { + memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, + vendorhdr->len + sizeof(struct ieee_types_header)); + ie_len += vendorhdr->len + sizeof(struct ieee_types_header); + } - chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH, - info->tail, info->tail_len); - if (chsw_ie) { - memcpy(gen_ie->ie_buffer + ie_len, - chsw_ie, chsw_ie->len + 2); - ie_len += chsw_ie->len + 2; - ge
[PATCH 05/17] mwifiex: reset 11h active flag when chandef does not require dfs
This patch fixes an issue where we were still setting 11h_active flag to true for channel defs where DFS is not required. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index d47799a..fb93e13 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1820,7 +1820,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, "Failed to disable 11h extensions!!"); return -1; } - priv->state_11h.is_11h_active = true; + priv->state_11h.is_11h_active = false; } if (mwifiex_config_start_uap(priv, bss_cfg)) { -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/17] mwifiex: add sta_list firmware command
From: Xinming Hu This patch add sta_list firmware command, which can be used to get power status and rssi for the stations associated to mwifiex micro AP. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/fw.h | 14 ++ drivers/net/wireless/mwifiex/sta_cmdresp.c | 24 drivers/net/wireless/mwifiex/uap_cmd.c | 1 + 4 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index b5033d1..b8f6aa1 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -575,6 +575,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_STOP: case HostCmd_CMD_UAP_STA_DEAUTH: case HOST_CMD_APCMD_SYS_RESET: + case HOSTCMD_CMD_UAP_STA_LIST: ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, cmd_oid, data_buf, cmd_ptr); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 1a87188..72e471b 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -334,6 +334,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_UAP_SYS_CONFIG0x00b0 #define HostCmd_CMD_UAP_BSS_START 0x00b1 #define HostCmd_CMD_UAP_BSS_STOP 0x00b2 +#define HOSTCMD_CMD_UAP_STA_LIST 0x00b3 #define HostCmd_CMD_UAP_STA_DEAUTH0x00b5 #define HostCmd_CMD_11N_CFG 0x00cd #define HostCmd_CMD_11N_ADDBA_REQ 0x00ce @@ -1465,6 +1466,18 @@ struct host_cmd_ds_sta_deauth { __le16 reason; } __packed; +struct mwifiex_ie_types_sta_info { + struct mwifiex_ie_types_header header; + u8 mac[ETH_ALEN]; + u8 power_mfg_status; + s8 rssi; +}; + +struct host_cmd_ds_sta_list { + u16 sta_count; + u8 tlv[0]; +} __packed; + struct mwifiex_ie_types_pwr_capability { struct mwifiex_ie_types_header header; s8 min_pwr; @@ -1994,6 +2007,7 @@ struct host_cmd_ds_command { struct host_cmd_ds_802_11_subsc_evt subsc_evt; struct host_cmd_ds_sys_config uap_sys_config; struct host_cmd_ds_sta_deauth sta_deauth; + struct host_cmd_ds_sta_list sta_list; struct host_cmd_11ac_vht_cfg vht_cfg; struct host_cmd_ds_coalesce_cfg coalesce_cfg; struct host_cmd_ds_tdls_oper tdls_oper; diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index f20a09e..166e7de 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -958,6 +958,27 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv, return 0; } +static int mwifiex_ret_uap_sta_list(struct mwifiex_private *priv, + struct host_cmd_ds_command *resp) +{ + struct host_cmd_ds_sta_list *sta_list = + &resp->params.sta_list; + struct mwifiex_ie_types_sta_info *sta_info = (void *)&sta_list->tlv; + int i; + struct mwifiex_sta_node *sta_node; + + for (i = 0; i < sta_list->sta_count; i++) { + sta_node = mwifiex_get_sta_entry(priv, sta_info->mac); + if (unlikely(!sta_node)) + continue; + + sta_node->stats.rssi = sta_info->rssi; + sta_info++; + } + + return 0; +} + /* This function handles the command response of set_cfg_data */ static int mwifiex_ret_cfg_data(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) @@ -1148,6 +1169,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case HostCmd_CMD_UAP_SYS_CONFIG: break; + case HOSTCMD_CMD_UAP_STA_LIST: + ret = mwifiex_ret_uap_sta_list(priv, resp); + break; case HostCmd_CMD_UAP_BSS_START: adapter->tx_lock_flag = false; adapter->pps_uapsd_mode = false; diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 68fbdf6..865b363 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -755,6 +755,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: case HOST_CMD_APCMD_SYS_RESET: + case HOSTCMD_CMD_UAP_STA_LIST: cmd->command = cpu_to_le16(cmd_no);
[PATCH 08/17] mwifiex: maintain station statistic in uap mode
From: Xinming Hu This patch maintain statistic information for the stations associated to the mwifiex micro AP, include tx/rx bytes/packets, signal strength, tx bitrate. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/fw.h | 7 ++- drivers/net/wireless/mwifiex/main.h | 13 + drivers/net/wireless/mwifiex/txrx.c | 13 +++-- drivers/net/wireless/mwifiex/uap_txrx.c | 18 +- drivers/net/wireless/mwifiex/util.c | 13 + 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 124120d..1a87188 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -632,7 +632,12 @@ struct uap_rxpd { __le16 rx_pkt_type; __le16 seq_num; u8 priority; - u8 reserved1; + u8 rx_rate; + s8 snr; + s8 nf; + u8 ht_info; + u8 reserved[3]; + u8 flags; }; struct mwifiex_fw_chan_stats { diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 88d3779..837e610 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -741,6 +741,18 @@ struct mwifiex_tdls_capab { struct ieee80211_vht_operation vhtoper; }; +struct mwifiex_station_stats { + u64 last_rx; + s8 rssi; + u64 rx_bytes; + u64 tx_bytes; + u32 rx_packets; + u32 tx_packets; + u32 tx_failed; + u8 last_tx_rate; + u8 last_tx_htinfo; +}; + /* This is AP/TDLS specific structure which stores information * about associated/peer STA */ @@ -755,6 +767,7 @@ struct mwifiex_sta_node { u16 max_amsdu; u8 tdls_status; struct mwifiex_tdls_capab tdls_cap; + struct mwifiex_station_stats stats; }; struct mwifiex_auto_tdls_peer { diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 28dcc84..c4c7d8d 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -88,13 +88,22 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, struct mwifiex_adapter *adapter = priv->adapter; u8 *head_ptr; struct txpd *local_tx_pd = NULL; + struct mwifiex_sta_node *dest_node; + struct ethhdr *hdr = (void *)skb->data; hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN; - if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) + if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) { + dest_node = mwifiex_get_sta_entry(priv, hdr->h_dest); + if (dest_node) { + dest_node->stats.tx_bytes += skb->len; + dest_node->stats.tx_packets++; + } + head_ptr = mwifiex_process_uap_txpd(priv, skb); - else + } else { head_ptr = mwifiex_process_sta_txpd(priv, skb); + } if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) { skb_queue_tail(&adapter->tx_data_q, skb); diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c index 61c52fd..8766741 100644 --- a/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/mwifiex/uap_txrx.c @@ -97,6 +97,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, struct mwifiex_txinfo *tx_info; int hdr_chop; struct ethhdr *p_ethhdr; + struct mwifiex_sta_node *src_node; uap_rx_pd = (struct uap_rxpd *)(skb->data); rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); @@ -180,6 +181,15 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, tx_info->bss_type = priv->bss_type; tx_info->flags |= MWIFIEX_BUF_FLAG_BRIDGED_PKT; + src_node = mwifiex_get_sta_entry(priv, rx_pkt_hdr->eth803_hdr.h_source); + if (src_node) { + src_node->stats.last_rx = jiffies; + src_node->stats.rx_bytes += skb->len; + src_node->stats.rx_packets++; + src_node->stats.last_tx_rate = uap_rx_pd->rx_rate; + src_node->stats.last_tx_htinfo = uap_rx_pd->ht_info; + } + if (is_unicast_ether_addr(rx_pkt_hdr->eth803_hdr.h_dest)) { /* Update bridge packet statistics as the * packet is not going to kernel/upper layer. @@ -275,6 +285,8 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_private *priv, rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); + ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source); + if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) + le16_to_cpu(uap_rx_pd->rx_pkt_length)) > (u16) skb->len) { mwifi
[PATCH 10/17] mwifiex: dump station support in uap mode
From: Xinming Hu This patch extend cfg80211 dump_station handler, support for dump stations associated to mwifiex micro AP. Signed-off-by: Xinming Hu Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cfg80211.c | 51 + 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ddeb919..16528c1 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1229,6 +1229,7 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo, */ static int mwifiex_dump_station_info(struct mwifiex_private *priv, + struct mwifiex_sta_node *node, struct station_info *sinfo) { u32 rate; @@ -1238,6 +1239,30 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, BIT(NL80211_STA_INFO_TX_BITRATE) | BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG); + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { + if (!node) + return -ENOENT; + + sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME) | + BIT(NL80211_STA_INFO_TX_FAILED); + sinfo->inactive_time = + jiffies_to_msecs(jiffies - node->stats.last_rx); + + sinfo->signal = node->stats.rssi; + sinfo->signal_avg = node->stats.rssi; + sinfo->rx_bytes = node->stats.rx_bytes; + sinfo->tx_bytes = node->stats.tx_bytes; + sinfo->rx_packets = node->stats.rx_packets; + sinfo->tx_packets = node->stats.tx_packets; + sinfo->tx_failed = node->stats.tx_failed; + + mwifiex_parse_htinfo(priv, node->stats.last_tx_htinfo, +&sinfo->txrate); + sinfo->txrate.legacy = node->stats.last_tx_rate * 5; + + return 0; + } + /* Get signal information from the firmware */ if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, HostCmd_ACT_GEN_GET, 0, NULL, true)) { @@ -1304,7 +1329,7 @@ mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, if (memcmp(mac, priv->cfg_bssid, ETH_ALEN)) return -ENOENT; - return mwifiex_dump_station_info(priv, sinfo); + return mwifiex_dump_station_info(priv, NULL, sinfo); } /* @@ -1315,13 +1340,29 @@ mwifiex_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + static struct mwifiex_sta_node *node; - if (!priv->media_connected || idx) - return -ENOENT; + if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && + priv->media_connected && idx == 0) { + ether_addr_copy(mac, priv->cfg_bssid); + return mwifiex_dump_station_info(priv, NULL, sinfo); + } else if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { + mwifiex_send_cmd(priv, HOSTCMD_CMD_UAP_STA_LIST, +HostCmd_ACT_GEN_GET, 0, NULL, true); + + if (node && (&node->list == &priv->sta_list)) { + node = NULL; + return -ENOENT; + } - memcpy(mac, priv->cfg_bssid, ETH_ALEN); + node = list_prepare_entry(node, &priv->sta_list, list); + list_for_each_entry_continue(node, &priv->sta_list, list) { + ether_addr_copy(mac, node->mac_addr); + return mwifiex_dump_station_info(priv, node, sinfo); + } + } - return mwifiex_dump_station_info(priv, sinfo); + return -ENOENT; } static int -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/17] mwifiex: parse power constraint IE from Tail
This patch adds support to parse power constraint IEs from Tail buffer. This power constraint is then set to FW during bss_config download. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/cfg80211.c | 3 +++ drivers/net/wireless/mwifiex/fw.h | 6 ++ drivers/net/wireless/mwifiex/ioctl.h| 1 + drivers/net/wireless/mwifiex/main.h | 3 +++ drivers/net/wireless/mwifiex/uap_cmd.c | 27 +++ 5 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 16528c1..1226555 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1867,6 +1867,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, mwifiex_set_wmm_params(priv, bss_cfg, params); + if (mwifiex_is_11h_active(priv)) + mwifiex_set_tpc_params(priv, bss_cfg, params); + if (mwifiex_is_11h_active(priv) && !cfg80211_chandef_dfs_required(wiphy, ¶ms->chandef, priv->bss_mode)) { diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 72e471b..f9dc715 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -128,6 +128,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_UAP_SSID 0x #define TLV_TYPE_UAP_RATES 0x0001 +#define TLV_TYPE_PWR_CONSTRAINT0x0020 #define PROPRIETARY_TLV_BASE_ID 0x0100 #define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) @@ -1780,6 +1781,11 @@ struct host_cmd_tlv_ageout_timer { __le32 sta_ao_timer; } __packed; +struct host_cmd_tlv_power_constraint { + struct mwifiex_ie_types_header header; + u8 constraint; +} __packed; + struct host_cmd_ds_version_ext { u8 version_str_sel; char version_str[128]; diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index 6f11a25..4f0174c 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -113,6 +113,7 @@ struct mwifiex_uap_bss_param { u32 sta_ao_timer; u32 ps_sta_ao_timer; u8 qos_info; + u8 power_constraint; struct mwifiex_types_wmm_info wmm_info; }; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 837e610..d92c527 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1149,6 +1149,9 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv, void mwifiex_set_vht_params(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_ap_settings *params); +void mwifiex_set_tpc_params(struct mwifiex_private *priv, + struct mwifiex_uap_bss_param *bss_cfg, + struct cfg80211_ap_settings *params); void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg, struct cfg80211_ap_settings *params); void mwifiex_set_vht_width(struct mwifiex_private *priv, diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 865b363..61e8bf3 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -222,6 +222,23 @@ void mwifiex_set_vht_params(struct mwifiex_private *priv, return; } +/* This function updates 11ac related parameters from IE + * and sets them into bss_config structure. + */ +void mwifiex_set_tpc_params(struct mwifiex_private *priv, + struct mwifiex_uap_bss_param *bss_cfg, + struct cfg80211_ap_settings *params) +{ + const u8 *tpc_ie; + + tpc_ie = cfg80211_find_ie(WLAN_EID_TPC_REQUEST, params->beacon.tail, + params->beacon.tail_len); + if (tpc_ie) + bss_cfg->power_constraint = *(tpc_ie + 2); + else + bss_cfg->power_constraint = 0; +} + /* Enable VHT only when cfg80211_ap_settings has VHT IE. * Otherwise disable VHT. */ @@ -466,6 +483,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_auth_type *auth_type; struct host_cmd_tlv_rates *tlv_rates; struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer; + struct host_cmd_tlv_power_constraint *pwr_ct; struct mwifiex_ie_types_htcap *htcap; struct mwifiex_ie_types_wmmcap *wmm_cap; struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; @@ -644,6 +662,15 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) tlv += sizeof(*ao_timer); } + if (bss_cfg->power_constraint) { + pwr_ct = (void *)tlv; +
[PATCH 13/17] mwifiex: drop block-ack action frames
We often see ADDBA request packets coming to driver because driver has registered for action frame subtype. We dont process BA action frames in host. Drop such frames. Signed-off-by: Avinash Patil Signed-off-by: Xinmin Hu Signed-off-by: Cathy Luo --- drivers/net/wireless/mwifiex/util.c | 43 + 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 2e3dc07..790e619 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -329,7 +329,7 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len, struct rxpd *rx_pd) { u16 stype; - u8 category, action_code; + u8 category, action_code, *addr2; struct ieee80211_hdr *ieee_hdr = (void *)payload; stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE); @@ -337,21 +337,35 @@ mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len, switch (stype) { case IEEE80211_STYPE_ACTION: category = *(payload + sizeof(struct ieee80211_hdr)); - action_code = *(payload + sizeof(struct ieee80211_hdr) + 1); - if (category == WLAN_CATEGORY_PUBLIC && - action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { + switch (category) { + case WLAN_CATEGORY_PUBLIC: + action_code = *(payload + sizeof(struct ieee80211_hdr) + + 1); + if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { + addr2 = ieee_hdr->addr2; + mwifiex_dbg(priv->adapter, INFO, + "TDLS discovery response %pM nf=%d, snr=%d\n", + addr2, rx_pd->nf, rx_pd->snr); + mwifiex_auto_tdls_update_peer_signal(priv, +addr2, +rx_pd->snr, +rx_pd->nf); + } + break; + case WLAN_CATEGORY_BACK: + /*we dont indicate BACK action frames to cfg80211*/ + mwifiex_dbg(priv->adapter, INFO, + "drop BACK action frames"); + return -1; + default: mwifiex_dbg(priv->adapter, INFO, - "TDLS discovery response %pM nf=%d, snr=%d\n", - ieee_hdr->addr2, rx_pd->nf, rx_pd->snr); - mwifiex_auto_tdls_update_peer_signal(priv, -ieee_hdr->addr2, -rx_pd->snr, -rx_pd->nf); + "unknown public action frame category %d\n", + category); } - break; default: mwifiex_dbg(priv->adapter, INFO, - "unknown mgmt frame subtype %#x\n", stype); + "unknown mgmt frame subtype %#x\n", stype); + return 0; } return 0; @@ -387,8 +401,9 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv, ieee_hdr = (void *)skb->data; if (ieee80211_is_mgmt(ieee_hdr->frame_control)) { - mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr, - pkt_len, rx_pd); + if (mwifiex_parse_mgmt_packet(priv, (u8 *)ieee_hdr, + pkt_len, rx_pd)) + return -1; } /* Remove address4 */ memmove(skb->data + sizeof(struct ieee80211_hdr_3addr), -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/17] mwifiex: disable CAC upon radar detection event
This patch adds support to disable ongoing CAC in FW upon detecting radar during CAC period. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/11h.c | 30 ++ drivers/net/wireless/mwifiex/main.h | 2 ++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c index 65cd461..bb2ffd9 100644 --- a/drivers/net/wireless/mwifiex/11h.c +++ b/drivers/net/wireless/mwifiex/11h.c @@ -161,19 +161,38 @@ int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv, cr_req->chan_desc.chan_width = radar_params->chandef->width; cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms); - mwifiex_dbg(priv->adapter, MSG, - "11h: issuing DFS Radar check for channel=%d\n", - radar_params->chandef->chan->hw_value); + if (radar_params->cac_time_ms) + mwifiex_dbg(priv->adapter, MSG, + "11h: issuing DFS Radar check for channel=%d\n", + radar_params->chandef->chan->hw_value); + else + mwifiex_dbg(priv->adapter, MSG, "cancelling CAC\n"); return 0; } +int mwifiex_stop_radar_detection(struct mwifiex_private *priv, +struct cfg80211_chan_def *chandef) +{ + struct mwifiex_radar_params radar_params; + + memset(&radar_params, 0, sizeof(struct mwifiex_radar_params)); + radar_params.chandef = chandef; + radar_params.cac_time_ms = 0; + + return mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST, + HostCmd_ACT_GEN_SET, 0, &radar_params, true); +} + /* This function is to abort ongoing CAC upon stopping AP operations * or during unload. */ void mwifiex_abort_cac(struct mwifiex_private *priv) { if (priv->wdev.cac_started) { + if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef)) + mwifiex_dbg(priv->adapter, ERROR, + "failed to stop CAC in FW\n"); mwifiex_dbg(priv->adapter, MSG, "Aborting delayed work for CAC.\n"); cancel_delayed_work_sync(&priv->dfs_cac_work); @@ -245,6 +264,9 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv, if (le32_to_cpu(rdr_event->passed)) { mwifiex_dbg(priv->adapter, MSG, "radar detected; indicating kernel\n"); + if (mwifiex_stop_radar_detection(priv, &priv->dfs_chandef)) + mwifiex_dbg(priv->adapter, ERROR, + "Failed to stop CAC in FW\n"); cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef, GFP_KERNEL); mwifiex_dbg(priv->adapter, MSG, "regdomain: %d\n", @@ -252,7 +274,7 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv, mwifiex_dbg(priv->adapter, MSG, "radar detection type: %d\n", rdr_event->det_type); } else { - mwifiex_dbg(priv->adapter, ERROR, + mwifiex_dbg(priv->adapter, MSG, "false radar detection event!\n"); } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 5a6c1c7..3ac18c6 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -1473,6 +1473,8 @@ mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, void mwifiex_dfs_cac_work_queue(struct work_struct *work); void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work); void mwifiex_abort_cac(struct mwifiex_private *priv); +int mwifiex_stop_radar_detection(struct mwifiex_private *priv, +struct cfg80211_chan_def *chandef); int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv, struct sk_buff *skb); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/17] mwifiex: enable 11d after bss reset
BSS reset would reset all state information in FW. Issue 11d config command after reset to enabled 11d in FW. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/uap_cmd.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 0a3297e..56a4768 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -806,6 +806,8 @@ void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg, int mwifiex_config_start_uap(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_cfg) { + enum state_11d_t state_11d; + if (mwifiex_del_mgmt_ies(priv)) mwifiex_dbg(priv->adapter, ERROR, "Failed to delete mgmt IEs!\n"); @@ -830,6 +832,16 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, return -1; } + /* Send cmd to FW to enable 11D function */ + state_11d = ENABLE_11D; + if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, +HostCmd_ACT_GEN_SET, DOT11D_I, +&state_11d, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "11D: failed to enable 11D\n"); + return -1; + } + if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START, HostCmd_ACT_GEN_SET, 0, NULL, false)) { mwifiex_dbg(priv->adapter, ERROR, -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/17] mwifiex patches
This patch series mainly adds enhancements for mwifiex AP. With this series, we support verbose information in station dump command also inforamation about AP link. Another important enhancement is related to parsing IEs from Tail of beacon_data. Few issues seen during DFS testing are also fixed in this series. Patch series also includes some other misc patches. Avinash Patil (11): mwifiex: verbose logging for association failure messages mwifiex: correct bss_type assignment mwifiex: support AP reset after bss_stop mwifiex: enable 11d after bss reset mwifiex: reset 11h active flag when chandef does not require dfs mwifiex: disable CAC upon radar detection event mwifiex: parse power constraint IE from Tail mwifiex: support downloading IEs from tail mwifiex: drop block-ack action frames mwifiex: advertise PS ON by default support to cfg80211 mwifiex: update AP WMM settings from BSS_START event Xinming Hu (6): mwifiex: add cfg80211 get_channel handler mwifiex: maintain station statistic in uap mode mwifiex: add sta_list firmware command mwifiex: dump station support in uap mode mwifiex: using right tid for addressing ra_list mwifiex: do not decrease tx_pending for AMSDU packet once more drivers/net/wireless/mwifiex/11h.c | 32 +-- drivers/net/wireless/mwifiex/11n.c | 11 ++- drivers/net/wireless/mwifiex/11n_rxreorder.c | 5 +- drivers/net/wireless/mwifiex/cfg80211.c | 130 --- drivers/net/wireless/mwifiex/cmdevt.c| 2 + drivers/net/wireless/mwifiex/fw.h| 43 - drivers/net/wireless/mwifiex/ie.c| 102 - drivers/net/wireless/mwifiex/ioctl.h | 1 + drivers/net/wireless/mwifiex/join.c | 30 ++- drivers/net/wireless/mwifiex/main.h | 23 - drivers/net/wireless/mwifiex/sta_cmdresp.c | 26 ++ drivers/net/wireless/mwifiex/txrx.c | 21 +++-- drivers/net/wireless/mwifiex/uap_cmd.c | 55 +++- drivers/net/wireless/mwifiex/uap_event.c | 63 + drivers/net/wireless/mwifiex/uap_txrx.c | 18 +++- drivers/net/wireless/mwifiex/util.c | 56 +--- 16 files changed, 525 insertions(+), 93 deletions(-) -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/17] mwifiex: correct bss_type assignment
Correct bss_type assignment in add_virtual_interface. This would ensure correct operation in multiple station scenarios. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 4eeceda..3a14d3a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2518,7 +2518,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.sta_intf; break; case NL80211_IFTYPE_AP: @@ -2544,7 +2544,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_UAP; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.uap_intf; priv->bss_mode = type; break; @@ -2580,7 +2580,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_priority = MWIFIEX_BSS_ROLE_STA; priv->bss_role = MWIFIEX_BSS_ROLE_STA; priv->bss_started = 0; - priv->bss_num = 0; + priv->bss_num = adapter->curr_iface_comb.p2p_intf; if (mwifiex_cfg80211_init_p2p_client(priv)) { memset(&priv->wdev, 0, sizeof(priv->wdev)); -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/17] mwifiex: support AP reset after bss_stop
This would enable clearing of FW bss data structures when AP operations are stopped. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/cfg80211.c| 7 +++ drivers/net/wireless/mwifiex/cmdevt.c | 1 + drivers/net/wireless/mwifiex/fw.h | 1 + drivers/net/wireless/mwifiex/sta_cmdresp.c | 2 ++ drivers/net/wireless/mwifiex/uap_cmd.c | 10 -- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 3a14d3a..d47799a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1725,6 +1725,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) return -1; } + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, + "Failed to reset BSS\n"); + return -1; + } + return 0; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index a1de83f..b5033d1 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -574,6 +574,7 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no, case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: case HostCmd_CMD_UAP_STA_DEAUTH: + case HOST_CMD_APCMD_SYS_RESET: ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, cmd_oid, data_buf, cmd_ptr); diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6a062dd..124120d 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -330,6 +330,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RSSI_INFO 0x00a4 #define HostCmd_CMD_FUNC_INIT 0x00a9 #define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa +#define HOST_CMD_APCMD_SYS_RESET 0x00af #define HostCmd_CMD_UAP_SYS_CONFIG0x00b0 #define HostCmd_CMD_UAP_BSS_START 0x00b1 #define HostCmd_CMD_UAP_BSS_STOP 0x00b2 diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index aa5b9a3..f20a09e 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -1159,6 +1159,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; case HostCmd_CMD_UAP_STA_DEAUTH: break; + case HOST_CMD_APCMD_SYS_RESET: + break; case HostCmd_CMD_MEF_CFG: break; case HostCmd_CMD_COALESCE_CFG: diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index a4ae283..0a3297e 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -754,6 +754,7 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, break; case HostCmd_CMD_UAP_BSS_START: case HostCmd_CMD_UAP_BSS_STOP: + case HOST_CMD_APCMD_SYS_RESET: cmd->command = cpu_to_le16(cmd_no); cmd->size = cpu_to_le16(S_DS_GEN); break; @@ -811,8 +812,13 @@ int mwifiex_config_start_uap(struct mwifiex_private *priv, if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL, true)) { - mwifiex_dbg(priv->adapter, ERROR, - "Failed to stop the BSS\n"); + mwifiex_dbg(priv->adapter, ERROR, "Failed to stop the BSS\n"); + return -1; + } + + if (mwifiex_send_cmd(priv, HOST_CMD_APCMD_SYS_RESET, +HostCmd_ACT_GEN_SET, 0, NULL, true)) { + mwifiex_dbg(priv->adapter, ERROR, "Failed to reset BSS\n"); return -1; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/17] mwifiex: verbose logging for association failure messages
This patch adds more logging support for association failure - reason and states. Signed-off-by: Avinash Patil --- drivers/net/wireless/mwifiex/fw.h | 15 +-- drivers/net/wireless/mwifiex/join.c | 30 +++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c404390..6a062dd 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -419,8 +419,12 @@ enum P2P_MODES { #define HS_CFG_COND_MAC_EVENT 0x0004 #define HS_CFG_COND_MULTICAST_DATA 0x0008 -#define MWIFIEX_TIMEOUT_FOR_AP_RESP0xfffc -#define MWIFIEX_STATUS_CODE_AUTH_TIMEOUT 2 +#define ASSOC_ERR_AUTH_ERR_STA_FAILURE 0xFFFB +#define ASSOC_ERR_ASSOC_ERR_TIMEOUT0xFFFC +#define ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED 0xFFFD +#define ASSOC_ERR_AUTH_MSG_UNHANDLED 0xFFFE +#define ASSOC_ERR_STA_FAILURE 0x + #define CMD_F_HOSTCMD (1 << 0) #define CMD_F_CANCELED (1 << 1) @@ -1151,6 +1155,13 @@ enum SNMP_MIB_INDEX { DOT11H_I = 10, }; +enum mwifiex_assocmd_failurepoint { + MWIFIEX_ASSOC_CMD_SUCCESS = 0, + MWIFIEX_ASSOC_CMD_FAILURE_ASSOC, + MWIFIEX_ASSOC_CMD_FAILURE_AUTH, + MWIFIEX_ASSOC_CMD_FAILURE_JOIN +}; + #define MAX_SNMP_BUF_SIZE 128 struct host_cmd_ds_802_11_snmp_mib { diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 6208ef1..69a44bb 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -556,6 +556,23 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return 0; } +static const char *assoc_failure_reason_to_str(u16 cap_info) +{ + switch (cap_info) { + case ASSOC_ERR_AUTH_ERR_STA_FAILURE: + return "ASSOC_ERR_AUTH_ERR_STA_FAILURE"; + case ASSOC_ERR_AUTH_MSG_UNHANDLED: + return "ASSOC_ERR_AUTH_MSG_UNHANDLED"; + case ASSOC_ERR_ASSOC_ERR_TIMEOUT: + return "ASSOC_ERR_ASSOC_ERR_TIMEOUT"; + case ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED: + return "ASSOC_ERR_ASSOC_ERR_AUTH_REFUSED"; + case ASSOC_ERR_STA_FAILURE: + return "ASSOC_ERR_STA_FAILURE"; + } + + return "Unknown failure"; +} /* * Association firmware command response handler * @@ -656,11 +673,18 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, status_code, cap_info, le16_to_cpu(assoc_rsp->a_id)); - if (cap_info == MWIFIEX_TIMEOUT_FOR_AP_RESP) { - if (status_code == MWIFIEX_STATUS_CODE_AUTH_TIMEOUT) + mwifiex_dbg(priv->adapter, ERROR, "assoc failure: reason %s\n", + assoc_failure_reason_to_str(cap_info)); + if (cap_info == ASSOC_ERR_ASSOC_ERR_TIMEOUT) { + if (status_code == MWIFIEX_ASSOC_CMD_FAILURE_AUTH) { ret = WLAN_STATUS_AUTH_TIMEOUT; - else + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: AUTH timeout\n"); + } else { ret = WLAN_STATUS_UNSPECIFIED_FAILURE; + mwifiex_dbg(priv->adapter, ERROR, + "ASSOC_RESP: UNSPECIFIED failure\n"); + } } else { ret = status_code; } -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
pull-request: mac80211 2015-05-28
Hi Dave, Please excuse the quick succession with another pull request - Ben pointed out to me that a fix I'd applied on -next is actually needed on 4.1 - we'll have to live with it being in both I suppose. Sorry about that. johannes The following changes since commit f9dca80b98caac8b4bfb43a2edf1e9f877ccf322: mac80211: fix AP_VLAN crypto tailroom calculation (2015-05-20 15:10:11 +0200) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2015-05-28 for you to fetch changes up to 3a7af58faa7829faa26026c245d2a8a44e9605c5: mac80211: Fix mac80211.h docbook comments (2015-05-28 14:37:43 +0200) This just has a single docbook build fix. In my confusion I'd already sent the same fix for -next, but Ben Hutchings noted it's necessary in 4.1. Jonathan Corbet (1): mac80211: Fix mac80211.h docbook comments include/net/mac80211.h | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mac80211: fix kernel-doc comments in mac80211.h
On Thu, 2015-05-28 at 09:00 +0200, Johannes Berg wrote: > On Thu, 2015-05-28 at 00:30 +0100, Ben Hutchings wrote: > > On Wed, 2015-05-20 at 15:03 +0200, Johannes Berg wrote: > > > On Mon, 2015-05-18 at 23:39 +0300, andrey.konova...@linaro.org wrote: > > > > Commits a818292 "mac80211: convert rssi_callback() to event_callback()" > > > > and a940909 "mac80211: notify the driver about authentication status" > > > > added two errors and one warning when building docs for the mac80211 > > > > driver. Fix the kernel-doc comments so that the documentation targets > > > > could be built successfully again. > > > > > > This was already fixed. > > > > It's been one week and this is still broken in Linus's tree. There was > > a fix for some of the other warnings, but I don't see these errors fixed > > anywhere. > > Yeah, somehow I put this into my -next pile... Given how late we are, I > don't think I want to change that now though. It's a build failure so it should go upstream now. I ran into this while packaging Linux 4.1 for Debian, and had to debug and fix it again, so that's now three people who have had to spend time on this. Ben. -- Ben Hutchings It is a miracle that curiosity survives formal education. - Albert Einstein signature.asc Description: This is a digitally signed message part
Re: [PATCH] mac80211: fix kernel-doc comments in mac80211.h
On Thu, 2015-05-28 at 13:34 +0100, Ben Hutchings wrote: > It's a build failure so it should go upstream now. Ok, I was under the impression it's a warning. I guess I'll just have to send a copy of the commit to 4.1 then - git will sort out getting it twice I suppose. johannes -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct
On 28 May 2015 at 13:54, Arend van Spriel wrote: > On 05/28/15 13:37, Rafał Miłecki wrote: >> >> As we plan to add support for platform NVRAM we should store direct >> data pointer without the extra struct firmware layer. This will allow >> us to support other sources with the only requirement being u8 buffer. >> >> Signed-off-by: Rafał Miłecki >> Signed-off-by: Hante Meuleman >> Signed-off-by: Arend van Spriel >> --- >> Tested on router with BCM43602-s using >> /lib/firmware/brcm/brcmfmac43602-pcie.txt >> >> I've written this patch from scratch, it's inspired by the dropped: >> [PATCH 6/6] brcmfmac: Add support for host platform NVRAM loading. > > > Hi Rafał, > > So what is your goal here. The inspirational patch was dropped so it can be > resubmitted when the mips change it relies on has made its way upstream. So > I have to rebase the patch over here and your patch will just give me > conflicts during that rebase. So can we please wait or do you need this > change right now. The dropped patch will require rebasing/rewriting anyway. There were few changes to firmware.c already, I've few more planned, you'll have to drop some code form your patch (parts that will go into MIPS tree) and probably apply few changes as requested in comments. I also don't think it makes much sense to pause any development because of having some out-of-tree patch queued for later submitting. And after all, hey, look at the bright side! :) With this patch you'll have to maintain smaller amount of out-of-tree(-for-now) code :) So my goals are: 1) Have all required cleanups pushed mainline early. 2) Make it easier to main out-of-tree changes. The personal reason behind that is to add OpenWrt support for BCM43602 as early as possible. Having clean backports + tiny NVRAM patch make it much easier to do now, maintain and update in the future. -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] brcmfmac: support NVRAMs containing pci devpaths (instead of pcie)
Recently Broadcom added support for NVRAMs with entries for multiple PCIe devices. One of the supported formats is based on prefixes defined like: devpath0=pcie/1/4/ and entries like 0:foo=bar 0:baz=qux etc. Unfortunately there are also a bit older devices using different way of defining prefixes, e.g. SmartRG SR400ac (2 x BCM43602) with entries: devpath0=pci/1/1/ devpath1=pci/2/1 Broadcom stated this old format will never be used/supported by brcmfmac but given the simplicity of this patch I'll insist on supporting it. Signed-off-by: Rafał Miłecki --- drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c index b72df87..743f16b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c @@ -232,6 +232,8 @@ static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, u16 bus_nr) { /* Device path with a leading '=' key-value separator */ + char pci_path[] = "=pci/?/?"; + size_t pci_len; char pcie_path[] = "=pcie/?/?"; size_t pcie_len; @@ -251,6 +253,9 @@ static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, /* First search for the devpathX and see if it is the configuration * for domain_nr/bus_nr. Search complete nvp */ + snprintf(pci_path, sizeof(pci_path), "=pci/%d/%d", domain_nr, +bus_nr); + pci_len = strlen(pci_path); snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr, bus_nr); pcie_len = strlen(pcie_path); @@ -260,8 +265,9 @@ static void brcmf_fw_strip_multi_v1(struct nvram_parser *nvp, u16 domain_nr, /* Format: devpathX=pcie/Y/Z/ * Y = domain_nr, Z = bus_nr, X = virtual ID */ - if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && - (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) { + if (strncmp(&nvp->nvram[i], "devpath", 7) == 0 && + (!strncmp(&nvp->nvram[i + 8], pci_path, pci_len) || +!strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len))) { id = nvp->nvram[i + 7] - '0'; found = true; break; -- 1.8.4.5 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct
On 05/28/15 13:37, Rafał Miłecki wrote: As we plan to add support for platform NVRAM we should store direct data pointer without the extra struct firmware layer. This will allow us to support other sources with the only requirement being u8 buffer. Signed-off-by: Rafał Miłecki Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel --- Tested on router with BCM43602-s using /lib/firmware/brcm/brcmfmac43602-pcie.txt I've written this patch from scratch, it's inspired by the dropped: [PATCH 6/6] brcmfmac: Add support for host platform NVRAM loading. Hi Rafał, So what is your goal here. The inspirational patch was dropped so it can be resubmitted when the mips change it relies on has made its way upstream. So I have to rebase the patch over here and your patch will just give me conflicts during that rebase. So can we please wait or do you need this change right now. Regards, Arend --- drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 40 +++--- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c index 7ae6461..b72df87 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c @@ -43,7 +43,7 @@ enum nvram_parser_state { * struct nvram_parser - internal info for parser. * * @state: current parser state. - * @fwnv: input buffer being parsed. + * @data: input buffer being parsed. * @nvram: output buffer with parse result. * @nvram_len: lenght of parse result. * @line: current line. @@ -55,7 +55,7 @@ enum nvram_parser_state { */ struct nvram_parser { enum nvram_parser_state state; - const struct firmware *fwnv; + const u8 *data; u8 *nvram; u32 nvram_len; u32 line; @@ -91,7 +91,7 @@ static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp) { char c; - c = nvp->fwnv->data[nvp->pos]; + c = nvp->data[nvp->pos]; if (c == '\n') return COMMENT; if (is_whitespace(c)) @@ -115,16 +115,16 @@ static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp) enum nvram_parser_state st = nvp->state; char c; - c = nvp->fwnv->data[nvp->pos]; + c = nvp->data[nvp->pos]; if (c == '=') { /* ignore RAW1 by treating as comment */ - if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0) + if (strncmp(&nvp->data[nvp->entry], "RAW1", 4) == 0) st = COMMENT; else st = VALUE; - if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) + if (strncmp(&nvp->data[nvp->entry], "devpath", 7) == 0) nvp->multi_dev_v1 = true; - if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) + if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) nvp->multi_dev_v2 = true; } else if (!is_nvram_char(c) || c == ' ') { brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", @@ -145,11 +145,11 @@ brcmf_nvram_handle_value(struct nvram_parser *nvp) char *ekv; u32 cplen; - c = nvp->fwnv->data[nvp->pos]; + c = nvp->data[nvp->pos]; if (!is_nvram_char(c)) { /* key,value pair complete */ - ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; - skv = (u8 *)&nvp->fwnv->data[nvp->entry]; + ekv = (u8 *)&nvp->data[nvp->pos]; + skv = (u8 *)&nvp->data[nvp->entry]; cplen = ekv - skv; if (nvp->nvram_len + cplen + 1>= BRCMF_FW_MAX_NVRAM_SIZE) return END; @@ -170,7 +170,7 @@ brcmf_nvram_handle_comment(struct nvram_parser *nvp) { char *eoc, *sol; - sol = (char *)&nvp->fwnv->data[nvp->pos]; + sol = (char *)&nvp->data[nvp->pos]; eoc = strchr(sol, '\n'); if (!eoc) { eoc = strchr(sol, '\0'); @@ -201,17 +201,17 @@ static enum nvram_parser_state }; static int brcmf_init_nvram_parser(struct nvram_parser *nvp, - const struct firmware *nv) + const u8 *data, size_t data_len) { size_t size; memset(nvp, 0, sizeof(*nvp)); - nvp->fwnv = nv; + nvp->data = data; /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ - if (nv->size> BRCMF_FW_MAX_NVRAM_SIZE) + if (data_len> BRCMF_FW_MAX_NVRAM_SIZE) size = BRCMF_FW_MAX_NVRAM_SIZE; else - size = nv->size; + size = data_len; /* Alloc for extra 0 byte + roundup by 4 + length field */ size += 1 + 3 + sizeof(u32); nvp->nvram = kzalloc(size, GFP_KERNEL); @@ -356,
Re: [for-4.1] brcmfmac: avoid null pointer access whenbrcmf_msgbuf_get_pktid() fails
On 05/28/15 11:03, Kalle Valo wrote: Kalle Valo writes: The function brcmf_msgbuf_get_pktid() may return a NULL pointer so the callers should check the return pointer before accessing it to avoid the crash below (see [1]): brcmfmac: brcmf_msgbuf_get_pktid: Invalid packet id 273 (not in use) BUG: unable to handle kernel NULL pointer dereference at 0080 IP: [] skb_pull+0x5/0x50 PGD 0 Oops: [#1] PREEMPT SMP Modules linked in: pci_stub vboxpci(O) vboxnetflt(O) vboxnetadp(O) vboxdrv(O) snd_hda_codec_hdmi bnep mousedev hid_generic ushwmon msr ext4 crc16 mbcache jbd2 sd_mod uas usb_storage ahci libahci libata scsi_mod xhci_pci xhci_hcd usbcore usb_common CPU: 0 PID: 1661 Comm: irq/61-brcmf_pc Tainted: G O4.0.1-MacbookPro-ARCH #1 Hardware name: Apple Inc. MacBookPro12,1/Mac-E43C1C25D4880AD6, BIOS MBP121.88Z.0167.B02.1503241251 03/24/2015 task: 880264203cc0 ti: 88025ffe4000 task.ti: 88025ffe4000 RIP: 0010:[] [] skb_pull+0x5/0x50 RSP: 0018:88025ffe7d40 EFLAGS: 00010202 RAX: RBX: 88008a33c000 RCX: 0044 RDX: RSI: 004a RDI: RBP: 88025ffe7da8 R08: 0096 R09: 004a R10: R11: 048e R12: 88025ff14f00 R13: R14: 880263b48200 R15: 88008a33c000 FS: () GS:88026ec0() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 0080 CR3: 0180b000 CR4: 003407f0 Stack: a06aed74 88025ffe7dc8 880263b48270 880263b48278 05ea8802004a 000281014635 1720b2f6 88026ec116c0 880263b48200 0001 880263b4ae00 880264203cc0 Call Trace: [] ? brcmf_msgbuf_process_rx+0x404/0x480 [brcmfmac] [] ? irq_finalize_oneshot.part.30+0xf0/0xf0 [] brcmf_proto_msgbuf_rx_trigger+0x35/0xf0 [brcmfmac] [] brcmf_pcie_isr_thread_v2+0x8a/0x130 [brcmfmac] [] irq_thread_fn+0x20/0x50 [] irq_thread+0x13f/0x170 [] ? wake_threads_waitq+0x30/0x30 [] ? irq_thread_dtor+0xb0/0xb0 [] kthread+0xd8/0xf0 [] ? kthread_create_on_node+0x1c0/0x1c0 [] ret_from_fork+0x58/0x90 [] ? kthread_create_on_node+0x1c0/0x1c0 Code: 01 83 e2 f7 88 50 01 48 83 c4 08 5b 5d f3 c3 0f 1f 80 00 00 00 00 83 e2 f7 88 50 01 c3 66 0f 1f 84 00 00 00 00 00 0f 1f RIP [] skb_pull+0x5/0x50 RSP CR2: 0080 ---[ end trace b074c0f90e7c997d ]--- [1] http://mid.gmane.org/20150430193259.ga5...@googlemail.com Cc: # v3.18, v3.19, v4.0, v4.1 Reported-by: Michael Hornung Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Thanks, applied to wireless-drivers.git. Oh, I forgot to mention that I'm not sure if this will make it into 4.1. But let's at least try. Thanks, Kalle It was a reported issue crashing the kernel so figured it would be 4.1 material, but indeed I should have sent it earlier. We'll see. Regards, Arend -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] brcmfmac: use direct data pointer in NVRAM parser struct
As we plan to add support for platform NVRAM we should store direct data pointer without the extra struct firmware layer. This will allow us to support other sources with the only requirement being u8 buffer. Signed-off-by: Rafał Miłecki Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel --- Tested on router with BCM43602-s using /lib/firmware/brcm/brcmfmac43602-pcie.txt I've written this patch from scratch, it's inspired by the dropped: [PATCH 6/6] brcmfmac: Add support for host platform NVRAM loading. --- drivers/net/wireless/brcm80211/brcmfmac/firmware.c | 40 +++--- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c index 7ae6461..b72df87 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c @@ -43,7 +43,7 @@ enum nvram_parser_state { * struct nvram_parser - internal info for parser. * * @state: current parser state. - * @fwnv: input buffer being parsed. + * @data: input buffer being parsed. * @nvram: output buffer with parse result. * @nvram_len: lenght of parse result. * @line: current line. @@ -55,7 +55,7 @@ enum nvram_parser_state { */ struct nvram_parser { enum nvram_parser_state state; - const struct firmware *fwnv; + const u8 *data; u8 *nvram; u32 nvram_len; u32 line; @@ -91,7 +91,7 @@ static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp) { char c; - c = nvp->fwnv->data[nvp->pos]; + c = nvp->data[nvp->pos]; if (c == '\n') return COMMENT; if (is_whitespace(c)) @@ -115,16 +115,16 @@ static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp) enum nvram_parser_state st = nvp->state; char c; - c = nvp->fwnv->data[nvp->pos]; + c = nvp->data[nvp->pos]; if (c == '=') { /* ignore RAW1 by treating as comment */ - if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0) + if (strncmp(&nvp->data[nvp->entry], "RAW1", 4) == 0) st = COMMENT; else st = VALUE; - if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) + if (strncmp(&nvp->data[nvp->entry], "devpath", 7) == 0) nvp->multi_dev_v1 = true; - if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) + if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) nvp->multi_dev_v2 = true; } else if (!is_nvram_char(c) || c == ' ') { brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", @@ -145,11 +145,11 @@ brcmf_nvram_handle_value(struct nvram_parser *nvp) char *ekv; u32 cplen; - c = nvp->fwnv->data[nvp->pos]; + c = nvp->data[nvp->pos]; if (!is_nvram_char(c)) { /* key,value pair complete */ - ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; - skv = (u8 *)&nvp->fwnv->data[nvp->entry]; + ekv = (u8 *)&nvp->data[nvp->pos]; + skv = (u8 *)&nvp->data[nvp->entry]; cplen = ekv - skv; if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE) return END; @@ -170,7 +170,7 @@ brcmf_nvram_handle_comment(struct nvram_parser *nvp) { char *eoc, *sol; - sol = (char *)&nvp->fwnv->data[nvp->pos]; + sol = (char *)&nvp->data[nvp->pos]; eoc = strchr(sol, '\n'); if (!eoc) { eoc = strchr(sol, '\0'); @@ -201,17 +201,17 @@ static enum nvram_parser_state }; static int brcmf_init_nvram_parser(struct nvram_parser *nvp, - const struct firmware *nv) + const u8 *data, size_t data_len) { size_t size; memset(nvp, 0, sizeof(*nvp)); - nvp->fwnv = nv; + nvp->data = data; /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ - if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE) + if (data_len > BRCMF_FW_MAX_NVRAM_SIZE) size = BRCMF_FW_MAX_NVRAM_SIZE; else - size = nv->size; + size = data_len; /* Alloc for extra 0 byte + roundup by 4 + length field */ size += 1 + 3 + sizeof(u32); nvp->nvram = kzalloc(size, GFP_KERNEL); @@ -356,18 +356,18 @@ fail: * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. * End of buffer is completed with token identifying length of buffer. */ -static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length, - u16 domain_nr, u16 bus_nr) +static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len, +
pull request: iwlwifi 2015-05-28
Hi Kalle, as we talked, here is the pull request for 4.1. Thanks. The following changes since commit 292208914d8ca5a41cf68c2f1d2810a2ea2044e9: iwlwifi: mvm: avoid use-after-free on iwl_mvm_d0i3_enable_tx() (2015-05-21 22:36:46 +0300) are available in the git repository at: https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git tags/iwlwifi-for-kalle-2015-05-28 for you to fetch changes up to f115fdfd61bd627e99d636bb61a3d3ff93397048: iwlwifi: nvm: fix otp parsing in 8000 hw family (2015-05-28 13:28:00 +0300) * fix OTP parsing 8260 * fix powersave handling for 8260 Ilan Peer (1): iwlwifi: pcie: fix tracking of cmd_in_flight Liad Kaufman (1): iwlwifi: nvm: fix otp parsing in 8000 hw family drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 2 +- drivers/net/wireless/iwlwifi/pcie/internal.h | 6 +++--- drivers/net/wireless/iwlwifi/pcie/trans.c| 4 ++-- drivers/net/wireless/iwlwifi/pcie/tx.c | 23 +-- 4 files changed, 15 insertions(+), 20 deletions(-)
pull request: iwlwifi-next 2015-05-28
Hi Kalle, this is the same pull request for 4.2 with the typo fixed and without the patches that are now targeted to 4.1 Thanks The following changes since commit bbbe8c8c596b3784a2ed08772900e827f8ba72c5: mac80211: add missing documentation for rate_ctrl_lock (2015-05-06 16:00:32 +0200) are available in the git repository at: https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git tags/iwlwifi-next-for-kalle-2015-05-28 for you to fetch changes up to 8b2b9fbf7e4e1b2e866239d46248431f719ba2c1: iwlwifi: mvm: clean interfaces on drv_stop (2015-05-28 13:36:54 +0300) Andrei Otcheretianski (1): iwlwifi: mvm: Configure agg. queue before assigning it to STA Arik Nemtsov (1): iwlwifi: mvm: clean interfaces on drv_stop Avraham Stern (3): iwlwifi: mvm: print scanned channel list on scan iteration complete notification iwlwifi: mvm: add UMAC scan iteration complete notification iwlwifi: mvm: add support for 8 level scan priority API Avri Altman (2): iwlwifi: pcie: don't disable the busmaster DMA clock for family 8000 iwlwifi: pcie: Remove redundant check for family type Eliad Peller (3): iwlwifi: mvm: avoid use-after-free on iwl_mvm_d0i3_enable_tx() iwlwifi: mvm: fix ROC reference accounting iwlwifi: tracing: add rx cmd header fields Emmanuel Grumbach (12): iwlwifi: mvm: forbid MIMO on devices that don't support it iwlwifi: 7000: modify the firmware name for 3165 iwlwifi: mvm: fix MLME trigger iwlwifi: mvm: BT Coex - duplicate the command if sent ASYNC Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next iwlwifi: bump API to 14 iwlwifi: pcie: simplify return value iwlwifi: mvm: BT Coex - remove useless code iwlwifi: mvm: BT Coex - allocate a short command on the stack iwlwifi: mvm: BT Coex - fix shared antenna check with new API Merge tag 'mac80211-next-for-davem-2015-05-06' into iwlwifi-next iwlwifi: mvm: implement the BlockAck related debug triggers Eran Harary (1): iwlwifi: 8000: fallback to default NVM file Haim Dreyfuss (1): iwlwifi: mvm: Free fw_status after use to avoid memory leak Ido Yariv (1): iwlwifi: update thermal throttling values for 8000 devices Johannes Berg (3): iwlwifi: refactor common transport alloc/init code iwlwifi: mvm: advertise randomised netdetect MAC address iwlwifi: mvm: handle device start failure correctly Liad Kaufman (1): iwlwifi: nvm: force mac from otp in case nvm mac is reserved Luciano Coelho (18): iwlwifi: mvm: take the UCODE_DOWN reference when resuming iwlwifi: mvm: clean net-detect info if device was reset during suspend iwlwifi: pcie: don't call set_pwr functions for family 8000 iwlwifi: mvm: small fix in a comment about UMAC scan schedules iwlwifi: mvm: remove the UMAC specific scan types iwlwifi: mvm: fix the net-detect SSIDs report order iwlwifi: mvm: make iwl_mvm_config_sched_scan_profiles() static iwlwifi: mvm: reorganize scan stopping functions iwlwifi: mvm: don't stop regular scans when going out of idle state iwlwifi: mvm: combine part of the scan stop flows iwlwifi: mvm: rename umac scan stop function iwlwifi: mvm: rename some LMAC-specific scan functions iwlwifi: mvm: refactor UMAC scan UID handling iwlwifi: mvm: remove code that stops multiple UMAC scans of a type iwlwifi: mvm: combine UMAC and LMAC scan_stop functions iwlwifi: mvm: combine regular and sched scan stop functions iwlwifi: mvm: make UMAC scans use the stopping scan status iwlwifi: mvm: treat scan races also on UMAC scans Matti Gottlieb (1): iwlwifi: mvm: Add debugfs entry for Tx power limit Nicholas Krause (1): iwlwifi: Remove use of the deprecacted PTR_RET drivers/net/wireless/iwlwifi/Kconfig| 13 +- drivers/net/wireless/iwlwifi/Makefile |1 + drivers/net/wireless/iwlwifi/iwl-7000.c | 41 - drivers/net/wireless/iwlwifi/iwl-8000.c | 70 +--- drivers/net/wireless/iwlwifi/iwl-config.h | 44 + drivers/net/wireless/iwlwifi/iwl-devtrace-iwlwifi.h | 15 +- drivers/net/wireless/iwlwifi/iwl-drv.c |6 +- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c |5 + drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h |3 + drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h|6 +- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 40 - drivers/net/wireless/iwlwifi/iwl-nvm-parse.c| 30 +++- drivers/net/wireless/iwlwifi/iwl-prph.h |3 + drivers/net/wireless/iwlwifi/iwl-trans.c| 113 drivers/net/wireless/iwlwifi/iwl-trans.h| 61 --- drivers/net/wireless/iwlwifi/mvm/coex.c | 81 ++--- drive
RE: pull request: iwlwifi-next 2015-05-26
> > "Grumbach, Emmanuel" writes: > > >> > Note that there are fixes here that didn't make it to my previous > >> > pull request for 4.1. I tagged them for stable since the wording of > >> > your last pull request for 4.1 to Dave hinted me that you won't > >> > send any pull request for 4.1 to him anymore. > >> > >> Yeah, I said that hopefully it's the last pull request. I got one > >> important fix from Arend so I will try to send one more, but let's see how > it goes. > >> > > ... if that's the case, do you want me to split the patches > > differently and add the ones I CCed to stable to iwlwifi-fixes? > > Sure, go ahead if you want to do that. But please keep in mind that the bar is > higher when we go closer to the actual release. I found two patches from the > patchset with CC stable (I hope I didn't miss > anything): > > [PATCH 03/39] iwlwifi: pcie: fix tracking of cmd_in_flight [PATCH 32/39] > iwlwifi: nvm: fix otp parsing in 8000 hw family > > In my opinion these two are ok. > Cool. I'll respin. > > If I re-spin iwlwifi-next anyway, I'll fix the typo above. > > Ok, I don't care about the typo in the commit log, we do those all the time > :) I > just wanted to check that I don't pull anything which I'm not supposed to > pull. > > > -- > Kalle Valo -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: pull request: iwlwifi-next 2015-05-26
"Grumbach, Emmanuel" writes: >> > Note that there are fixes here that didn't make it to my previous pull >> > request for 4.1. I tagged them for stable since the wording of your >> > last pull request for 4.1 to Dave hinted me that you won't send any >> > pull request for 4.1 to him anymore. >> >> Yeah, I said that hopefully it's the last pull request. I got one important >> fix >> from Arend so I will try to send one more, but let's see how it goes. >> > ... if that's the case, do you want me to split the patches > differently and add the ones I CCed to stable to iwlwifi-fixes? Sure, go ahead if you want to do that. But please keep in mind that the bar is higher when we go closer to the actual release. I found two patches from the patchset with CC stable (I hope I didn't miss anything): [PATCH 03/39] iwlwifi: pcie: fix tracking of cmd_in_flight [PATCH 32/39] iwlwifi: nvm: fix otp parsing in 8000 hw family In my opinion these two are ok. > If I re-spin iwlwifi-next anyway, I'll fix the typo above. Ok, I don't care about the typo in the commit log, we do those all the time :) I just wanted to check that I don't pull anything which I'm not supposed to pull. -- Kalle Valo -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH next 0/2] net: rfkill: gpio: make better use of gpiod API
Hello, this series adapts the rfkill-gpio driver to make use of the flags parameter of the gpiod_get* family of functions. Currently this is optional (with a crude cpp hack) but this should change. The second patch was split out because it probably makes davem break out in spots. Still I send it because I consider it a sensible change. Up to you if you want the discussion. (See http://mid.gmane.org/20150331.140700.1574593248925827837.da...@davemloft.net for a similar previous discussion.) For other subsystems I did similar changes in a single patch without any resulting criticism. Best regards Uwe Uwe Kleine-König (2): net: rfkill: gpio: make better use of gpiod API net: rfkill: gpio: simplify code flow net/rfkill/rfkill-gpio.c | 23 --- 1 file changed, 8 insertions(+), 15 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html