[PATCH v2 1/2] pci: Add vendor id of Ubiquiti Networks
Signed-off-by: Tobias Schramm--- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..6b01ac1e9bce 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -149,6 +149,8 @@ #define PCI_VENDOR_ID_DYNALINK 0x0675 #define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702 +#define PCI_VENDOR_ID_UBNT 0x0777 + #define PCI_VENDOR_ID_BERKOM 0x0871 #define PCI_DEVICE_ID_BERKOM_A1T 0xffa1 #define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2 -- 2.16.0
[PATCH v2 2/2] ath10k: Add support for Uiquiti rebranded QCA988X v2
Some modern Ubiquiti devices contain a rebranded QCA988X rev2 with a custom Ubiquiti vendor and device id. This patch adds support for those devices, treating them as a QCA988X v2. Signed-off-by: Tobias Schramm--- drivers/net/wireless/ath/ath10k/core.c | 24 drivers/net/wireless/ath/ath10k/hw.h | 1 + drivers/net/wireless/ath/ath10k/pci.c | 4 3 files changed, 29 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index b29fdbd21ead..9fb38f2c1d6e 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -52,6 +52,30 @@ MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software"); MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath"); static const struct ath10k_hw_params ath10k_hw_params_list[] = { + { + .id = QCA988X_HW_2_0_VERSION, + .dev_id = QCA988X_2_0_DEVICE_ID_UBNT, + .name = "qca988x hw2.0", + .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, + .otp_exe_param = 0, + .channel_counters_freq_hz = 88000, + .max_probe_resp_desc_thres = 0, + .cal_data_len = 2116, + .fw = { + .dir = QCA988X_HW_2_0_FW_DIR, + .board = QCA988X_HW_2_0_BOARD_DATA_FILE, + .board_size = QCA988X_BOARD_DATA_SZ, + .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ, + }, + .hw_ops = _ops, + .decap_align_bytes = 4, + .spectral_bin_discard = 0, + .vht160_mcs_rx_highest = 0, + .vht160_mcs_tx_highest = 0, + .n_cipher_suites = 8, + }, { .id = QCA988X_HW_2_0_VERSION, .dev_id = QCA988X_2_0_DEVICE_ID, diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 05f26e5858ad..5ae3b56acc19 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -22,6 +22,7 @@ #define ATH10K_FW_DIR "ath10k" +#define QCA988X_2_0_DEVICE_ID_UBNT (0x11ac) #define QCA988X_2_0_DEVICE_ID (0x003c) #define QCA6164_2_1_DEVICE_ID (0x0041) #define QCA6174_2_1_DEVICE_ID (0x003e) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index ffea348b2190..ccac6740795d 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -52,6 +52,7 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)"); #define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3 static const struct pci_device_id ath10k_pci_id_table[] = { + { PCI_VDEVICE(UBNT, QCA988X_2_0_DEVICE_ID_UBNT) }, /* PCI-E QCA988X V2 (Ubiquiti branded) */ { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */ { PCI_VDEVICE(ATHEROS, QCA6164_2_1_DEVICE_ID) }, /* PCI-E QCA6164 V2.1 */ { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */ @@ -68,6 +69,7 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = { * hacks. ath10k doesn't have them and these devices crash horribly * because of that. */ + { QCA988X_2_0_DEVICE_ID_UBNT, QCA988X_HW_2_0_CHIP_ID_REV }, { QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV }, { QCA6164_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV }, @@ -1977,6 +1979,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); switch (ar_pci->pdev->device) { + case QCA988X_2_0_DEVICE_ID_UBNT: case QCA988X_2_0_DEVICE_ID: case QCA99X0_2_0_DEVICE_ID: case QCA9888_2_0_DEVICE_ID: @@ -3208,6 +3211,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); switch (pci_dev->device) { + case QCA988X_2_0_DEVICE_ID_UBNT: case QCA988X_2_0_DEVICE_ID: hw_rev = ATH10K_HW_QCA988X; pci_ps = false; -- 2.16.0
[PATCH v2 0/2] ath10k: Add support for Ubiquiti-branded QCA988X
A lot of more modern Ubiquiti AirMAX wireless devices contain a rebranded QCA988X with changed PCI vendor and device id. This patch adds support for those chips by treating them as QCA988X rev2 radios. Changes since v1: * Send patch to more people and lists Tobias Schramm (2): pci: Add vendor id of Ubiquiti Networks ath10k: Add support for Uiquiti rebranded QCA988X v2 drivers/net/wireless/ath/ath10k/core.c | 24 drivers/net/wireless/ath/ath10k/hw.h | 1 + drivers/net/wireless/ath/ath10k/pci.c | 4 include/linux/pci_ids.h| 2 ++ 4 files changed, 31 insertions(+) -- 2.16.0
Re: [2/2] mwifiex: use more_rx_task_flag to avoid USB RX stall
Ganapathi Bhatwrote: > From: Shrenik Shikhare > > There is a race condition for acquiring rx_proc_lock between > rx worker thread and USB RX data interrupt > (mwifiex_usb_rx_complete): > > 1. USB receives an RX data interrupt, queues rx_work > 2. rx_work empties rx_data_q, tries to acquire rx_proc_lock (to > clear rx_processing flag) > 3. While #2 is yet to acquire rx_proc_lock, driver receives > continuous RX data interupts(mwifiex_usb_rx_complete) > 3. For each interrupt at #3, driver acquires rx_proc_lock(it gets > the lock since it is in interrupt context), tries to queue > rx_work, but fails to do so since rx_processing is still set(#2) > 4. When rx_pending exceeds HIGH_RX_PENDING, driver stops > submitting URBs back to USB subsystem and thus firmware stops > uploading RX data to driver > 5. Now finally #2 will acquire rx_proc_lock, but because of #4, > there are no further triggers to schedule rx_work again > > The above scenario occurs in some platforms where the RX > processing is comparitively slower. This results in RX stall in > driver, command/TX timeouts in firmware. The above scenario is > introduced after commit c7dbdcb2a4e1 > ("mwifiex: schedule rx_work on RX interrupt for USB") > > To fix this set a new more_rx_task_flag whenever RX data callback > is trying to schedule rx_work but rx_processing is not yet > cleared. This will let the current rx_work(which was waiting for > rx_proc_lock) to loopback and process newly arrived RX packets. > > Signed-off-by: Cathy Luo > Signed-off-by: Ganapathi Bhat I can't find any commit with id c7dbdcb2a4e1, is it correct? -- https://patchwork.kernel.org/patch/10178729/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [1/2] mwifiex: schedule rx_work on RX interrupt for USB
Ganapathi Bhatwrote: > From: Shrenik Shikhare > > There is race for data_received flag between main thread and > RX data interrupt(mwifiex_usb_rx_complete()): > 1. USB received an RX data interrupt, set data_received flag > 2. main thread checks data_received, if set queues rx_work > 3. rx worker thread independently start processing rx_data_q > 4. rx work exits (once rx_data_q is empty) > 5. main thread resets the data_received flag(after #2) > 6. Now at the corner case there will be high RX data interrupts > between #4 and #5 > 7. Driver stops submitting URBs to firmware, once rx_pending > exceeds HIGH_RX_PENDING > 8. The flag data_received(cleared in #5) will remain unset since > there will be no interrupts from firmware to set it(after #7) > > Above scenario causes RX stall in driver, which will finally > result in command/TX timeouts in firmware. > > As a fix, queue rx_work directly in mwifiex_usb_rx_complete() > callback, instead in the main thread. This removes dependency > of RX processing on data_received flag. > > Signed-off-by: Cathy Luo > Signed-off-by: Ganapathi Bhat Brian, did you have a chance to review these two? -- https://patchwork.kernel.org/patch/10178731/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [2/2] mwifiex: use more_rx_task_flag to avoid USB RX stall
Kalle Valowrites: > Ganapathi Bhat wrote: > >> From: Shrenik Shikhare >> >> There is a race condition for acquiring rx_proc_lock between >> rx worker thread and USB RX data interrupt >> (mwifiex_usb_rx_complete): >> >> 1. USB receives an RX data interrupt, queues rx_work >> 2. rx_work empties rx_data_q, tries to acquire rx_proc_lock (to >> clear rx_processing flag) >> 3. While #2 is yet to acquire rx_proc_lock, driver receives >> continuous RX data interupts(mwifiex_usb_rx_complete) >> 3. For each interrupt at #3, driver acquires rx_proc_lock(it gets >> the lock since it is in interrupt context), tries to queue >> rx_work, but fails to do so since rx_processing is still set(#2) >> 4. When rx_pending exceeds HIGH_RX_PENDING, driver stops >> submitting URBs back to USB subsystem and thus firmware stops >> uploading RX data to driver >> 5. Now finally #2 will acquire rx_proc_lock, but because of #4, >> there are no further triggers to schedule rx_work again >> >> The above scenario occurs in some platforms where the RX >> processing is comparitively slower. This results in RX stall in >> driver, command/TX timeouts in firmware. The above scenario is >> introduced after commit c7dbdcb2a4e1 >> ("mwifiex: schedule rx_work on RX interrupt for USB") >> >> To fix this set a new more_rx_task_flag whenever RX data callback >> is trying to schedule rx_work but rx_processing is not yet >> cleared. This will let the current rx_work(which was waiting for >> rx_proc_lock) to loopback and process newly arrived RX packets. >> >> Signed-off-by: Cathy Luo >> Signed-off-by: Ganapathi Bhat > > I can't find any commit with id c7dbdcb2a4e1, is it correct? Oh, and please use Fixes line to mark the commit which broke this. -- Kalle Valo
Re: [v2] wcn36xx: release resources in case of error
Ramon Friedwrote: > wcn36xx_dxe_init() doesn't check for the return value of > wcn36xx_dxe_init_descs(), release the resources in case an error ocurred. > > Signed-off-by: Ramon Fried > Signed-off-by: Kalle Valo Patch applied to ath-next branch of ath.git, thanks. d0bb950b9f5f wcn36xx: release DMA memory in case of error -- https://patchwork.kernel.org/patch/10180503/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [v2,1/4] ath9k: Alternative EEPROM size for AR9003
Wojciech Dubowikwrote: > AR9003 factory calibration allows to use bigger EEPROM than > standard 1k without changing the default layout. Allow > probing of EEPROM at alternative address if initial check > for default fails. > The original ar9003 eeprom ops are still be used. > > Signed-off-by: Wojciech Dubowik > Signed-off-by: Kalle Valo 4 patches applied to ath-next branch of ath.git, thanks. 528782ecf59f ath9k: Alternative EEPROM size for AR9003 34d4fcd8813a ath9k: Read noise floor calibration data from eeprom 8da58553cc63 ath9k: Use calibrated noise floor value when available 3717957ce55c ath9k: Display calibration data piers in debugfs -- https://patchwork.kernel.org/patch/10181889/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [v2,1/8] wil6210: add Talyn PCIe device ID
Maya Erezwrote: > PCIe device ID has changed in Talyn. > Add this ID to wil6210_pcie_ids list to allow > recognition of Talyn device. > > Signed-off-by: Maya Erez > Signed-off-by: Kalle Valo 8 patches applied to ath-next branch of ath.git, thanks. 10cd2d45f6c7 wil6210: add Talyn PCIe device ID 4fe1fccecf87 wil6210: recognize Talyn JTAG ID 4276d7711e7c wil6210: add support for Talyn AHB address map 2a0efe6a32ac wil6210: support flashless device b8e13b87b15d wil6210: configure OTP HW vectors in SW reset flow 70bcc658c0b1 wil6210: fix random failure to bring network interface up 54fca595d1ee wil6210: enlarge FW mac_rgf_ext section for Sparrow D0 81b35afa49c8 wil6210: support parsing brd file address from fw file -- https://patchwork.kernel.org/patch/10176857/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: ath9k: discard undersized packets
Felix Fietkauwrote: > Sometimes the hardware will push small packets that trigger a WARN_ON > in mac80211. Discard them early to avoid this issue. > > Reported-by: Stijn Tintel > Signed-off-by: Felix Fietkau > Signed-off-by: Kalle Valo Patch applied to ath-next branch of ath.git, thanks. 3c0efb745a17 ath9k: discard undersized packets -- https://patchwork.kernel.org/patch/10168963/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [mac80211-next:master 3/5] net//wireless/wext-compat.c:1351:9: warning: function returns address of local variable
On Mon, 2018-01-22 at 13:00 +, kbuild test robot wrote: > tree: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.gi > t master > head: 076dc671ee9fa374e77c3d05925dafb75b23a74c > commit: c179e91512cab01e83be35a60eaeda0f170a9101 [3/5] cfg80211: wext: don't > use static struct > config: x86_64-randconfig-x016-01221834 (attached as .config) > compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025 > reproduce: > git checkout c179e91512cab01e83be35a60eaeda0f170a9101 > # save the attached .config to linux build tree > make ARCH=x86_64 > > All warnings (new ones prefixed by >>): > >net//wireless/wext-compat.c: In function 'cfg80211_wireless_stats': > >> net//wireless/wext-compat.c:1351:9: warning: function returns address of > local variable [-Wreturn-local-addr] > return > ^~~ > Hi Johannes, In commit c179e9151, you remove 'static' from struct, but function return the address of local variable as kbuild robot mentioned. It is a problem, but my prior experiment looks fine. Hence, I check the callers of get_wireless_stats(), and found they use the address that points to stack immediately, so content of stack wasn't broken luckily. So, please recall the 'static' of 'struct iw_statistics wstats'. Thanks PK
[PATCH v2] rtlwifi: btcoex: Fix some static warnings from Sparse
From: Ping-Ke ShihAdd 'static' or declaration to resolve the warnings, and remove two unused functions halbtc_set_macreg() and halbtc_get_macreg() exposed when they were made static. Signed-off-by: Ping-Ke Shih --- The original subject of this patch is '[PATCH 07/10]' in previous patchset, and other patches are applied excepcting to this one that Larry suggested to add comments why two functions are revmoed, but the content is unchanged. --- .../realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 36 +++--- .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h | 4 +++ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c index 73ef5b271f3b..1404729441a2 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c @@ -29,7 +29,7 @@ * Debug related function ***/ -const char *const gl_btc_wifi_bw_string[] = { +static const char *const gl_btc_wifi_bw_string[] = { "11bg", "HT20", "HT40", @@ -37,7 +37,7 @@ const char *const gl_btc_wifi_bw_string[] = { "HT160" }; -const char *const gl_btc_wifi_freq_string[] = { +static const char *const gl_btc_wifi_freq_string[] = { "2.4G", "5G" }; @@ -156,7 +156,7 @@ static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist) return chnl; } -u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) +static u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) { struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; @@ -171,12 +171,12 @@ u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) return rtlpriv->btcoexist.btc_info.single_ant_path; } -u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv) +static u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv) { return rtlpriv->btcoexist.btc_info.bt_type; } -u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) +static u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) { struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; u8 num; @@ -193,7 +193,7 @@ u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) return num; } -u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv) +static u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv) { struct rtl_hal *rtlhal = rtl_hal(rtlpriv); @@ -504,7 +504,7 @@ static u32 halbtc_get_bt_forbidden_slot_val(void *btc_context) return btcoexist->bt_info.bt_forb_slot_val; } -u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist) +static u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist) { /* return value: * [31:16] => connected port number @@ -980,7 +980,8 @@ static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data) rtl_write_dword(rtlpriv, reg_addr, data); } -void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr, u8 data) +static void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr, +u8 data) { struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; struct rtl_priv *rtlpriv = btcoexist->adapter; @@ -993,22 +994,6 @@ void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr, u8 data) rtl_write_byte(rtlpriv, reg_addr, data); } -void halbtc_set_macreg(void *btc_context, u32 reg_addr, u32 bit_mask, u32 data) -{ - struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; - struct rtl_priv *rtlpriv = btcoexist->adapter; - - rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data); -} - -u32 halbtc_get_macreg(void *btc_context, u32 reg_addr, u32 bit_mask) -{ - struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; - struct rtl_priv *rtlpriv = btcoexist->adapter; - - return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask); -} - static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask, u32 data) { @@ -1054,6 +1039,7 @@ static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id, cmd_len, cmd_buf); } +static void halbtc_set_bt_reg(void *btc_context, u8 reg_type, u32 offset, u32 set_val) { struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context; @@ -1093,7 +1079,7 @@ static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type, } } -bool halbtc_under_ips(struct btc_coexist *btcoexist) +static bool halbtc_under_ips(struct btc_coexist *btcoexist) { struct rtl_priv *rtlpriv = btcoexist->adapter; struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
[PATCH v3] mac80211: mesh: fix wrong mesh TTL offset calculation
From: Peter Ohmesh TTL offset in Mesh Channel Switch Parameters element depends on not only Secondary Channel Offset element, but also affected by HT Control field and Wide Bandwidth Channel Switch element. Use element structure to correct the miscalculation. Signed-off-by: Peter Oh --- net/mac80211/mesh.c | 17 ++--- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 73ac607..6a381cb 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1255,13 +1255,12 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, } static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, - struct ieee80211_mgmt *mgmt, size_t len) + struct ieee80211_mgmt *mgmt, size_t len, + struct ieee802_11_elems *elems) { struct ieee80211_mgmt *mgmt_fwd; struct sk_buff *skb; struct ieee80211_local *local = sdata->local; - u8 *pos = mgmt->u.action.u.chan_switch.variable; - size_t offset_ttl; skb = dev_alloc_skb(local->tx_headroom + len); if (!skb) @@ -1269,13 +1268,9 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, skb_reserve(skb, local->tx_headroom); mgmt_fwd = skb_put(skb, len); - /* offset_ttl is based on whether the secondary channel -* offset is available or not. Subtract 1 from the mesh TTL -* and disable the initiator flag before forwarding. -*/ - offset_ttl = (len < 42) ? 7 : 10; - *(pos + offset_ttl) -= 1; - *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; + elems->mesh_chansw_params_ie->mesh_ttl--; + elems->mesh_chansw_params_ie->mesh_flags &= + ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; memcpy(mgmt_fwd, mgmt, len); eth_broadcast_addr(mgmt_fwd->da); @@ -1323,7 +1318,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, /* forward or re-broadcast the CSA frame */ if (fwd_csa) { - if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0) + if (mesh_fwd_csa_frame(sdata, mgmt, len, ) < 0) mcsa_dbg(sdata, "Failed to forward the CSA frame"); } } -- 2.7.4
[PATCH] ath10k: Update the phymode along with bandwidth change request
From: Ryan HsuIn the case of Station connects to AP with narrower bandwidth at beginning. And later the AP changes the bandwidth to winder bandwidth, the AP will beacon with wider bandwidth IE, eg VHT20->VHT40->VHT80 or VHT40->VHT80. Since the supported BANDWIDTH will be limited by the PHYMODE, so while Station receives the bandwidth change request, it will also need to reconfigure the PHYMODE setting to firmware instead of just configuring the BANDWIDTH info, otherwise it'll trigger a firmware crash with non-support bandwidth. The issue was observed in WLAN.RM.4.4.1-00051-QCARMSWP-1, QCA6174 with below scenario. -- AP xxx changed bandwidth, new config is 5200 MHz, width 2 (5190/0 MHz) disconnect from AP xxx for new auth to yyy RX ReassocResp from xxx (capab=0x status=0 aid=102) associated AP xxx changed bandwidth, new config is 5200 MHz, width 2 (5190/0 MHz) AP xxx changed bandwidth, new config is 5200 MHz, width 3 (5210/0 MHz) firmware register dump: [00]: 0x0503 0x15B3 0x00987291 0x00955B31 [04]: 0x00987291 0x00060730 0x0004 0x0001 [08]: 0x004089F0 0x00955A00 0x000A0B00 0x0040 [12]: 0x0009 0x 0x00952CD0 0x00952CE6 [16]: 0x00952CC4 0x0098E25F 0x 0x0091080D [20]: 0x40987291 0x0040E7A8 0x 0x0041EE3C [24]: 0x809ABF05 0x0040E808 0x 0xC0987291 [28]: 0x809A650C 0x0040E948 0x0041FE40 0x004345C4 [32]: 0x809A5C63 0x0040E988 0x0040E9AC 0x0042D1A8 [36]: 0x8091D252 0x0040E9A8 0x0002 0x0001 [40]: 0x809FDA9D 0x0040EA58 0x0043D554 0x0042D554 [44]: 0x809F8B22 0x0040EA78 0x0043D554 0x0001 [48]: 0x80911210 0x0040EAC8 0x0010 0x004041D0 [52]: 0x80911154 0x0040EB28 0x0040 0x [56]: 0x8091122D 0x0040EB48 0x 0x00400600 -- Reported-by: Rouven Czerwinski Signed-off-by: Ryan Hsu --- drivers/net/wireless/ath/ath10k/mac.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index ebb3f1b..68a5256 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2005-2011 Atheros Communications Inc. * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -5996,8 +5997,18 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) ath10k_mac_max_vht_nss(vht_mcs_mask))); if (changed & IEEE80211_RC_BW_CHANGED) { - ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n", - sta->addr, bw); + mode = chan_to_phymode(); + + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n", + sta->addr, bw, mode); + + err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, + WMI_PEER_PHYMODE, mode); + if (err) { + ath10k_warn(ar, "failed to update STA %pM peer phymode %d: %d\n", + sta->addr, mode, err); + goto exit; + } err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, WMI_PEER_CHAN_WIDTH, bw); @@ -6039,6 +6050,7 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) sta->addr); } +exit: mutex_unlock(>conf_mutex); } -- 1.9.1
Regulatory: reg.c : wiphy_apply_custom_regulatory()
Hello, Can wiphy_apply_custom_regulatory() be called after wiphy registeration? The documentation(comment) says "/* Used by drivers prior to wiphy registration */" Whys is there a restriction to call this after registration? Is the comment outdated? After Tracing the regulatory code in the cfg80211, it seems that there should be no restriction. Regards Neelansh
Re: [PATCH 8/8] mt76: validate rx CCMP PN
On 2018-01-24 17:20, Johannes Berg wrote: > On Wed, 2018-01-24 at 17:11 +0100, Felix Fietkau wrote: >> >> I guess I will have to look into fragmentation. I have a second driver >> pending that only reports the CCMP PN outside of the packet, and for >> performance reasons I really don't want to translate it and move it to a >> place where mac80211 can parse it. >> I'm also looking into doing parallel rx in software to see if I can get >> more performance that way. I think for that I would also need CCMP PN >> validation in the driver. > > Fair enough. We also do it, except we just decide that fragmented > packets we don't care and can use mac80211 - but we get the PN in- > frame, just can't always use mac80211 due to parallel RX. I guess I could make the driver translate the header for fragmented packets only. - Felix
Re: [PATCH 8/8] mt76: validate rx CCMP PN
On Wed, 2018-01-24 at 17:11 +0100, Felix Fietkau wrote: > > I guess I will have to look into fragmentation. I have a second driver > pending that only reports the CCMP PN outside of the packet, and for > performance reasons I really don't want to translate it and move it to a > place where mac80211 can parse it. > I'm also looking into doing parallel rx in software to see if I can get > more performance that way. I think for that I would also need CCMP PN > validation in the driver. Fair enough. We also do it, except we just decide that fragmented packets we don't care and can use mac80211 - but we get the PN in- frame, just can't always use mac80211 due to parallel RX. johannes
Re: [1/2] brcmfmac: assure bcdc dcmd api does not return value > 0
Arend Van Sprielwrote: > The protocol layer api defines callbacks for dongle commands. > Although not really well documented these should only return an > error code in case of an error, or 0 upon success. In the bcdc > protocol it can return value above 0 and we carry a fix in the > caller of the protocol layer api. This patch makes it adhere to > the intent of the api as described above. > > Reviewed-by: Hante Meuleman > Reviewed-by: Pieter-Paul Giesberts > Reviewed-by: Franky Lin > Signed-off-by: Arend van Spriel 2 patches applied to wireless-drivers-next.git, thanks. 5242a5444e0b brcmfmac: assure bcdc dcmd api does not return value > 0 b69c1df47281 brcmfmac: separate firmware errors from i/o errors -- https://patchwork.kernel.org/patch/10179309/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [01/11] qtnfmac: remove struct qlink_cmd_set_mac_acl
Sergey Matyukevichwrote: > From: Vasily Ulyanov > > TLV is used to pass ACL data to firmware in start_ap cfg80211 callback. > Use the same approach in set_mac_acl cfg80211 callback. > > Signed-off-by: Vasily Ulyanov 11 patches applied to wireless-drivers-next.git, thanks. 33f9899234a2 qtnfmac: remove struct qlink_cmd_set_mac_acl 87affddef94e qtnfmac: fix warnings when mBSS setup is stopped 04b01affb824 qtnfmac: support 64-bit network interface stats 5ec5b532dabc qtnfmac: get more hardware info from card 0b419d0182bc qtnfmac: report hardware/firmware information via ethtool 537faf269d76 qtnfmac: modify supported interface combinations 01efff526235 qtnfmac: validate interface combinations on changes 39845020b39e qtnfmac: fix STA disconnect procedure f2cddd5469b0 qtnfmac: do not use mutexes in timer context 237d29f6ce46 qtnfmac: do not use bus mutex for events processing c93fe71c91d0 qtnfmac: remove redundant 'unlikely' checks -- https://patchwork.kernel.org/patch/10178447/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [PATCH 8/8] mt76: validate rx CCMP PN
On Wed, 2018-01-24 at 16:19 +0100, Felix Fietkau wrote: > Apparently hardware does not perform CCMP PN validation in hardware, so > we need to take care of this in the driver. This is important for > protecting against replay attacks > > +static int > +mt76_check_ccmp_pn(struct sk_buff *skb) > +{ > + struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb; > + struct mt76_wcid *wcid = status->wcid; > + int ret; > + > + if (!(status->flag & RX_FLAG_DECRYPTED)) > + return 0; > + > + if (!wcid || !wcid->rx_check_pn) > + return 0; > + > + BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0])); > + ret = memcmp(status->iv, wcid->rx_key_pn[status->tid], > + sizeof(status->iv)); > + if (ret <= 0) > + return -EINVAL; /* replay */ > + > + memcpy(wcid->rx_key_pn[status->tid], status->iv, sizeof(status->iv)); > + status->flag |= RX_FLAG_PN_VALIDATED; You shouldn't do this, try to somehow make it rely on mac80211 instead. Otherwise, you really have to handle CCMP vs. fragmentation. johannes
Re: rtl8xxxu: Fix trailing semicolon
Luis de Bethencourtwrote: > The trailing semicolon is an empty statement that does no operation. > Removing it since it doesn't do anything. > > Signed-off-by: Luis de Bethencourt > Acked-by: Jes Sorensen Patch applied to wireless-drivers-next.git, thanks. 8054a275de08 rtl8xxxu: Fix trailing semicolon -- https://patchwork.kernel.org/patch/10169063/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [PATCH 10/10] rtlwifi: Add spec_ver to check whether use new rate-id or not
Pkshihwrites: > On Mon, 2018-01-22 at 13:10 -0600, Larry Finger wrote: >> On 01/19/2018 12:45 AM, pks...@realtek.com wrote: >> > >> > From: Ping-Ke Shih >> > >> > The field spec_ver is IC's specification mask for common code to do proper >> > process to specified IC. This commit add a field new rate ID for new >> > generation IC. >> > >> > Signed-off-by: Ping-Ke Shih >> Acked-by: Larry Finger >> > > Shall I append "Acked-by" in v2? Yes, you can add Acked-by in the next version (if the patch in question is not modified after the ack). But do note that patchwork can automatically take Acked-by from the mailing list, for example that happened in the 9 patches I just applied from this series. So you no need to resend the rtlwifi patches for just to add the Acked-by line. -- Kalle Valo
Re: [01/10] rtlwifi: btcoex: extend get_wifi_bw to support bandwidth 80M
Ping-Ke Shihwrote: > From: Ping-Ke Shih > > The rtlwifi newer ICs support 80M bandwidth in 5G band, so extend > get_wifi_bw() to know bandwidth 80M that helps btcoex to make correct > decisions. > > Signed-off-by: Ping-Ke Shih > Acked-by: Larry Finger 9 patches applied to wireless-drivers-next.git, thanks. 66d0f9deba36 rtlwifi: btcoex: extend get_wifi_bw to support bandwidth 80M 17bf85101181 rtlwifi: btcoex: Add switch band notify for btc f243bca13893 rtlwifi: btcoex: Add variable ant_div_cfg to support antenna diversity ee373844849c rtlwifi: btcoex: add scan_notify within ips_notify if RFON 9177c3363994 rtlwifi: btcoex: Add wifi_only series ops to control solo card 8d73e53e8a87 rtlwifi: btcoex: add boolean variables dbg_mode ba3cca4d0c3e rtlwifi: 8822be has to report vht capability to mac80211 be98db155646 rtlwifi: Add ratr_table for newer IC a75f3eebfa3d rtlwifi: Add spec_ver to check whether use new rate-id or not -- https://patchwork.kernel.org/patch/10174643/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [07/10] rtlwifi: btcoex: Fix some static warnings from Sparse
Ping-Ke Shihwrote: > From: Ping-Ke Shih > > Add 'static' or declaration to resolve the warnings. > > Signed-off-by: Ping-Ke Shih Dropping this patch 7 per comments, but I'll try to take the rest (if they apply). Patch set to Changes Requested. -- https://patchwork.kernel.org/patch/10174655/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
[PATCH 1/8] mt76: retry rx polling as long as there is budget left
Sending frames to mac80211 needs time, which could allow for more rx packets to end up in the DMA ring. Retry polling until there are no more frames left. Improves rx latency under load. Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/dma.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index ecd409a4a89b..e539b3838b94 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -387,17 +387,21 @@ static int mt76_dma_rx_poll(struct napi_struct *napi, int budget) { struct mt76_dev *dev; - int qid, done; + int qid, done = 0, cur; dev = container_of(napi->dev, struct mt76_dev, napi_dev); qid = napi - dev->napi; - done = mt76_dma_rx_process(dev, >q_rx[qid], budget); + do { + cur = mt76_dma_rx_process(dev, >q_rx[qid], budget - done); + mt76_rx_complete(dev, qid); + done += cur; + } while (cur && done < budget); + if (done < budget) { napi_complete(napi); dev->drv->rx_poll_complete(dev, qid); } - mt76_rx_complete(dev, qid); return done; } -- 2.14.2
[PATCH 8/8] mt76: validate rx CCMP PN
Apparently hardware does not perform CCMP PN validation in hardware, so we need to take care of this in the driver. This is important for protecting against replay attacks Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/mac80211.c| 51 drivers/net/wireless/mediatek/mt76/mt76.h| 12 +- drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 45 - drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 1 + 5 files changed, 98 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 77f1be161009..c203e7b48c58 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -384,6 +384,27 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx, } EXPORT_SYMBOL_GPL(mt76_get_survey); +void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, +struct ieee80211_key_conf *key) +{ + struct ieee80211_key_seq seq; + int i; + + wcid->rx_check_pn = false; + + if (!key) + return; + + if (key->cipher == WLAN_CIPHER_SUITE_CCMP) + wcid->rx_check_pn = true; + + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { + ieee80211_get_key_rx_seq(key, i, ); + memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn)); + } +} +EXPORT_SYMBOL(mt76_wcid_key_setup); + static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); @@ -410,6 +431,31 @@ static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) return wcid_to_sta(mstat.wcid); } +static int +mt76_check_ccmp_pn(struct sk_buff *skb) +{ + struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb; + struct mt76_wcid *wcid = status->wcid; + int ret; + + if (!(status->flag & RX_FLAG_DECRYPTED)) + return 0; + + if (!wcid || !wcid->rx_check_pn) + return 0; + + BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0])); + ret = memcmp(status->iv, wcid->rx_key_pn[status->tid], +sizeof(status->iv)); + if (ret <= 0) + return -EINVAL; /* replay */ + + memcpy(wcid->rx_key_pn[status->tid], status->iv, sizeof(status->iv)); + status->flag |= RX_FLAG_PN_VALIDATED; + + return 0; +} + void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, int queue) { @@ -421,6 +467,11 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, napi = >napi[queue]; while ((skb = __skb_dequeue(frames)) != NULL) { + if (mt76_check_ccmp_pn(skb)) { + dev_kfree_skb(skb); + continue; + } + sta = mt76_rx_convert(skb); ieee80211_rx_napi(dev->hw, sta, skb, napi); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index af98bc65c2e1..129015c9d116 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -131,6 +131,9 @@ struct mt76_wcid { u8 sta:1; + u8 rx_check_pn; + u8 rx_key_pn[IEEE80211_NUM_TIDS][6]; + __le16 tx_rate; bool tx_rate_set; u8 tx_rate_nss; @@ -279,12 +282,14 @@ struct mt76_rx_status { unsigned long reorder_time; - u8 aggr; + u8 iv[6]; + + u8 aggr:1; u8 tid; u16 seqno; - u32 flag; u16 freq; + u32 flag; u8 enc_flags; u8 encoding:2, bw:3; u8 rate_idx; @@ -413,6 +418,9 @@ int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, u16 ssn, u8 size); void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); +void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, +struct ieee80211_key_conf *key); + /* internal */ void mt76_tx_free(struct mt76_dev *dev); void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c index 1e34b578b151..1b00ae4465a2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c @@ -131,7 +131,7 @@ mt76_write_mac_initvals(struct mt76x2_dev *dev) { MT_RX_FILTR_CFG, 0x00015f97 }, { MT_LEGACY_BASIC_RATE, 0x017f }, { MT_HT_BASIC_RATE, 0x4003 }, - { MT_PN_PAD_MODE, 0x0002 }, + { MT_PN_PAD_MODE,
[PATCH 3/8] mt76: add an intermediate struct for rx status information
Preparation for passing in more internal rx data via skb->cb Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/mac80211.c | 29 - drivers/net/wireless/mediatek/mt76/mt76.h | 13 +++ drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 4 ++-- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 3acf0e175d71..258d2623d1bf 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -384,10 +384,37 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx, } EXPORT_SYMBOL_GPL(mt76_get_survey); +static void +mt76_rx_convert(struct sk_buff *skb) +{ + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct mt76_rx_status mstat; + + mstat = *((struct mt76_rx_status *) skb->cb); + memset(status, 0, sizeof(*status)); + + status->flag = mstat.flag; + status->freq = mstat.freq; + status->enc_flags = mstat.enc_flags; + status->encoding = mstat.encoding; + status->bw = mstat.bw; + status->rate_idx = mstat.rate_idx; + status->nss = mstat.nss; + status->band = mstat.band; + status->signal = mstat.signal; + status->chains = mstat.chains; + + BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb)); + BUILD_BUG_ON(sizeof(status->chain_signal) != sizeof(mstat.chain_signal)); + memcpy(status->chain_signal, mstat.chain_signal, sizeof(mstat.chain_signal)); +} + void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q) { struct sk_buff *skb; - while ((skb = __skb_dequeue(>rx_skb[q])) != NULL) + while ((skb = __skb_dequeue(>rx_skb[q])) != NULL) { + mt76_rx_convert(skb); ieee80211_rx_napi(dev->hw, NULL, skb, >napi[q]); + } } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index f88d9a15210a..be4846ee4828 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -250,6 +250,19 @@ struct mt76_rate_power { }; }; +struct mt76_rx_status { + u32 flag; + u16 freq; + u8 enc_flags; + u8 encoding:2, bw:3; + u8 rate_idx; + u8 nss; + u8 band; + u8 signal; + u8 chains; + s8 chain_signal[IEEE80211_MAX_CHAINS]; +}; + #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) #define mt76_wr(dev, ...) (dev)->mt76.bus->wr(&((dev)->mt76), __VA_ARGS__) #define mt76_rmw(dev, ...) (dev)->mt76.bus->rmw(&((dev)->mt76), __VA_ARGS__) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index 98219b971463..2e12fc0d5c9e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -29,7 +29,7 @@ void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr) } static int -mt76x2_mac_process_rate(struct ieee80211_rx_status *status, u16 rate) +mt76x2_mac_process_rate(struct mt76_rx_status *status, u16 rate) { u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate); @@ -268,7 +268,7 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb) int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void *rxi) { - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb; struct mt76x2_rxwi *rxwi = rxi; u32 ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); -- 2.14.2
[PATCH 6/8] mt76: split mt76_rx_complete
Add a separate function for processing frames after A-MPDU reordering, reduce code duplication Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/agg-rx.c | 8 +--- drivers/net/wireless/mediatek/mt76/dma.c | 2 +- drivers/net/wireless/mediatek/mt76/mac80211.c | 24 ++-- drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++-- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c index ecd0bcd149e5..8027bb7c03c2 100644 --- a/drivers/net/wireless/mediatek/mt76/agg-rx.c +++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c @@ -97,9 +97,7 @@ mt76_rx_aggr_reorder_work(struct work_struct *work) struct mt76_rx_tid *tid = container_of(work, struct mt76_rx_tid, reorder_work.work); struct mt76_dev *dev = tid->dev; - struct ieee80211_sta *sta; struct sk_buff_head frames; - struct sk_buff *skb; __skb_queue_head_init(); @@ -110,11 +108,7 @@ mt76_rx_aggr_reorder_work(struct work_struct *work) spin_unlock(>lock); ieee80211_queue_delayed_work(tid->dev->hw, >reorder_work, REORDER_TIMEOUT); - - while ((skb = __skb_dequeue()) != NULL) { - sta = mt76_rx_convert(skb); - ieee80211_rx_napi(dev->hw, sta, skb, NULL); - } + mt76_rx_complete(dev, , -1); local_bh_enable(); } diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index fd8bea144973..3518703524e7 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -396,7 +396,7 @@ mt76_dma_rx_poll(struct napi_struct *napi, int budget) do { cur = mt76_dma_rx_process(dev, >q_rx[qid], budget - done); - mt76_rx_complete(dev, qid); + mt76_rx_poll_complete(dev, qid); done += cur; } while (cur && done < budget); diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 5978e5b0a2fe..77f1be161009 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -384,7 +384,7 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx, } EXPORT_SYMBOL_GPL(mt76_get_survey); -struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) +static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct mt76_rx_status mstat; @@ -410,9 +410,24 @@ struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb) return wcid_to_sta(mstat.wcid); } -void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q) +void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, + int queue) { + struct napi_struct *napi = NULL; struct ieee80211_sta *sta; + struct sk_buff *skb; + + if (queue >= 0) + napi = >napi[queue]; + + while ((skb = __skb_dequeue(frames)) != NULL) { + sta = mt76_rx_convert(skb); + ieee80211_rx_napi(dev->hw, sta, skb, napi); + } +} + +void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q) +{ struct sk_buff_head frames; struct sk_buff *skb; @@ -421,8 +436,5 @@ void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q) while ((skb = __skb_dequeue(>rx_skb[q])) != NULL) mt76_rx_aggr_reorder(skb, ); - while ((skb = __skb_dequeue()) != NULL) { - sta = mt76_rx_convert(skb); - ieee80211_rx_napi(dev->hw, sta, skb, >napi[q]); - } + mt76_rx_complete(dev, , q); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index cde199ed3f57..af98bc65c2e1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -416,8 +416,9 @@ void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); /* internal */ void mt76_tx_free(struct mt76_dev *dev); void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); -void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q); +void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, + int queue); +void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q); void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); -struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb); #endif -- 2.14.2
[PATCH 7/8] mt76: pass the per-vif wcid to the core for multicast rx
Preparation for adding software rx CCMP PN validation Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/mt76x2.h | 1 + drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 15 --- drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h index a12dfce8c0d1..17df17afd9bf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2.h +++ b/drivers/net/wireless/mediatek/mt76/mt76x2.h @@ -144,6 +144,7 @@ struct mt76x2_vif { struct mt76x2_sta { struct mt76_wcid wcid; /* must be first */ + struct mt76x2_vif *vif; struct mt76x2_tx_status status; int n_frames; }; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index b96d8a88656c..f56a8f459fe6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -266,12 +266,20 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb) } static struct mt76_wcid * -mt76x2_rx_get_wcid(struct mt76x2_dev *dev, u8 idx) +mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, u8 idx, bool unicast) { + struct mt76x2_sta *sta; + struct mt76_wcid *wcid; + if (idx >= ARRAY_SIZE(dev->wcid)) return NULL; - return rcu_dereference(dev->wcid[idx]); + wcid = rcu_dereference(dev->wcid[idx]); + if (unicast || !wcid) + return wcid; + + sta = container_of(wcid, struct mt76x2_sta, wcid); + return >vif->group_wcid; } int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, @@ -282,11 +290,12 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, u32 ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); u16 tid_sn = le16_to_cpu(rxwi->tid_sn); + bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST); u8 wcid; int len; wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl); - status->wcid = mt76x2_rx_get_wcid(dev, wcid); + status->wcid = mt76x2_rx_get_sta_wcid(dev, wcid, unicast); if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) mt76x2_remove_hdr_pad(skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index bc08040123b9..08fe804c6a43 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c @@ -273,6 +273,7 @@ mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; } + msta->vif = mvif; msta->wcid.sta = 1; msta->wcid.idx = idx; msta->wcid.hw_key_idx = -1; -- 2.14.2
[PATCH 4/8] mt76: get station pointer by wcid and pass it to mac80211
Avoids the rhashtable lookup based on the MAC address inside mac80211 Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/dma.c | 4 drivers/net/wireless/mediatek/mt76/mac80211.c| 9 ++--- drivers/net/wireless/mediatek/mt76/mt76.h| 14 ++ drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 13 + drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 1 + 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index e539b3838b94..fd8bea144973 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -392,12 +392,16 @@ mt76_dma_rx_poll(struct napi_struct *napi, int budget) dev = container_of(napi->dev, struct mt76_dev, napi_dev); qid = napi - dev->napi; + rcu_read_lock(); + do { cur = mt76_dma_rx_process(dev, >q_rx[qid], budget - done); mt76_rx_complete(dev, qid); done += cur; } while (cur && done < budget); + rcu_read_unlock(); + if (done < budget) { napi_complete(napi); dev->drv->rx_poll_complete(dev, qid); diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 258d2623d1bf..c1982211d658 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -384,7 +384,7 @@ int mt76_get_survey(struct ieee80211_hw *hw, int idx, } EXPORT_SYMBOL_GPL(mt76_get_survey); -static void +static struct ieee80211_sta * mt76_rx_convert(struct sk_buff *skb) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); @@ -407,14 +407,17 @@ mt76_rx_convert(struct sk_buff *skb) BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb)); BUILD_BUG_ON(sizeof(status->chain_signal) != sizeof(mstat.chain_signal)); memcpy(status->chain_signal, mstat.chain_signal, sizeof(mstat.chain_signal)); + + return wcid_to_sta(mstat.wcid); } void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q) { + struct ieee80211_sta *sta; struct sk_buff *skb; while ((skb = __skb_dequeue(>rx_skb[q])) != NULL) { - mt76_rx_convert(skb); - ieee80211_rx_napi(dev->hw, NULL, skb, >napi[q]); + sta = mt76_rx_convert(skb); + ieee80211_rx_napi(dev->hw, sta, skb, >napi[q]); } } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index be4846ee4828..e20c52607c66 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -125,6 +125,8 @@ struct mt76_wcid { u8 idx; u8 hw_key_idx; + u8 sta:1; + __le16 tx_rate; bool tx_rate_set; u8 tx_rate_nss; @@ -251,6 +253,7 @@ struct mt76_rate_power { }; struct mt76_rx_status { + struct mt76_wcid *wcid; u32 flag; u16 freq; u8 enc_flags; @@ -343,6 +346,17 @@ mtxq_to_txq(struct mt76_txq *mtxq) return container_of(ptr, struct ieee80211_txq, drv_priv); } +static inline struct ieee80211_sta * +wcid_to_sta(struct mt76_wcid *wcid) +{ + void *ptr = wcid; + + if (!wcid || !wcid->sta) + return NULL; + + return container_of(ptr, struct ieee80211_sta, drv_priv); +} + int mt76_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, struct sk_buff *skb, struct mt76_wcid *wcid, struct ieee80211_sta *sta); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index 2e12fc0d5c9e..75f2843847d0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -265,6 +265,15 @@ static void mt76x2_remove_hdr_pad(struct sk_buff *skb) skb_pull(skb, 2); } +static struct mt76_wcid * +mt76x2_rx_get_wcid(struct mt76x2_dev *dev, u8 idx) +{ + if (idx >= ARRAY_SIZE(dev->wcid)) + return NULL; + + return rcu_dereference(dev->wcid[idx]); +} + int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void *rxi) { @@ -272,8 +281,12 @@ int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, struct mt76x2_rxwi *rxwi = rxi; u32 ctl = le32_to_cpu(rxwi->ctl); u16 rate = le16_to_cpu(rxwi->rate); + u8 wcid; int len; + wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl); + status->wcid = mt76x2_rx_get_wcid(dev, wcid); + if (rxwi->rxinfo & cpu_to_le32(MT_RXINFO_L2PAD)) mt76x2_remove_hdr_pad(skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c index aa5fbb64e218..2a1cb65c5edb 100644 ---
[PATCH 2/8] mt76: fix TSF value in probe responses
Like beacons, probe responses need a hardware-generated TSF value. Set the flag that causes the hw to generate it Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c index a7416a01baa4..98219b971463 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c @@ -172,6 +172,7 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_rate *rate = >control.rates[0]; struct ieee80211_key_conf *key = info->control.hw_key; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2)); u16 txwi_flags = 0; u8 nss; @@ -248,6 +249,10 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, sta->ht_cap.ampdu_density); } + if (ieee80211_is_probe_resp(hdr->frame_control) || + ieee80211_is_beacon(hdr->frame_control)) + txwi_flags |= MT_TXWI_FLAGS_TS; + txwi->flags |= cpu_to_le16(txwi_flags); txwi->len_ctl = cpu_to_le16(skb->len); } @@ -634,7 +639,6 @@ mt76_write_beacon(struct mt76x2_dev *dev, int offset, struct sk_buff *skb) return -ENOSPC; mt76x2_mac_write_txwi(dev, , skb, NULL, NULL); - txwi.flags |= cpu_to_le16(MT_TXWI_FLAGS_TS); mt76_wr_copy(dev, offset, , sizeof(txwi)); offset += sizeof(txwi); -- 2.14.2
[PATCH 5/8] mt76: implement A-MPDU rx reordering in the driver code
This is required for performing CCMP PN validation in software Signed-off-by: Felix Fietkau--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- drivers/net/wireless/mediatek/mt76/agg-rx.c | 264 +++ drivers/net/wireless/mediatek/mt76/mac80211.c| 11 +- drivers/net/wireless/mediatek/mt76/mt76.h| 35 +++ drivers/net/wireless/mediatek/mt76/mt76x2_init.c | 2 + drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 7 + drivers/net/wireless/mediatek/mt76/mt76x2_main.c | 2 + 7 files changed, 319 insertions(+), 4 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/agg-rx.c diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 2bb919863616..a0156bc01dea 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_MT76_CORE) += mt76.o obj-$(CONFIG_MT76x2E) += mt76x2e.o mt76-y := \ - mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o tx.o + mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o tx.o agg-rx.o CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c new file mode 100644 index ..ecd0bcd149e5 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2018 Felix Fietkau + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "mt76.h" + +#define REORDER_TIMEOUT (HZ / 10) + +static void +mt76_aggr_release(struct mt76_rx_tid *tid, struct sk_buff_head *frames, int idx) +{ + struct sk_buff *skb; + + tid->head = ieee80211_sn_inc(tid->head); + + skb = tid->reorder_buf[idx]; + if (!skb) + return; + + tid->reorder_buf[idx] = NULL; + tid->nframes--; + __skb_queue_tail(frames, skb); +} + +static void +mt76_rx_aggr_release_frames(struct mt76_rx_tid *tid, struct sk_buff_head *frames, +u16 head) +{ + int idx; + + while (ieee80211_sn_less(tid->head, head)) { + idx = tid->head % tid->size; + mt76_aggr_release(tid, frames, idx); + } +} + +static void +mt76_rx_aggr_release_head(struct mt76_rx_tid *tid, struct sk_buff_head *frames) +{ + int idx = tid->head % tid->size; + + while (tid->reorder_buf[idx]) { + mt76_aggr_release(tid, frames, idx); + idx = tid->head % tid->size; + } +} + +static void +mt76_rx_aggr_check_release(struct mt76_rx_tid *tid, struct sk_buff_head *frames) +{ + struct mt76_rx_status *status; + struct sk_buff *skb; + int start, idx, nframes; + + if (!tid->nframes) + return; + + mt76_rx_aggr_release_head(tid, frames); + + start = tid->head % tid->size; + nframes = tid->nframes; + + for (idx = (tid->head + 1) % tid->size; +idx != start && nframes; +idx = (idx + 1) % tid->size) { + + skb = tid->reorder_buf[idx]; + if (!skb) + continue; + + nframes--; + status = (struct mt76_rx_status *) skb->cb; + if (!time_after(jiffies, status->reorder_time + +REORDER_TIMEOUT)) + continue; + + mt76_rx_aggr_release_frames(tid, frames, status->seqno); + } + + mt76_rx_aggr_release_head(tid, frames); +} + +static void +mt76_rx_aggr_reorder_work(struct work_struct *work) +{ + struct mt76_rx_tid *tid = container_of(work, struct mt76_rx_tid, + reorder_work.work); + struct mt76_dev *dev = tid->dev; + struct ieee80211_sta *sta; + struct sk_buff_head frames; + struct sk_buff *skb; + + __skb_queue_head_init(); + + local_bh_disable(); + + spin_lock(>lock); + mt76_rx_aggr_check_release(tid, ); + spin_unlock(>lock); + + ieee80211_queue_delayed_work(tid->dev->hw, >reorder_work, REORDER_TIMEOUT); + + while ((skb = __skb_dequeue()) != NULL) { + sta = mt76_rx_convert(skb); +
Re: [v2] mt76x2: init: disable all pending tasklets during device removal
Lorenzo Bianconiwrote: > There is a possible race in mt76x2_stop_hardware() since pre_tbtt and > dfs tasklets could run during driver cleanup. Fix it disabling all > pending tasklets during device removal > > Signed-off-by: Lorenzo Bianconi > Acked-by: Felix Fietkau Patch applied to wireless-drivers-next.git, thanks. ba9797b2a7a5 mt76x2: init: disable all pending tasklets during device removal -- https://patchwork.kernel.org/patch/10179831/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [1/3] mt76x2: dfs: avoid tasklet scheduling during mt76x2_dfs_init_params()
Lorenzo Bianconiwrote: > Substitute tasklet_kill with tasklet_disable/tasklet_enable in order to > guarantee dfs tasklet can not be executed during dfs parameter > initialization > > Signed-off-by: Lorenzo Bianconi 3 patches applied to wireless-drivers-next.git, thanks. 8c9f6491a313 mt76x2: dfs: avoid tasklet scheduling during mt76x2_dfs_init_params() 2070f3cc2c2c mt76x2: dfs: add set_domain handler 634e99f0d4da mt76x2: dfs: take into account dfs region in mt76x2_dfs_init_params() -- https://patchwork.kernel.org/patch/10152031/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: mt76: fix transmission of encrypted management frames
Felix Fietkauwrote: > Hardware encryption seems to break encrypted unicast mgmt tx. > Unfortunately the hardware TXWI header does not have a bit to indicate > that a frame is software encrypted, so sw-encrypted frames need to use a > different WCID. For that to work, the CCMP PN needs to be generated in > software, which makes things a bit slower, so only do it for keys that > also need to tx management frames. > > Signed-off-by: Felix Fietkau Patch applied to wireless-drivers-next.git, thanks. 23405236460b mt76: fix transmission of encrypted management frames -- https://patchwork.kernel.org/patch/10173781/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: mt76x2: fix WMM parameter configuration
Lorenzo Bianconiwrote: > Fix hw queue configuration since mt76x2 devices use a reverse queue > enumeration respect to mac80211 one: > - 0: AC_BE > - 1: AC_BK > - 2: AC_VI > - 3: AC_VO > > The issue can be reproduced sending two concurrent flow using > two separate queues: > - VO: 20Mbps UDP traffic > - BE: TCP traffic > > In this scenario the UDP traffic will be blocked by the TCP one. > Fix it configuring properly WMM hw queue parameters > > Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e") > Tested-by: Gaetano Catalli > Signed-off-by: Gaetano Catalli > Signed-off-by: Lorenzo Bianconi > Acked-by: Felix Fietkau Patch applied to wireless-drivers-next.git, thanks. 1cbbf69cc83e mt76x2: fix WMM parameter configuration -- https://patchwork.kernel.org/patch/10169067/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Re: [PATCH v2] wcn36xx: release resources in case of error
Ramon Friedwrites: > wcn36xx_dxe_init() doesn't check for the return value > of wcn36xx_dxe_init_descs(). > This patch releases the resources in case an error ocurred. > > Change-Id: I924bd7489b60243c0a0cbaa716caf924f11d7587 > Signed-off-by: Ramon Fried This compiled now, thanks. But I did some minor changes in the commit log and in indentation on the pending branch: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending=e5ff4344eab68c86e00036e937847ce89dfaeef6 > @@ -819,11 +847,19 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) > > ret = wcn36xx_dxe_request_irqs(wcn); > if (ret < 0) > - goto out_err; > + goto out_err_irq; The recommended style is to label the err_ based what the target does, not from where they are called from. It's easier to manage the labels that way. But as this is a style issue I didn't change it. -- Kalle Valo
Re: [PATCH 1/2] cfg80211: Add tx ack signal attribute in sta info
On 2018-01-22 17:52, Johannes Berg wrote: On Thu, 2018-01-18 at 18:10 +0530, Venkateswara Naralasetty wrote: From: Bhagavathi Perumal SThis patch provides support for users to get ack signal strength of last transmitted by introducing new attribute 'NL80211_STA_INFO_ACK_SIGNAL'. No real objection to the patch itself, but you should say *why* you need this, and I'm not really sure I see much point in having the signal strength of the very last ACK frame? If user wants to get instant RSSI for the station which is ideal for long time, user can sent null frame and get RSSI form the ack of that null frame. At least provide reasoning so other drivers can decide whether to implement it or not. + * @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm) more like s8, really. I have taken reference from 'NL80211_STA_INFO_SIGNAL_AVG'.
Re: [PATCH v2] mac80211_hwsim: don't use WQ_MEM_RECLAIM
On Wed, 2018-01-24 at 10:39 +0100, Benjamin Beichler wrote: > sorry for introducing that error, but I'm a bit confused by the > workqueue documentation. > My assumption was, that deleting hwsim radios is reclaiming memory, and > since this queue does nothing else it would save/necessary to set this flag. > > Maybe a hint in the documentation, that a work item on a WQ_MEM_RECLAIM > queue must not call flush of an !WQ_MEM_RECLAIM queue would be nice. > Maybe it's kind of obvious, but there is also a reminder not to forget > that flag, if a queue may have work items that reclaim memory Yeah, honestly, I'm not really sure either. Clearly we can't set it, but other drivers also set it... I don't think it was *intended* for when you're freeing memory, since I think reclaiming is what happens when you write out dirty buffers to disk etc. johannes
Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping frame due to full tx queue...?
Hi So if 3.9 works and current kernel does not, the best way to address the issue would be identify change that broke. Ideally if bisecton could be performed, but this can be hard taking that the problem is not easy reproducible. Further difficultly comes from a fact that OpenWRT has custom patches. So I suggest some kind of manual semi-bisection on OpenWRT repository with long testing, to find out first or close to first OpenWRT change that start to broke things. Cheers Stanislaw On Wed, Jan 24, 2018 at 09:18:23AM +0100, Enrico Mioso wrote: > Hello! > I can confirm - there is no firmware being uploaded to the device, or at > least: if it's there, it's not uploaded from an external file. > root@smalltalk:~# ls -Fa -1 /lib/firmware/ > ./ > ../ > regulatory.db > root@smalltalk:~# > > Anything I might do? I can also give an ssh session to the device in case. > > Enrico > > On Tue, 23 Jan 2018, Stanislaw Gruszka wrote: > > >Date: Tue, 23 Jan 2018 14:22:35 > >From: Stanislaw Gruszka> >To: Enrico Mioso > >Cc: Tom Psyborg , > >linux-wireless , > >Johannes Berg , > >Daniel Golle , Arnd Bergmann , > >John Crispin , Felix Fietkau > >Subject: Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping > >frame due to full tx queue...? > > > >On Mon, Jan 22, 2018 at 06:45:57AM +0100, Enrico Mioso wrote: > >>Crash happening here also in the WL-330n3G device; unfortunately, no > >>messages to report. > >>Regarding your hypothesis regardingthe firmware not being able to > >>communicate a problem regarding it's inability to send frames: around when > >>OpenWRT had 3.9.9 kernel, this device worked for weeks no stop with no > >>issues I think. > >>And I don't think this is only a coicnidence. So I suspect, but it's only > >>an impression, also because I know ... very very little about this, that at > >>some point things worked. > > > >I think FW was upgraded since 3.9 kernel as well. But this > >could be also problem how driver program the device registers, > >not only FW problem. > > > >Regards > >Stanislaw > >
Re: [PATCH v2] mac80211_hwsim: don't use WQ_MEM_RECLAIM
Hi Johannes, sorry for introducing that error, but I'm a bit confused by the workqueue documentation. My assumption was, that deleting hwsim radios is reclaiming memory, and since this queue does nothing else it would save/necessary to set this flag. Maybe a hint in the documentation, that a work item on a WQ_MEM_RECLAIM queue must not call flush of an !WQ_MEM_RECLAIM queue would be nice. Maybe it's kind of obvious, but there is also a reminder not to forget that flag, if a queue may have work items that reclaim memory. Again sorry for not seeing the warning on my test system ... kind regards Benjamin Am 24.01.2018 um 08:40 schrieb Johannes Berg: > From: Johannes Berg> > We're obviously not part of a memory reclaim path, so don't set the flag. > > This also causes a warning in check_flush_dependency() since we end up > in a code path that flushes a non-reclaim workqueue, and we shouldn't do > that if we were really part of reclaim. > -- M.Sc. Benjamin Beichler Universität Rostock, Fakultät für Informatik und Elektrotechnik Institut für Angewandte Mikroelektronik und Datentechnik University of Rostock, Department of CS and EE Institute of Applied Microelectronics and CE Richard-Wagner-Straße 31 18119 Rostock Deutschland/Germany phone: +49 (0) 381 498 - 7278 email: benjamin.beich...@uni-rostock.de www: http://www.imd.uni-rostock.de/ smime.p7s Description: S/MIME Cryptographic Signature
RE: [linuxwifi] Null pointer dereference in iwlwifi when starting ad-hoc network
Hi, > I get this oops in 4.15rc9 when doing the following: > > # iw dev wlp2s0 set type ibss > # ip link set dev wlp2s0 up > # iw dev wlp2s0 ibss join "TEST" 2412 > > The oops happens after some delay (approx. 5 seconds). > > Hardware is: > > 02:00.0 Network controller: Intel Corporation Wireless 8265 / 8275 (rev 78) > pci > vendor code 8086:24fd > Subsystem: 8086:0050 > > Oops message is: > > IPv6: ADDRCONF(NETDEV_UP): wlp2s0: link is not ready > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Trigger new scan to find an IBSS to join > wlp2s0: Creating new IBSS network, BSSID 3a:94:1d:dd:ab:09 > BUG: unable to handle kernel NULL pointer dereference at > 0068 We have a fix for this which should go upstream soon: commit 0e37a1940fcfae99ffec59ad620ed81feb2d Author: Sara SharonDate: Thu Dec 21 15:05:28 2017 +0200 [BUGFIX] iwlwifi: mvm: fix IBSS for devices that support station type API in our internal tree which is mirrored here: https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/backport-iwlwifi.git/
Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping frame due to full tx queue...?
Hello! I can confirm - there is no firmware being uploaded to the device, or at least: if it's there, it's not uploaded from an external file. root@smalltalk:~# ls -Fa -1 /lib/firmware/ ./ ../ regulatory.db root@smalltalk:~# Anything I might do? I can also give an ssh session to the device in case. Enrico On Tue, 23 Jan 2018, Stanislaw Gruszka wrote: Date: Tue, 23 Jan 2018 14:22:35 From: Stanislaw GruszkaTo: Enrico Mioso Cc: Tom Psyborg , linux-wireless , Johannes Berg , Daniel Golle , Arnd Bergmann , John Crispin , Felix Fietkau Subject: Re: ieee80211 phy0: rt2x00queue_write_tx_frame: Error - Dropping frame due to full tx queue...? On Mon, Jan 22, 2018 at 06:45:57AM +0100, Enrico Mioso wrote: Crash happening here also in the WL-330n3G device; unfortunately, no messages to report. Regarding your hypothesis regardingthe firmware not being able to communicate a problem regarding it's inability to send frames: around when OpenWRT had 3.9.9 kernel, this device worked for weeks no stop with no issues I think. And I don't think this is only a coicnidence. So I suspect, but it's only an impression, also because I know ... very very little about this, that at some point things worked. I think FW was upgraded since 3.9 kernel as well. But this could be also problem how driver program the device registers, not only FW problem. Regards Stanislaw
Null pointer dereference in iwlwifi when starting ad-hoc network
I get this oops in 4.15rc9 when doing the following: # iw dev wlp2s0 set type ibss # ip link set dev wlp2s0 up # iw dev wlp2s0 ibss join "TEST" 2412 The oops happens after some delay (approx. 5 seconds). Hardware is: 02:00.0 Network controller: Intel Corporation Wireless 8265 / 8275 (rev 78) pci vendor code 8086:24fd Subsystem: 8086:0050 Oops message is: IPv6: ADDRCONF(NETDEV_UP): wlp2s0: link is not ready wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Trigger new scan to find an IBSS to join wlp2s0: Creating new IBSS network, BSSID 3a:94:1d:dd:ab:09 BUG: unable to handle kernel NULL pointer dereference at 0068 IP: iwl_trans_pcie_txq_enable+0x5e/0x440 [iwlwifi] PGD 0 P4D 0 Oops: 0002 [#1] PREEMPT SMP PTI Modules linked in: snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic btusb btrtl btbcm btintel bluetooth uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core videodev media ecdh_generic crc16 joydev mousedev arc4 hid_multitouch msr mei_wdt nouveau iwlmvm i915 intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel mac80211 kvm iTCO_wdt iTCO_vendor_support nls_iso8859_1 nls_cp437 vfat irqbypass crct10dif_pclmul fat wmi_bmof crc32_pclmul dell_smbios_wmi iwlwifi dell_wmi dell_rbtn ghash_clmulni_intel dell_wmi_descriptor intel_wmi_thunderbolt dell_laptop dell_smbios_smm dell_smbios pcbc dcdbas mxm_wmi dell_smm_hwmon ttm snd_hda_intel i2c_algo_bit drm_kms_helper snd_hda_codec tpm_crb idma64 cfg80211 aesni_intel snd_hda_core aes_x86_64 crypto_simd drm glue_helper snd_hwdep cryptd intel_cstate snd_pcm intel_rapl_perf psmouse evdev snd_timer input_leds intel_gtt rfkill led_class mac_hid agpgart snd rtsx_pci_ms pcspkr mei_me memstick syscopyarea i2c_hid sysfillrect tpm_tis sysimgblt processor_thermal_device tpm_tis_core i2c_i801 intel_lpss_pci soundcore mei fb_sys_fops shpchp intel_pch_thermal thermal intel_lpss intel_soc_dts_iosf hid battery tpm int3400_thermal ac wmi video acpi_thermal_rel int3403_thermal intel_hid acpi_pad int340x_thermal_zone sparse_keymap button sch_fq_codel crypto_user ip_tables x_tables btrfs xor zstd_decompress zstd_compress xxhash raid6_pq rtsx_pci_sdmmc mmc_core serio_raw atkbd libps2 crc32c_intel ahci libahci xhci_pci libata nvme xhci_hcd nvme_core rtsx_pci scsi_mod usbcore usb_common i8042 serio CPU: 4 PID: 371 Comm: kworker/u16:6 Not tainted 4.15.0-rc9-1-mainline #4 Hardware name: Dell Inc. Precision 5520/0R6JFH, BIOS 1.7.0 12/15/2017 Workqueue: phy0 ieee80211_iface_work [mac80211] RIP: 0010:iwl_trans_pcie_txq_enable+0x5e/0x440 [iwlwifi] RSP: 0018:bb4702b4bb90 EFLAGS: 00010246 RAX: 0bb8 RBX: 00ff RCX: RDX: RSI: 00ff RDI: 17700fa0 RBP: R08: 2710 R09: 0001 R10: R11: 8f45cb5aacd0 R12: R13: R14: R15: 8f45d7020018 FS: () GS:8f45fe50() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 0068 CR3: 0003f100a005 CR4: 003606e0 DR0: DR1: DR2: DR3: DR6: fffe0ff0 DR7: 0400 Call Trace: iwl_mvm_enable_txq+0x205/0x390 [iwlmvm] ? ieee80211_iterate_active_interfaces_atomic+0x2e/0x40 [mac80211] ? iwl_mvm_add_mcast_sta+0x159/0x1e0 [iwlmvm] iwl_mvm_add_mcast_sta+0x159/0x1e0 [iwlmvm] iwl_mvm_start_ap_ibss+0xb4/0x1b0 [iwlmvm] __ieee80211_sta_join_ibss+0x340/0x7f0 [mac80211] ieee80211_sta_create_ibss+0x8c/0xf0 [mac80211] ieee80211_ibss_work+0x3a4/0x5a0 [mac80211] ? skb_dequeue+0x52/0x60 ? ieee80211_iface_work+0xbe/0x340 [mac80211] process_one_work+0x1de/0x410 worker_thread+0x2b/0x3d0 ? process_one_work+0x410/0x410 kthread+0x111/0x130 ? kthread_create_worker_on_cpu+0x70/0x70 ? do_group_exit+0x3a/0xa0 ret_from_fork+0x3a/0x50 Code: 4c 8b ac c7 e8 7d 00 00 f0 48 0f ab 87 e8 8d 00 00 73 0d 80 3d 0a 07 03 00 00 0f 84 97 03 00 00 44 89 c7 e8 a5 88 71 e8 4d 85 e4 <49> 89 45 68 0f 84 d6 02 00 00 41 0f b6 04 24 89 44 24 04 41 0f RIP: iwl_trans_pcie_txq_enable+0x5e/0x440 [iwlwifi] RSP: bb4702b4bb90 CR2: 0068 ---[ end trace 3e02d7f42559c48e ]--- GDB tells me that iwl_trans_pcie_txq_enable+0x5e is in drivers/net/wireless/intel/iwlwifi/pcie/tx.c: txq->wd_timeout = msecs_to_jiffies(wdg_timeout);
[PATCH v2 0/4] ath9k: AR9003 noise floor calibration support
AR9003 series allows to calibrate noise floor for different frequency bins. Once it's done it's possible to get more accurate rssi/signal values over whole frequency band at a given temperature. The RSSI/signal accuracy reported by calibrated RF cards improves from 6 to up to 2dB. This could be interesting for application which require good signal accuracy like roaming or mesh protocols. V2: Copied cover letter feature description to patch 3 in the series. Wojciech Dubowik (4): ath9k: Alternative EEPROM size for AR9003 ath9k: Read noise floor calibration data from eeprom ath9k: Use calibrated noise floor value when available ath9k: Display calibration data piers in debugfs drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 133 +++-- drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 10 ++ drivers/net/wireless/ath/ath9k/calib.c | 38 --- drivers/net/wireless/ath/ath9k/hw.h| 2 + 4 files changed, 160 insertions(+), 23 deletions(-) -- 2.7.4
[PATCH v2 4/4] ath9k: Display calibration data piers in debugfs
Display per frequency calibration data in dump_modal debugfs entry including reference power, voltage, tx temperature and noise floor. Example of chain 0 of OEM card (dump from modal_eeprom): Chain 0 Freq refvolttempnf_Cal nf_Pow rx_temp 5180-30 0 137 0 0 0 5320-24 0 137 0 0 0 5500-15 0 137 0 0 0 5620-10 0 137 0 0 0 5700-15 0 137 0 0 0 5745-16 0 135 0 0 0 5785-19 0 136 0 0 0 5825-22 0 136 0 0 0 Example of a card with calibrated noise floor. Chain 0 Freq refvolttempnf_Cal nf_Pow rx_temp 4890-49 0 128 -107-97 124 5100-23 0 128 -101-96 124 5180-18 0 128 -101-96 124 5300-12 0 128 -102-97 124 5500-9 0 128 -101-97 125 5640-17 0 128 -101-98 124 5785-25 0 128 -101-98 124 5940-33 0 128 -106-99 124 Signed-off-by: Wojciech Dubowik--- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 64 +- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index de2e503..f019a20 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3436,6 +3436,60 @@ static u32 ar9003_dump_modal_eeprom(char *buf, u32 len, u32 size, return len; } +static u32 ar9003_dump_cal_data(struct ath_hw *ah, char *buf, u32 len, u32 size, + bool is_2g) +{ + struct ar9300_eeprom *eep = >eeprom.ar9300_eep; + struct ar9300_base_eep_hdr *pBase; + struct ar9300_cal_data_per_freq_op_loop *cal_pier; + int cal_pier_nr; + int freq; + int i, j; + + pBase = >baseEepHeader; + + if (is_2g) + cal_pier_nr = AR9300_NUM_2G_CAL_PIERS; + else + cal_pier_nr = AR9300_NUM_5G_CAL_PIERS; + + for (i = 0; i < AR9300_MAX_CHAINS; i++) { + if (!((pBase->txrxMask >> i) & 1)) + continue; + + len += snprintf(buf + len, size - len, "Chain %d\n", i); + + len += snprintf(buf + len, size - len, + "Freq\t ref\tvolt\ttemp\tnf_cal\tnf_pow\trx_temp\n"); + + for (j = 0; j < cal_pier_nr; j++) { + if (is_2g) { + cal_pier = >calPierData2G[i][j]; + freq = 2300 + eep->calFreqPier2G[j]; + } else { + cal_pier = >calPierData5G[i][j]; + freq = 4800 + eep->calFreqPier5G[j] * 5; + } + + len += snprintf(buf + len, size - len, + "%d\t", freq); + + len += snprintf(buf + len, size - len, + "%d\t%d\t%d\t%d\t%d\t%d\n", + cal_pier->refPower, + cal_pier->voltMeas, + cal_pier->tempMeas, + cal_pier->rxTempMeas ? + N2DBM(cal_pier->rxNoisefloorCal) : 0, + cal_pier->rxTempMeas ? + N2DBM(cal_pier->rxNoisefloorPower) : 0, + cal_pier->rxTempMeas); + } + } + + return len; +} + static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, u8 *buf, u32 len, u32 size) { @@ -3447,10 +3501,18 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, "%20s :\n", "2GHz modal Header"); len = ar9003_dump_modal_eeprom(buf, len, size, >modalHeader2G); - len += scnprintf(buf + len, size - len, + + len += scnprintf(buf + len, size - len, "Calibration data\n"); + len = ar9003_dump_cal_data(ah, buf, len, size, true); + + len += snprintf(buf + len, size - len, "%20s :\n", "5GHz modal Header"); len = ar9003_dump_modal_eeprom(buf, len, size, >modalHeader5G); + + len += snprintf(buf + len, size - len, "Calibration data\n"); + len = ar9003_dump_cal_data(ah, buf, len, size, false); + goto out; } -- 2.7.4
[PATCH v2 3/4] ath9k: Use calibrated noise floor value when available
AR9003 series allows to calibrate noise floor for different frequency bins. Once it's done it's possible to get more accurate rssi/signal values over whole frequency band at a given temperature. The RSSI/signal accuracy reported by calibrated RF cards improves from 6 to up to 2dB. This could be interesting for application which require good signal accuracy like roaming or mesh protocols. Signed-off-by: Wojciech Dubowik--- drivers/net/wireless/ath/ath9k/calib.c | 38 +- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 13ab6bc..3d9447e 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -58,19 +58,25 @@ static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah, } static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, - struct ath9k_channel *chan) + struct ath9k_channel *chan, + int chain) { - return ath9k_hw_get_nf_limits(ah, chan)->nominal; + s16 calib_nf = ath9k_hw_get_nf_limits(ah, chan)->cal[chain]; + + if (calib_nf) + return calib_nf; + else + return ath9k_hw_get_nf_limits(ah, chan)->nominal; } s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan, s16 nf) { - s8 noise = ATH_DEFAULT_NOISE_FLOOR; + s8 noise = ath9k_hw_get_default_nf(ah, chan, 0); if (nf) { s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH - - ath9k_hw_get_default_nf(ah, chan); + ath9k_hw_get_default_nf(ah, chan, 0); if (delta > 0) noise += delta; } @@ -240,7 +246,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) unsigned i, j; u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; struct ath_common *common = ath9k_hw_common(ah); - s16 default_nf = ath9k_hw_get_default_nf(ah, chan); + s16 default_nf = ath9k_hw_get_nf_limits(ah, chan)->nominal; u32 bb_agc_ctl = REG_READ(ah, AR_PHY_AGC_CONTROL); if (ah->caldata) @@ -258,8 +264,13 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) nfval = ah->nf_override; else if (h) nfval = h[i].privNF; - else - nfval = default_nf; + else { + /* Try to get calibrated noise floor value */ + nfval = + ath9k_hw_get_nf_limits(ah, chan)->cal[i]; + if (nfval > -60 || nfval < -127) + nfval = default_nf; + } REG_RMW(ah, ah->nf_regs[i], (((u32) nfval << 1) & 0x1ff), 0x1ff); @@ -429,20 +440,19 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath9k_nfcal_hist *h; - s16 default_nf; - int i, j; + int i, j, k = 0; ah->caldata->channel = chan->channel; ah->caldata->channelFlags = chan->channelFlags; h = ah->caldata->nfCalHist; - default_nf = ath9k_hw_get_default_nf(ah, chan); for (i = 0; i < NUM_NF_READINGS; i++) { h[i].currIndex = 0; - h[i].privNF = default_nf; + h[i].privNF = ath9k_hw_get_default_nf(ah, chan, k); h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH; - for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { - h[i].nfCalBuffer[j] = default_nf; - } + for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) + h[i].nfCalBuffer[j] = h[i].privNF; + if (++k >= AR5416_MAX_CHAINS) + k = 0; } } -- 2.7.4
[PATCH v2 1/4] ath9k: Alternative EEPROM size for AR9003
AR9003 factory calibration allows to use bigger EEPROM than standard 1k without changing the default layout. Allow probing of EEPROM at alternative address if initial check for default fails. The original ar9003 eeprom ops are still be used. Signed-off-by: Wojciech Dubowik--- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c2e210c..23bb677 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3310,6 +3310,12 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, if (ar9300_check_eeprom_header(ah, read, cptr)) goto found; + cptr = AR9300_BASE_ADDR_4K; + ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n", + cptr); + if (ar9300_check_eeprom_header(ah, read, cptr)) + goto found; + cptr = AR9300_BASE_ADDR_512; ath_dbg(common, EEPROM, "Trying EEPROM access at Address 0x%04x\n", cptr); -- 2.7.4
[PATCH v2 2/4] ath9k: Read noise floor calibration data from eeprom
AR9003 devices can have calibrated noise floor values which can be used instead of hard coded one. Read them from eeprom and save interpolated value in nf limits for the current channel. Signed-off-by: Wojciech Dubowik--- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 63 ++ drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 10 drivers/net/wireless/ath/ath9k/hw.h| 2 + 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 23bb677..de2e503 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -4689,7 +4689,8 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, int ichain, int *pfrequency, int *pcorrection, - int *ptemperature, int *pvoltage) + int *ptemperature, int *pvoltage, + int *pnf_cal, int *pnf_power) { u8 *pCalPier; struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct; @@ -4731,6 +4732,10 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, *pcorrection = pCalPierStruct->refPower; *ptemperature = pCalPierStruct->tempMeas; *pvoltage = pCalPierStruct->voltMeas; + *pnf_cal = pCalPierStruct->rxTempMeas ? + N2DBM(pCalPierStruct->rxNoisefloorCal) : 0; + *pnf_power = pCalPierStruct->rxTempMeas ? + N2DBM(pCalPierStruct->rxNoisefloorPower) : 0; return 0; } @@ -4895,14 +4900,18 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) int mode; int lfrequency[AR9300_MAX_CHAINS], lcorrection[AR9300_MAX_CHAINS], - ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS]; + ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS], + lnf_cal[AR9300_MAX_CHAINS], lnf_pwr[AR9300_MAX_CHAINS]; int hfrequency[AR9300_MAX_CHAINS], hcorrection[AR9300_MAX_CHAINS], - htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS]; + htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS], + hnf_cal[AR9300_MAX_CHAINS], hnf_pwr[AR9300_MAX_CHAINS]; int fdiff; int correction[AR9300_MAX_CHAINS], - voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS]; - int pfrequency, pcorrection, ptemperature, pvoltage; + voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS], + nf_cal[AR9300_MAX_CHAINS], nf_pwr[AR9300_MAX_CHAINS]; + int pfrequency, pcorrection, ptemperature, pvoltage, + pnf_cal, pnf_pwr; struct ath_common *common = ath9k_hw_common(ah); mode = (frequency >= 4000); @@ -4920,7 +4929,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) for (ipier = 0; ipier < npier; ipier++) { if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain, , , - , )) { + , , + _cal, _pwr)) { fdiff = frequency - pfrequency; /* @@ -4942,6 +4952,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) htemperature[ichain] = ptemperature; hvoltage[ichain] = pvoltage; + hnf_cal[ichain] = pnf_cal; + hnf_pwr[ichain] = pnf_pwr; } } if (fdiff >= 0) { @@ -4958,6 +4970,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ltemperature[ichain] = ptemperature; lvoltage[ichain] = pvoltage; + lnf_cal[ichain] = pnf_cal; + lnf_pwr[ichain] = pnf_pwr; } } } @@ -4966,15 +4980,20 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) /* interpolate */ for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { - ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n", + ath_dbg(common,