* [PATCH AUTOSEL 5.1 25/95] iwlwifi: fix load in rfkill flow for unified firmware
From: Sasha Levin @ 2019-06-27 0:29 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Emmanuel Grumbach, Luca Coelho, Kalle Valo, Sasha Levin,
linux-wireless, netdev
In-Reply-To: <20190627003021.19867-1-sashal@kernel.org>
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
[ Upstream commit b3500b472c880b5abe90ffd5c4a25aa736f906ad ]
When we have a single image (same firmware image for INIT and
OPERATIONAL), we couldn't load the driver and register to the
stack if we had hardware RF-Kill asserted.
Fix this. This required a few changes:
1) Run the firmware as part of the INIT phase even if its
ucode_type is not IWL_UCODE_INIT.
2) Send the commands that are sent to the unified image in
INIT flow even in RF-Kill.
3) Don't ask the transport to stop the hardware upon RF-Kill
interrupt if the RF-Kill is asserted.
4) Allow the RF-Kill interrupt to take us out of L1A so that
the RF-Kill interrupt will be received by the host (to
enable the radio).
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 23 ++++++++++++++-----
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 17 ++++++++++----
.../wireless/intel/iwlwifi/pcie/internal.h | 2 +-
5 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index ab68b5d53ec9..153717587aeb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -311,6 +311,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
int ret;
enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;
static const u16 alive_cmd[] = { MVM_ALIVE };
+ bool run_in_rfkill =
+ ucode_type == IWL_UCODE_INIT || iwl_mvm_has_unified_ucode(mvm);
if (ucode_type == IWL_UCODE_REGULAR &&
iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
@@ -328,7 +330,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
alive_cmd, ARRAY_SIZE(alive_cmd),
iwl_alive_fn, &alive_data);
- ret = iwl_trans_start_fw(mvm->trans, fw, ucode_type == IWL_UCODE_INIT);
+ /*
+ * We want to load the INIT firmware even in RFKILL
+ * For the unified firmware case, the ucode_type is not
+ * INIT, but we still need to run it.
+ */
+ ret = iwl_trans_start_fw(mvm->trans, fw, run_in_rfkill);
if (ret) {
iwl_fw_set_current_image(&mvm->fwrt, old_type);
iwl_remove_notification(&mvm->notif_wait, &alive_wait);
@@ -433,7 +440,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
* commands
*/
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(SYSTEM_GROUP,
- INIT_EXTENDED_CFG_CMD), 0,
+ INIT_EXTENDED_CFG_CMD),
+ CMD_SEND_IN_RFKILL,
sizeof(init_cfg), &init_cfg);
if (ret) {
IWL_ERR(mvm, "Failed to run init config command: %d\n",
@@ -457,7 +465,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
}
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP,
- NVM_ACCESS_COMPLETE), 0,
+ NVM_ACCESS_COMPLETE),
+ CMD_SEND_IN_RFKILL,
sizeof(nvm_complete), &nvm_complete);
if (ret) {
IWL_ERR(mvm, "Failed to run complete NVM access: %d\n",
@@ -482,6 +491,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
}
}
+ mvm->rfkill_safe_init_done = true;
+
return 0;
error:
@@ -526,7 +537,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
lockdep_assert_held(&mvm->mutex);
- if (WARN_ON_ONCE(mvm->calibrating))
+ if (WARN_ON_ONCE(mvm->rfkill_safe_init_done))
return 0;
iwl_init_notification_wait(&mvm->notif_wait,
@@ -576,7 +587,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
goto remove_notif;
}
- mvm->calibrating = true;
+ mvm->rfkill_safe_init_done = true;
/* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
@@ -612,7 +623,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
remove_notif:
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
out:
- mvm->calibrating = false;
+ mvm->rfkill_safe_init_done = false;
if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
/* we want to debug INIT and we have no NVM - fake */
mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 6a3b11dd2edf..4ddf620c267d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1211,7 +1211,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
mvm->scan_status = 0;
mvm->ps_disabled = false;
- mvm->calibrating = false;
+ mvm->rfkill_safe_init_done = false;
/* just in case one was running */
iwl_mvm_cleanup_roc_te(mvm);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index a50dc53df086..b698d55ace1b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -877,7 +877,7 @@ struct iwl_mvm {
struct iwl_mvm_vif *bf_allowed_vif;
bool hw_registered;
- bool calibrating;
+ bool rfkill_safe_init_done;
bool support_umac_log;
u32 ampdu_ref;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 13681b03c10e..20115770e75a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1222,7 +1222,8 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
- bool calibrating = READ_ONCE(mvm->calibrating);
+ bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done);
+ bool unified = iwl_mvm_has_unified_ucode(mvm);
if (state)
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
@@ -1231,15 +1232,23 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
iwl_mvm_set_rfkill_state(mvm);
- /* iwl_run_init_mvm_ucode is waiting for results, abort it */
- if (calibrating)
+ /* iwl_run_init_mvm_ucode is waiting for results, abort it. */
+ if (rfkill_safe_init_done)
iwl_abort_notification_waits(&mvm->notif_wait);
+ /*
+ * Don't ask the transport to stop the firmware. We'll do it
+ * after cfg80211 takes us down.
+ */
+ if (unified)
+ return false;
+
/*
* Stop the device if we run OPERATIONAL firmware or if we are in the
* middle of the calibrations.
*/
- return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT || calibrating);
+ return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT ||
+ rfkill_safe_init_done);
}
static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 59213164f35e..2afce5c41322 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -948,7 +948,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
MSIX_HW_INT_CAUSES_REG_RF_KILL);
}
- if (trans->cfg->device_family == IWL_DEVICE_FAMILY_9000) {
+ if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_9000) {
/*
* On 9000-series devices this bit isn't enabled by default, so
* when we power down the device we need set the bit to allow it
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.1 22/95] mwifiex: Fix possible buffer overflows at parsing bss descriptor
From: Sasha Levin @ 2019-06-27 0:29 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Takashi Iwai, huangwen, Kalle Valo, Sasha Levin, linux-wireless,
netdev
In-Reply-To: <20190627003021.19867-1-sashal@kernel.org>
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 13ec7f10b87f5fc04c4ccbd491c94c7980236a74 ]
mwifiex_update_bss_desc_with_ie() calls memcpy() unconditionally in
a couple places without checking the destination size. Since the
source is given from user-space, this may trigger a heap buffer
overflow.
Fix it by putting the length check before performing memcpy().
This fix addresses CVE-2019-3846.
Reported-by: huangwen <huangwen@venustech.com.cn>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/marvell/mwifiex/scan.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 935778ec9a1b..64ab6fe78c0d 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -1247,6 +1247,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
}
switch (element_id) {
case WLAN_EID_SSID:
+ if (element_len > IEEE80211_MAX_SSID_LEN)
+ return -EINVAL;
bss_entry->ssid.ssid_len = element_len;
memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
element_len);
@@ -1256,6 +1258,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break;
case WLAN_EID_SUPP_RATES:
+ if (element_len > MWIFIEX_SUPPORTED_RATES)
+ return -EINVAL;
memcpy(bss_entry->data_rates, current_ptr + 2,
element_len);
memcpy(bss_entry->supported_rates, current_ptr + 2,
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.1 13/95] mac80211: fix rate reporting inside cfg80211_calculate_bitrate_he()
From: Sasha Levin @ 2019-06-27 0:28 UTC (permalink / raw)
To: linux-kernel, stable
Cc: John Crispin, Shashidhar Lakkavalli, Johannes Berg, Sasha Levin,
linux-wireless, netdev
In-Reply-To: <20190627003021.19867-1-sashal@kernel.org>
From: John Crispin <john@phrozen.org>
[ Upstream commit 25d16d124a5e249e947c0487678b61dcff25cf8b ]
The reported rate is not scaled down correctly. After applying this patch,
the function will behave just like the v/ht equivalents.
Signed-off-by: Shashidhar Lakkavalli <slakkavalli@datto.com>
Signed-off-by: John Crispin <john@phrozen.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 75899b62bdc9..5a03f38788e7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1237,7 +1237,7 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
if (rate->he_dcm)
result /= 2;
- return result;
+ return result / 10000;
}
u32 cfg80211_calculate_bitrate(struct rate_info *rate)
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 2/2] iwlwifi: Extended Key ID support
From: Alexander Wetzel @ 2019-06-26 21:10 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, luca
In-Reply-To: <20190506190149.3624-2-alexander@wetzel-home.de>
> iwlwifi cards are all able to support Extended Key ID as long as
> mac80211 stops A-MPDU aggregation when replacing the unicast key.
>
> Enable Extended Key ID support and tell mac80211 that it has to tear
> down any running Tx aggregation sessions during rekey when using
> Extended Key ID.
With the merge of the A-MPDU handling patch
https://patchwork.kernel.org/patch/10931861/ we probably should simplify
the API for Extended Key ID and not merge the patch as it is:
1) We can drop EXT_KEY_ID_NATIVE from mac80211 and let the drivers set
NL80211_EXT_FEATURE_EXT_KEY_ID instead of mac80211.
Without the COMPAT support the naming is off and the flag is simply
pointless. Assuming we want to pick up the COMPAT Extended Key ID we
still can just define a new flag, e.g.
SINGLE_STA_UNICAST_KEY_OFFLOAD_ONLY to tell mac80211 it can only
have one unicast key active in the HW per STA.
2) Mac80211 would then enable Extended Key ID for all drivers using SW
crypto and just also set NO_AMPDU_KEYBORDER_SUPPORT when the driver
supports A-MPDU
3) we then could undo (revert?) cfe7007a9b4c ("mac80211_hwsim: Extended
Key ID support") and let the more generic code in mac80211 handle it
If you agree I'll prepare and test a small patch series for that.
And we better only merge a iteration of this patch here once we got the
API updated.
Alexander
^ permalink raw reply
* Re: pull-request: wireless-drivers-next 2019-06-26
From: David Miller @ 2019-06-26 17:12 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <87ef3gjq16.fsf@kamboji.qca.qualcomm.com>
From: Kalle Valo <kvalo@codeaurora.org>
Date: Wed, 26 Jun 2019 18:59:49 +0300
> here's a pull request to net-next for 5.3, more info below. Please let
> me know if there are any problems.
Pulled, thanks Kalo.
^ permalink raw reply
* Re: [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Williams @ 2019-06-26 16:02 UTC (permalink / raw)
To: Dan Carpenter
Cc: Philip Rakity, libertas-dev, kernel-janitors, linux-wireless,
Lubomir Rintel, Kalle Valo, Allison Randal
In-Reply-To: <20190626132340.GE28859@kadam>
On Wed, 2019-06-26 at 16:23 +0300, Dan Carpenter wrote:
> Yeah. That looks nicer. Could you send it as a proper patch and
> give
> me Reported-by credit?
Will do.
Dan
^ permalink raw reply
* pull-request: wireless-drivers-next 2019-06-26
From: Kalle Valo @ 2019-06-26 15:59 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel
Hi Dave,
here's a pull request to net-next for 5.3, more info below. Please let
me know if there are any problems.
Kalle
The following changes since commit f4aa80129ff71909380ee0bde8be36c5cc031d4c:
cxgb4: Make t4_get_tp_e2c_map static (2019-05-26 22:16:26 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git tags/wireless-drivers-next-for-davem-2019-06-26
for you to fetch changes up to e5db0ad7563c38b7b329504836c9a64ae025a47a:
airo: switch to skcipher interface (2019-06-25 08:12:20 +0300)
----------------------------------------------------------------
wireless-drivers-next patches for 5.3
First set of patches for 5.3, but not that many patches this time.
This pull request fails to compile with the tip tree due to
ktime_get_boot_ns() API changes there. It should be easy for Linus to
fix it in p54 driver once he pulls this, an example resolution here:
https://lkml.kernel.org/r/20190625160432.533aa140@canb.auug.org.au
Major changes:
airo
* switch to use skcipher interface
p54
* support boottime in scan results
rtw88
* add fast xmit support
* add random mac address on scan support
rt2x00
* add software watchdog to detect hangs, it's disabled by default
----------------------------------------------------------------
Ahmad Masri (1):
wil6210: fix overwriting max_assoc_sta module param
Alagu Sankar (3):
ath10k: htt: don't use txdone_fifo with SDIO
ath10k: htt: support MSDU ids with SDIO
ath10k: add initialization of HTC header
Alan Stern (1):
p54usb: Fix race between disconnect and firmware loading
Alexei Avshalom Lazar (1):
wil6210: fix _desc access in __wil_tx_vring_tso
Anilkumar Kolli (1):
ath: DFS JP domain W56 fixed pulse type 3 RADAR detection
Ard Biesheuvel (1):
airo: switch to skcipher interface
Arend van Spriel (6):
brcm80211: switch common header files to using SPDX license identifier
brcmutil: switch source files to using SPDX license identifier
brcmsmac: switch phy source files to using SPDX license identifier
brcmfmac: switch source files to using SPDX license identifier
brcmfmac: use separate Kconfig file for brcmfmac
brcm80211: select WANT_DEV_COREDUMP conditionally for brcmfmac
Arnd Bergmann (1):
wireless: carl9170: fix clang build warning
Balaji Pothunoori (1):
ath10k: rx_duration update for fw_stats debugfs entry
Brandon Huang (1):
ath10k: Fix the tx stats bytes & packets parsing
Brian Norris (2):
mwifiex: drop 'set_consistent_dma_mask' log message
mwifiex: print PCI mmap with %pK
Chien-Hsun Liao (2):
rtw88: 8822c: add rf write protection when switching channel
rtw88: 8822c: update channel and bandwidth BB setting
Chin-Yen Lee (1):
rtw88: add beacon function setting
Christian Lamparter (3):
p54: fix crash during initialization
p54: Support boottime in scan results
p54: remove dead branch in op_conf_tx callback
Colin Ian King (5):
ath6kl: remove redundant check of status != 0
libertas: fix spelling mistake "Donwloading" -> "Downloading"
rtlwifi: remove redundant assignment to variable badworden
rtlwifi: remove redundant assignment to variable k
rtlwifi: rtl8188ee: remove redundant assignment to rtstatus
Dan Carpenter (1):
ath6kl: add some bounds checking
Dedy Lansky (3):
wil6210: add printout of platform capabilities
wil6210: enhancements for descriptor and status ring debugfs
wil6210: check rx_buff_mgmt before accessing it
Erik Stromdahl (1):
ath10k: sdio: add missing error check
Govind Singh (2):
ath10k: Move board id and fw version logging to info level
ath10k: Modify CE4 src buffer entries to 2048 for WCN3990
Greg Kroah-Hartman (2):
iwlegacy: 3945: no need to check return value of debugfs_create functions
iwlegacy: 4965: no need to check return value of debugfs_create functions
Gustavo A. R. Silva (6):
ath6kl: debug: Use struct_size() helper
ath6kl: wmi: use struct_size() helper
wil6210: fix potential out-of-bounds read
ath10k: Use struct_size() helper
ath10k: coredump: use struct_size() helper
qtnfmac: Use struct_size() in kzalloc()
Jia-Ju Bai (1):
b43: Avoid possible double calls to b43_one_core_detach()
Kalle Valo (3):
ath10k: initialise struct ath10k_bus params to zero
ath10k: fix use-after-free on SDIO data frames
Merge ath-next from git://git.kernel.org/.../kvalo/ath.git
Larry Finger (4):
rtlwifi: rtl8821ae: Remove unused GET_XXX and SET_XXX descriptor macros
rtlwifi: rtl8821ae: Replace local bit manipulation macros
rtlwifi: rtl8821ae: Convert macros that set descriptor
rtlwifi: rtl8821ae: Convert inline routines to little-endian words
Lorenzo Bianconi (2):
mt7601u: do not schedule rx_tasklet when the device has been disconnected
mt7601u: fix possible memory leak when the device is disconnected
Maharaja Kennadyrajan (2):
ath10k: Extended the HTT stats support to retrieve Mu-MIMO related stats
ath10k: Added support to reset HTT stats in debugfs
Maya Erez (4):
wil6210: fix spurious interrupts in 3-msi
wil6210: add support for multiple sections in brd file
wil6210: fix missed MISC mbox interrupt
wil6210: remove HALP for Talyn devices
Michael Buesch (1):
ssb/gpio: Remove unnecessary WARN_ON from driver_gpio
Neo Jou (1):
brcmfmac: use strlcpy() instead of strcpy()
Ping-Ke Shih (5):
rtlwifi: 8192de: Reduce indentation and fix coding style
rtlwifi: 8192de: make tables to be 'static const'
rtlwifi: 8192de: Fix used uninitialized variables in power tracking
rtlwifi: 8192de: use le32 to access cckswing tables
rtlwifi: rtl8192cu: fix error handle when usb probe failed
Pradeep kumar Chitrapu (1):
ath10k: fix incorrect multicast/broadcast rate setting
Rakesh Pillai (1):
ath10k: Fix encoding for protected management frames
Sharvari Harisangam (1):
mwifiex: update set_mac_address logic
Stanislaw Gruszka (7):
rt2x00: allow to specify watchdog interval
rt2800: add helpers for reading dma done index
rt2800: initial watchdog implementation
rt2800: add pre_reset_hw callback
rt2800: do not nullify initialization vector data
rt2x00: add restart hw
rt2800: do not enable watchdog by default
Surabhi Vishnoi (4):
ath10k: Fix the wrong value of enums for wmi tlv stats id
ath10k: Add wmi tlv vdev subtype for mesh in WCN3990
ath10k: Do not send probe response template for mesh
ath10k: Add wmi tlv service map for mesh 11s
Sven Eckelmann (1):
ath9k: Differentiate between max combined and per chain power
Swati Kushwaha (1):
mwifiex: ignore processing invalid command response
Tim Schumacher (1):
ath9k: Check for errors when reading SREV register
Toke Høiland-Jørgensen (1):
ath9k: Don't trust TX status TID number when reporting airtime
Tomislav Požega (2):
ath: drop duplicated define
ath9k: drop redundant code in ar9003_hw_set_channel
Tzu-En Huang (1):
rtw88: fix typo rtw_writ16_set
Weitao Hou (1):
brcmfmac: fix typos in code comments
Wen Gong (9):
ath10k: sdio: workaround firmware UART pin configuration bug
ath10k: don't disable interrupts in ath10k_sdio_remove()
ath10k: add struct for high latency PN replay protection
ath10k: add handler for HTT_T2H_MSG_TYPE_SEC_IND event
ath10k: add PN replay protection for high latency devices
ath10k: add fragmentation handler for high latency devices
ath10k: enable QCA6174 hw3.2 SDIO hardware
ath10k: change swap mail box config for UTF mode of SDIO
ath10k: add peer id check in ath10k_peer_find_by_id
Yan-Hsuan Chuang (10):
rtw88: pci: use ieee80211_ac_numbers instead of 0-3
rtw88: pci: check if queue mapping exceeds size of ac_to_hwq
rtw88: more descriptions about LPS
rtw88: add fast xmit support
rtw88: add support for random mac scan
rtw88: 8822c: disable rx clock gating before counter reset
rtw88: 8822c: use more accurate ofdm fa counting
rtw88: power on again if it was already on
rtw88: restore DACK results to save time
rtw88: rsvd page should go though management queue
Yingying Tang (1):
ath10k: Check tx_stats before use it
YueHaibing (4):
ath9k: Remove some set but not used variables
rtlwifi: rtl8821ae: Remove set but not used variables 'cur_txokcnt' and 'b_last_is_cur_rdl_state'
rtlwifi: btcoex: Remove set but not used variable 'len' and 'asso_type_v2'
rtlwifi: btcoex: remove unused function exhalbtc_stack_operation_notify
drivers/net/wireless/ath/ath10k/ahb.c | 2 +-
drivers/net/wireless/ath/ath10k/core.c | 48 +-
drivers/net/wireless/ath/ath10k/core.h | 12 +-
drivers/net/wireless/ath/ath10k/coredump.c | 4 +-
drivers/net/wireless/ath/ath10k/debug.c | 50 +-
drivers/net/wireless/ath/ath10k/debugfs_sta.c | 7 +
drivers/net/wireless/ath/ath10k/htc.c | 1 +
drivers/net/wireless/ath/ath10k/htt.h | 60 +-
drivers/net/wireless/ath/ath10k/htt_rx.c | 387 ++++++++++-
drivers/net/wireless/ath/ath10k/htt_tx.c | 29 +-
drivers/net/wireless/ath/ath10k/hw.h | 6 +
drivers/net/wireless/ath/ath10k/mac.c | 14 +-
drivers/net/wireless/ath/ath10k/pci.c | 2 +-
drivers/net/wireless/ath/ath10k/qmi.c | 15 +-
drivers/net/wireless/ath/ath10k/sdio.c | 18 +-
drivers/net/wireless/ath/ath10k/snoc.c | 4 +-
drivers/net/wireless/ath/ath10k/txrx.c | 3 +
drivers/net/wireless/ath/ath10k/usb.c | 2 +-
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 28 +-
drivers/net/wireless/ath/ath10k/wmi-tlv.h | 12 +
drivers/net/wireless/ath/ath10k/wmi.c | 37 +-
drivers/net/wireless/ath/ath10k/wmi.h | 7 +-
drivers/net/wireless/ath/ath6kl/debug.c | 3 +-
drivers/net/wireless/ath/ath6kl/htc_pipe.c | 3 -
drivers/net/wireless/ath/ath6kl/wmi.c | 13 +-
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 24 +-
drivers/net/wireless/ath/ath9k/eeprom.c | 2 +-
drivers/net/wireless/ath/ath9k/eeprom_4k.c | 1 +
drivers/net/wireless/ath/ath9k/hw.c | 40 +-
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/init.c | 2 +-
drivers/net/wireless/ath/ath9k/xmit.c | 18 +-
drivers/net/wireless/ath/carl9170/mac.c | 2 +-
drivers/net/wireless/ath/carl9170/rx.c | 2 +-
drivers/net/wireless/ath/dfs_pattern_detector.c | 2 +-
drivers/net/wireless/ath/regd.h | 1 -
drivers/net/wireless/ath/wil6210/cfg80211.c | 4 +-
drivers/net/wireless/ath/wil6210/debugfs.c | 70 +-
drivers/net/wireless/ath/wil6210/fw.h | 11 +-
drivers/net/wireless/ath/wil6210/fw_inc.c | 148 +++--
drivers/net/wireless/ath/wil6210/interrupt.c | 67 +-
drivers/net/wireless/ath/wil6210/main.c | 18 +-
drivers/net/wireless/ath/wil6210/pcie_bus.c | 2 +
drivers/net/wireless/ath/wil6210/rx_reorder.c | 2 +-
drivers/net/wireless/ath/wil6210/txrx.c | 26 +-
drivers/net/wireless/ath/wil6210/txrx_edma.c | 10 +-
drivers/net/wireless/ath/wil6210/wil6210.h | 33 +-
drivers/net/wireless/ath/wil6210/wmi.c | 14 +-
drivers/net/wireless/broadcom/b43/main.c | 7 +-
drivers/net/wireless/broadcom/brcm80211/Kconfig | 52 +-
drivers/net/wireless/broadcom/brcm80211/Makefile | 14 +-
.../wireless/broadcom/brcm80211/brcmfmac/Kconfig | 50 ++
.../wireless/broadcom/brcm80211/brcmfmac/Makefile | 14 +-
.../wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/bcdc.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/btcoex.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/btcoex.h | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 13 +-
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 13 +-
.../broadcom/brcm80211/brcmfmac/cfg80211.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/chip.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/chip.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/common.c | 15 +-
.../wireless/broadcom/brcm80211/brcmfmac/common.h | 16 +-
.../broadcom/brcm80211/brcmfmac/commonring.c | 16 +-
.../broadcom/brcm80211/brcmfmac/commonring.h | 16 +-
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/debug.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/debug.h | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/feature.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/feature.h | 13 +-
.../broadcom/brcm80211/brcmfmac/firmware.c | 13 +-
.../broadcom/brcm80211/brcmfmac/firmware.h | 13 +-
.../broadcom/brcm80211/brcmfmac/flowring.c | 16 +-
.../broadcom/brcm80211/brcmfmac/flowring.h | 16 +-
.../wireless/broadcom/brcm80211/brcmfmac/fweh.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/fweh.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/fwil.c | 15 +-
.../wireless/broadcom/brcm80211/brcmfmac/fwil.h | 13 +-
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 13 +-
.../broadcom/brcm80211/brcmfmac/fwsignal.c | 13 +-
.../broadcom/brcm80211/brcmfmac/fwsignal.h | 14 +-
.../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 16 +-
.../wireless/broadcom/brcm80211/brcmfmac/msgbuf.h | 16 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/of.c | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/of.h | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 16 +-
.../wireless/broadcom/brcm80211/brcmfmac/pcie.h | 16 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/proto.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/proto.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 13 +-
.../broadcom/brcm80211/brcmfmac/tracepoint.c | 13 +-
.../broadcom/brcm80211/brcmfmac/tracepoint.h | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 13 +-
.../net/wireless/broadcom/brcm80211/brcmfmac/usb.h | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/vendor.c | 13 +-
.../wireless/broadcom/brcm80211/brcmfmac/vendor.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_cmn.c | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_hal.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_int.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_lcn.c | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_lcn.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_n.c | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_qmath.c | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_qmath.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_radio.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phyreg_n.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.c | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.h | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phytbl_n.c | 13 +-
.../broadcom/brcm80211/brcmsmac/phy/phytbl_n.h | 13 +-
.../wireless/broadcom/brcm80211/brcmutil/Makefile | 13 +-
.../net/wireless/broadcom/brcm80211/brcmutil/d11.c | 13 +-
.../wireless/broadcom/brcm80211/brcmutil/utils.c | 13 +-
.../broadcom/brcm80211/include/brcm_hw_ids.h | 13 +-
.../broadcom/brcm80211/include/brcmu_d11.h | 13 +-
.../broadcom/brcm80211/include/brcmu_utils.h | 13 +-
.../broadcom/brcm80211/include/brcmu_wifi.h | 13 +-
.../broadcom/brcm80211/include/chipcommon.h | 13 +-
.../net/wireless/broadcom/brcm80211/include/defs.h | 13 +-
.../net/wireless/broadcom/brcm80211/include/soc.h | 13 +-
drivers/net/wireless/cisco/Kconfig | 2 +
drivers/net/wireless/cisco/airo.c | 57 +-
drivers/net/wireless/intel/iwlegacy/3945-rs.c | 14 +-
drivers/net/wireless/intel/iwlegacy/3945.h | 3 -
drivers/net/wireless/intel/iwlegacy/4965-rs.c | 31 +-
drivers/net/wireless/intel/iwlegacy/common.h | 4 -
drivers/net/wireless/intersil/p54/main.c | 9 +-
drivers/net/wireless/intersil/p54/p54usb.c | 43 +-
drivers/net/wireless/intersil/p54/txrx.c | 11 +-
drivers/net/wireless/marvell/libertas/if_usb.c | 2 +-
drivers/net/wireless/marvell/libertas_tf/if_usb.c | 2 +-
drivers/net/wireless/marvell/mwifiex/cmdevt.c | 27 +-
drivers/net/wireless/marvell/mwifiex/main.c | 6 +-
drivers/net/wireless/marvell/mwifiex/main.h | 2 +-
drivers/net/wireless/marvell/mwifiex/pcie.c | 5 +-
drivers/net/wireless/mediatek/mt7601u/dma.c | 54 +-
drivers/net/wireless/mediatek/mt7601u/tx.c | 4 +-
drivers/net/wireless/quantenna/qtnfmac/commands.c | 5 +-
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 96 ++-
drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 11 +
drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 31 +
drivers/net/wireless/ralink/rt2x00/rt2800mmio.h | 2 +
drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 3 +
drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 3 +
drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 11 +
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 10 +
drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | 35 +
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 10 +-
drivers/net/wireless/ralink/rt2x00/rt2x00link.c | 15 +-
drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 6 +
.../realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 35 +-
.../realtek/rtlwifi/btcoexist/halbtcoutsrc.h | 1 -
.../wireless/realtek/rtlwifi/btcoexist/rtl_btc.c | 3 +-
drivers/net/wireless/realtek/rtlwifi/efuse.c | 5 +-
.../net/wireless/realtek/rtlwifi/rtl8188ee/hw.c | 2 +-
.../net/wireless/realtek/rtlwifi/rtl8192de/dm.c | 695 ++++++++++----------
.../net/wireless/realtek/rtlwifi/rtl8821ae/dm.c | 8 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/trx.c | 253 ++++----
.../net/wireless/realtek/rtlwifi/rtl8821ae/trx.h | 708 +++++++++++----------
drivers/net/wireless/realtek/rtlwifi/usb.c | 5 +-
drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 +
drivers/net/wireless/realtek/rtw88/hci.h | 2 +-
drivers/net/wireless/realtek/rtw88/mac.c | 8 +-
drivers/net/wireless/realtek/rtw88/mac80211.c | 32 +
drivers/net/wireless/realtek/rtw88/main.c | 10 +-
drivers/net/wireless/realtek/rtw88/main.h | 11 +
drivers/net/wireless/realtek/rtw88/pci.c | 10 +-
drivers/net/wireless/realtek/rtw88/phy.c | 13 +-
drivers/net/wireless/realtek/rtw88/rtw8822c.c | 436 ++++++++++++-
drivers/net/wireless/realtek/rtw88/rtw8822c.h | 23 +
drivers/net/wireless/realtek/rtw88/tx.c | 2 +-
drivers/ssb/driver_gpio.c | 6 -
181 files changed, 2885 insertions(+), 2322 deletions(-)
create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig
^ permalink raw reply
* Re: [PATCH] ath: fix SPDX tags
From: Kalle Valo @ 2019-06-26 15:10 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-wireless
In-Reply-To: <1561474345-1439-1-git-send-email-kvalo@codeaurora.org>
Kalle Valo <kvalo@codeaurora.org> wrote:
> Commit ec8f24b7faaf ("treewide: Add SPDX license identifier -
> Makefile/Kconfig") marked various Makefiles and Kconfig files within ath
> directories as GPL-2.0. But these modules and drivers are actually ISC:
>
> * ath
> * ar5523
> * ath10k
> * ath5k
> * ath6kl
> * ath9k
> * wcn36xx
> * wil6210
>
> Fix SPDX tags accordingly.
>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Patch applied to wireless-drivers.git, thanks.
e780d22757fb ath: fix SPDX tags
--
https://patchwork.kernel.org/patch/11015875/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH] carl9170: fix enum compare splat
From: Kalle Valo @ 2019-06-26 14:17 UTC (permalink / raw)
To: Christian Lamparter; +Cc: linux-wireless
In-Reply-To: <4392478.8kWN0Ehzps@debian64>
Christian Lamparter <chunkeey@gmail.com> writes:
> On Tuesday, June 18, 2019 2:11:53 PM CEST Kalle Valo wrote:
>> Christian Lamparter <chunkeey@gmail.com> writes:
>> > On Monday, June 10, 2019 9:06:30 AM CEST Kalle Valo wrote:
>> >> Christian Lamparter <chunkeey@gmail.com> writes:
>> >>
>> >> > This patch fixes a noisy warning triggered by -Wenum-compare
>> >> >
>> >> > |main.c:1390:31: warning: comparison between ‘enum nl80211_ac’
>> >> > | and ‘enum ar9170_txq’ [-Wenum-compare]
>> >> > | BUILD_BUG_ON(NL80211_NUM_ACS > __AR9170_NUM_TXQ);
>> >> > | ^
>> >> > | [...]
>> >> >
>> >> > This is a little bit unfortunate, since the number of queues
>> >> > (hence NL80211_NUM_ACS) is a constant based on the IEEE 802.11
>> >> > (much like IEEE80211_NUM_ACS) and __AR9170_NUM_TXQ is more or
>> >> > less defined by the AR9170 hardware.
>> >>
>> >> Is the warning enabled by default? TBH I'm not seeing how useful this
>> >> warning is for kernel development.
>> >
>> > It is included in the "-Wall" (which is coming from "KBUILD_CFLAGS"
>> > in the main Makefile).
>> >
>> > I tried debian's gcc starting from 4.6 to the lastest 8.3. They all
>> > complain about it in various degrees.
>> >
>> > https://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Warning-Options.html#Warning-Options
>>
>> Ok, odd that I haven't noticed this warning. Maybe I have been just
>> blind.
>
> Sorry. No, I messed up there. I made a patch back in the day during the spectre
> mac80211 patches that I kept in my tree for the driver. But I now remember that
> I never published those because of that exact "warning".
> These lines are coming from there.
>
>> >> > --- a/drivers/net/wireless/ath/carl9170/main.c
>> >> > +++ b/drivers/net/wireless/ath/carl9170/main.c
>> >> > @@ -1387,7 +1387,7 @@ static int carl9170_op_conf_tx(struct ieee80211_hw *hw,
>> >> > int ret;
>> >> >
>> >> > BUILD_BUG_ON(ARRAY_SIZE(ar9170_qmap) != __AR9170_NUM_TXQ);
>> >> > - BUILD_BUG_ON(NL80211_NUM_ACS > __AR9170_NUM_TXQ);
>> >> > + BUILD_BUG_ON((size_t)NL80211_NUM_ACS > (size_t)__AR9170_NUM_TXQ);
>> >>
>> >> IMHO this just makes the code worse. Does it make sense to workaround
>> >> (stupid) compiler warnings like this?
>> >
>> > True. What's worse: This isn't really code. The BUILD_BUG_ON Macro is there
>> > to guard but it's getting compiled away. I could also just drop it.
>>
>> Either way is fine for me. If the GCC (by default) emits a warning for
>> this we need to silence that warning, so in that respect I guess we
>> should apply this. Unless better solutions come up, of course :)
>
> Note: I dropped this patch from patchwork. So, there's nothing that
> needs to be done now ;)
Thanks, except I would prefer that I drop the patch myself :) In
numerous cases I have been wondering there a patch has disappeared and
only after a while I realise the submitter deleted the patch altogether
(which also destroys the conversation from patchwork etc). IMHO that's
really bad UX in patchwork, I should file a bug report about that.
So in general it's enough to say "Kalle, please drop the patch" and I'll
do the rest.
> Well, except OT: Would you mind adding the QCA4019 boardfiles that
> have accumulated over the past six-ish months?
Yeah, those are in my queue. But I'll first want to implement a script
so that I don't need to manually add all of them and I just haven't
found the time for that.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH] rt2x00: fix rx queue hang
From: Soeren Moch @ 2019-06-26 13:28 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Helmut Schaa, Kalle Valo, David S. Miller, linux-wireless, netdev,
linux-kernel, stable
In-Reply-To: <20190625095734.GA2886@redhat.com>
On 25.06.19 11:57, Stanislaw Gruszka wrote:
> Hello
>
> On Fri, Jun 21, 2019 at 01:30:01PM +0200, Soeren Moch wrote:
>> On 18.06.19 11:34, Stanislaw Gruszka wrote:
>>> Hi
>>>
>>> On Mon, Jun 17, 2019 at 11:46:56AM +0200, Soeren Moch wrote:
>>>> Since commit ed194d136769 ("usb: core: remove local_irq_save() around
>>>> ->complete() handler") the handlers rt2x00usb_interrupt_rxdone() and
>>>> rt2x00usb_interrupt_txdone() are not running with interrupts disabled
>>>> anymore. So these handlers are not guaranteed to run completely before
>>>> workqueue processing starts. So only mark entries ready for workqueue
>>>> processing after proper accounting in the dma done queue.
>>> It was always the case on SMP machines that rt2x00usb_interrupt_{tx/rx}done
>>> can run concurrently with rt2x00_work_{rx,tx}done, so I do not
>>> understand how removing local_irq_save() around complete handler broke
>>> things.
>> I think because completion handlers can be interrupted now and scheduled
>> away
>> in the middle of processing.
>>> Have you reverted commit ed194d136769 and the revert does solve the problem ?
>> Yes, I already sent a patch for this, see [1]. But this was not considered
>> an acceptablesolution. Especially RT folks do not like code running with
>> interrupts disabled,particularly when trying to acquire spinlocks then.
>>
>> [1] https://lkml.org/lkml/2019/5/31/863
>>> Between 4.19 and 4.20 we have some quite big changes in rt2x00 driver:
>>>
>>> 0240564430c0 rt2800: flush and txstatus rework for rt2800mmio
>>> adf26a356f13 rt2x00: use different txstatus timeouts when flushing
>>> 5022efb50f62 rt2x00: do not check for txstatus timeout every time on tasklet
>>> 0b0d556e0ebb rt2800mmio: use txdone/txstatus routines from lib
>>> 5c656c71b1bf rt2800: move usb specific txdone/txstatus routines to rt2800lib
>>>
>>> so I'm a bit afraid that one of those changes is real cause of
>>> the issue not ed194d136769 .
>> I tested 4.20 and 5.1 and see the exact same behavior. Reverting this
>> usb core patchsolves the problem.
>> 4.19.x (before this usb core patch) is running fine.
>>>> Note that rt2x00usb_work_rxdone() processes all available entries, not
>>>> only such for which queue_work() was called.
>>>>
>>>> This fixes a regression on a RT5370 based wifi stick in AP mode, which
>>>> suddenly stopped data transmission after some period of heavy load. Also
>>>> stopping the hanging hostapd resulted in the error message "ieee80211
>>>> phy0: rt2x00queue_flush_queue: Warning - Queue 14 failed to flush".
>>>> Other operation modes are probably affected as well, this just was
>>>> the used testcase.
>>> Do you know what actually make the traffic stop,
>>> TX queue hung or RX queue hung?
>> I think RX queue hang, as stated in the patch title. "Queue 14" means QID_RX
>> (rt2x00queue.h, enum data_queue_qid).
>> I also tried to re-add local_irq_save() in only one of the handlers. Adding
>> this tort2x00usb_interrupt_rxdone() alone solved the issue, while doing so
>> for tx alonedid not.
>>
>> Note that this doesn't mean there is no problem for tx, that's maybe
>> just more
>> difficult to trigger.
>>>> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
>>>> index 1b08b01db27b..9c102a501ee6 100644
>>>> --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
>>>> +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
>>>> @@ -263,9 +263,9 @@ EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
>>>>
>>>> void rt2x00lib_dmadone(struct queue_entry *entry)
>>>> {
>>>> - set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
>>>> clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
>>>> rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE);
>>>> + set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
>>> Unfortunately I do not understand how this suppose to fix the problem,
>>> could you elaborate more about this change?
>>>
>> Re-adding local_irq_save() around thisrt2x00lib_dmadone()solved
>> the issue. So I also tried to reverse the order of these calls.
>> It seems totally plausible to me, that the correct sequence is to
>> first clear the device assignment, then to set the status to dma_done,
>> then to trigger the workqueue processing for this entry. When the handler
>> is scheduled away in the middle of this sequence, now there is no
>> strange state where the entry can be processed by the workqueue while
>> not declared dma_done for it.
>> With this changed sequence there is no need anymore to disable interrupts
>> for solving the hang issue.
> Thanks very much for explanations. However I still do not fully
> understand the issue. Q_INDEX_DMA_DONE index is only checked on TX
> processing (on RX we use only Q_INDEX_DONE and Q_INDEX) and
> ENTRY_OWNER_DEVICE_DATA is already cleared before rt2x00lib_dmadone()
> in rt2x00usb_interrupt_rxdone() .
>
> So I'm not sure how changing the order solve the problem. Looks
> for me that the issue is triggered by some rt2x00lib_dmadone()
> call done on error path (not in rt2x00usb_interrupt_rxdone())
> and it race with this check:
>
> if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
> test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
> return false;
>
> in rt2x00usb_kick_rx_entry() - we return instead of submit urb.
Hi Stanislaw,
the good news is: your patch below also solves the issue for me. But
removing the ENTRY_DATA_STATUS_PENDING check in
rt2x00usb_kick_rx_entry() alone does not help, while removing this check
in rt2x00usb_work_rxdone() alone does the trick.
So the real race seems to be that the flags set in the completion
handler are not yet visible on the cpu core running the workqueue. And
because the worker is not rescheduled when aborted, the entry can just
wait forever.
Do you think this could make sense?
> I'm somewhat reluctant to change the order, because TX processing
> might relay on it (we first mark we wait for TX status and
> then mark entry is no longer owned by hardware).
OK, maybe it's just good luck that changing the order solves the rx
problem. Or can memory barriers associated with the spinlock in
rt2x00lib_dmadone() be responsible for that?
(I'm testing on a armv7 system, Cortex-A9 quadcore.)
While looking at it, why we double-clear ENTRY_OWNER_DEVICE_DATA in
rt2x00usb_interrupt_rxdone() directly and in rt2x00lib_dmadone() again,
while not doing the same for tx? Would it make more sense to possibly
set ENTRY_DATA_IO_FAILED before clearing ENTRY_OWNER_DEVICE_DATA in
rt2x00usb_interrupt_rxdone() as for tx?
> However on RX
> side ENTRY_DATA_STATUS_PENDING bit make no sense as we do not
> wait for status. We should remove ENTRY_DATA_STATUS_PENDING on
> RX side and perhaps this also will solve issue you observe.
I agree that removing the unnecessary checks is a good idea in any case.
> Could you please check below patch, if it fixes the problem as well?
At least I could not trigger the problem within transferring 10GB of
data. But maybe the probability for triggering this bug is just lower
because ENTRY_OWNER_DEVICE_DATA is cleared some time before
ENTRY_DATA_STATUS_PENDING is set?
Soeren
>
> Stanislaw
>
> diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
> index b6c1344..731e633 100644
> --- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
> +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
> @@ -360,8 +360,7 @@ static void rt2x00usb_work_rxdone(struct work_struct *work)
> while (!rt2x00queue_empty(rt2x00dev->rx)) {
> entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE);
>
> - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
> - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
> + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
> break;
>
> /*
> @@ -413,8 +412,7 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void *data)
> struct queue_entry_priv_usb *entry_priv = entry->priv_data;
> int status;
>
> - if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
> - test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
> + if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
> return false;
>
> rt2x00lib_dmastart(entry);
^ permalink raw reply
* Re: [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Carpenter @ 2019-06-26 13:23 UTC (permalink / raw)
To: Dan Williams
Cc: Kalle Valo, Philip Rakity, Lubomir Rintel, kernel-janitors,
linux-wireless, Allison Randal, libertas-dev
In-Reply-To: <be491ab35ba46111a1c90cc12b6d5ff6ea3f57e8.camel@redhat.com>
Yeah. That looks nicer. Could you send it as a proper patch and give
me Reported-by credit?
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Williams @ 2019-06-26 13:16 UTC (permalink / raw)
To: Dan Carpenter, Kalle Valo, Philip Rakity
Cc: Lubomir Rintel, kernel-janitors, linux-wireless, Allison Randal,
libertas-dev
In-Reply-To: <20190626100926.GD3242@mwanda>
On Wed, 2019-06-26 at 13:09 +0300, Dan Carpenter wrote:
> The lbs_process_rxed_packet() frees the skb. It didn't originally,
> but
> we fixed it in commit f54930f36311 ("libertas: don't leak skb on
> receive
> error").
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> drivers/net/wireless/marvell/libertas/if_spi.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c
> b/drivers/net/wireless/marvell/libertas/if_spi.c
> index 27067e79e83f..e38f02d1f2e4 100644
> --- a/drivers/net/wireless/marvell/libertas/if_spi.c
> +++ b/drivers/net/wireless/marvell/libertas/if_spi.c
> @@ -772,7 +772,7 @@ static int if_spi_c2h_data(struct if_spi_card
> *card)
> /* pass the SKB to libertas */
> err = lbs_process_rxed_packet(card->priv, skb);
> if (err)
> - goto free_skb;
> + goto out; /* lbs_process_rxed_packet() frees skb */
>
> /* success */
> goto out;
It can be further simplified (not compile tested yet):
diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c
index 27067e79e83fe..072da89c4986f 100644
--- a/drivers/net/wireless/marvell/libertas/if_spi.c
+++ b/drivers/net/wireless/marvell/libertas/if_spi.c
@@ -766,19 +766,15 @@ static int if_spi_c2h_data(struct if_spi_card *card)
/* Read the data from the WLAN module into our skb... */
err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4));
- if (err)
- goto free_skb;
+ if (err) {
+ dev_kfree_skb(skb);
+ goto out
+ }
/* pass the SKB to libertas */
err = lbs_process_rxed_packet(card->priv, skb);
- if (err)
- goto free_skb;
+ /* lbs_process_rxed_packet() consumes the skb */
- /* success */
- goto out;
-
-free_skb:
- dev_kfree_skb(skb);
out:
if (err)
netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
^ permalink raw reply related
* [PATCH 6/8] staging: wilc1000: remove use of 'src_addr' element in 'wilc_vif' struct
From: Ajay.Kathat @ 2019-06-26 12:41 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
Remove use of 'src_addr' element in wilc_vif, as the same information
already copied to net_device->dev_addr.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/wilc_netdev.c | 3 +--
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 2 +-
drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 -
3 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index 0af60b2..565e2b5 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -638,8 +638,7 @@ static int wilc_mac_open(struct net_device *ndev)
wilc_get_mac_address(vif, mac_add);
netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
- memcpy(vif->src_addr, mac_add, ETH_ALEN);
- memcpy(ndev->dev_addr, vif->src_addr, ETH_ALEN);
+ ether_addr_copy(ndev->dev_addr, mac_add);
if (!is_valid_ether_addr(ndev->dev_addr)) {
netdev_err(ndev, "Wrong MAC address\n");
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 1580909..d72fdd3 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -1499,7 +1499,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
if (ret != 0)
netdev_err(dev, "Error in setting channel\n");
- wilc_wlan_set_bssid(dev, vif->src_addr, WILC_AP_MODE);
+ wilc_wlan_set_bssid(dev, dev->dev_addr, WILC_AP_MODE);
wilc_set_power_mgmt(vif, 0, 0);
return wilc_add_beacon(vif, settings->beacon_interval,
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index d5d830d..e28c8de 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -198,7 +198,6 @@ struct wilc_vif {
struct frame_reg frame_reg[NUM_REG_FRAME];
struct net_device_stats netstats;
struct wilc *wilc;
- u8 src_addr[ETH_ALEN];
u8 bssid[ETH_ALEN];
struct host_if_drv *hif_drv;
struct net_device *ndev;
--
2.7.4
^ permalink raw reply related
* [PATCH 8/8] staging: wilc1000: rename 'host_interface' source and header
From: Ajay.Kathat @ 2019-06-26 12:41 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
Rename 'host_interface' source and header file to include the 'wilc_'
prefix in its name.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/Makefile | 2 +-
drivers/staging/wilc1000/{host_interface.c => wilc_hif.c} | 0
drivers/staging/wilc1000/{host_interface.h => wilc_hif.h} | 0
drivers/staging/wilc1000/wilc_wfi_netdevice.h | 2 +-
4 files changed, 2 insertions(+), 2 deletions(-)
rename drivers/staging/wilc1000/{host_interface.c => wilc_hif.c} (100%)
rename drivers/staging/wilc1000/{host_interface.h => wilc_hif.h} (100%)
diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile
index 2ad3fee..a5a8e80 100644
--- a/drivers/staging/wilc1000/Makefile
+++ b/drivers/staging/wilc1000/Makefile
@@ -5,7 +5,7 @@ ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \
-DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\"
wilc1000-objs := wilc_wfi_cfgoperations.o wilc_netdev.o wilc_mon.o \
- host_interface.o wilc_wlan_cfg.o wilc_wlan.o
+ wilc_hif.o wilc_wlan_cfg.o wilc_wlan.o
obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o
wilc1000-sdio-objs += wilc_sdio.o
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/wilc_hif.c
similarity index 100%
rename from drivers/staging/wilc1000/host_interface.c
rename to drivers/staging/wilc1000/wilc_hif.c
diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/wilc_hif.h
similarity index 100%
rename from drivers/staging/wilc1000/host_interface.h
rename to drivers/staging/wilc1000/wilc_hif.h
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index e28c8de..1e74a08 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -14,7 +14,7 @@
#include <linux/if_arp.h>
#include <linux/gpio/consumer.h>
-#include "host_interface.h"
+#include "wilc_hif.h"
#include "wilc_wlan.h"
#include "wilc_wlan_cfg.h"
--
2.7.4
^ permalink raw reply related
* [PATCH 4/8] staging: wilc1000: remove use of driver_handler_id & ifc_id
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
Removed the 'driver_handler_id' & 'ifc_id' elements and used 'idx' to
identify the handler.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/host_interface.c | 3 +--
drivers/staging/wilc1000/host_interface.h | 1 -
drivers/staging/wilc1000/wilc_netdev.c | 3 +--
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 5 ++---
drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 -
5 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index b505990..389f9f8c 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1472,7 +1472,7 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
drv.mode = (ifc_id | (mode << 1));
result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- hif_drv->driver_handler_id);
+ wilc_get_vif_idx(vif));
if (result)
netdev_err(vif->ndev, "Failed to set driver handler\n");
@@ -1644,7 +1644,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
for (i = 0; i < wilc->vif_num; i++)
if (dev == wilc->vif[i]->ndev) {
wilc->vif[i]->hif_drv = hif_drv;
- hif_drv->driver_handler_id = i + 1;
break;
}
diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h
index 4fcc7a3..be1d249 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -166,7 +166,6 @@ struct host_if_drv {
struct wilc_vif *remain_on_ch_timer_vif;
bool ifc_up;
- int driver_handler_id;
u8 assoc_resp[WILC_MAX_ASSOC_RESP_FRAME_SIZE];
};
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index 9006111..ad04744 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -636,7 +636,7 @@ static int wilc_mac_open(struct net_device *ndev)
for (i = 0; i < wl->vif_num; i++) {
if (ndev == wl->vif[i]->ndev) {
wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
- vif->iftype, vif->ifc_id);
+ vif->iftype, vif->idx);
wilc_set_operation_mode(vif, vif->iftype);
break;
}
@@ -995,7 +995,6 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
ndev->needs_free_netdev = true;
vif->iftype = vif_type;
vif->wilc->vif[wl->vif_num] = vif;
- vif->ifc_id = wl->vif_num;
vif->idx = wl->vif_num;
wl->vif_num += 1;
vif->mac_opened = 0;
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 012e325..1580909 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -1462,7 +1462,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
if (wl->initialized) {
wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
- 0, vif->ifc_id);
+ 0, vif->idx);
wilc_set_operation_mode(vif, WILC_AP_MODE);
wilc_set_power_mgmt(vif, 0, 0);
}
@@ -1693,11 +1693,10 @@ static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
wl->vif[i] = NULL;
} else {
vif = wl->vif[i + 1];
- vif->ifc_id = i;
vif->idx = i;
wl->vif[i] = vif;
wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
- vif->iftype, vif->ifc_id);
+ vif->iftype, vif->idx);
}
}
wl->vif_num--;
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index fca3380..d5d830d 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -203,7 +203,6 @@ struct wilc_vif {
struct host_if_drv *hif_drv;
struct net_device *ndev;
u8 mode;
- u8 ifc_id;
struct timer_list during_ip_timer;
bool obtaining_ip;
struct timer_list periodic_rssi;
--
2.7.4
^ permalink raw reply related
* [PATCH 7/8] staging: wilc1000: remove extra argument passing to wilc_send_config_pkt()
From: Ajay.Kathat @ 2019-06-26 12:41 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
Cleanup patch to remove the passing of driver handler, get the 'idx'
value inside the called function.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/host_interface.c | 116 ++++++++++--------------------
drivers/staging/wilc1000/wilc_wlan.c | 3 +-
drivers/staging/wilc1000/wilc_wlan.h | 2 +-
3 files changed, 40 insertions(+), 81 deletions(-)
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 3688088..9345cab 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -205,9 +205,7 @@ static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
wid.val = (s8 *)&abort_running_scan;
wid.size = sizeof(char);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
-
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result) {
netdev_err(vif->ndev, "Failed to set abort running\n");
result = -EFAULT;
@@ -328,9 +326,7 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
hif_drv->usr_scan_req.scan_result = scan_result_fn;
hif_drv->usr_scan_req.arg = user_arg;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
- index,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, index);
if (result) {
netdev_err(vif->ndev, "Failed to send scan parameters\n");
goto error;
@@ -380,9 +376,7 @@ static int wilc_send_connect_wid(struct wilc_vif *vif)
wid_list[wid_cnt].val = (u8 *)bss_param;
wid_cnt++;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
- wid_cnt,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, wid_cnt);
if (result) {
netdev_err(vif->ndev, "failed to send config packet\n");
goto error;
@@ -430,8 +424,7 @@ static void handle_connect_timeout(struct work_struct *work)
wid.val = (s8 *)&dummy_reason_code;
wid.size = sizeof(char);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to send disconnect\n");
@@ -619,8 +612,7 @@ static void host_int_get_assoc_res_info(struct wilc_vif *vif,
wid.val = assoc_resp_info;
wid.size = max_assoc_resp_info_len;
- result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
if (result) {
*rcvd_assoc_resp_info_len = 0;
netdev_err(vif->ndev, "Failed to send association response\n");
@@ -783,8 +775,7 @@ int wilc_disconnect(struct wilc_vif *vif)
vif->obtaining_ip = false;
wilc_set_power_mgmt(vif, 0, 0);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result) {
netdev_err(vif->ndev, "Failed to send disconnect\n");
return result;
@@ -864,10 +855,7 @@ int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
wid_list[wid_cnt].val = (s8 *)&stats->tx_fail_cnt;
wid_cnt++;
- result = wilc_send_config_pkt(vif, WILC_GET_CFG, wid_list,
- wid_cnt,
- wilc_get_vif_idx(vif));
-
+ result = wilc_send_config_pkt(vif, WILC_GET_CFG, wid_list, wid_cnt);
if (result) {
netdev_err(vif->ndev, "Failed to send scan parameters\n");
return result;
@@ -950,8 +938,7 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
wid.val[0] = remain_on_chan_flag;
wid.val[1] = (s8)hif_remain_ch->ch;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
kfree(wid.val);
if (result)
return -EBUSY;
@@ -986,8 +973,7 @@ static int wilc_handle_roc_expired(struct wilc_vif *vif, u64 cookie)
wid.val[0] = remain_on_chan_flag;
wid.val[1] = WILC_FALSE_FRMWR_CHANNEL;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
kfree(wid.val);
if (result != 0) {
netdev_err(vif->ndev, "Failed to set remain channel\n");
@@ -1062,8 +1048,7 @@ static void handle_set_mcast_filter(struct work_struct *work)
if (set_mc->cnt > 0 && set_mc->mc_list)
memcpy(cur_byte, set_mc->mc_list, set_mc->cnt * ETH_ALEN);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to send setup multicast\n");
@@ -1139,8 +1124,7 @@ int wilc_remove_wep_key(struct wilc_vif *vif, u8 index)
wid.size = sizeof(char);
wid.val = &index;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev,
"Failed to send remove wep key config packet\n");
@@ -1156,8 +1140,7 @@ int wilc_set_wep_default_keyid(struct wilc_vif *vif, u8 index)
wid.type = WID_CHAR;
wid.size = sizeof(char);
wid.val = &index;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev,
"Failed to send wep default key config packet\n");
@@ -1185,8 +1168,7 @@ int wilc_add_wep_key_bss_sta(struct wilc_vif *vif, const u8 *key, u8 len,
wep_key->key_len = len;
memcpy(wep_key->key, key, len);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev,
"Failed to add wep key config packet\n");
@@ -1225,8 +1207,7 @@ int wilc_add_wep_key_bss_ap(struct wilc_vif *vif, const u8 *key, u8 len,
wep_key->key_len = len;
memcpy(wep_key->key, key, len);
result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
- ARRAY_SIZE(wid_list),
- wilc_get_vif_idx(vif));
+ ARRAY_SIZE(wid_list));
if (result)
netdev_err(vif->ndev,
"Failed to add wep ap key config packet\n");
@@ -1273,8 +1254,7 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
wid_list[1].size = sizeof(*key_buf) + t_key_len;
wid_list[1].val = (u8 *)key_buf;
result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
- ARRAY_SIZE(wid_list),
- wilc_get_vif_idx(vif));
+ ARRAY_SIZE(wid_list));
kfree(key_buf);
} else if (mode == WILC_STATION_MODE) {
struct wid wid;
@@ -1300,8 +1280,7 @@ int wilc_add_ptk(struct wilc_vif *vif, const u8 *ptk, u8 ptk_key_len,
wid.type = WID_STR;
wid.size = sizeof(*key_buf) + t_key_len;
wid.val = (s8 *)key_buf;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
kfree(key_buf);
}
@@ -1353,8 +1332,7 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
wid_list[1].val = (u8 *)gtk_key;
result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
- ARRAY_SIZE(wid_list),
- wilc_get_vif_idx(vif));
+ ARRAY_SIZE(wid_list));
} else if (mode == WILC_STATION_MODE) {
struct wid wid;
@@ -1362,8 +1340,7 @@ int wilc_add_rx_gtk(struct wilc_vif *vif, const u8 *rx_gtk, u8 gtk_key_len,
wid.type = WID_STR;
wid.size = sizeof(*gtk_key) + t_key_len;
wid.val = (u8 *)gtk_key;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
}
kfree(gtk_key);
@@ -1379,8 +1356,7 @@ int wilc_set_pmkid_info(struct wilc_vif *vif, struct wilc_pmkid_attr *pmkid)
wid.size = (pmkid->numpmkid * sizeof(struct wilc_pmkid)) + 1;
wid.val = (u8 *)pmkid;
- return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
}
int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
@@ -1393,8 +1369,7 @@ int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
wid.size = ETH_ALEN;
wid.val = mac_addr;
- result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to get mac address\n");
@@ -1444,8 +1419,7 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
wid.size = sizeof(char);
wid.val = &channel;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to set channel\n");
@@ -1471,8 +1445,7 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
drv.handler = cpu_to_le32(index);
drv.mode = (ifc_id | (mode << 1));
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to set driver handler\n");
@@ -1492,8 +1465,7 @@ int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
op_mode.mode = cpu_to_le32(mode);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to set operation mode\n");
@@ -1513,8 +1485,7 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
return -ENOMEM;
ether_addr_copy(wid.val, mac);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
kfree(wid.val);
if (result) {
netdev_err(vif->ndev, "Failed to set inactive mac\n");
@@ -1525,8 +1496,7 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
wid.type = WID_INT;
wid.val = (s8 *)out_val;
wid.size = sizeof(u32);
- result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to get inactive time\n");
@@ -1547,8 +1517,7 @@ int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
wid.type = WID_CHAR;
wid.size = sizeof(char);
wid.val = rssi_level;
- result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to get RSSI value\n");
@@ -1610,8 +1579,7 @@ int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *param)
i++;
}
- return wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
- i, wilc_get_vif_idx(vif));
+ return wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list, i);
}
static void get_periodic_rssi(struct timer_list *t)
@@ -1876,8 +1844,7 @@ void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
break;
}
reg_frame.frame_type = cpu_to_le16(frame_type);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to frame register\n");
}
@@ -1914,8 +1881,7 @@ int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
if (params->tail_len > 0)
memcpy(cur_byte, params->tail, params->tail_len);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to send add beacon\n");
@@ -1935,8 +1901,7 @@ int wilc_del_beacon(struct wilc_vif *vif)
wid.size = sizeof(char);
wid.val = &del_beacon;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to send delete beacon\n");
@@ -1960,8 +1925,7 @@ int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
cur_byte = wid.val;
wilc_hif_pack_sta_param(cur_byte, mac, params);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result != 0)
netdev_err(vif->ndev, "Failed to send add station\n");
@@ -1987,8 +1951,7 @@ int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr)
else
ether_addr_copy(wid.val, mac_addr);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to del station\n");
@@ -2023,8 +1986,7 @@ int wilc_del_allstation(struct wilc_vif *vif, u8 mac_addr[][ETH_ALEN])
wid.size = (assoc_sta * ETH_ALEN) + 1;
wid.val = (u8 *)&del_sta;
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to send delete all station\n");
@@ -2048,8 +2010,7 @@ int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
cur_byte = wid.val;
wilc_hif_pack_sta_param(cur_byte, mac, params);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to send edit station\n");
@@ -2074,8 +2035,7 @@ int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout)
wid.id = WID_POWER_MANAGEMENT;
wid.val = &power_mode;
wid.size = sizeof(char);
- result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ result = wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
if (result)
netdev_err(vif->ndev, "Failed to send power management\n");
@@ -2113,8 +2073,7 @@ int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power)
wid.val = &tx_power;
wid.size = sizeof(char);
- return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ return wilc_send_config_pkt(vif, WILC_SET_CFG, &wid, 1);
}
int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
@@ -2126,6 +2085,5 @@ int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power)
wid.val = tx_power;
wid.size = sizeof(char);
- return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1,
- wilc_get_vif_idx(vif));
+ return wilc_send_config_pkt(vif, WILC_GET_CFG, &wid, 1);
}
diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c
index bd2ffc3..d46876e 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -1202,10 +1202,11 @@ int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, u32 buffer_size)
}
int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
- u32 count, u32 drv)
+ u32 count)
{
int i;
int ret = 0;
+ u32 drv = wilc_get_vif_idx(vif);
if (mode == WILC_GET_CFG) {
for (i = 0; i < count; i++) {
diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h
index 3e54a56..d2eef7b 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -307,7 +307,7 @@ void host_sleep_notify(struct wilc *wilc);
void chip_allow_sleep(struct wilc *wilc);
void chip_wakeup(struct wilc *wilc);
int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
- u32 count, u32 drv);
+ u32 count);
int wilc_wlan_init(struct net_device *dev);
u32 wilc_get_chipid(struct wilc *wilc, bool update);
#endif
--
2.7.4
^ permalink raw reply related
* [PATCH 5/8] staging: wilc1000: remove unnecessary loop to traverse vif interfaces
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
Cleanup patch to avoid loop to traverse the interfaces instead make use
of vif received from net_device priv data.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/host_interface.c | 7 +------
drivers/staging/wilc1000/wilc_netdev.c | 16 +++++-----------
2 files changed, 6 insertions(+), 17 deletions(-)
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 389f9f8c..3688088 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1634,19 +1634,14 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
struct host_if_drv *hif_drv;
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
- int i;
hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL);
if (!hif_drv)
return -ENOMEM;
*hif_drv_handler = hif_drv;
- for (i = 0; i < wilc->vif_num; i++)
- if (dev == wilc->vif[i]->ndev) {
- wilc->vif[i]->hif_drv = hif_drv;
- break;
- }
+ vif->hif_drv = hif_drv;
vif->obtaining_ip = false;
if (wilc->clients_count == 0)
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index ad04744..0af60b2 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -614,7 +614,6 @@ static int wilc_mac_open(struct net_device *ndev)
struct wilc_priv *priv = wdev_priv(vif->ndev->ieee80211_ptr);
unsigned char mac_add[ETH_ALEN] = {0};
int ret = 0;
- int i = 0;
if (!wl || !wl->dev) {
netdev_err(ndev, "device not ready\n");
@@ -633,19 +632,14 @@ static int wilc_mac_open(struct net_device *ndev)
return ret;
}
- for (i = 0; i < wl->vif_num; i++) {
- if (ndev == wl->vif[i]->ndev) {
- wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
- vif->iftype, vif->idx);
- wilc_set_operation_mode(vif, vif->iftype);
- break;
- }
- }
+ wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), vif->iftype,
+ vif->idx);
+ wilc_set_operation_mode(vif, vif->iftype);
wilc_get_mac_address(vif, mac_add);
netdev_dbg(ndev, "Mac address: %pM\n", mac_add);
- memcpy(wl->vif[i]->src_addr, mac_add, ETH_ALEN);
- memcpy(ndev->dev_addr, wl->vif[i]->src_addr, ETH_ALEN);
+ memcpy(vif->src_addr, mac_add, ETH_ALEN);
+ memcpy(ndev->dev_addr, vif->src_addr, ETH_ALEN);
if (!is_valid_ether_addr(ndev->dev_addr)) {
netdev_err(ndev, "Wrong MAC address\n");
--
2.7.4
^ permalink raw reply related
* [PATCH 3/8] staging: wilc1000: added support to dynamically add/remove interfaces
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
Removed the use of two hardcoded interfaces and added support to
add/remove the network interfaces dynamically.
Now the driver will have single default interface with name 'wlan0' and
later other interface can be added from user space application e.g
using 'iw add' command.
Also taken care to maintain 'wilc_vif' as part of 'net_device'
private data and 'wilc' struct as 'wiphy' private data.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/wilc_mon.c | 9 +-
drivers/staging/wilc1000/wilc_netdev.c | 269 ++++-------
drivers/staging/wilc1000/wilc_sdio.c | 7 +-
drivers/staging/wilc1000/wilc_spi.c | 3 +-
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 535 ++++++++++++++--------
drivers/staging/wilc1000/wilc_wfi_cfgoperations.h | 13 +-
drivers/staging/wilc1000/wilc_wfi_netdevice.h | 20 +-
drivers/staging/wilc1000/wilc_wlan.c | 20 +-
drivers/staging/wilc1000/wilc_wlan.h | 6 +-
9 files changed, 492 insertions(+), 390 deletions(-)
diff --git a/drivers/staging/wilc1000/wilc_mon.c b/drivers/staging/wilc1000/wilc_mon.c
index 9fe19a3..7d7933d4 100644
--- a/drivers/staging/wilc1000/wilc_mon.c
+++ b/drivers/staging/wilc1000/wilc_mon.c
@@ -233,6 +233,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
strncpy(wl->monitor_dev->name, name, IFNAMSIZ);
wl->monitor_dev->name[IFNAMSIZ - 1] = 0;
wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
+ wl->monitor_dev->needs_free_netdev = true;
if (register_netdevice(wl->monitor_dev)) {
netdev_err(real_dev, "register_netdevice failed\n");
@@ -247,12 +248,14 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
return wl->monitor_dev;
}
-void wilc_wfi_deinit_mon_interface(struct wilc *wl)
+void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked)
{
if (!wl->monitor_dev)
return;
- unregister_netdev(wl->monitor_dev);
- free_netdev(wl->monitor_dev);
+ if (rtnl_locked)
+ unregister_netdevice(wl->monitor_dev);
+ else
+ unregister_netdev(wl->monitor_dev);
wl->monitor_dev = NULL;
}
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index 0e0a4ee..9006111 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -97,22 +97,29 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
{
u8 *bssid, *bssid1;
int i = 0;
+ struct net_device *ndev = NULL;
bssid = mac_header + 10;
bssid1 = mac_header + 4;
+ mutex_lock(&wilc->vif_mutex);
for (i = 0; i < wilc->vif_num; i++) {
if (wilc->vif[i]->mode == WILC_STATION_MODE)
if (ether_addr_equal_unaligned(bssid,
- wilc->vif[i]->bssid))
- return wilc->vif[i]->ndev;
+ wilc->vif[i]->bssid)) {
+ ndev = wilc->vif[i]->ndev;
+ goto out;
+ }
if (wilc->vif[i]->mode == WILC_AP_MODE)
if (ether_addr_equal_unaligned(bssid1,
- wilc->vif[i]->bssid))
- return wilc->vif[i]->ndev;
+ wilc->vif[i]->bssid)) {
+ ndev = wilc->vif[i]->ndev;
+ goto out;
+ }
}
-
- return NULL;
+out:
+ mutex_unlock(&wilc->vif_mutex);
+ return ndev;
}
void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode)
@@ -143,9 +150,7 @@ static int wilc_txq_task(void *vp)
{
int ret;
u32 txq_count;
- struct net_device *dev = vp;
- struct wilc_vif *vif = netdev_priv(dev);
- struct wilc *wl = vif->wilc;
+ struct wilc *wl = vp;
complete(&wl->txq_thread_started);
while (1) {
@@ -159,14 +164,18 @@ static int wilc_txq_task(void *vp)
break;
}
do {
- ret = wilc_wlan_handle_txq(dev, &txq_count);
+ ret = wilc_wlan_handle_txq(wl, &txq_count);
if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
- if (wl->vif[0]->mac_opened &&
- netif_queue_stopped(wl->vif[0]->ndev))
- netif_wake_queue(wl->vif[0]->ndev);
- if (wl->vif[1]->mac_opened &&
- netif_queue_stopped(wl->vif[1]->ndev))
- netif_wake_queue(wl->vif[1]->ndev);
+ int i;
+ struct wilc_vif *ifc;
+
+ mutex_lock(&wl->vif_mutex);
+ for (i = 0; i < wl->vif_num; i++) {
+ ifc = wl->vif[i];
+ if (ifc->mac_opened && ifc->ndev)
+ netif_wake_queue(ifc->ndev);
+ }
+ mutex_unlock(&wl->vif_mutex);
}
} while (ret == -ENOBUFS && !wl->close);
}
@@ -245,14 +254,13 @@ static int wilc1000_firmware_download(struct net_device *dev)
static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif)
{
- struct wilc_priv *priv;
+ struct wilc_priv *priv = &vif->priv;
struct host_if_drv *hif_drv;
u8 b;
u16 hw;
u32 w;
netdev_dbg(dev, "Start configuring Firmware\n");
- priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
hif_drv = (struct host_if_drv *)priv->hif_drv;
netdev_dbg(dev, "Host = %p\n", hif_drv);
@@ -424,6 +432,7 @@ static void wlan_deinit_locks(struct net_device *dev)
mutex_destroy(&wilc->rxq_cs);
mutex_destroy(&wilc->cfg_cmd_lock);
mutex_destroy(&wilc->txq_add_to_head_cs);
+ mutex_destroy(&wilc->vif_mutex);
}
static void wlan_deinitialize_threads(struct net_device *dev)
@@ -477,31 +486,12 @@ static void wilc_wlan_deinitialize(struct net_device *dev)
}
}
-static void wlan_init_locks(struct net_device *dev)
-{
- struct wilc_vif *vif = netdev_priv(dev);
- struct wilc *wl = vif->wilc;
-
- mutex_init(&wl->hif_cs);
- mutex_init(&wl->rxq_cs);
- mutex_init(&wl->cfg_cmd_lock);
-
- spin_lock_init(&wl->txq_spinlock);
- mutex_init(&wl->txq_add_to_head_cs);
-
- init_completion(&wl->txq_event);
-
- init_completion(&wl->cfg_event);
- init_completion(&wl->sync_event);
- init_completion(&wl->txq_thread_started);
-}
-
static int wlan_initialize_threads(struct net_device *dev)
{
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
- wilc->txq_thread = kthread_run(wilc_txq_task, (void *)dev,
+ wilc->txq_thread = kthread_run(wilc_txq_task, (void *)wilc,
"K_TXQ_TASK");
if (IS_ERR(wilc->txq_thread)) {
netdev_err(dev, "couldn't create TXQ thread\n");
@@ -513,6 +503,12 @@ static int wlan_initialize_threads(struct net_device *dev)
return 0;
}
+static int dev_state_ev_handler(struct notifier_block *this,
+ unsigned long event, void *ptr);
+static struct notifier_block g_dev_notifier = {
+ .notifier_call = dev_state_ev_handler
+};
+
static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
{
int ret = 0;
@@ -522,13 +518,9 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
wl->mac_status = WILC_MAC_STATUS_INIT;
wl->close = 0;
- wlan_init_locks(dev);
-
ret = wilc_wlan_init(dev);
- if (ret < 0) {
- ret = -EIO;
- goto fail_locks;
- }
+ if (ret < 0)
+ return -EIO;
ret = wlan_initialize_threads(dev);
if (ret < 0) {
@@ -582,7 +574,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
ret = -EIO;
goto fail_fw_start;
}
-
+ register_inetaddr_notifier(&g_dev_notifier);
wl->initialized = true;
return 0;
@@ -600,8 +592,6 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
wlan_deinitialize_threads(dev);
fail_wilc_wlan:
wilc_wlan_cleanup(dev);
-fail_locks:
- wlan_deinit_locks(dev);
netdev_err(dev, "WLAN initialization FAILED\n");
} else {
netdev_dbg(dev, "wilc1000 already initialized\n");
@@ -758,16 +748,19 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
vif->netstats.tx_packets++;
vif->netstats.tx_bytes += tx_data->size;
- tx_data->bssid = wilc->vif[vif->idx]->bssid;
queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data,
tx_data->buff, tx_data->size,
wilc_tx_complete);
if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
- if (wilc->vif[0]->mac_opened)
- netif_stop_queue(wilc->vif[0]->ndev);
- if (wilc->vif[1]->mac_opened)
- netif_stop_queue(wilc->vif[1]->ndev);
+ int i;
+
+ mutex_lock(&wilc->vif_mutex);
+ for (i = 0; i < wilc->vif_num; i++) {
+ if (wilc->vif[i]->mac_opened)
+ netif_stop_queue(wilc->vif[i]->ndev);
+ }
+ mutex_unlock(&wilc->vif_mutex);
}
return 0;
@@ -794,6 +787,7 @@ static int wilc_mac_close(struct net_device *ndev)
if (wl->open_ifcs == 0) {
netdev_dbg(ndev, "Deinitializing wilc1000\n");
wl->close = 1;
+ unregister_inetaddr_notifier(&g_dev_notifier);
wilc_wlan_deinitialize(ndev);
}
@@ -848,18 +842,23 @@ void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
int i = 0;
struct wilc_vif *vif;
+ mutex_lock(&wilc->vif_mutex);
for (i = 0; i < wilc->vif_num; i++) {
+ u16 type = le16_to_cpup((__le16 *)buff);
+
vif = netdev_priv(wilc->vif[i]->ndev);
+ if ((type == vif->frame_reg[0].type && vif->frame_reg[0].reg) ||
+ (type == vif->frame_reg[1].type && vif->frame_reg[1].reg)) {
+ wilc_wfi_p2p_rx(vif, buff, size);
+ break;
+ }
+
if (vif->monitor_flag) {
wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size);
- return;
+ break;
}
}
-
- vif = netdev_priv(wilc->vif[1]->ndev);
- if ((buff[0] == vif->frame_reg[0].type && vif->frame_reg[0].reg) ||
- (buff[0] == vif->frame_reg[1].type && vif->frame_reg[1].reg))
- wilc_wfi_p2p_rx(wilc->vif[1]->ndev, buff, size);
+ mutex_unlock(&wilc->vif_mutex);
}
static const struct net_device_ops wilc_netdev_ops = {
@@ -890,14 +889,10 @@ static int dev_state_ev_handler(struct notifier_block *this,
if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy)
return NOTIFY_DONE;
- priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
- if (!priv)
- return NOTIFY_DONE;
+ vif = netdev_priv(dev);
+ priv = &vif->priv;
hif_drv = (struct host_if_drv *)priv->hif_drv;
- vif = netdev_priv(dev);
- if (!vif || !hif_drv)
- return NOTIFY_DONE;
switch (event) {
case NETDEV_UP:
@@ -932,10 +927,6 @@ static int dev_state_ev_handler(struct notifier_block *this,
return NOTIFY_DONE;
}
-static struct notifier_block g_dev_notifier = {
- .notifier_call = dev_state_ev_handler
-};
-
void wilc_netdev_cleanup(struct wilc *wilc)
{
int i;
@@ -943,136 +934,72 @@ void wilc_netdev_cleanup(struct wilc *wilc)
if (!wilc)
return;
- if (wilc->vif[0]->ndev || wilc->vif[1]->ndev)
- unregister_inetaddr_notifier(&g_dev_notifier);
-
if (wilc->firmware) {
release_firmware(wilc->firmware);
wilc->firmware = NULL;
}
- for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) {
- if (wilc->vif[i] && wilc->vif[i]->ndev) {
+ for (i = 0; i < wilc->vif_num; i++) {
+ if (wilc->vif[i] && wilc->vif[i]->ndev)
unregister_netdev(wilc->vif[i]->ndev);
- wilc_free_wiphy(wilc->vif[i]->ndev);
- free_netdev(wilc->vif[i]->ndev);
- }
}
- wilc_wfi_deinit_mon_interface(wilc);
+ wilc_wfi_deinit_mon_interface(wilc, false);
flush_workqueue(wilc->hif_workqueue);
destroy_workqueue(wilc->hif_workqueue);
wilc_wlan_cfg_deinit(wilc);
kfree(wilc->bus_data);
- kfree(wilc);
+ wiphy_unregister(wilc->wiphy);
+ wiphy_free(wilc->wiphy);
}
EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
-int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
- const struct wilc_hif_func *ops)
+struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+ int vif_type, enum nl80211_iftype type,
+ bool rtnl_locked)
{
- int i, ret;
- struct wilc_vif *vif;
struct net_device *ndev;
- struct wilc *wl;
-
- wl = kzalloc(sizeof(*wl), GFP_KERNEL);
- if (!wl)
- return -ENOMEM;
-
- ret = wilc_wlan_cfg_init(wl);
- if (ret)
- goto free_wl;
-
- *wilc = wl;
- wl->io_type = io_type;
- wl->hif_func = ops;
- wl->enable_ps = true;
- wl->chip_ps_state = WILC_CHIP_WAKEDUP;
- INIT_LIST_HEAD(&wl->txq_head.list);
- INIT_LIST_HEAD(&wl->rxq_head.list);
-
- wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
- if (!wl->hif_workqueue) {
- ret = -ENOMEM;
- goto free_cfg;
- }
-
- register_inetaddr_notifier(&g_dev_notifier);
-
- for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) {
- struct wireless_dev *wdev;
+ struct wilc_vif *vif;
+ int ret;
- ndev = alloc_etherdev(sizeof(struct wilc_vif));
- if (!ndev) {
- ret = -ENOMEM;
- goto free_ndev;
- }
+ ndev = alloc_etherdev(sizeof(*vif));
+ if (!ndev)
+ return ERR_PTR(-ENOMEM);
- vif = netdev_priv(ndev);
+ vif = netdev_priv(ndev);
+ ndev->ieee80211_ptr = &vif->priv.wdev;
+ strcpy(ndev->name, name);
+ vif->wilc = wl;
+ vif->ndev = ndev;
+ ndev->ml_priv = vif;
- if (i == 0) {
- strcpy(ndev->name, "wlan%d");
- vif->ifc_id = 1;
- } else {
- strcpy(ndev->name, "p2p%d");
- vif->ifc_id = 0;
- }
- vif->wilc = *wilc;
- vif->ndev = ndev;
- wl->vif[i] = vif;
- wl->vif_num = i + 1;
- vif->idx = i;
-
- ndev->netdev_ops = &wilc_netdev_ops;
-
- wdev = wilc_create_wiphy(ndev, dev);
- if (!wdev) {
- netdev_err(ndev, "Can't register WILC Wiphy\n");
- ret = -ENOMEM;
- goto free_ndev;
- }
+ ndev->netdev_ops = &wilc_netdev_ops;
- SET_NETDEV_DEV(ndev, dev);
+ SET_NETDEV_DEV(ndev, wiphy_dev(wl->wiphy));
- vif->ndev->ieee80211_ptr = wdev;
- vif->ndev->ml_priv = vif;
- wdev->netdev = vif->ndev;
- vif->netstats.rx_packets = 0;
- vif->netstats.tx_packets = 0;
- vif->netstats.rx_bytes = 0;
- vif->netstats.tx_bytes = 0;
+ vif->priv.wdev.wiphy = wl->wiphy;
+ vif->priv.wdev.netdev = ndev;
+ vif->priv.wdev.iftype = type;
+ vif->priv.dev = ndev;
+ if (rtnl_locked)
+ ret = register_netdevice(ndev);
+ else
ret = register_netdev(ndev);
- if (ret)
- goto free_ndev;
- vif->iftype = WILC_STATION_MODE;
- vif->mac_opened = 0;
+ if (ret) {
+ free_netdev(ndev);
+ return ERR_PTR(-EFAULT);
}
- return 0;
-
-free_ndev:
- for (; i >= 0; i--) {
- if (wl->vif[i]) {
- if (wl->vif[i]->iftype == WILC_STATION_MODE)
- unregister_netdev(wl->vif[i]->ndev);
-
- if (wl->vif[i]->ndev) {
- wilc_free_wiphy(wl->vif[i]->ndev);
- free_netdev(wl->vif[i]->ndev);
- }
- }
- }
- unregister_inetaddr_notifier(&g_dev_notifier);
- destroy_workqueue(wl->hif_workqueue);
-free_cfg:
- wilc_wlan_cfg_deinit(wl);
-free_wl:
- kfree(wl);
- return ret;
+ ndev->needs_free_netdev = true;
+ vif->iftype = vif_type;
+ vif->wilc->vif[wl->vif_num] = vif;
+ vif->ifc_id = wl->vif_num;
+ vif->idx = wl->vif_num;
+ wl->vif_num += 1;
+ vif->mac_opened = 0;
+ return vif;
}
-EXPORT_SYMBOL_GPL(wilc_netdev_init);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c
index b789c57..4c1c81f 100644
--- a/drivers/staging/wilc1000/wilc_sdio.c
+++ b/drivers/staging/wilc1000/wilc_sdio.c
@@ -8,6 +8,7 @@
#include <linux/mmc/host.h>
#include "wilc_wfi_netdevice.h"
+#include "wilc_wfi_cfgoperations.h"
#define SDIO_MODALIAS "wilc1000_sdio"
@@ -139,11 +140,9 @@ static int wilc_sdio_probe(struct sdio_func *func,
}
}
- dev_dbg(&func->dev, "Initializing netdev\n");
- ret = wilc_netdev_init(&wilc, &func->dev, WILC_HIF_SDIO,
- &wilc_hif_sdio);
+ ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,
+ &wilc_hif_sdio);
if (ret) {
- dev_err(&func->dev, "Couldn't initialize netdev\n");
kfree(sdio_priv);
return ret;
}
diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c
index d8910bf..3c1ae9e 100644
--- a/drivers/staging/wilc1000/wilc_spi.c
+++ b/drivers/staging/wilc1000/wilc_spi.c
@@ -7,6 +7,7 @@
#include <linux/spi/spi.h>
#include "wilc_wfi_netdevice.h"
+#include "wilc_wfi_cfgoperations.h"
struct wilc_spi {
int crc_off;
@@ -120,7 +121,7 @@ static int wilc_bus_probe(struct spi_device *spi)
dev_err(&spi->dev, "failed to get the irq gpio\n");
}
- ret = wilc_netdev_init(&wilc, NULL, WILC_HIF_SPI, &wilc_hif_spi);
+ ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi);
if (ret) {
kfree(spi_priv);
return ret;
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index b0daa11..012e325 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -183,48 +183,67 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status,
eth_zero_addr(priv->associated_bss);
wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE);
- if (vif->iftype != WILC_CLIENT_MODE)
+ if (vif->iftype != WILC_CLIENT_MODE) {
wl->sta_ch = WILC_INVALID_CHANNEL;
-
- if (wfi_drv->ifc_up && dev == wl->vif[1]->ndev)
- reason = 3;
- else if (!wfi_drv->ifc_up && dev == wl->vif[1]->ndev)
- reason = 1;
+ } else {
+ if (wfi_drv->ifc_up)
+ reason = 3;
+ else
+ reason = 1;
+ }
cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL);
}
}
+static struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
+{
+ int i;
+
+ for (i = 0; i < wl->vif_num; i++)
+ if (wl->vif[i])
+ return wl->vif[i];
+
+ return ERR_PTR(-EINVAL);
+}
+
static int set_channel(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef)
{
- u32 channelnum = 0;
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
- int result = 0;
+ struct wilc *wl = wiphy_priv(wiphy);
+ struct wilc_vif *vif;
+ u32 channelnum;
+ int result;
+
+ mutex_lock(&wl->vif_mutex);
+ vif = wilc_get_wl_to_vif(wl);
+ if (IS_ERR(vif)) {
+ mutex_unlock(&wl->vif_mutex);
+ return PTR_ERR(vif);
+ }
channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
- vif->wilc->op_ch = channelnum;
+ wl->op_ch = channelnum;
result = wilc_set_mac_chnl_num(vif, channelnum);
+ if (result)
+ netdev_err(vif->ndev, "Error in setting channel\n");
- if (result != 0)
- netdev_err(priv->dev, "Error in setting channel\n");
-
+ mutex_unlock(&wl->vif_mutex);
return result;
}
static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(request->wdev->netdev);
+ struct wilc_priv *priv = &vif->priv;
u32 i;
int ret = 0;
u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH];
u8 scan_type;
if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) {
- netdev_err(priv->dev, "Requested scanned channels over\n");
+ netdev_err(vif->ndev, "Requested scanned channels over\n");
return -EINVAL;
}
@@ -256,8 +275,8 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
static int connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(dev);
+ struct wilc_priv *priv = &vif->priv;
struct host_if_drv *wfi_drv = priv->hif_drv;
int ret;
u32 i;
@@ -410,8 +429,8 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
static int disconnect(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(dev);
+ struct wilc_priv *priv = &vif->priv;
struct wilc *wilc = vif->wilc;
int ret;
@@ -501,17 +520,17 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
{
int ret = 0, keylen = params->key_len;
- struct wilc_priv *priv = wiphy_priv(wiphy);
const u8 *rx_mic = NULL;
const u8 *tx_mic = NULL;
u8 mode = WILC_FW_SEC_NO;
u8 op_mode;
struct wilc_vif *vif = netdev_priv(netdev);
+ struct wilc_priv *priv = &vif->priv;
switch (params->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
- if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
+ if (priv->wdev.iftype == NL80211_IFTYPE_AP) {
wilc_wfi_cfg_copy_wep_info(priv, key_index, params);
if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
@@ -538,8 +557,8 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
case WLAN_CIPHER_SUITE_TKIP:
case WLAN_CIPHER_SUITE_CCMP:
- if (priv->wdev->iftype == NL80211_IFTYPE_AP ||
- priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
+ if (priv->wdev.iftype == NL80211_IFTYPE_AP ||
+ priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
struct wilc_wfi_key *key;
ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index);
@@ -611,9 +630,9 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev,
bool pairwise,
const u8 *mac_addr)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
+ struct wilc *wl = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(netdev);
- struct wilc *wl = vif->wilc;
+ struct wilc_priv *priv = &vif->priv;
if (netdev == wl->vif[0]->ndev) {
if (priv->wilc_gtk[key_index]) {
@@ -650,7 +669,8 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
bool pairwise, const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, struct key_params *))
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
+ struct wilc_vif *vif = netdev_priv(netdev);
+ struct wilc_priv *priv = &vif->priv;
struct key_params key_params;
if (!pairwise) {
@@ -675,8 +695,7 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
u8 key_index, bool unicast, bool multicast)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(netdev);
wilc_set_wep_default_keyid(vif, key_index);
@@ -686,8 +705,8 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev,
static int get_station(struct wiphy *wiphy, struct net_device *dev,
const u8 *mac, struct station_info *sinfo)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(dev);
+ struct wilc_priv *priv = &vif->priv;
u32 i = 0;
u32 associatedsta = ~0;
u32 inactive_time = 0;
@@ -743,13 +762,35 @@ static int change_bss(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
+struct wilc_vif *wilc_get_interface(struct wilc *wl)
+{
+ int i;
+ struct wilc_vif *vif = NULL;
+
+ mutex_lock(&wl->vif_mutex);
+ for (i = 0; i < wl->vif_num; i++) {
+ if (wl->vif[i]) {
+ vif = wl->vif[i];
+ break;
+ }
+ }
+ mutex_unlock(&wl->vif_mutex);
+ return vif;
+}
+
static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
int ret;
struct cfg_param_attr cfg_param_val;
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc *wl = wiphy_priv(wiphy);
+ struct wilc_vif *vif;
+ struct wilc_priv *priv;
+ vif = wilc_get_interface(wl);
+ if (!vif)
+ return -EINVAL;
+
+ priv = &vif->priv;
cfg_param_val.flag = 0;
if (changed & WIPHY_PARAM_RETRY_SHORT) {
@@ -804,8 +845,8 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
struct cfg80211_pmksa *pmksa)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(netdev);
+ struct wilc_priv *priv = &vif->priv;
u32 i;
int ret = 0;
u8 flag = 0;
@@ -840,7 +881,8 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
{
u32 i;
int ret = 0;
- struct wilc_priv *priv = wiphy_priv(wiphy);
+ struct wilc_vif *vif = netdev_priv(netdev);
+ struct wilc_priv *priv = &vif->priv;
for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
@@ -870,9 +912,9 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
+ struct wilc_vif *vif = netdev_priv(netdev);
- memset(&priv->pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
+ memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr));
return 0;
}
@@ -987,12 +1029,11 @@ static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff,
}
}
-void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
+void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size)
{
- struct wilc_priv *priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
- struct host_if_drv *wfi_drv = priv->hif_drv;
- struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wl = vif->wilc;
+ struct wilc_priv *priv = &vif->priv;
+ struct host_if_drv *wfi_drv = priv->hif_drv;
u32 header, pkt_offset;
s32 freq;
__le16 fc;
@@ -1008,8 +1049,8 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
pkt_offset & IS_MGMT_STATUS_SUCCES)
ack = true;
- cfg80211_mgmt_tx_status(priv->wdev, priv->tx_cookie, buff, size,
- ack, GFP_KERNEL);
+ cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff,
+ size, ack, GFP_KERNEL);
return;
}
@@ -1017,13 +1058,13 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
fc = ((struct ieee80211_hdr *)buff)->frame_control;
if (!ieee80211_is_action(fc)) {
- cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0);
+ cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
return;
}
if (priv->cfg_scanning &&
time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) {
- netdev_dbg(dev, "Receiving action wrong ch\n");
+ netdev_dbg(vif->ndev, "Receiving action wrong ch\n");
return;
}
if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
@@ -1046,14 +1087,14 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size)
break;
default:
- netdev_dbg(dev,
+ netdev_dbg(vif->ndev,
"%s: Not handled action frame type:%x\n",
__func__, buff[ACTION_SUBTYPE_ID]);
break;
}
}
- cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0);
+ cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0);
}
static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
@@ -1066,7 +1107,8 @@ static void wilc_wfi_mgmt_tx_complete(void *priv, int status)
static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
{
- struct wilc_priv *priv = data;
+ struct wilc_vif *vif = data;
+ struct wilc_priv *priv = &vif->priv;
struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params;
if (cookie != params->listen_cookie)
@@ -1074,7 +1116,7 @@ static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie)
priv->p2p_listen_state = false;
- cfg80211_remain_on_channel_expired(priv->wdev, params->listen_cookie,
+ cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie,
params->listen_ch, GFP_KERNEL);
}
@@ -1084,8 +1126,8 @@ static int remain_on_channel(struct wiphy *wiphy,
unsigned int duration, u64 *cookie)
{
int ret = 0;
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(wdev->netdev);
+ struct wilc_priv *priv = &vif->priv;
u64 id;
if (wdev->iftype == NL80211_IFTYPE_AP) {
@@ -1099,7 +1141,7 @@ static int remain_on_channel(struct wiphy *wiphy,
ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value,
wilc_wfi_remain_on_channel_expired,
- (void *)priv);
+ (void *)vif);
if (ret)
return ret;
@@ -1122,8 +1164,8 @@ static int cancel_remain_on_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
u64 cookie)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(wdev->netdev);
+ struct wilc_priv *priv = &vif->priv;
if (cookie != priv->remain_on_ch_params.listen_cookie)
return -ENOENT;
@@ -1193,9 +1235,9 @@ static int mgmt_tx(struct wiphy *wiphy,
size_t len = params->len;
const struct ieee80211_mgmt *mgmt;
struct wilc_p2p_mgmt_data *mgmt_tx;
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct host_if_drv *wfi_drv = priv->hif_drv;
struct wilc_vif *vif = netdev_priv(wdev->netdev);
+ struct wilc_priv *priv = &vif->priv;
+ struct host_if_drv *wfi_drv = priv->hif_drv;
u32 buf_len = len + sizeof(p2p_vendor_spec) +
sizeof(priv->p2p.local_random);
int ret = 0;
@@ -1279,7 +1321,8 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
struct wireless_dev *wdev,
u64 cookie)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
+ struct wilc_vif *vif = netdev_priv(wdev->netdev);
+ struct wilc_priv *priv = &vif->priv;
struct host_if_drv *wfi_drv = priv->hif_drv;
wfi_drv->p2p_timeout = jiffies;
@@ -1289,7 +1332,7 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
params = &priv->remain_on_ch_params;
- cfg80211_remain_on_channel_expired(priv->wdev,
+ cfg80211_remain_on_channel_expired(wdev,
params->listen_cookie,
params->listen_ch,
GFP_KERNEL);
@@ -1301,9 +1344,8 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
u16 frame_type, bool reg)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->wdev->netdev);
- struct wilc *wl = vif->wilc;
+ struct wilc *wl = wiphy_priv(wiphy);
+ struct wilc_vif *vif = netdev_priv(wdev->netdev);
if (!frame_type)
return;
@@ -1337,8 +1379,7 @@ static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
static int dump_station(struct wiphy *wiphy, struct net_device *dev,
int idx, u8 *mac, struct station_info *sinfo)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(dev);
int ret;
if (idx != 0)
@@ -1350,15 +1391,15 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev,
if (ret)
return ret;
- memcpy(mac, priv->associated_bss, ETH_ALEN);
+ memcpy(mac, vif->priv.associated_bss, ETH_ALEN);
return 0;
}
static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
bool enabled, int timeout)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(dev);
+ struct wilc_priv *priv = &vif->priv;
if (!priv->hif_drv)
return -EIO;
@@ -1373,9 +1414,9 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
enum nl80211_iftype type,
struct vif_params *params)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
+ struct wilc *wl = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(dev);
- struct wilc *wl = vif->wilc;
+ struct wilc_priv *priv = &vif->priv;
priv->p2p.local_random = 0x01;
priv->p2p.recv_random = 0x00;
@@ -1387,8 +1428,10 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
case NL80211_IFTYPE_STATION:
vif->connecting = false;
dev->ieee80211_ptr->iftype = type;
- priv->wdev->iftype = type;
+ priv->wdev.iftype = type;
vif->monitor_flag = 0;
+ if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE)
+ wilc_wfi_deinit_mon_interface(wl, true);
vif->iftype = WILC_STATION_MODE;
wilc_set_operation_mode(vif, WILC_STATION_MODE);
@@ -1402,7 +1445,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
case NL80211_IFTYPE_P2P_CLIENT:
vif->connecting = false;
dev->ieee80211_ptr->iftype = type;
- priv->wdev->iftype = type;
+ priv->wdev.iftype = type;
vif->monitor_flag = 0;
vif->iftype = WILC_CLIENT_MODE;
wilc_set_operation_mode(vif, WILC_STATION_MODE);
@@ -1414,7 +1457,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
case NL80211_IFTYPE_AP:
wl->enable_ps = false;
dev->ieee80211_ptr->iftype = type;
- priv->wdev->iftype = type;
+ priv->wdev.iftype = type;
vif->iftype = WILC_AP_MODE;
if (wl->initialized) {
@@ -1431,7 +1474,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
jiffies + msecs_to_jiffies(WILC_IP_TIMEOUT_MS));
wilc_set_operation_mode(vif, WILC_AP_MODE);
dev->ieee80211_ptr->iftype = type;
- priv->wdev->iftype = type;
+ priv->wdev.iftype = type;
vif->iftype = WILC_GO_MODE;
wl->enable_ps = false;
@@ -1450,14 +1493,13 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ap_settings *settings)
{
struct wilc_vif *vif = netdev_priv(dev);
- struct wilc *wl = vif->wilc;
int ret;
ret = set_channel(wiphy, &settings->chandef);
if (ret != 0)
netdev_err(dev, "Error in setting channel\n");
- wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, WILC_AP_MODE);
+ wilc_wlan_set_bssid(dev, vif->src_addr, WILC_AP_MODE);
wilc_set_power_mgmt(vif, 0, 0);
return wilc_add_beacon(vif, settings->beacon_interval,
@@ -1467,8 +1509,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,
static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_beacon_data *beacon)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(dev);
return wilc_add_beacon(vif, 0, 0, beacon);
}
@@ -1476,8 +1517,7 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
{
int ret;
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(dev);
wilc_wlan_set_bssid(dev, NULL, WILC_AP_MODE);
@@ -1493,8 +1533,8 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev,
const u8 *mac, struct station_parameters *params)
{
int ret = 0;
- struct wilc_priv *priv = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(dev);
+ struct wilc_priv *priv = &vif->priv;
if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) {
memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac,
@@ -1513,8 +1553,8 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev,
{
const u8 *mac = params->mac;
int ret = 0;
- struct wilc_priv *priv = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(dev);
+ struct wilc_priv *priv = &vif->priv;
struct sta_info *info;
if (!(vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE))
@@ -1545,60 +1585,158 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev,
return ret;
}
+static int wilc_get_vif_from_type(struct wilc *wl, int type)
+{
+ int i;
+
+ mutex_lock(&wl->vif_mutex);
+ for (i = 0; i < wl->vif_num; i++) {
+ if (wl->vif[i]->iftype == type) {
+ mutex_unlock(&wl->vif_mutex);
+ return i;
+ }
+ }
+ mutex_unlock(&wl->vif_mutex);
+
+ return -EINVAL;
+}
+
static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
const char *name,
unsigned char name_assign_type,
enum nl80211_iftype type,
struct vif_params *params)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->wdev->netdev);
- struct net_device *new_ifc;
+ struct wilc *wl = wiphy_priv(wiphy);
+ struct wilc_vif *vif;
+ struct wireless_dev *wdev;
+ int iftype;
+ int ret;
if (type == NL80211_IFTYPE_MONITOR) {
- new_ifc = wilc_wfi_init_mon_interface(vif->wilc, name,
- vif->ndev);
- if (new_ifc) {
- vif = netdev_priv(priv->wdev->netdev);
- vif->monitor_flag = 1;
+ struct net_device *ndev;
+ int ap_index = wilc_get_vif_from_type(wl, WILC_AP_MODE);
+
+ if (ap_index < 0) {
+ ap_index = wilc_get_vif_from_type(wl, WILC_GO_MODE);
+ if (ap_index < 0)
+ goto validate_interface;
}
+
+ vif = wl->vif[ap_index];
+ if (vif->monitor_flag)
+ goto validate_interface;
+
+ ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
+ if (ndev)
+ vif->monitor_flag = 1;
+ else
+ return ERR_PTR(-EINVAL);
+
+ wdev = &vif->priv.wdev;
+ return wdev;
+ }
+
+validate_interface:
+ mutex_lock(&wl->vif_mutex);
+ if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
+ pr_err("Reached maximum number of interface\n");
+ ret = -EINVAL;
+ goto out_err;
+ }
+
+ switch (type) {
+ case NL80211_IFTYPE_STATION:
+ iftype = WILC_STATION_MODE;
+ break;
+ case NL80211_IFTYPE_AP:
+ iftype = WILC_AP_MODE;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto out_err;
+ }
+
+ vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
+ if (IS_ERR(vif)) {
+ ret = PTR_ERR(vif);
+ goto out_err;
}
- return priv->wdev;
+
+ mutex_unlock(&wl->vif_mutex);
+
+ return &vif->priv.wdev;
+
+out_err:
+ mutex_unlock(&wl->vif_mutex);
+ return ERR_PTR(ret);
}
static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
{
+ struct wilc *wl = wiphy_priv(wiphy);
+ struct wilc_vif *vif;
+ int i;
+
+ if (wdev->iftype == NL80211_IFTYPE_AP ||
+ wdev->iftype == NL80211_IFTYPE_P2P_GO)
+ wilc_wfi_deinit_mon_interface(wl, true);
+ vif = netdev_priv(wdev->netdev);
+ cfg80211_stop_iface(wiphy, wdev, GFP_KERNEL);
+ unregister_netdevice(vif->ndev);
+ vif->monitor_flag = 0;
+
+ mutex_lock(&wl->vif_mutex);
+ wilc_set_wfi_drv_handler(vif, 0, 0, 0);
+ for (i = vif->idx; i < wl->vif_num ; i++) {
+ if ((i + 1) >= wl->vif_num) {
+ wl->vif[i] = NULL;
+ } else {
+ vif = wl->vif[i + 1];
+ vif->ifc_id = i;
+ vif->idx = i;
+ wl->vif[i] = vif;
+ wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif),
+ vif->iftype, vif->ifc_id);
+ }
+ }
+ wl->vif_num--;
+ mutex_unlock(&wl->vif_mutex);
+
return 0;
}
static int wilc_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc *wl = wiphy_priv(wiphy);
- if (!wow && wilc_wlan_get_num_conn_ifcs(vif->wilc))
- vif->wilc->suspend_event = true;
+ if (!wow && wilc_wlan_get_num_conn_ifcs(wl))
+ wl->suspend_event = true;
else
- vif->wilc->suspend_event = false;
+ wl->suspend_event = false;
return 0;
}
static int wilc_resume(struct wiphy *wiphy)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
-
- netdev_info(vif->ndev, "cfg resume\n");
return 0;
}
static void wilc_set_wakeup(struct wiphy *wiphy, bool enabled)
{
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc *wl = wiphy_priv(wiphy);
+ struct wilc_vif *vif;
+
+ mutex_lock(&wl->vif_mutex);
+ vif = wilc_get_wl_to_vif(wl);
+ if (IS_ERR(vif)) {
+ mutex_unlock(&wl->vif_mutex);
+ return;
+ }
netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
+ mutex_unlock(&wl->vif_mutex);
}
static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
@@ -1606,8 +1744,7 @@ static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
{
int ret;
s32 tx_power = MBM_TO_DBM(mbm);
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(wdev->netdev);
if (tx_power < 0)
tx_power = 0;
@@ -1624,8 +1761,7 @@ static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
int *dbm)
{
int ret;
- struct wilc_priv *priv = wiphy_priv(wiphy);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(wdev->netdev);
struct wilc *wl = vif->wilc;
/* If firmware is not started, return. */
@@ -1682,98 +1818,137 @@ static const struct cfg80211_ops wilc_cfg80211_ops = {
};
-static struct wireless_dev *wilc_wfi_cfg_alloc(void)
+static void wlan_init_locks(struct wilc *wl)
{
- struct wireless_dev *wdev;
+ mutex_init(&wl->hif_cs);
+ mutex_init(&wl->rxq_cs);
+ mutex_init(&wl->cfg_cmd_lock);
+ mutex_init(&wl->vif_mutex);
+
+ spin_lock_init(&wl->txq_spinlock);
+ mutex_init(&wl->txq_add_to_head_cs);
+
+ init_completion(&wl->txq_event);
+ init_completion(&wl->cfg_event);
+ init_completion(&wl->sync_event);
+ init_completion(&wl->txq_thread_started);
+}
- wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
- if (!wdev)
- goto out;
+int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+ const struct wilc_hif_func *ops)
+{
+ struct wilc *wl;
+ struct wilc_vif *vif;
+ int ret;
- wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
- if (!wdev->wiphy)
- goto free_mem;
+ wl = wilc_create_wiphy(dev);
+ if (!wl)
+ return -EINVAL;
- return wdev;
+ ret = wilc_wlan_cfg_init(wl);
+ if (ret)
+ goto free_wl;
+
+ *wilc = wl;
+ wl->io_type = io_type;
+ wl->hif_func = ops;
+ wl->enable_ps = false;
+ wl->chip_ps_state = WILC_CHIP_WAKEDUP;
+ INIT_LIST_HEAD(&wl->txq_head.list);
+ INIT_LIST_HEAD(&wl->rxq_head.list);
+
+ wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
+ if (!wl->hif_workqueue) {
+ ret = -ENOMEM;
+ goto free_cfg;
+ }
+ vif = wilc_netdev_ifc_init(wl, "wlan%d", WILC_STATION_MODE,
+ NL80211_IFTYPE_STATION, false);
+ if (IS_ERR(vif)) {
+ ret = PTR_ERR(vif);
+ goto free_hq;
+ }
-free_mem:
- kfree(wdev);
-out:
- return NULL;
+ wlan_init_locks(wl);
+
+ return 0;
+
+free_hq:
+ destroy_workqueue(wl->hif_workqueue);
+
+free_cfg:
+ wilc_wlan_cfg_deinit(wl);
+
+free_wl:
+ wiphy_unregister(wl->wiphy);
+ wiphy_free(wl->wiphy);
+ return ret;
}
+EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
-struct wireless_dev *wilc_create_wiphy(struct net_device *net,
- struct device *dev)
+struct wilc *wilc_create_wiphy(struct device *dev)
{
- struct wilc_priv *priv;
- struct wireless_dev *wdev;
+ struct wiphy *wiphy;
+ struct wilc *wl;
int ret;
- wdev = wilc_wfi_cfg_alloc();
- if (!wdev) {
- netdev_err(net, "wiphy new allocate failed\n");
+ wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(*wl));
+ if (!wiphy)
return NULL;
- }
- priv = wdev_priv(wdev);
- priv->wdev = wdev;
+ wl = wiphy_priv(wiphy);
- memcpy(priv->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
- memcpy(priv->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
- priv->band.bitrates = priv->bitrates;
- priv->band.n_bitrates = ARRAY_SIZE(priv->bitrates);
- priv->band.channels = priv->channels;
- priv->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
+ memcpy(wl->bitrates, wilc_bitrates, sizeof(wilc_bitrates));
+ memcpy(wl->channels, wilc_2ghz_channels, sizeof(wilc_2ghz_channels));
+ wl->band.bitrates = wl->bitrates;
+ wl->band.n_bitrates = ARRAY_SIZE(wl->bitrates);
+ wl->band.channels = wl->channels;
+ wl->band.n_channels = ARRAY_SIZE(wilc_2ghz_channels);
- priv->band.ht_cap.ht_supported = 1;
- priv->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
- priv->band.ht_cap.mcs.rx_mask[0] = 0xff;
- priv->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
- priv->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
+ wl->band.ht_cap.ht_supported = 1;
+ wl->band.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+ wl->band.ht_cap.mcs.rx_mask[0] = 0xff;
+ wl->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
+ wl->band.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
- wdev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
+ wiphy->bands[NL80211_BAND_2GHZ] = &wl->band;
- wdev->wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
+ wiphy->max_scan_ssids = WILC_MAX_NUM_PROBED_SSID;
#ifdef CONFIG_PM
- wdev->wiphy->wowlan = &wowlan_support;
+ wiphy->wowlan = &wowlan_support;
#endif
- wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
- wdev->wiphy->max_scan_ie_len = 1000;
- wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
- memcpy(priv->cipher_suites, wilc_cipher_suites,
+ wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
+ wiphy->max_scan_ie_len = 1000;
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ memcpy(wl->cipher_suites, wilc_cipher_suites,
sizeof(wilc_cipher_suites));
- wdev->wiphy->cipher_suites = priv->cipher_suites;
- wdev->wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
- wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
-
- wdev->wiphy->max_remain_on_channel_duration = 500;
- wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP) |
- BIT(NL80211_IFTYPE_MONITOR) |
- BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_CLIENT);
- wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
- wdev->iftype = NL80211_IFTYPE_STATION;
-
- set_wiphy_dev(wdev->wiphy, dev);
-
- ret = wiphy_register(wdev->wiphy);
+ wiphy->cipher_suites = wl->cipher_suites;
+ wiphy->n_cipher_suites = ARRAY_SIZE(wilc_cipher_suites);
+ wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
+
+ wiphy->max_remain_on_channel_duration = 500;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_MONITOR) |
+ BIT(NL80211_IFTYPE_P2P_GO) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT);
+ wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+
+ set_wiphy_dev(wiphy, dev);
+ wl->wiphy = wiphy;
+ ret = wiphy_register(wiphy);
if (ret) {
- netdev_err(net, "Cannot register wiphy device\n");
- wiphy_free(wdev->wiphy);
- kfree(wdev);
+ wiphy_free(wiphy);
return NULL;
}
-
- priv->dev = net;
- return wdev;
+ return wl;
}
int wilc_init_host_int(struct net_device *net)
{
int ret;
- struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(net);
+ struct wilc_priv *priv = &vif->priv;
timer_setup(&vif->during_ip_timer, clear_during_ip, 0);
@@ -1790,8 +1965,8 @@ int wilc_init_host_int(struct net_device *net)
void wilc_deinit_host_int(struct net_device *net)
{
int ret;
- struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr);
- struct wilc_vif *vif = netdev_priv(priv->dev);
+ struct wilc_vif *vif = netdev_priv(net);
+ struct wilc_priv *priv = &vif->priv;
priv->p2p_listen_state = false;
@@ -1804,19 +1979,3 @@ void wilc_deinit_host_int(struct net_device *net)
netdev_err(net, "Error while deinitializing host interface\n");
}
-void wilc_free_wiphy(struct net_device *net)
-{
- if (!net)
- return;
-
- if (!net->ieee80211_ptr)
- return;
-
- if (!net->ieee80211_ptr->wiphy)
- return;
-
- wiphy_unregister(net->ieee80211_ptr->wiphy);
-
- wiphy_free(net->ieee80211_ptr->wiphy);
- kfree(net->ieee80211_ptr);
-}
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
index 31dfa1f..234faaa 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h
@@ -8,17 +8,20 @@
#define NM_WFI_CFGOPERATIONS
#include "wilc_wfi_netdevice.h"
-struct wireless_dev *wilc_create_wiphy(struct net_device *net,
- struct device *dev);
-void wilc_free_wiphy(struct net_device *net);
+struct wiphy *wilc_cfg_alloc(void);
+int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
+ const struct wilc_hif_func *ops);
+struct wilc *wilc_create_wiphy(struct device *dev);
void wilc_deinit_host_int(struct net_device *net);
int wilc_init_host_int(struct net_device *net);
void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size);
-void wilc_wfi_deinit_mon_interface(struct wilc *wl);
+struct wilc_vif *wilc_netdev_interface(struct wilc *wl, const char *name,
+ enum nl80211_iftype type);
+void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked);
struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
const char *name,
struct net_device *real_dev);
void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
u16 frame_type, bool reg);
-
+struct wilc_vif *wilc_get_interface(struct wilc *wl);
#endif
diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index df00762..fca3380 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -129,7 +129,7 @@ static struct ieee80211_rate wilc_bitrates[] = {
};
struct wilc_priv {
- struct wireless_dev *wdev;
+ struct wireless_dev wdev;
struct cfg80211_scan_request *scan_req;
struct wilc_wfi_p2p_listen_params remain_on_ch_params;
@@ -156,10 +156,6 @@ struct wilc_priv {
int scanned_cnt;
struct wilc_p2p_var p2p;
- struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
- struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
- struct ieee80211_supported_band band;
- u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
u64 inc_roc_cookie;
};
@@ -214,9 +210,11 @@ struct wilc_vif {
struct rf_info periodic_stat;
struct tcp_ack_filter ack_filter;
bool connecting;
+ struct wilc_priv priv;
};
struct wilc {
+ struct wiphy *wiphy;
const struct wilc_hif_func *hif_func;
int io_type;
s8 mac_status;
@@ -226,6 +224,8 @@ struct wilc {
int close;
u8 vif_num;
struct wilc_vif *vif[WILC_NUM_CONCURRENT_IFC];
+ /*protect vif list*/
+ struct mutex vif_mutex;
u8 open_ifcs;
/*protect head of transmit queue*/
struct mutex txq_add_to_head_cs;
@@ -275,6 +275,10 @@ struct wilc {
struct mutex deinit_lock;
u8 sta_ch;
u8 op_ch;
+ struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
+ struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
+ struct ieee80211_supported_band band;
+ u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
};
struct wilc_wfi_mon_priv {
@@ -284,9 +288,9 @@ struct wilc_wfi_mon_priv {
void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
void wilc_mac_indicate(struct wilc *wilc);
void wilc_netdev_cleanup(struct wilc *wilc);
-int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
- const struct wilc_hif_func *ops);
void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode);
-
+struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
+ int vif_type, enum nl80211_iftype type,
+ bool rtnl_locked);
#endif
diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c
index dcd7285..bd2ffc3 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -6,7 +6,7 @@
#include <linux/if_ether.h>
#include <linux/ip.h>
-#include "wilc_wfi_netdevice.h"
+#include "wilc_wfi_cfgoperations.h"
#include "wilc_wlan_cfg.h"
static inline bool is_wilc1000(u32 id)
@@ -267,6 +267,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
tqe->tx_complete_func = NULL;
tqe->priv = NULL;
tqe->ack_idx = NOT_TCP_ACK;
+ tqe->vif = vif;
wilc_wlan_txq_add_to_head(vif, tqe);
@@ -295,6 +296,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
tqe->buffer_size = buffer_size;
tqe->tx_complete_func = tx_complete_fn;
tqe->priv = priv;
+ tqe->vif = vif;
tqe->ack_idx = NOT_TCP_ACK;
if (vif->ack_filter.enabled)
@@ -326,6 +328,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
tqe->tx_complete_func = tx_complete_fn;
tqe->priv = priv;
tqe->ack_idx = NOT_TCP_ACK;
+ tqe->vif = vif;
wilc_wlan_txq_add_to_tail(dev, tqe);
return 1;
}
@@ -482,7 +485,7 @@ void host_sleep_notify(struct wilc *wilc)
}
EXPORT_SYMBOL_GPL(host_sleep_notify);
-int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
+int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
{
int i, entries = 0;
u32 sum;
@@ -494,17 +497,20 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
int counter;
int timeout;
u32 vmm_table[WILC_VMM_TBL_SIZE];
- struct wilc_vif *vif = netdev_priv(dev);
- struct wilc *wilc = vif->wilc;
const struct wilc_hif_func *func;
u8 *txb = wilc->tx_buffer;
+ struct net_device *dev;
+ struct wilc_vif *vif;
if (wilc->quit)
goto out;
mutex_lock(&wilc->txq_add_to_head_cs);
- wilc_wlan_txq_filter_dup_tcp_ack(dev);
tqe = wilc_wlan_txq_get_first(wilc);
+ if (!tqe)
+ goto out;
+ dev = tqe->vif->ndev;
+ wilc_wlan_txq_filter_dup_tcp_ack(dev);
i = 0;
sum = 0;
do {
@@ -629,6 +635,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
if (!tqe)
break;
+ vif = tqe->vif;
if (vmm_table[i] == 0)
break;
@@ -648,8 +655,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
if (tqe->type == WILC_CFG_PKT) {
buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
} else if (tqe->type == WILC_NET_PKT) {
- bssid = ((struct tx_complete_data *)(tqe->priv))->bssid;
-
+ bssid = tqe->vif->bssid;
buffer_offset = ETH_ETHERNET_HDR_OFFSET;
memcpy(&txb[offset + 8], bssid, 6);
} else {
diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h
index 1a27f62..3e54a56 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -216,6 +216,7 @@ struct txq_entry_t {
int buffer_size;
void *priv;
int status;
+ struct wilc_vif *vif;
void (*tx_complete_func)(void *priv, int status);
};
@@ -253,7 +254,6 @@ struct wilc_hif_func {
struct tx_complete_data {
int size;
void *buff;
- u8 *bssid;
struct sk_buff *skb;
};
@@ -284,7 +284,7 @@ int wilc_wlan_stop(struct wilc *wilc);
int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
u32 buffer_size,
void (*tx_complete_fn)(void *, int));
-int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count);
+int wilc_wlan_handle_txq(struct wilc *wl, u32 *txq_count);
void wilc_handle_isr(struct wilc *wilc);
void wilc_wlan_cleanup(struct net_device *dev);
int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
@@ -301,7 +301,7 @@ void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value);
int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc);
netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
-void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size);
+void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size);
void host_wakeup_notify(struct wilc *wilc);
void host_sleep_notify(struct wilc *wilc);
void chip_allow_sleep(struct wilc *wilc);
--
2.7.4
^ permalink raw reply related
* [PATCH 2/8] staging: wilc1000: fix error path cleanup in wilc_wlan_initialize()
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
To: linux-wireless
Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat, stable
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
For the error path in wilc_wlan_initialize(), the resources are not
cleanup in the correct order. Reverted the previous changes and use the
correct order to free during error condition.
Fixes: b46d68825c2d ("staging: wilc1000: remove COMPLEMENT_BOOT")
Cc: <stable@vger.kernel.org>
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/wilc_netdev.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c
index c4efec2..0e0a4ee 100644
--- a/drivers/staging/wilc1000/wilc_netdev.c
+++ b/drivers/staging/wilc1000/wilc_netdev.c
@@ -530,17 +530,17 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
goto fail_locks;
}
- if (wl->gpio_irq && init_irq(dev)) {
- ret = -EIO;
- goto fail_locks;
- }
-
ret = wlan_initialize_threads(dev);
if (ret < 0) {
ret = -EIO;
goto fail_wilc_wlan;
}
+ if (wl->gpio_irq && init_irq(dev)) {
+ ret = -EIO;
+ goto fail_threads;
+ }
+
if (!wl->dev_irq_num &&
wl->hif_func->enable_interrupt &&
wl->hif_func->enable_interrupt(wl)) {
@@ -596,7 +596,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
fail_irq_init:
if (wl->dev_irq_num)
deinit_irq(dev);
-
+fail_threads:
wlan_deinitialize_threads(dev);
fail_wilc_wlan:
wilc_wlan_cleanup(dev);
--
2.7.4
^ permalink raw reply related
* [PATCH 1/8] staging: wilc1000: handle p2p operations in caller context
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
In-Reply-To: <1561552810-8933-1-git-send-email-ajay.kathat@microchip.com>
From: Ajay Singh <ajay.kathat@microchip.com>
Moved the handling of p2p related operation in the caller context instead
of using workqueue.
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
---
drivers/staging/wilc1000/host_interface.c | 46 ++++++++++++-------------------
1 file changed, 17 insertions(+), 29 deletions(-)
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index 13c991535..b505990 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -965,11 +965,8 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
return 0;
}
-static void handle_listen_state_expired(struct work_struct *work)
+static int wilc_handle_roc_expired(struct wilc_vif *vif, u64 cookie)
{
- struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
- struct wilc_vif *vif = msg->vif;
- struct wilc_remain_ch *hif_remain_ch = &msg->body.remain_on_ch;
u8 remain_on_chan_flag;
struct wid wid;
int result;
@@ -981,10 +978,10 @@ static void handle_listen_state_expired(struct work_struct *work)
wid.id = WID_REMAIN_ON_CHAN;
wid.type = WID_STR;
wid.size = 2;
- wid.val = kmalloc(wid.size, GFP_KERNEL);
+ wid.val = kmalloc(wid.size, GFP_KERNEL);
if (!wid.val)
- goto free_msg;
+ return -ENOMEM;
wid.val[0] = remain_on_chan_flag;
wid.val[1] = WILC_FALSE_FRMWR_CHANNEL;
@@ -994,18 +991,25 @@ static void handle_listen_state_expired(struct work_struct *work)
kfree(wid.val);
if (result != 0) {
netdev_err(vif->ndev, "Failed to set remain channel\n");
- goto free_msg;
+ return -EINVAL;
}
if (hif_drv->remain_on_ch.expired) {
hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg,
- hif_remain_ch->cookie);
+ cookie);
}
} else {
netdev_dbg(vif->ndev, "Not in listen state\n");
}
-free_msg:
+ return 0;
+}
+
+static void wilc_handle_listen_state_expired(struct work_struct *work)
+{
+ struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+
+ wilc_handle_roc_expired(msg->vif, msg->body.remain_on_ch.cookie);
kfree(msg);
}
@@ -1019,7 +1023,7 @@ static void listen_timer_cb(struct timer_list *t)
del_timer(&vif->hif_drv->remain_on_ch_timer);
- msg = wilc_alloc_work(vif, handle_listen_state_expired, false);
+ msg = wilc_alloc_work(vif, wilc_handle_listen_state_expired, false);
if (IS_ERR(msg))
return;
@@ -1841,30 +1845,14 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u64 cookie,
int wilc_listen_state_expired(struct wilc_vif *vif, u64 cookie)
{
- int result;
- struct host_if_msg *msg;
- struct host_if_drv *hif_drv = vif->hif_drv;
-
- if (!hif_drv) {
+ if (!vif->hif_drv) {
netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
return -EFAULT;
}
- del_timer(&hif_drv->remain_on_ch_timer);
-
- msg = wilc_alloc_work(vif, handle_listen_state_expired, false);
- if (IS_ERR(msg))
- return PTR_ERR(msg);
-
- msg->body.remain_on_ch.cookie = cookie;
-
- result = wilc_enqueue_work(msg);
- if (result) {
- netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
- kfree(msg);
- }
+ del_timer(&vif->hif_drv->remain_on_ch_timer);
- return result;
+ return wilc_handle_roc_expired(vif, cookie);
}
void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
--
2.7.4
^ permalink raw reply related
* [PATCH 0/8] staging: wilc1000: dynamically add/delete interfaces & cleanup fixes
From: Ajay.Kathat @ 2019-06-26 12:40 UTC (permalink / raw)
To: linux-wireless; +Cc: devel, gregkh, Adham.Abozaeid, johannes, Ajay.Kathat
From: Ajay Singh <ajay.kathat@microchip.com>
This patch series mainly contains the changes to support the
add/delete of wlan0/p2p0 network interfaces dynamically. The driver
will be loaded with a single default interface and later new interfaces
can be added or removed.
Also included few cleanup patches in this series.
Ajay Singh (8):
staging: wilc1000: handle p2p operations in caller context
staging: wilc1000: fix error path cleanup in wilc_wlan_initialize()
staging: wilc1000: added support to dynamically add/remove interfaces
staging: wilc1000: remove use of driver_handler_id & ifc_id
staging: wilc1000: remove unnecessary loop to traverse vif interfaces
staging: wilc1000: remove use of 'src_addr' element in 'wilc_vif'
struct
staging: wilc1000: remove extra argument passing to
wilc_send_config_pkt()
staging: wilc1000: rename 'host_interface' source and header
drivers/staging/wilc1000/Makefile | 2 +-
.../wilc1000/{host_interface.c => wilc_hif.c} | 170 +++----
.../wilc1000/{host_interface.h => wilc_hif.h} | 1 -
drivers/staging/wilc1000/wilc_mon.c | 9 +-
drivers/staging/wilc1000/wilc_netdev.c | 293 ++++-------
drivers/staging/wilc1000/wilc_sdio.c | 7 +-
drivers/staging/wilc1000/wilc_spi.c | 3 +-
drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 536 +++++++++++++--------
drivers/staging/wilc1000/wilc_wfi_cfgoperations.h | 13 +-
drivers/staging/wilc1000/wilc_wfi_netdevice.h | 24 +-
drivers/staging/wilc1000/wilc_wlan.c | 23 +-
drivers/staging/wilc1000/wilc_wlan.h | 8 +-
12 files changed, 560 insertions(+), 529 deletions(-)
rename drivers/staging/wilc1000/{host_interface.c => wilc_hif.c} (91%)
rename drivers/staging/wilc1000/{host_interface.h => wilc_hif.h} (99%)
--
2.7.4
^ permalink raw reply
* [PATCH] libertas: Fix a double free in if_spi_c2h_data()
From: Dan Carpenter @ 2019-06-26 10:09 UTC (permalink / raw)
To: Kalle Valo, Philip Rakity
Cc: Allison Randal, Lubomir Rintel, libertas-dev, linux-wireless,
kernel-janitors
The lbs_process_rxed_packet() frees the skb. It didn't originally, but
we fixed it in commit f54930f36311 ("libertas: don't leak skb on receive
error").
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
drivers/net/wireless/marvell/libertas/if_spi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c
index 27067e79e83f..e38f02d1f2e4 100644
--- a/drivers/net/wireless/marvell/libertas/if_spi.c
+++ b/drivers/net/wireless/marvell/libertas/if_spi.c
@@ -772,7 +772,7 @@ static int if_spi_c2h_data(struct if_spi_card *card)
/* pass the SKB to libertas */
err = lbs_process_rxed_packet(card->priv, skb);
if (err)
- goto free_skb;
+ goto out; /* lbs_process_rxed_packet() frees skb */
/* success */
goto out;
--
2.20.1
^ permalink raw reply related
* Re: [RFC 0/5] add hw dfs pattern detector support to mt7615 driver
From: Ryder Lee @ 2019-06-26 9:46 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: nbd, lorenzo.bianconi, linux-wireless, royluo, yf.luo
In-Reply-To: <cover.1561499275.git.lorenzo@kernel.org>
On Wed, 2019-06-26 at 00:01 +0200, Lorenzo Bianconi wrote:
> Introduce radar pattern detection support to mt7615 driver. Please note I have
> tested this series just through the radar pattern test knob added to debugfs
> and not through I real radar signal generator.
> CSA is currently missing (I am currently working on it).
> This series is based on 'mt76: move nl80211_dfs_regions in mt76_dev data
> structure' https://patchwork.kernel.org/patch/11010723/
>
> Lorenzo Bianconi (5):
> mt76: mt7615: introduce mt7615_regd_notifier
> mt76: mt7615: add hw dfs pattern detector support
> mt76: mt7615: do not perform txcalibration before cac is complited
> mt76: mt7615: unlock dfs bands
> mt76: mt7615: add radar pattern test knob to debugfs
>
> .../wireless/mediatek/mt76/mt7615/Makefile | 3 +-
> .../wireless/mediatek/mt76/mt7615/debugfs.c | 38 ++++++
> .../net/wireless/mediatek/mt76/mt7615/dma.c | 2 +-
> .../net/wireless/mediatek/mt76/mt7615/init.c | 43 +++++--
> .../net/wireless/mediatek/mt76/mt7615/mac.c | 88 +++++++++++++
> .../net/wireless/mediatek/mt76/mt7615/main.c | 6 +
> .../net/wireless/mediatek/mt76/mt7615/mcu.c | 121 ++++++++++++++++--
> .../net/wireless/mediatek/mt76/mt7615/mcu.h | 23 ++++
> .../wireless/mediatek/mt76/mt7615/mt7615.h | 55 ++++++++
> 9 files changed, 356 insertions(+), 23 deletions(-)
> create mode 100644 drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
>
For the series
Acked-by: Ryder Lee <ryder.lee@mediatek.com>
^ permalink raw reply
* [PATCH] ath10k: Move non-fatal warn logs to dbg level for SDIO chip
From: Wen Gong @ 2019-06-26 2:29 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless
ath10k will receive some message with invalid peer id from firmware.
reason is:
There are incoming frames to MAC hardware that NOT find relative
address search table, then peer id is invalid set by MAC hardware,
it is hardware's logic, so fix it in ath10k will be more convenient.
log:
ath10k_sdio mmc1:0001:1: Got RX ind from invalid peer: 65535
Tested with QCA6174 SDIO with firmware
WLAN.RMH.4.4.1-00007-QCARMSWP-1.
Signed-off-by: Wen Gong <wgong@codeaurora.org>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a20ea27..14b838f 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2082,7 +2082,7 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
spin_lock_bh(&ar->data_lock);
peer = ath10k_peer_find_by_id(ar, peer_id);
spin_unlock_bh(&ar->data_lock);
- if (!peer)
+ if (!peer && peer_id != HTT_INVALID_PEERID)
ath10k_warn(ar, "Got RX ind from invalid peer: %u\n", peer_id);
num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
--
1.9.1
^ permalink raw reply related
* [PATCH] ath10k: destroy sdio workqueue while remove sdio module
From: Wen Gong @ 2019-06-26 2:25 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless
The workqueue need to flush and destory while remove sdio module,
otherwise it will have thread which is not destory after remove
sdio modules.
Tested with QCA6174 SDIO with firmware
WLAN.RMH.4.4.1-00007-QCARMSWP-1.
Signed-off-by: Wen Gong <wgong@codeaurora.org>
---
drivers/net/wireless/ath/ath10k/sdio.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
index fae56c6..40c3b4b 100644
--- a/drivers/net/wireless/ath/ath10k/sdio.c
+++ b/drivers/net/wireless/ath/ath10k/sdio.c
@@ -2077,6 +2077,9 @@ static void ath10k_sdio_remove(struct sdio_func *func)
cancel_work_sync(&ar_sdio->wr_async_work);
ath10k_core_unregister(ar);
ath10k_core_destroy(ar);
+
+ flush_workqueue(ar_sdio->workqueue);
+ destroy_workqueue(ar_sdio->workqueue);
}
static const struct sdio_device_id ath10k_sdio_devices[] = {
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox