[PATCH v2 07/10] rtlwifi: btcoex: Add power_on_setting routine

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

After mac power-on sequence, wifi will start to work so notify btcoex the
event to configure registers especially related to antenna. This will not
only help to assign antenna but also to yield better user experience.

Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h | 1 +
 drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c  | 6 ++
 drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h  | 1 +
 drivers/net/wireless/realtek/rtlwifi/wifi.h   | 1 +
 4 files changed, 9 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
index ea12b9d63a73..bc523af7ef88 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -608,6 +608,7 @@ extern struct btc_coexist gl_bt_coexist;
 
 bool exhalbtc_initlize_variables(void);
 bool exhalbtc_bind_bt_coex_withadapter(void *adapter);
+void exhalbtc_power_on_setting(struct btc_coexist *btcoexist);
 void exhalbtc_init_hw_config(struct btc_coexist *btcoexist, bool wifi_only);
 void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist);
 void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type);
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
index 4d9e33078d4f..9e3623b0423c 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
@@ -32,6 +32,7 @@
 static struct rtl_btc_ops rtl_btc_operation = {
.btc_init_variables = rtl_btc_init_variables,
.btc_init_hal_vars = rtl_btc_init_hal_vars,
+   .btc_power_on_setting = rtl_btc_power_on_setting,
.btc_init_hw_config = rtl_btc_init_hw_config,
.btc_ips_notify = rtl_btc_ips_notify,
.btc_lps_notify = rtl_btc_lps_notify,
@@ -116,6 +117,11 @@ void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv)
 */
 }
 
+void rtl_btc_power_on_setting(struct rtl_priv *rtlpriv)
+{
+   exhalbtc_power_on_setting(_bt_coexist);
+}
+
 void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv)
 {
u8 bt_exist;
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
index 40f1ce8c8a06..9becfa59407d 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h
@@ -29,6 +29,7 @@
 
 void rtl_btc_init_variables(struct rtl_priv *rtlpriv);
 void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv);
+void rtl_btc_power_on_setting(struct rtl_priv *rtlpriv);
 void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv);
 void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type);
 void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type);
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h 
b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index 941694060f48..b27dbe10b163 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -2557,6 +2557,7 @@ struct bt_coexist_info {
 struct rtl_btc_ops {
void (*btc_init_variables) (struct rtl_priv *rtlpriv);
void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv);
+   void (*btc_power_on_setting)(struct rtl_priv *rtlpriv);
void (*btc_init_hw_config) (struct rtl_priv *rtlpriv);
void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type);
void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type);
-- 
2.15.1



[PATCH v2 05/10] rtlwifi: enable mac80211 fast-tx support

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

To enable the mac80211 fast-tx feature, the hw/driver needs to support
dynamic power saving and fragmentation. Since our driver does not
need to fragment packet into smaller pieces, we just hook an empty
callback of set_frag_threshold to avoid fragmentation in mac80211.

After this, the mac80211 will not fragment the packets and can transmit
them faster by cache the header information.

Signed-off-by: Yan-Hsuan Chuang 
Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/base.c | 2 ++
 drivers/net/wireless/realtek/rtlwifi/core.c | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c 
b/drivers/net/wireless/realtek/rtlwifi/base.c
index 89ec318598ea..e902cd7adbfe 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -395,6 +395,8 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
ieee80211_hw_set(hw, CONNECTION_MONITOR);
ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
+   ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);
+   ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
 
/* swlps or hwlps has been set in diff chip in init_sw_vars */
if (rtlpriv->psc.swctrl_lps) {
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c 
b/drivers/net/wireless/realtek/rtlwifi/core.c
index 6c698123ac07..d454c38fc9cd 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -1001,6 +1001,11 @@ static void rtl_op_sta_statistics(struct ieee80211_hw 
*hw,
sinfo->filled = 0;
 }
 
+static int rtl_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
+{
+   return -EOPNOTSUPP;
+}
+
 /*
  *for mac80211 VO = 0, VI = 1, BE = 2, BK = 3
  *for rtl819x  BE = 0, BK = 1, VI = 2, VO = 3
@@ -1906,6 +1911,7 @@ const struct ieee80211_ops rtl_ops = {
.configure_filter = rtl_op_configure_filter,
.set_key = rtl_op_set_key,
.sta_statistics = rtl_op_sta_statistics,
+   .set_frag_threshold = rtl_op_set_frag_threshold,
.conf_tx = rtl_op_conf_tx,
.bss_info_changed = rtl_op_bss_info_changed,
.get_tsf = rtl_op_get_tsf,
-- 
2.15.1



[PATCH v2 02/10] rtlwifi: fix scan channel 1 fail after IPS

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

If there is no connection, driver will enter IPS state. Meanwhile, it
fails to scan channel 1 by the command 'iw dev wlan0 scan freq 2412',
because hardware channel setting lose after IPS. Thus, restore channel
setting from hw->conf.channel set by last rtl_op_config().

Signed-off-by: Tim Lee 
Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/ps.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c 
b/drivers/net/wireless/realtek/rtlwifi/ps.c
index 6a4008845f49..71af24e2e051 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
@@ -51,6 +51,11 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
>retry_long);
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 
+   rtlpriv->cfg->ops->switch_channel(hw);
+   rtlpriv->cfg->ops->set_channel_access(hw);
+   rtlpriv->cfg->ops->set_bw_mode(hw,
+   cfg80211_get_chandef_type(>conf.chandef));
+
/*<3> Enable Interrupt */
rtlpriv->cfg->ops->enable_interrupt(hw);
 
-- 
2.15.1



[PATCH v2 01/10] rtlwifi: Use mutex to replace spin_lock to protect IPS and LPS

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

Enter/leavel IPS and LPS are large critical section, and they can't use
sleep function because running in atomic-context, which own a spin_lock.
In commit ba9f93f82aba ("rtlwifi: Fix enter/exit power_save"), it moves
LPS functions to thread-context, so this commit can simply change LPS's
spin lock to mutex.
Considering IPS functions, rtl_ips_nic_on() may be called by TX tasklet
(softirq-context) that check whether packet is auth frame. Fortunately,
current mac80211 will ask driver to leave IPS using op_config with
changed flag IEEE80211_CONF_CHANGE_IDLE, before issuing auth frame, so
IPS functions can run in thread-context and use mutex to protect critical
section, too.
Also, this commit removes some useless spin locks.

Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/base.c |  6 ++
 drivers/net/wireless/realtek/rtlwifi/ps.c   | 24 ++--
 drivers/net/wireless/realtek/rtlwifi/usb.c  |  1 -
 drivers/net/wireless/realtek/rtlwifi/wifi.h | 10 ++
 4 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c 
b/drivers/net/wireless/realtek/rtlwifi/base.c
index 0ba9c0cc95e1..89ec318598ea 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -551,7 +551,8 @@ int rtl_init_core(struct ieee80211_hw *hw)
 
/* <4> locks */
mutex_init(>locks.conf_mutex);
-   spin_lock_init(>locks.ips_lock);
+   mutex_init(>locks.ips_mutex);
+   mutex_init(>locks.lps_mutex);
spin_lock_init(>locks.irq_th_lock);
spin_lock_init(>locks.h2c_lock);
spin_lock_init(>locks.rf_ps_lock);
@@ -561,9 +562,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
spin_lock_init(>locks.c2hcmd_lock);
spin_lock_init(>locks.scan_list_lock);
spin_lock_init(>locks.cck_and_rw_pagea_lock);
-   spin_lock_init(>locks.check_sendpkt_lock);
spin_lock_init(>locks.fw_ps_lock);
-   spin_lock_init(>locks.lps_lock);
spin_lock_init(>locks.iqk_lock);
/* <5> init list */
INIT_LIST_HEAD(>entry_list);
@@ -1229,7 +1228,6 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct 
sk_buff *skb)
}
if (ieee80211_is_auth(fc)) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
-   rtl_ips_nic_on(hw);
 
mac->link_state = MAC80211_LINKING;
/* Dul mac */
diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c 
b/drivers/net/wireless/realtek/rtlwifi/ps.c
index 24c87fae5382..6a4008845f49 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
@@ -289,7 +289,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)
 
cancel_delayed_work(>works.ips_nic_off_wq);
 
-   spin_lock(>locks.ips_lock);
+   mutex_lock(>locks.ips_mutex);
if (ppsc->inactiveps) {
rtstate = ppsc->rfpwr_state;
 
@@ -306,7 +306,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw)

ppsc->inactive_pwrstate);
}
}
-   spin_unlock(>locks.ips_lock);
+   mutex_unlock(>locks.ips_mutex);
 }
 EXPORT_SYMBOL_GPL(rtl_ips_nic_on);
 
@@ -415,7 +415,6 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw)
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_priv *rtlpriv = rtl_priv(hw);
-   unsigned long flag;
 
if (!ppsc->fwctrl_lps)
return;
@@ -436,7 +435,7 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw)
if (mac->link_state != MAC80211_LINKED)
return;
 
-   spin_lock_irqsave(>locks.lps_lock, flag);
+   mutex_lock(>locks.lps_mutex);
 
/* Don't need to check (ppsc->dot11_psmode == EACTIVE), because
 * bt_ccoexist may ask to enter lps.
@@ -446,7 +445,7 @@ static void rtl_lps_enter_core(struct ieee80211_hw *hw)
 "Enter 802.11 power save mode...\n");
rtl_lps_set_psmode(hw, EAUTOPS);
 
-   spin_unlock_irqrestore(>locks.lps_lock, flag);
+   mutex_unlock(>locks.lps_mutex);
 }
 
 /* Interrupt safe routine to leave the leisure power save mode.*/
@@ -455,9 +454,8 @@ static void rtl_lps_leave_core(struct ieee80211_hw *hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-   unsigned long flag;
 
-   spin_lock_irqsave(>locks.lps_lock, flag);
+   mutex_lock(>locks.lps_mutex);
 
if (ppsc->fwctrl_lps) {
if (ppsc->dot11_psmode != EACTIVE) {
@@ -478,7 +476,7 @@ static void rtl_lps_leave_core(struct ieee80211_hw *hw)
rtl_lps_set_psmode(hw, EACTIVE);
}
}
-   

[PATCH v2 04/10] rtlwifi: unlink bss when un-association

2018-01-10 Thread pkshih
From: Tsang-Shian Lin 

When AP change bandwidth setting from 20M to 40M, STA may use old 20M AP
information to association with AP. Driver unlink bss in the
.bss_info_changed of ieee80211_ops to make sure that later scan can get
correct AP bandwidth capability.

Signed-off-by: Tsang-Shian Lin 
Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/core.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c 
b/drivers/net/wireless/realtek/rtlwifi/core.c
index ec639fa8095e..6c698123ac07 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -1171,6 +1171,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw 
*hw,
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
 "BSS_CHANGED_ASSOC\n");
} else {
+   struct cfg80211_bss *bss = NULL;
+
mstatus = RT_MEDIA_DISCONNECT;
 
if (mac->link_state == MAC80211_LINKED)
@@ -1178,6 +1180,22 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw 
*hw,
if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
mac->link_state = MAC80211_NOLINK;
+
+   bss = cfg80211_get_bss(hw->wiphy, NULL,
+  (u8 *)mac->bssid, NULL, 0,
+  IEEE80211_BSS_TYPE_ESS,
+  IEEE80211_PRIVACY_OFF);
+
+   RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+"bssid = %pMF\n", mac->bssid);
+
+   if (bss) {
+   cfg80211_unlink_bss(hw->wiphy, bss);
+   cfg80211_put_bss(hw->wiphy, bss);
+   RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+"cfg80211_unlink !!\n");
+   }
+
eth_zero_addr(mac->bssid);
mac->vendor = PEER_UNKNOWN;
mac->mode = 0;
-- 
2.15.1



[PATCH v2 10/10] rtlwifi: btcoex: add rfe_type parameter to btcoex

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

btcoex configure antenna by rfe_type that is RF type programmed in efuse.

Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c | 10 ++
 drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index 30d940cf3abf..7b7099cbb1c7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -207,6 +207,14 @@ u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
return rtlhal->package_type;
 }
 
+static
+u8 rtl_get_hwpg_rfe_type(struct rtl_priv *rtlpriv)
+{
+   struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+
+   return rtlhal->rfe_type;
+}
+
 static
 bool halbtc_is_hw_mailbox_exist(struct btc_coexist *btcoexist)
 {
@@ -1309,6 +1317,8 @@ bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
 "[BTCoex], Package Type = Non-TFBGA\n");
 
+   btcoexist->board_info.rfe_type = rtl_get_hwpg_rfe_type(rtlpriv);
+
return true;
 }
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
index cbbf5e5a9c9b..ee7bbbd87eae 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -151,6 +151,8 @@ struct btc_board_info {
u8 btdm_ant_pos;
u8 single_ant_path; /* current used for 8723b only, 1=>s0,  0=>s1 */
bool tfbga_package;
+
+   u8 rfe_type;
 };
 
 enum btc_dbg_opcode {
-- 
2.15.1



[PATCH v2 00/10] rtlwifi: fix some bugs and add btcoex functions

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

Fix some bugs reported by QC, and continue to submit btcoex patches for
further use.

v2: add my sob to commit log if missing, and remove trivial comments.

Ping-Ke Shih (8):
  rtlwifi: Use mutex to replace spin_lock to protect IPS and LPS
  rtlwifi: fix scan channel 1 fail after IPS
  rtlwifi: Add sta_statistics of mac80211's op, and set filled=0 by
default
  rtlwifi: enable mac80211 fast-tx support
  rtlwifi: btcoex: Add power_on_setting routine
  rtlwifi: btcoex: Remove global variables from btcoex
  rtlwifi: btcoex: Add common function for qeurying BT information
  rtlwifi: btcoex: add rfe_type parameter to btcoex

Steven Ting (1):
  rtlwifi: Support A-MSDU in A-MPDU capability

Tsang-Shian Lin (1):
  rtlwifi: unlink bss when un-association

 drivers/net/wireless/realtek/rtlwifi/base.c|   9 +-
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.c   | 398 +
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h   |  94 -
 .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.c   | 234 ++--
 .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.h   |   4 +-
 drivers/net/wireless/realtek/rtlwifi/core.c|  34 ++
 drivers/net/wireless/realtek/rtlwifi/pci.c |   5 +-
 drivers/net/wireless/realtek/rtlwifi/ps.c  |  30 +-
 drivers/net/wireless/realtek/rtlwifi/usb.c |   1 -
 drivers/net/wireless/realtek/rtlwifi/wifi.h|  16 +-
 10 files changed, 688 insertions(+), 137 deletions(-)

-- 
2.15.1



[PATCH v2 09/10] rtlwifi: btcoex: Add common function for qeurying BT information

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

This commit implement the common function to sort old features, and add
more new features that are get_supported_feature, get_supported_version,
get_ant_det_val, ble_scan_type, ble_scan_para, bt_dev_info,
forbidden_slot_val, afh_map and etc.

Signed-off-by: Ping-Ke Shih 
---
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.c   | 309 ++---
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h   |  70 +
 .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.c   |  48 +++-
 3 files changed, 394 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index 2be81fec789a..30d940cf3abf 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -207,6 +207,102 @@ u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
return rtlhal->package_type;
 }
 
+static
+bool halbtc_is_hw_mailbox_exist(struct btc_coexist *btcoexist)
+{
+   if (IS_HARDWARE_TYPE_8812(btcoexist->adapter))
+   return false;
+   else
+   return true;
+}
+
+static
+bool halbtc_send_bt_mp_operation(struct btc_coexist *btcoexist, u8 op_code,
+u8 *cmd, u32 len, unsigned long wait_ms)
+{
+   struct rtl_priv *rtlpriv;
+   const u8 oper_ver = 0;
+   u8 req_num;
+
+   if (!halbtc_is_hw_mailbox_exist(btcoexist))
+   return false;
+
+   if (wait_ms)/* before h2c to avoid race condition */
+   reinit_completion(>bt_mp_comp);
+
+   rtlpriv = btcoexist->adapter;
+
+   /* fill req_num by op_code, and rtl_btc_btmpinfo_notify() use it
+* to know message type
+*/
+   switch (op_code) {
+   case BT_OP_GET_BT_VERSION:
+   req_num = BT_SEQ_GET_BT_VERSION;
+   break;
+   case BT_OP_GET_AFH_MAP_L:
+   req_num = BT_SEQ_GET_AFH_MAP_L;
+   break;
+   case BT_OP_GET_AFH_MAP_M:
+   req_num = BT_SEQ_GET_AFH_MAP_M;
+   break;
+   case BT_OP_GET_AFH_MAP_H:
+   req_num = BT_SEQ_GET_AFH_MAP_H;
+   break;
+   case BT_OP_GET_BT_COEX_SUPPORTED_FEATURE:
+   req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE;
+   break;
+   case BT_OP_GET_BT_COEX_SUPPORTED_VERSION:
+   req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION;
+   break;
+   case BT_OP_GET_BT_ANT_DET_VAL:
+   req_num = BT_SEQ_GET_BT_ANT_DET_VAL;
+   break;
+   case BT_OP_GET_BT_BLE_SCAN_PARA:
+   req_num = BT_SEQ_GET_BT_BLE_SCAN_PARA;
+   break;
+   case BT_OP_GET_BT_BLE_SCAN_TYPE:
+   req_num = BT_SEQ_GET_BT_BLE_SCAN_TYPE;
+   break;
+   case BT_OP_GET_BT_DEVICE_INFO:
+   req_num = BT_SEQ_GET_BT_DEVICE_INFO;
+   break;
+   case BT_OP_GET_BT_FORBIDDEN_SLOT_VAL:
+   req_num = BT_SEQ_GET_BT_FORB_SLOT_VAL;
+   break;
+   case BT_OP_WRITE_REG_ADDR:
+   case BT_OP_WRITE_REG_VALUE:
+   case BT_OP_READ_REG:
+   default:
+   req_num = BT_SEQ_DONT_CARE;
+   break;
+   }
+
+   cmd[0] |= (oper_ver & 0x0f);/* Set OperVer */
+   cmd[0] |= ((req_num << 4) & 0xf0);  /* Set ReqNum */
+   cmd[1] = op_code;
+   rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, len, cmd);
+
+   /* wait? */
+   if (!wait_ms)
+   return true;
+
+   RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
+"btmpinfo wait req_num=%d wait=%ld\n", req_num, wait_ms);
+
+   if (in_interrupt())
+   return false;
+
+   if (wait_for_completion_timeout(>bt_mp_comp,
+   msecs_to_jiffies(wait_ms)) == 0) {
+   RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
+"btmpinfo wait (req_num=%d) timeout\n", req_num);
+
+   return false;   /* timeout */
+   }
+
+   return true;
+}
+
 static void halbtc_leave_lps(struct btc_coexist *btcoexist)
 {
struct rtl_priv *rtlpriv;
@@ -334,24 +430,79 @@ static void halbtc_aggregation_check(struct btc_coexist 
*btcoexist)
 
 static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
 {
-   struct rtl_priv *rtlpriv = btcoexist->adapter;
u8 cmd_buffer[4] = {0};
-   u8 oper_ver = 0;
-   u8 req_num = 0x0E;
 
if (btcoexist->bt_info.bt_real_fw_ver)
goto label_done;
 
-   cmd_buffer[0] |= (oper_ver & 0x0f); /* Set OperVer */
-   cmd_buffer[0] |= ((req_num << 4) & 0xf0);   /* Set ReqNum */
-   cmd_buffer[1] = 0; /* BT_OP_GET_BT_VERSION = 0 */
-   rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, 4,
-  

[PATCH v2 08/10] rtlwifi: btcoex: Remove global variables from btcoex

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

Remove global variables, so btcoexist can support multiple instances
simultaneously.

Signed-off-by: Ping-Ke Shih 
---
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.c   |  79 -
 .../realtek/rtlwifi/btcoexist/halbtcoutsrc.h   |  21 +--
 .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.c   | 182 +
 .../wireless/realtek/rtlwifi/btcoexist/rtl_btc.h   |   3 +-
 drivers/net/wireless/realtek/rtlwifi/pci.c |   5 +-
 drivers/net/wireless/realtek/rtlwifi/wifi.h|   5 +-
 6 files changed, 217 insertions(+), 78 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c 
b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
index 5f3eda31187a..2be81fec789a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -25,14 +25,6 @@
 
 #include "halbt_precomp.h"
 
-/***
- * Global variables
- ***/
-
-struct btc_coexist gl_bt_coexist;
-
-u32 btc_dbg_type[BTC_MSG_MAX];
-
 /***
  * Debug related function
  ***/
@@ -971,9 +963,12 @@ bool halbtc_under_ips(struct btc_coexist *btcoexist)
 /*
  * Extern functions called by other module
  */
-bool exhalbtc_initlize_variables(void)
+bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv)
 {
-   struct btc_coexist *btcoexist = _bt_coexist;
+   struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+
+   if (!btcoexist)
+   return false;
 
halbtc_dbg_init();
 
@@ -1009,9 +1004,12 @@ bool exhalbtc_initlize_variables(void)
 
 bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
 {
-   struct btc_coexist *btcoexist = _bt_coexist;
struct rtl_priv *rtlpriv = adapter;
-   u8 ant_num = 2, chip_type;
+   struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
+   u8 ant_num = 2, chip_type, single_ant_path = 0;
+
+   if (!btcoexist)
+   return false;
 
if (btcoexist->binded)
return false;
@@ -1042,10 +1040,16 @@ bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
btcoexist->bt_info.miracast_plus_bt = false;
 
chip_type = rtl_get_hwpg_bt_type(rtlpriv);
-   exhalbtc_set_chip_type(chip_type);
+   exhalbtc_set_chip_type(btcoexist, chip_type);
ant_num = rtl_get_hwpg_ant_num(rtlpriv);
exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num);
 
+   /* set default antenna position to main  port */
+   btcoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
+
+   single_ant_path = rtl_get_hwpg_single_ant_path(rtlpriv);
+   exhalbtc_set_single_ant_path(btcoexist, single_ant_path);
+
if (rtl_get_hwpg_package_type(rtlpriv) == 0)
btcoexist->board_info.tfbga_package = false;
else if (rtl_get_hwpg_package_type(rtlpriv) == 1)
@@ -1550,30 +1554,25 @@ void exhalbtc_stack_update_profile_info(void)
 {
 }
 
-void exhalbtc_update_min_bt_rssi(s8 bt_rssi)
+void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi)
 {
-   struct btc_coexist *btcoexist = _bt_coexist;
-
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
 
btcoexist->stack_info.min_bt_rssi = bt_rssi;
 }
 
-void exhalbtc_set_hci_version(u16 hci_version)
+void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version)
 {
-   struct btc_coexist *btcoexist = _bt_coexist;
-
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
 
btcoexist->stack_info.hci_version = hci_version;
 }
 
-void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version)
+void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
+  u16 bt_hci_version, u16 bt_patch_version)
 {
-   struct btc_coexist *btcoexist = _bt_coexist;
-
if (!halbtc_is_bt_coexist_available(btcoexist))
return;
 
@@ -1581,7 +1580,7 @@ void exhalbtc_set_bt_patch_version(u16 bt_hci_version, 
u16 bt_patch_version)
btcoexist->bt_info.bt_hci_ver = bt_hci_version;
 }
 
-void exhalbtc_set_chip_type(u8 chip_type)
+void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type)
 {
switch (chip_type) {
default:
@@ -1589,48 +1588,54 @@ void exhalbtc_set_chip_type(u8 chip_type)
case BT_ISSC_3WIRE:
case BT_ACCEL:
case BT_RTL8756:
-   gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_UNDEF;
+   btcoexist->board_info.bt_chip_type = BTC_CHIP_UNDEF;
break;
case 

[PATCH v2 03/10] rtlwifi: Add sta_statistics of mac80211's op, and set filled=0 by default

2018-01-10 Thread pkshih
From: Ping-Ke Shih 

When using iwconfig to check wifi status, wext uses 'static struct' of
sinfo to get station info so sinfo->filled will be persistent. Since the
commit 2b9a7e1bac24 ("mac80211: allow drivers to provide most station
statistics") assumes driver initializes sinfo->filled to declare supported
fields, without initialization it will report wrong info. This commit
simply set 'filled' to be zero simply, and left sinfo to be filled by
mac80211.

Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/core.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c 
b/drivers/net/wireless/realtek/rtlwifi/core.c
index a78b828f531a..ec639fa8095e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -992,6 +992,15 @@ static int _rtl_get_hal_qnum(u16 queue)
return qnum;
 }
 
+static void rtl_op_sta_statistics(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct station_info *sinfo)
+{
+   /* nothing filled by driver, so mac80211 will update all info */
+   sinfo->filled = 0;
+}
+
 /*
  *for mac80211 VO = 0, VI = 1, BE = 2, BK = 3
  *for rtl819x  BE = 0, BK = 1, VI = 2, VO = 3
@@ -1878,6 +1887,7 @@ const struct ieee80211_ops rtl_ops = {
.config = rtl_op_config,
.configure_filter = rtl_op_configure_filter,
.set_key = rtl_op_set_key,
+   .sta_statistics = rtl_op_sta_statistics,
.conf_tx = rtl_op_conf_tx,
.bss_info_changed = rtl_op_bss_info_changed,
.get_tsf = rtl_op_get_tsf,
-- 
2.15.1



[PATCH v2 06/10] rtlwifi: Support A-MSDU in A-MPDU capability

2018-01-10 Thread pkshih
From: Steven Ting 

Due to the fact that A-MSDU deaggregation is done in software,
we set this flag to support the A-MSDU in A-MPDU

Signed-off-by: Steven Ting 
Signed-off-by: Ping-Ke Shih 
---
 drivers/net/wireless/realtek/rtlwifi/base.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c 
b/drivers/net/wireless/realtek/rtlwifi/base.c
index e902cd7adbfe..07b91bc9adf9 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -397,6 +397,7 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
ieee80211_hw_set(hw, SUPPORTS_TX_FRAG);
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
+   ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
 
/* swlps or hwlps has been set in diff chip in init_sw_vars */
if (rtlpriv->psc.swctrl_lps) {
-- 
2.15.1



RE: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS

2018-01-10 Thread Pkshih

> -Original Message-
> From: Arend van Spriel [mailto:arend.vanspr...@broadcom.com]
> Sent: Wednesday, January 10, 2018 10:08 PM
> To: Pkshih; kv...@codeaurora.org
> Cc: larry.fin...@lwfinger.net; 莊彥宣; linux-wireless@vger.kernel.org
> Subject: Re: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS
> 
> On 1/10/2018 10:38 AM, Pkshih wrote:
> >
> >
> >> -Original Message-
> >> From: Arend van Spriel [mailto:arend.vanspr...@broadcom.com]
> >> Sent: Wednesday, January 10, 2018 4:13 PM
> >> To: Pkshih; kv...@codeaurora.org
> >> Cc: larry.fin...@lwfinger.net; 莊彥宣; linux-wireless@vger.kernel.org
> >> Subject: Re: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS
> >>
> >> On 1/10/2018 6:19 AM, pks...@realtek.com wrote:
> >>> From: Ping-Ke Shih 
> >>>
> >>> If there is no connection, driver will enter IPS state. Meanwhile, it
> >>> fails to scan channel 1 by the command 'iw dev wlan0 scan freq 2412',
> >>> because hardware channel setting lose after IPS. Thus, restore channel
> >>> setting from hw->conf.channel set by last rtl_op_config().
> >>>
> >>> Signed-off-by: Tim Lee 
> >>
> >> You need to add your sob here as well as you are submitting them.
> >>
> >
> > I'll add it in v2.
> >
> >>> ---
> >>>drivers/net/wireless/realtek/rtlwifi/ps.c | 6 ++
> >>>1 file changed, 6 insertions(+)
> >>>
> >>> diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c
> b/drivers/net/wireless/realtek/rtlwifi/ps.c
> >>> index 6a4008845f49..0ffe43772c9a 100644
> >>> --- a/drivers/net/wireless/realtek/rtlwifi/ps.c
> >>> +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
> >>> @@ -51,6 +51,12 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
> >>>   >retry_long);
> >>>   RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
> >>>
> >>> + /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/
> >>
> >> Is this type of comment really helpful? To me it seems the callback
> >> names provide enough context.
> >>
> >
> > Do you mean the "<2.1>" isn't needed?
> > This is because "<1>, <2>, <3>..." exist in the function, so
> > we want to make it to be consistent.
> 
> That is not what I mean. I mean why have a comment describing what is
> obvious from reading the code itself. So in this example:
> 
> On 1/10/2018 6:19 AM, pks...@realtek.com wrote:
> > +   /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/
> > +   rtlpriv->cfg->ops->switch_channel(hw);
> > +   rtlpriv->cfg->ops->set_channel_access(hw);
> > +   rtlpriv->cfg->ops->set_bw_mode(hw,
> > +   cfg80211_get_chandef_type(>conf.chandef));
> > +
> > /*<3> Enable Interrupt */
> > rtlpriv->cfg->ops->enable_interrupt(hw);
> 
> the code after the <2.1> comment calls a switch_channel() callback and a
> set_bw_mode() callback. In my opinion those names are pretty
> self-explanatory for the reader making the comment preceding it only
> noise. The same applies to step <3>.
> 

Got it! I'll follow this coding convention.
Thanks

PK




Re: ath9k dropping connections

2018-01-10 Thread Flávio Silveira



On 29/12/2017 15:59, Alexander Wetzel wrote:

Hello,

I guess there are quite some potential issues which could cause that.
Since you do not see any error logs one of them could be the WPA rekey IV 
poisoning one I encountered in the past.

Do you have wpa rekey enabled? If so please check if disabling it fixes the 
issue for you.
Assuming you are only using a WPA passoword and not EAP you can check if you 
have rekey enabled from a CLI on the router with the folowing command:
"uci show wireless | grep wpa_pair_rekey"

You have to delete any config statements found by the command and restart the 
router (or wifi) to apply the changes.

If that helps, at least one STA is sending frames using wrong IV's and tricks 
the other end into dropping valid frames.
In that case I can offer some options how to work around that, but I'm not 
aware of a real fix and disabling rekey is still probably the best...

Regards,

Alexander


Hello Alexander, thanks for your reply!

  Unfortunately "uci show wireless | grep wpa_pair_rekey" returns 
nothing, so I guess this is not the issue.


  I didn't know I was running LEDE snapshot with kernel 4.9.65, since 
then I built a LEDE 17.01.4 which has kernel 4.4.92 with ATH Debug 
enabled. What I can see is "pending" increases for queue BE (best 
effort) when the issue occurs, any other thing I could do to help 
understand why this is happening?


  I think I didn't mention in first post that I am using virtual 
interfaces, I don't know if it matters.


Regards,
  Flavio Silveira


Re: pull-request: wireless-drivers 2018-01-09

2018-01-10 Thread David Miller
From: Kalle Valo 
Date: Tue, 09 Jan 2018 14:59:37 +0200

> My first pull request in 2018 so Happy New Year!

Happy New Year to you as well :)

> This is for 4.15 to the net tree. Only two fixes this time so should be
> an easy pull.
> 
> This is quite late due to the holidays but it has been pretty quiet so I
> guess I wasn't the only one trying to not touch the computer ;) And
> Linus said that he will be releasing -rc8 anyway so this shouldn't be
> that late.
> 
> Please let me know if you have any problems.

Pulled, thanks Kalle.


Re: [PATCH v2 5/9] staging: wilc1000: removed few unnecessary enums typedef

2018-01-10 Thread Greg KH
On Wed, Jan 10, 2018 at 04:42:47PM +0530, Ajay Singh wrote:
> This patch removes following N_OPERATING_MODE_T,N_OBSS_DETECTION_T,
> N_PROTECTION_TYPE_T,N_SMPS_MODE_T,TX_ABORT_OPTION_T, typedef enum.
> Now, these enums are used as anonymous-enums for constants.
> 
> checkpatch.pl warning to not add new typedef is fixes with this patch.
> 
> Signed-off-by: Ajay Singh 
> ---
>  drivers/staging/wilc1000/wilc_wlan_if.h | 20 ++--
>  1 file changed, 10 insertions(+), 10 deletions(-)

This is the same subject line as the previous patch in the series, yet
they are doing different things.

Please take this series and work on the subject lines to make them a bit
more unique and different from each other, and resend.

thanks,

greg k-h


[RFC v2 1/5] nl80211: Add CONTROL_PORT_OVER_NL80211 attribute

2018-01-10 Thread Denis Kenzior
Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h   |  6 ++
 include/uapi/linux/nl80211.h | 14 +-
 net/wireless/nl80211.c   | 20 
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3a4a1a903a4d..f46bdc4298f1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -646,6 +646,8 @@ struct survey_info {
  * allowed through even on unauthorized ports
  * @control_port_no_encrypt: TRUE to prevent encryption of control port
  * protocol frames.
+ * @control_port_over_nl80211: TRUE if userspace expects to exchange control
+ * port frames over NL80211 instead of the network interface.
  * @wep_keys: static WEP keys, if not NULL points to an array of
  * CFG80211_MAX_WEP_KEYS WEP keys
  * @wep_tx_key: key index (0..3) of the default TX static WEP key
@@ -661,6 +663,7 @@ struct cfg80211_crypto_settings {
bool control_port;
__be16 control_port_ethertype;
bool control_port_no_encrypt;
+   bool control_port_over_nl80211;
struct key_params *wep_keys;
int wep_tx_key;
const u8 *psk;
@@ -3236,6 +3239,8 @@ struct cfg80211_ops {
  * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the
  * control port protocol ethertype. The device also honours the
  * control_port_no_encrypt flag.
+ * @WIPHY_FLAG_CONTROL_PORT_OVER_NL80211: This device supports sending and
+ * receiving control port frames over NL80211 instead of the netdevice.
  * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
  * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing
  * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH.
@@ -3288,6 +3293,7 @@ enum wiphy_flags {
WIPHY_FLAG_SUPPORTS_5_10_MHZ= BIT(22),
WIPHY_FLAG_HAS_CHANNEL_SWITCH   = BIT(23),
WIPHY_FLAG_HAS_STATIC_WEP   = BIT(24),
+   WIPHY_FLAG_CONTROL_PORT_OVER_NL80211= BIT(25),
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c587a61c32bf..8855b7eaf92c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -542,7 +542,8 @@
  * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
  * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
- * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and
+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
+ * %NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and
  * %NL80211_ATTR_WIPHY_FREQ_HINT.
  * If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are
  * restrictions on BSS selection, i.e., they effectively prevent roaming
@@ -1445,6 +1446,15 @@ enum nl80211_commands {
  * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
  * ethertype frames used for key negotiation must not be encrypted.
+ * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control
+ * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
+ * will be sent directly to the network interface or sent via the NL80211
+ * socket.  If this attribute is missing, then legacy behavior of sending
+ * control port frames directly to the network interface is used.  If the
+ * flag is included, then control port frames are sent over NL80211 instead
+ * using %CMD_CONTROL_PORT_FRAME.  If control port routing over NL80211 is
+ * to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
+ * flag.
  *
  * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
  * We recommend using nested, driver-specific attributes within this.
@@ -2579,6 +2589,8 @@ enum nl80211_attrs {
NL80211_ATTR_PMKR0_NAME,
NL80211_ATTR_PORT_AUTHORIZED,
 
+   NL80211_ATTR_CONTROL_PORT_OVER_NL80211,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b3f8970c3a47..840ee6d73269 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -286,6 +286,7 @@ static const struct nla_policy 
nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
[NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
+   [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
[NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
@@ -1547,6 +1548,13 @@ static int nl80211_send_wiphy(struct 
cfg80211_registered_device 

[RFC v2 5/5] mac80211: Add support for tx_control_port

2018-01-10 Thread Denis Kenzior
Signed-off-by: Denis Kenzior 
---
 net/mac80211/cfg.c |  1 +
 net/mac80211/ieee80211_i.h |  3 +++
 net/mac80211/main.c|  1 +
 net/mac80211/tx.c  | 46 ++
 4 files changed, 51 insertions(+)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f53bfb27295f..71cb45e517b0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3787,4 +3787,5 @@ const struct cfg80211_ops mac80211_config_ops = {
.add_nan_func = ieee80211_add_nan_func,
.del_nan_func = ieee80211_del_nan_func,
.set_multicast_to_unicast = ieee80211_set_multicast_to_unicast,
+   .tx_control_port = ieee80211_tx_control_port,
 };
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6f91aea6a4cb..be444305ef06 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1735,6 +1735,9 @@ void ieee80211_check_fast_xmit(struct sta_info *sta);
 void ieee80211_check_fast_xmit_all(struct ieee80211_local *local);
 void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata);
 void ieee80211_clear_fast_xmit(struct sta_info *sta);
+int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *dest, u16 proto, bool unencrypted);
 
 /* HT */
 void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0785d04a80bc..fe163c31d431 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -976,6 +976,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
/* mac80211 supports control port protocol changing */
local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL;
+   local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_OVER_NL80211;
 
if (ieee80211_hw_check(>hw, SIGNAL_DBM)) {
local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 25904af38839..c22d2fa02d76 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4754,3 +4754,49 @@ void __ieee80211_tx_skb_tid_band(struct 
ieee80211_sub_if_data *sdata,
ieee80211_xmit(sdata, NULL, skb);
local_bh_enable();
 }
+
+int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *dest, u16 proto, bool unencrypted)
+{
+   struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+   struct ieee80211_local *local = sdata->local;
+   struct sk_buff *skb;
+   struct ethhdr *ehdr;
+   u32 flags;
+
+   /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
+* or Pre-Authentication
+*/
+   if (proto != sdata->control_port_protocol &&
+   proto != cpu_to_be16(0x88c7))
+   return -EINVAL;
+
+   if (unencrypted)
+   flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
+   else
+   flags = 0;
+
+   skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+   sizeof(struct ethhdr) + len);
+   if (!skb)
+   return -ENOMEM;
+
+   skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr));
+
+   skb_put_data(skb, buf, len);
+
+   ehdr = skb_push(skb, sizeof(struct ethhdr));
+   memcpy(ehdr->h_dest, dest, ETH_ALEN);
+   memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
+   ehdr->h_proto = proto;
+
+   skb->dev = dev;
+   skb->protocol = htons(ETH_P_802_3);
+   skb_reset_network_header(skb);
+   skb_reset_mac_header(skb);
+
+   __ieee80211_subif_start_xmit(skb, skb->dev, flags);
+
+   return 0;
+}
-- 
2.13.5



[RFC v2 4/5] nl80211: Implement TX of control port frames

2018-01-10 Thread Denis Kenzior
This commit implements the TX side of NL80211_CMD_CONTROL_PORT_FRAME.
Userspace provides the raw EAPoL frame using NL80211_ATTR_FRAME.
Userspace should also provide the destination address and the protocol
type to use when sending the frame.  This is used to implement TX of
Pre-authentication frames.  If CONTROL_PORT_ETHERTYPE_NO_ENCRYPT is
specified, then the driver will be asked not to encrypt the outgoing
frame.

Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h  |  9 
 net/wireless/nl80211.c  | 60 -
 net/wireless/rdev-ops.h | 15 +
 net/wireless/trace.h| 25 +
 4 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 84cba57dd8d0..5d1afe3579e7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2924,6 +2924,9 @@ struct cfg80211_pmk_conf {
  * (invoked with the wireless_dev mutex held)
  * @del_pmk: delete the previously configured PMK for the given authenticator.
  * (invoked with the wireless_dev mutex held)
+ *
+ * @tx_control_port: TX a control port frame (EAPoL).  The noencrypt parameter
+ * tells the driver that the frame should not be encrypted.
  */
 struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3217,6 +3220,12 @@ struct cfg80211_ops {
   const struct cfg80211_pmk_conf *conf);
int (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
   const u8 *aa);
+
+   int (*tx_control_port)(struct wiphy *wiphy,
+  struct net_device *dev,
+  const u8 *buf, size_t len,
+  const u8 *dest, const u16 proto,
+  const bool noencrypt);
 };
 
 /*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c0f2bb24e7dd..2c1082c7b1ea 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12474,6 +12474,57 @@ static int nl80211_del_pmk(struct sk_buff *skb, struct 
genl_info *info)
return ret;
 }
 
+static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
+{
+   struct cfg80211_registered_device *rdev = info->user_ptr[0];
+   struct net_device *dev = info->user_ptr[1];
+   struct wireless_dev *wdev = dev->ieee80211_ptr;
+   const u8 *buf;
+   size_t len;
+   u8 *dest;
+   u16 proto;
+   bool noencrypt;
+   int err;
+
+   if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_OVER_NL80211) ||
+   !rdev->ops->tx_control_port)
+   return -EOPNOTSUPP;
+
+   if (!info->attrs[NL80211_ATTR_FRAME] ||
+   !info->attrs[NL80211_ATTR_MAC] ||
+   !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE])
+   return -EINVAL;
+
+   wdev_lock(wdev);
+
+   switch (wdev->iftype) {
+   case NL80211_IFTYPE_STATION:
+   if (wdev->current_bss)
+   break;
+   err = -ENOTCONN;
+   goto out;
+   default:
+   err = -EOPNOTSUPP;
+   goto out;
+   }
+
+   wdev_unlock(wdev);
+
+   buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+   len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+   dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
+   proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
+   noencrypt =
+   nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
+
+   return rdev_tx_control_port(rdev, dev, buf, len,
+   dest, cpu_to_be16(proto), noencrypt);
+
+ out:
+   wdev_unlock(wdev);
+   return err;
+}
+
 #define NL80211_FLAG_NEED_WIPHY0x01
 #define NL80211_FLAG_NEED_NETDEV   0x02
 #define NL80211_FLAG_NEED_RTNL 0x04
@@ -13369,7 +13420,14 @@ static const struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
  NL80211_FLAG_NEED_RTNL,
},
-
+   {
+   .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
+   .doit = nl80211_tx_control_port,
+   .policy = nl80211_policy,
+   .flags = GENL_UNS_ADMIN_PERM,
+   .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+   },
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 0c06240d25af..fbd67e32bb91 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -714,6 +714,21 @@ static inline int rdev_mgmt_tx(struct 
cfg80211_registered_device *rdev,
return ret;
 }
 
+static inline int rdev_tx_control_port(struct cfg80211_registered_device *rdev,
+  struct 

[RFC v2 2/5] nl80211: Add CMD_CONTROL_PORT_FRAME API

2018-01-10 Thread Denis Kenzior
This commit also adds cfg80211_rx_control_port function.  This is used
to generate a CMD_CONTROL_PORT_FRAME event out to userspace.  The
conn_owner_nlportid is used as the unicast destination.  This means that
userspace must specify NL80211_ATTR_SOCKET_OWNER flag if control port
over nl80211 routing is requested in NL80211_CMD_CONNECT or
NL80211_CMD_ASSOCIATE

Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h   | 17 +
 include/uapi/linux/nl80211.h | 15 +++
 net/wireless/nl80211.c   | 59 
 net/wireless/trace.h | 21 
 4 files changed, 112 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f46bdc4298f1..84cba57dd8d0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5629,6 +5629,23 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, 
u64 cookie,
 
 
 /**
+ * cfg80211_rx_control_port - inform userspace about a received control port
+ * frame, e.g. EAPoL.  This is used if userspace has specified it wants to
+ * receive control port frames over NL80211.
+ * @dev: The device the frame matched to
+ * @buf: control port frame
+ * @len: length of the frame data
+ * @addr: The peer from which the frame was received
+ * @proto: frame protocol, typically PAE or Pre-authentication
+ * @unencrypted: Whether the frame was received unencrypted
+ *
+ * Return: %true if the frame was passed to userspace
+ */
+bool cfg80211_rx_control_port(struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *addr, u16 proto, bool unencrypted);
+
+/**
  * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event
  * @dev: network device
  * @rssi_event: the triggered RSSI event
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 8855b7eaf92c..b902614e876e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -991,6 +991,17 @@
  * _CMD_CONNECT or _CMD_ROAM. If the 4 way handshake failed
  * _CMD_DISCONNECT should be indicated instead.
  *
+ * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
+ * and RX notification.  This command is used both as a request to transmit
+ * a control port frame and as a notification that a control port frame
+ * has been received. %NL80211_ATTR_FRAME is used to specify the
+ * frame contents.  The frame is the raw EAPoL data, without ethernet or
+ * 802.11 headers.
+ * When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added
+ * indicating the protocol type of the received frame; whether the frame
+ * was received unencrypted and the MAC address of the peer respectively.
+ *
  * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
  *
  * @NL80211_CMD_MAX: highest used command number
@@ -1199,6 +1210,8 @@ enum nl80211_commands {
 
NL80211_CMD_RELOAD_REGDB,
 
+   NL80211_CMD_CONTROL_PORT_FRAME,
+
/* add new commands above here */
 
/* used to define NL80211_CMD_MAX below */
@@ -1446,6 +1459,8 @@ enum nl80211_commands {
  * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
  * ethertype frames used for key negotiation must not be encrypted.
+ * When included in %NL80211_CMD_CONTROL_PORT_FRAME it means that the
+ * control port frame was received unencrypted.
  * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control
  * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
  * will be sent directly to the network interface or sent via the NL80211
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 840ee6d73269..c0f2bb24e7dd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14500,6 +14500,65 @@ void cfg80211_mgmt_tx_status(struct wireless_dev 
*wdev, u64 cookie,
 }
 EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
 
+static int __nl80211_control_port(struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *addr, u16 proto,
+ bool unencrypted, gfp_t gfp)
+{
+   struct wireless_dev *wdev = dev->ieee80211_ptr;
+   struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+   struct sk_buff *msg;
+   void *hdr;
+   u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
+
+   if (!nlportid)
+   return -ENOENT;
+
+   msg = nlmsg_new(100 + len, gfp);
+   if (!msg)
+   return -ENOMEM;
+
+   hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
+   if (!hdr) {
+   nlmsg_free(msg);
+   return -ENOMEM;
+   }
+
+   if 

[RFC v2 3/5] mac80211: Send control port frames over nl80211

2018-01-10 Thread Denis Kenzior
If userspace requested control port frames to go over 80211, then do so.
The control packets are intercepted just prior to delivery of the packet
to the underlying network device.

Pre-authentication type frames (protocol: 0x88c7) are also forwarded
over nl80211.

Signed-off-by: Denis Kenzior 
---
 net/mac80211/cfg.c |  2 ++
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/mlme.c|  2 ++
 net/mac80211/rx.c  | 31 ---
 4 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 46028e12e216..f53bfb27295f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -925,6 +925,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct 
net_device *dev,
 */
sdata->control_port_protocol = params->crypto.control_port_ethertype;
sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
+   sdata->control_port_over_nl80211 = false;
sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local,
>crypto,
sdata->vif.type);
@@ -934,6 +935,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct 
net_device *dev,
params->crypto.control_port_ethertype;
vlan->control_port_no_encrypt =
params->crypto.control_port_no_encrypt;
+   vlan->control_port_over_nl80211 = false;
vlan->encrypt_headroom =
ieee80211_cs_headroom(sdata->local,
  >crypto,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 26900025de2f..6f91aea6a4cb 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -899,6 +899,7 @@ struct ieee80211_sub_if_data {
u16 sequence_number;
__be16 control_port_protocol;
bool control_port_no_encrypt;
+   bool control_port_over_nl80211;
int encrypt_headroom;
 
atomic_t num_tx_queued;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 39b660b9a908..fc71a906939b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4830,6 +4830,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data 
*sdata,
 
sdata->control_port_protocol = req->crypto.control_port_ethertype;
sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
+   sdata->control_port_over_nl80211 =
+   req->crypto.control_port_over_nl80211;
sdata->encrypt_headroom = ieee80211_cs_headroom(local, >crypto,
sdata->vif.type);
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b3cff69bfd66..28b74ae1ee48 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2326,16 +2326,41 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
}
 #endif
 
-   if (skb) {
+   if (!skb)
+   goto try_xmit;
+
+   skb->protocol = eth_type_trans(skb, dev);
+   memset(skb->cb, 0, sizeof(skb->cb));
+
+   if (unlikely((skb->protocol == sdata->control_port_protocol ||
+ skb->protocol == cpu_to_be16(0x88c7)) &&
+sdata->control_port_over_nl80211)) {
+   struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+   bool noencrypt;
+
+   ehdr = eth_hdr(skb);
+
+   if (status->flag & RX_FLAG_DECRYPTED)
+   noencrypt = false;
+   else
+   noencrypt = true;
+
+   if (!cfg80211_rx_control_port(dev, skb->data, skb->len,
+ ehdr->h_source,
+ be16_to_cpu(skb->protocol),
+ noencrypt)) {
+   dev_kfree_skb(skb);
+   skb = NULL;
+   }
+   } else {
/* deliver to local stack */
-   skb->protocol = eth_type_trans(skb, dev);
-   memset(skb->cb, 0, sizeof(skb->cb));
if (rx->napi)
napi_gro_receive(rx->napi, skb);
else
netif_receive_skb(skb);
}
 
+try_xmit:
if (xmit_skb) {
/*
 * Send to wireless media and increase priority by 256 to
-- 
2.13.5



[RFC v2 0/5] EAPoL over NL80211

2018-01-10 Thread Denis Kenzior
This patchset adds support for running 802.11 authentication mechanisms (e.g.
802.1X, 4-Way Handshake, etc) over NL80211 instead of putting them onto the
network device.  This has the advantage of fixing several long-standing race
conditions that result from userspace operating on multiple transports in order
to manage a 802.11 connection (e.g. NL80211 and wireless netdev, wlan0, etc).

For example, userspace would sometimes see 4-Way handshake packets before
NL80211 signaled that the connection has been established.  Leading to ugly
hacks or having the STA wait for retransmissions from the AP.

This also provides a way to mitigate a particularly nasty race condition where
the encryption key could be set prior to the 4-way handshake packet 4/4 being
sent.  This would result in the packet being sent encrypted and discarded by
the peer.  The mitigation strategy for this race is for userspace to explicitly
tell the kernel that a particular EAPoL packet should not be encrypted.

To make this possible this patchset introduces a new NL80211 command and several
new attributes.  A userspace that is capable of processing EAPoL packets over
NL80211 includes a new NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute in its
NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT requests being sent to the kernel.
The previously added NL80211_ATTR_SOCKET_OWNER attribute must also be included.
The latter is used by the kernel to send NL80211_CMD_CONTROL_PORT_FRAME
notifications back to userspace via a netlink unicast.  If the
NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute is not specified, then legacy
behavior is kept and control port packets continue to flow over the network
interface.

If control port over nl80211 transport is requested, then control port packets
are intercepted just prior to being handed to the network device and sent over
netlink via the NL80211_CMD_CONTROL_PORT_FRAME notification.  
NL80211_ATTR_CONTROL_PORT_ETHERTYPE and NL80211_ATTR_MAC are included to 
specify the control port
frame protocol and source address respectively.  If the control port frame was
received unencrypted then NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag is also
included.  NL80211_ATTR_FRAME attribute contains the raw control port frame with
all transport layer headers stripped (e.g. this would be the raw EAPoL frame).

Userspace can reply to control port frames either via legacy methods (by sending
frames to the network device) or via NL80211_CMD_CONTROL_PORT_FRAME request.
Userspace would included NL80211_ATTR_FRAME with the raw control port frame as
well as NL80211_Attr_MAC and NL80211_ATTR_CONTROL_PORT_ETHERTYPE attributes to
specify the destination address and protocol respectively.  This allows
Pre-Authentication (protocol 0x88c7) frames to be sent via this mechanism as
well.  Finally, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag can be included to
tell the driver to send the frame unencrypted, e.g. for 4-Way handshake 4/4
frames.

The proposed patchset has been tested in a mac80211_hwsim based environment with
hostapd and iwd.

ChangeLog

v2

- Added WIPHY_FLAG_CONTROL_PORT_OVER_NL80211 flag.  This is a capability flag
used by the drivers, e.g. that the driver supports control port over nl80211
capability.  This capability is now checked when CONTROL_PORT_OVER_NL80211 is
requested.

- mac80211 rx path now forwards Pre-Authentication frames over NL80211 as well,
if requested.  Tweaked the signature of cfg80211_rx_control_port.

- TX path reworked completely.  tx_control_port method has been introduced to
cfg80211_ops.  An implementation of tx_control_port for mac80211 was added.


Denis Kenzior (5):
  nl80211: Add CONTROL_PORT_OVER_NL80211 attribute
  nl80211: Add CMD_CONTROL_PORT_FRAME API
  mac80211: Send control port frames over nl80211
  nl80211: Implement TX of control port frames
  mac80211: Add support for tx_control_port

 include/net/cfg80211.h   |  32 ++
 include/uapi/linux/nl80211.h |  29 -
 net/mac80211/cfg.c   |   3 +
 net/mac80211/ieee80211_i.h   |   4 ++
 net/mac80211/main.c  |   1 +
 net/mac80211/mlme.c  |   2 +
 net/mac80211/rx.c|  31 +-
 net/mac80211/tx.c|  46 ++
 net/wireless/nl80211.c   | 139 ++-
 net/wireless/rdev-ops.h  |  15 +
 net/wireless/trace.h |  46 ++
 11 files changed, 343 insertions(+), 5 deletions(-)

-- 
2.13.5



[PATCH v3 5/5] mac80211_hwsim: add hwsim_tx_rate_flags to netlink attributes

2018-01-10 Thread Benjamin Beichler
For correct interpretation of a tx rate, the corresponding rate flags are
needed (e.g. whether a HT-MCS rate or a legacy rate) and moreover for more
correct simulation the other infos of the flags are important (like
short-GI). Keeping compatibility, the flags are not integrated into the
existing hwsim_tx_rate, but transmitted as an additional netlink attribute.

Signed-off-by: Benjamin Beichler 
---
 drivers/net/wireless/mac80211_hwsim.c | 41 -
 drivers/net/wireless/mac80211_hwsim.h | 68 ++-
 2 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 1e0d651c43fc..226fa98f16a6 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1026,6 +1026,36 @@ static int hwsim_unicast_netgroup(struct 
mac80211_hwsim_data *data,
return res;
 }
 
+static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate 
*rate)
+{
+   u16 result = 0;
+
+   if (rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
+   result |= MAC80211_HWSIM_TX_RC_USE_RTS_CTS;
+   if (rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+   result |= MAC80211_HWSIM_TX_RC_USE_CTS_PROTECT;
+   if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+   result |= MAC80211_HWSIM_TX_RC_USE_SHORT_PREAMBLE;
+   if (rate->flags & IEEE80211_TX_RC_MCS)
+   result |= MAC80211_HWSIM_TX_RC_MCS;
+   if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+   result |= MAC80211_HWSIM_TX_RC_GREEN_FIELD;
+   if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+   result |= MAC80211_HWSIM_TX_RC_40_MHZ_WIDTH;
+   if (rate->flags & IEEE80211_TX_RC_DUP_DATA)
+   result |= MAC80211_HWSIM_TX_RC_DUP_DATA;
+   if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+   result |= MAC80211_HWSIM_TX_RC_SHORT_GI;
+   if (rate->flags & IEEE80211_TX_RC_VHT_MCS)
+   result |= MAC80211_HWSIM_TX_RC_VHT_MCS;
+   if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+   result |= MAC80211_HWSIM_TX_RC_80_MHZ_WIDTH;
+   if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+   result |= MAC80211_HWSIM_TX_RC_160_MHZ_WIDTH;
+
+   return result;
+}
+
 static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
   struct sk_buff *my_skb,
   int dst_portid)
@@ -1038,6 +1068,7 @@ static void mac80211_hwsim_tx_frame_nl(struct 
ieee80211_hw *hw,
unsigned int hwsim_flags = 0;
int i;
struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES];
+   struct hwsim_tx_rate_flag tx_attempts_flags[IEEE80211_TX_MAX_RATES];
uintptr_t cookie;
 
if (data->ps != PS_DISABLED)
@@ -1089,7 +1120,11 @@ static void mac80211_hwsim_tx_frame_nl(struct 
ieee80211_hw *hw,
 
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
tx_attempts[i].idx = info->status.rates[i].idx;
+   tx_attempts_flags[i].idx = info->status.rates[i].idx;
tx_attempts[i].count = info->status.rates[i].count;
+   tx_attempts_flags[i].flags =
+   trans_tx_rate_flags_ieee2hwsim(
+   >status.rates[i]);
}
 
if (nla_put(skb, HWSIM_ATTR_TX_INFO,
@@ -1097,6 +1132,11 @@ static void mac80211_hwsim_tx_frame_nl(struct 
ieee80211_hw *hw,
tx_attempts))
goto nla_put_failure;
 
+   if (nla_put(skb, HWSIM_ATTR_TX_INFO_FLAGS,
+   sizeof(struct hwsim_tx_rate_flag) * IEEE80211_TX_MAX_RATES,
+   tx_attempts_flags))
+   goto nla_put_failure;
+
/* We create a cookie to identify this skb */
data->pending_cookie++;
cookie = data->pending_cookie;
@@ -3003,7 +3043,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff 
*skb_2,
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
txi->status.rates[i].idx = tx_attempts[i].idx;
txi->status.rates[i].count = tx_attempts[i].count;
-   /*txi->status.rates[i].flags = 0;*/
}
 
txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
diff --git a/drivers/net/wireless/mac80211_hwsim.h 
b/drivers/net/wireless/mac80211_hwsim.h
index e2592b596090..b304dfb70036 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -64,7 +64,8 @@ enum hwsim_tx_control_flags {
  * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to
  * kernel, uses:
  * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,
- * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
+ * %HWSIM_ATTR_TX_INFO, %WSIM_ATTR_TX_INFO_FLAGS,
+ * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
  * 

[PATCH v3 1/5] mac80211_hwsim: add workqueue to wait for deferred radio deletion on mod unload

2018-01-10 Thread Benjamin Beichler
When closing multiple wmediumd instances with many radios and try to
unload the  mac80211_hwsim module, it may happen that the work items live
longer than the module. To wait especially for this deletion work items,
add a work queue, otherwise flush_scheduled_work would be necessary.

Signed-off-by: Benjamin Beichler 
---
 drivers/net/wireless/mac80211_hwsim.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 45cca54c05bf..742a1551bb1c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -489,6 +489,7 @@ static const struct ieee80211_iface_combination 
hwsim_if_comb_p2p_dev[] = {
 
 static spinlock_t hwsim_radio_lock;
 static LIST_HEAD(hwsim_radios);
+static struct workqueue_struct *hwsim_wq;
 static int hwsim_radio_idx;
 
 static struct platform_driver mac80211_hwsim_driver = {
@@ -3346,7 +3347,7 @@ static void remove_user_radios(u32 portid)
if (entry->destroy_on_close && entry->portid == portid) {
list_del(>list);
INIT_WORK(>destroy_work, destroy_radio);
-   schedule_work(>destroy_work);
+   queue_work(hwsim_wq, >destroy_work);
}
}
spin_unlock_bh(_radio_lock);
@@ -3421,7 +3422,7 @@ static void __net_exit hwsim_exit_net(struct net *net)
 
list_del(>list);
INIT_WORK(>destroy_work, destroy_radio);
-   schedule_work(>destroy_work);
+   queue_work(hwsim_wq, >destroy_work);
}
spin_unlock_bh(_radio_lock);
 }
@@ -3453,6 +3454,10 @@ static int __init init_mac80211_hwsim(void)
 
spin_lock_init(_radio_lock);
 
+   hwsim_wq = alloc_workqueue("hwsim_wq",WQ_MEM_RECLAIM,0);
+   if (!hwsim_wq)
+   return -ENOMEM;
+
err = register_pernet_device(_net_ops);
if (err)
return err;
@@ -3591,8 +3596,11 @@ static void __exit exit_mac80211_hwsim(void)
hwsim_exit_netlink();
 
mac80211_hwsim_free();
+   flush_workqueue(hwsim_wq);
+
unregister_netdev(hwsim_mon);
platform_driver_unregister(_hwsim_driver);
unregister_pernet_device(_net_ops);
+   destroy_workqueue(hwsim_wq);
 }
 module_exit(exit_mac80211_hwsim);
-- 
2.15.1




[PATCH v3 3/5] mac80211_hwsim: add generation count for netlink dump operation

2018-01-10 Thread Benjamin Beichler
Make the dump operation aware of changes on radio list and corresponding
inconsistent dumps. Change the dump iteration to be independent from
increasing radio indices on radio list.

Signed-off-by: Benjamin Beichler 
---
 drivers/net/wireless/mac80211_hwsim.c | 43 ---
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 55d25e3fbbcc..2d4e97b6dc8f 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -493,6 +493,7 @@ static LIST_HEAD(hwsim_radios);
 static struct workqueue_struct *hwsim_wq;
 static struct rhashtable hwsim_radios_rht;
 static int hwsim_radio_idx;
+static int hwsim_radios_generation = 1;
 
 static struct platform_driver mac80211_hwsim_driver = {
.driver = {
@@ -2758,6 +2759,7 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
}
 
list_add_tail(>list, _radios);
+   hwsim_radios_generation++;
spin_unlock_bh(_radio_lock);
 
if (idx > 0)
@@ -3209,6 +3211,7 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct 
genl_info *info)
list_del(>list);
rhashtable_remove_fast(_radios_rht, >rht,
   hwsim_rht_params);
+   hwsim_radios_generation++;
spin_unlock_bh(_radio_lock);
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
 info);
@@ -3265,19 +3268,34 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, 
struct genl_info *info)
 static int hwsim_dump_radio_nl(struct sk_buff *skb,
   struct netlink_callback *cb)
 {
-   int idx = cb->args[0];
-   struct mac80211_hwsim_data *data = NULL;
-   int res;
+   struct mac80211_hwsim_data *data =
+   (struct mac80211_hwsim_data *)cb->args[0];
+   int res = 0;
+   void *hdr;
 
spin_lock_bh(_radio_lock);
+   cb->seq = hwsim_radios_generation;
+
+   /* list changed, send msg with dump interrupted header*/
+   if (cb->prev_seq && cb->seq != cb->prev_seq) {
+   hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, _genl_family,
+ NLM_F_MULTI, HWSIM_CMD_GET_RADIO);
+   if (!hdr)
+   res = -EMSGSIZE;
+   genl_dump_check_consistent(cb, hdr);
+   genlmsg_end(skb, hdr);
+   goto cleanup;
+   }
 
-   if (idx == hwsim_radio_idx)
-   goto done;
+   /* iterator is at head again, finish*/
+   if (data && >list == _radios)
+   goto cleanup;
 
-   list_for_each_entry(data, _radios, list) {
-   if (data->idx < idx)
-   continue;
+   /* data will NULL or valid since we quit, if list changed */
+   data = list_prepare_entry(data, _radios, list);
 
+   list_for_each_entry_continue(data, _radios, list) {
if (!net_eq(wiphy_net(data->hw->wiphy), sock_net(skb->sk)))
continue;
 
@@ -3287,15 +3305,13 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
   NLM_F_MULTI);
if (res < 0)
break;
-
-   idx = data->idx + 1;
}
 
-   cb->args[0] = idx;
+   cb->args[0] = (long)data;
 
-done:
+cleanup:
spin_unlock_bh(_radio_lock);
-   return skb->len;
+   return (res)? res : skb->len;
 }
 
 /* Generic Netlink operations array */
@@ -3353,6 +3369,7 @@ static void destroy_radio(struct work_struct *work)
struct mac80211_hwsim_data *data =
container_of(work, struct mac80211_hwsim_data, destroy_work);
 
+   hwsim_radios_generation++;
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy), NULL);
 }
 
-- 
2.15.1




[PATCH v3 4/5] mac80211_hwsim: add permanent mac address option for new radios

2018-01-10 Thread Benjamin Beichler
If simulation needs predictable permanent mac addresses of hwsim wireless
phy, this patch add the ability to create a new radio with a user defined
permanent mac address. Allowed mac addresses needs to be locally
administrated mac addresses (as also the former fixed 42:* and 02:* were).

To do not break the operation with legacy software using hwsim, the new
address is set twice. The problem here is, the netlink call backs use
wiphy->addresses[1] as identification of a radio and not the proposed
permanent address (wiphy->addresses[0]). This design decision is not
documented in the kernel repo, therefore this patch simply reproduces this,
but with the same address.

Signed-off-by: Benjamin Beichler 
---
 drivers/net/wireless/mac80211_hwsim.c | 53 +--
 drivers/net/wireless/mac80211_hwsim.h |  9 +-
 2 files changed, 52 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 2d4e97b6dc8f..1e0d651c43fc 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2375,6 +2375,7 @@ struct hwsim_new_radio_params {
bool destroy_on_close;
const char *hwname;
bool no_vif;
+   u8 *perm_addr;
 };
 
 static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
@@ -2539,15 +2540,25 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
skb_queue_head_init(>pending);
 
SET_IEEE80211_DEV(hw, data->dev);
-   eth_zero_addr(addr);
-   addr[0] = 0x02;
-   addr[3] = idx >> 8;
-   addr[4] = idx;
-   memcpy(data->addresses[0].addr, addr, ETH_ALEN);
-   memcpy(data->addresses[1].addr, addr, ETH_ALEN);
-   data->addresses[1].addr[0] |= 0x40;
-   hw->wiphy->n_addresses = 2;
-   hw->wiphy->addresses = data->addresses;
+   if (!param->perm_addr) {
+   eth_zero_addr(addr);
+   addr[0] = 0x02;
+   addr[3] = idx >> 8;
+   addr[4] = idx;
+   memcpy(data->addresses[0].addr, addr, ETH_ALEN);
+   /* Why need here second address ? */
+   data->addresses[1].addr[0] |= 0x40;
+   memcpy(data->addresses[1].addr, addr, ETH_ALEN);
+   hw->wiphy->n_addresses = 2;
+   hw->wiphy->addresses = data->addresses;
+   /* possible address clash is checked at hash table insertion */
+   } else {
+   memcpy(data->addresses[0].addr, param->perm_addr, ETH_ALEN);
+   /* compatibility with automatically generated mac addr */
+   memcpy(data->addresses[1].addr, param->perm_addr, ETH_ALEN);
+   hw->wiphy->n_addresses = 2;
+   hw->wiphy->addresses = data->addresses;
+   }
 
data->channels = param->channels;
data->use_chanctx = param->use_chanctx;
@@ -3172,6 +3183,30 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, 
struct genl_info *info)
param.regd = hwsim_world_regdom_custom[idx];
}
 
+   if (info->attrs[HWSIM_ATTR_PERM_ADDR]) {
+   if (nla_len(info->attrs[HWSIM_ATTR_PERM_ADDR]) != ETH_ALEN) {
+   pr_debug("mac80211_hwsim: MAC has wrong size\n");
+   return -EINVAL;
+   }
+   if (!is_valid_ether_addr(
+   nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
+   pr_debug("mac80211_hwsim: MAC is no valid source 
addr\n");
+   return -EINVAL;
+   }
+   if (!is_local_ether_addr(
+   nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
+   pr_debug("mac80211_hwsim: MAC is not locally 
administered\n");
+   return -EINVAL;
+   }
+   if (get_hwsim_data_ref_from_addr(
+   nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]))) {
+   pr_debug("mac80211_hwsim: perm MAC already in use\n");
+   return -EINVAL;
+   }
+
+   param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
+   }
+
ret = mac80211_hwsim_new_radio(info, );
kfree(hwname);
return ret;
diff --git a/drivers/net/wireless/mac80211_hwsim.h 
b/drivers/net/wireless/mac80211_hwsim.h
index 3f5eda591dba..e2592b596090 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -67,7 +67,12 @@ enum hwsim_tx_control_flags {
  * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE
  * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters,
  * returns the radio ID (>= 0) or negative on errors, if successful
- * then multicast the result
+ * then multicast the result, uses optional parameter:
+ * %HWSIM_ATTR_REG_STRICT_REG, %HWSIM_ATTR_SUPPORT_P2P_DEVICE,
+ * 

[PATCH v3 2/5] mac80211_hwsim: add hashtable with mac address keys for faster lookup

2018-01-10 Thread Benjamin Beichler
This patch adds a rhastable for mac address lookup of hwsim radios. This
especially improve the speed on reception of a netlink message with a new
frame. Although redundant, we keep holding a normal list for all radios,
since the rhashtable_walk interface adds a lot of overhead for iterating
over all radios and the doc of rhashtable recommend a redundant structure
for stable walks in such situations.

Since rhashtable is rcu protected we do not need a lock for delivering
frames and thus improving this scenario.

Signed-off-by: Benjamin Beichler 
---
 drivers/net/wireless/mac80211_hwsim.c | 57 +--
 1 file changed, 41 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 742a1551bb1c..55d25e3fbbcc 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "mac80211_hwsim.h"
 
 #define WARN_QUEUE 100
@@ -490,6 +491,7 @@ static const struct ieee80211_iface_combination 
hwsim_if_comb_p2p_dev[] = {
 static spinlock_t hwsim_radio_lock;
 static LIST_HEAD(hwsim_radios);
 static struct workqueue_struct *hwsim_wq;
+static struct rhashtable hwsim_radios_rht;
 static int hwsim_radio_idx;
 
 static struct platform_driver mac80211_hwsim_driver = {
@@ -500,6 +502,7 @@ static struct platform_driver mac80211_hwsim_driver = {
 
 struct mac80211_hwsim_data {
struct list_head list;
+   struct rhash_head rht;
struct ieee80211_hw *hw;
struct device *dev;
struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
@@ -574,6 +577,20 @@ struct mac80211_hwsim_data {
u64 tx_failed;
 };
 
+static u32 hwsim_table_hash(const void *addr, u32 len, u32 seed)
+{
+   /* Use last four bytes of hw addr as hash index */
+   return jhash_1word(*(u32 *)(addr + 2), seed);
+}
+
+static const struct rhashtable_params hwsim_rht_params = {
+   .nelem_hint = 2,
+   .automatic_shrinking = true,
+   .key_len = ETH_ALEN,
+   .key_offset = offsetof(struct mac80211_hwsim_data, addresses[1]),
+   .head_offset = offsetof(struct mac80211_hwsim_data, rht),
+   .hashfn = hwsim_table_hash,
+};
 
 struct hwsim_radiotap_hdr {
struct ieee80211_radiotap_header hdr;
@@ -2731,6 +2748,15 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
 CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
 
spin_lock_bh(_radio_lock);
+   err = rhashtable_insert_fast(_radios_rht, >rht,
+hwsim_rht_params);
+   if (err < 0) {
+   pr_debug("mac80211_hwsim: radio index %d already present\n",
+idx);
+   spin_unlock_bh(_radio_lock);
+   goto failed_final_insert;
+   }
+
list_add_tail(>list, _radios);
spin_unlock_bh(_radio_lock);
 
@@ -2739,6 +2765,9 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
 
return idx;
 
+failed_final_insert:
+   debugfs_remove_recursive(data->debugfs);
+   ieee80211_unregister_hw(data->hw);
 failed_hw:
device_release_driver(data->dev);
 failed_bind:
@@ -2874,22 +2903,9 @@ static void hwsim_mon_setup(struct net_device *dev)
 
 static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)
 {
-   struct mac80211_hwsim_data *data;
-   bool _found = false;
-
-   spin_lock_bh(_radio_lock);
-   list_for_each_entry(data, _radios, list) {
-   if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) {
-   _found = true;
-   break;
-   }
-   }
-   spin_unlock_bh(_radio_lock);
-
-   if (!_found)
-   return NULL;
-
-   return data;
+   return rhashtable_lookup_fast(_radios_rht,
+ addr,
+ hwsim_rht_params);
 }
 
 static void hwsim_register_wmediumd(struct net *net, u32 portid)
@@ -3191,6 +3207,8 @@ static int hwsim_del_radio_nl(struct sk_buff *msg, struct 
genl_info *info)
continue;
 
list_del(>list);
+   rhashtable_remove_fast(_radios_rht, >rht,
+  hwsim_rht_params);
spin_unlock_bh(_radio_lock);
mac80211_hwsim_del_radio(data, wiphy_name(data->hw->wiphy),
 info);
@@ -3346,6 +3364,8 @@ static void remove_user_radios(u32 portid)
list_for_each_entry_safe(entry, tmp, _radios, list) {
if (entry->destroy_on_close && entry->portid == portid) {
list_del(>list);
+   rhashtable_remove_fast(_radios_rht, >rht,
+  hwsim_rht_params);
INIT_WORK(>destroy_work, destroy_radio);

Re: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS

2018-01-10 Thread Arend van Spriel
On 1/10/2018 10:38 AM, Pkshih wrote:
> 
> 
>> -Original Message-
>> From: Arend van Spriel [mailto:arend.vanspr...@broadcom.com]
>> Sent: Wednesday, January 10, 2018 4:13 PM
>> To: Pkshih; kv...@codeaurora.org
>> Cc: larry.fin...@lwfinger.net; 莊彥宣; linux-wireless@vger.kernel.org
>> Subject: Re: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS
>>
>> On 1/10/2018 6:19 AM, pks...@realtek.com wrote:
>>> From: Ping-Ke Shih 
>>>
>>> If there is no connection, driver will enter IPS state. Meanwhile, it
>>> fails to scan channel 1 by the command 'iw dev wlan0 scan freq 2412',
>>> because hardware channel setting lose after IPS. Thus, restore channel
>>> setting from hw->conf.channel set by last rtl_op_config().
>>>
>>> Signed-off-by: Tim Lee 
>>
>> You need to add your sob here as well as you are submitting them.
>>
> 
> I'll add it in v2.
> 
>>> ---
>>>drivers/net/wireless/realtek/rtlwifi/ps.c | 6 ++
>>>1 file changed, 6 insertions(+)
>>>
>>> diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c 
>>> b/drivers/net/wireless/realtek/rtlwifi/ps.c
>>> index 6a4008845f49..0ffe43772c9a 100644
>>> --- a/drivers/net/wireless/realtek/rtlwifi/ps.c
>>> +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
>>> @@ -51,6 +51,12 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
>>> >retry_long);
>>> RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
>>>
>>> +   /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/
>>
>> Is this type of comment really helpful? To me it seems the callback
>> names provide enough context.
>>
> 
> Do you mean the "<2.1>" isn't needed?
> This is because "<1>, <2>, <3>..." exist in the function, so
> we want to make it to be consistent.

That is not what I mean. I mean why have a comment describing what is
obvious from reading the code itself. So in this example:

On 1/10/2018 6:19 AM, pks...@realtek.com wrote:
> + /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/
> + rtlpriv->cfg->ops->switch_channel(hw);
> + rtlpriv->cfg->ops->set_channel_access(hw);
> + rtlpriv->cfg->ops->set_bw_mode(hw,
> + cfg80211_get_chandef_type(>conf.chandef));
> +
>   /*<3> Enable Interrupt */
>   rtlpriv->cfg->ops->enable_interrupt(hw);

the code after the <2.1> comment calls a switch_channel() callback and a
set_bw_mode() callback. In my opinion those names are pretty
self-explanatory for the reader making the comment preceding it only
noise. The same applies to step <3>.

Regards,
Arend


Re: Re: Re: [PATCH] mwifiex: cancel pcie/sdio work in remove/shutdown handler

2018-01-10 Thread Xinming Hu
Hi Brian,

> -Original Message-
> From: Brian Norris [mailto:briannor...@chromium.org]
> Sent: 2018年1月10日 6:01
> To: Xinming Hu ; Kalle Valo 
> Cc: Kalle Valo ; Linux Wireless
> ; Dmitry Torokhov ;
> raja...@google.com; Zhiyuan Yang ; Tim Song
> ; Cathy Luo ; James Cao
> ; Ganapathi Bhat ; Ellie Reeves
> ; Christoph Hellwig 
> Subject: [EXT] Re: Re: [PATCH] mwifiex: cancel pcie/sdio work in
> remove/shutdown handler
> 
> External Email
> 
> --
> + Christopher
> 
> Hi Simon and Kalle,
> 
> On Tue, Jan 09, 2018 at 11:42:21AM +, Xinming Hu wrote:
> > Hi,
> >
> > > -Original Message-
> > > From: Kalle Valo [mailto:kv...@codeaurora.org]
> > > Sent: 2018年1月9日 15:40
> > > To: Brian Norris 
> > > Cc: Xinming Hu ; Linux Wireless
> > > ; Dmitry Torokhov ;
> > > raja...@google.com; Zhiyuan Yang ; Tim Song
> > > ; Cathy Luo ; James Cao
> > > ; Ganapathi Bhat ; Ellie Reeves
> > > 
> > > Subject: [EXT] Re: [PATCH] mwifiex: cancel pcie/sdio work in
> > > remove/shutdown handler
> > >
> > > External Email
> > >
> > > 
> > > -- Brian Norris  writes:
> > >
> > > >> --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
> > > >> +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
> > > >> @@ -310,6 +310,8 @@ static void mwifiex_pcie_remove(struct
> > > >> pci_dev
> > > *pdev)
> > > >>mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
> > > >>}
> > > >>
> > > >> +  cancel_work_sync(>work);
> > > >> +
> > > >
> > > > Just FYI, this "fix" is not a real fix. It will likely paper over
> > > > some of your bugs (where, e.g., the FW shutdown command times out
> > > > in the previous couple of lines), but this highlights the fact
> > > > that there are other races that could trigger the same behavior.
> > > > You're not fixing those.
> > > >
> > > > For example, what if somebody initiates a scan or other nl80211
> > > > command between the above line and mwifiex_remove_card()? That
> > > command
> > > > could potentially time out too.
> > > >
> >
> > The hardware status have been reset before downloading the last
> > command(FUNC SHUTDOWN), in this way, follow commands  download will
> be
> > ignored and warned.
> 
> Hmm, I suppose that's true. So the race I'm talking about probably can't
> happen usually. What about in manufacturing mode
> or !FIRMWARE_READY_PCIE though? Those cases don't shut down the
> firmware. Can we still have outstanding timeouts in those cases?
> 
> Anyway, I still think there's a problem though, and this patch is just going 
> to
> make things worse. See below.
> 
> > > > The proper fix would be to institute some kind of mutual exclusion
> > > > (locking) between mwifiex_shutdown_sw() and mwifiex_remove_card(),
> > > > so that they can't occur at the same time.
> > > >
> >
> > I am not sure whether there is any mutual exclusion protect between
> pcie_reset and pcie_remove in pcie core.
> > But it looks a different race.
> > We still need this fix, right?
> 
> Good point. Previously, there wasn't any such exclusion, and that's why races
> like the above were even more likely. But as of 4.13, now there
> *is* exclusion. See commit b014e96d1abb ("PCI: Protect
> pci_error_handlers->reset_notify() usage with device_lock()"). That 
> incidentally
> means that you're creating a deadlock with this patch! [1]
> 
> If we start a timeout/reset sequence in mwifiex_init_shutdown_fw() (called
> from remove()), then you'll eventually have pci_reset_function() waiting on 
> the
> device lock, but mwifiex_pcie_remove() will be holding the device lock 
> already,
> and now (with your patch), remove() will be waiting on the worker thread to
> finish pci_reset_function()...deadlock!
> 
> I actually think that the above patch (adding device_lock()) resolves most of 
> the
> race but introduces a possible deadlock. I believe an easy solution is just to
> switch to pci_try_reset_function() instead? That will just abort a reset 
> attempt
> if we're in the middle of removing the device. Problem solved? Diff appended,
> but I'll send out a real version if that looks right. Can you test your 
> original
> problem with the above commit from Christopher, as well as the appended
> diff?
> 

Since I don't have the original customer platform, which is 4.1 based.
Just run the stress test on my 4.14, with commands:
while true; do rmmod mwifiex;insmod $mwd/mwifiex.ko; sleep 1; insmod 

RTL8723bu: poor signal and connection troubles

2018-01-10 Thread Carlo Caione
Hi,
this is a follow up email to [0] since the problem was never fully
investigated / solved and I keep seeing the same problem also on my
hardware.

Also in my case the hardware is a rtl8723bt transceiver
(0x0bda:0xb720), this time shipped on the internal USB bus in a cheap
laptop branded Zyrex Sky 232.

As already reported by Mylene the problem is that using this
transceiver and the latest Linus master you can barely see any WiFi
network around and also when a WiFi network is actually seen, the
connection is impossible since the signal strength is too low to have
a reliable connection. Of course during my tests BT is off and no BT
driver is probed at all.

Using the downstream driver at [1] everything works correctly.

I tried to debug a bit the issue, in particular comparing functions
and registers related to the antenna setup (.power_on, .enable_rf,
.phy_init_antenna_selection, .phy_iq_calibrate hooks) but everything
seems pretty much the same on the two drivers (even though slightly
differences do exist).

Any idea / suggestion on how to debug this problem? I guess it's worth
to start looking at this since several platforms are being affected
now.

Cheers,

[0] https://www.spinics.net/lists/netdev/msg468028.html
[1] https://github.com/lwfinger/rtl8723bu

-- 
Carlo Caione  |  +44.7384.69.16.04  |  Endless


[PATCH v2 3/9] staging: wilc1000: removed unnecessary enums typedefs

2018-01-10 Thread Ajay Singh
This patch removes following G_PREAMBLE_T,SCANTYPE_T,
USER_PS_MODE_T,SECURITY_T,ACK_POLICY_T,RESET_REQ_T typedef enum.

Now, these enums are used as anonymous-enums for constants.

checkpatch.pl warning to avoid new typedef is fixes with this patch.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan_if.h | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index 222bde2..598ba9e 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -114,28 +114,28 @@ enum {
G_MIXED_11B_2_MODE, /* 1,2,5,11,6,12,24 otherwise all on */
 };
 
-typedef enum {
+enum {
G_SHORT_PREAMBLE= 0,/* Short Preamble */
G_LONG_PREAMBLE = 1,/* Long Preamble */
G_AUTO_PREAMBLE = 2,/* Auto Preamble Selection */
-} G_PREAMBLE_T;
+};
 
 #define MAC_CONNECTED  1
 #define MAC_DISCONNECTED   0
 
 #define SCAN_DONE  TRUE
-typedef enum {
+enum {
PASSIVE_SCAN= 0,
ACTIVE_SCAN = 1,
-} SCANTYPE_T;
+};
 
-typedef enum {
+enum {
NO_POWERSAVE= 0,
MIN_FAST_PS = 1,
MAX_FAST_PS = 2,
MIN_PSPOLL_PS   = 3,
MAX_PSPOLL_PS   = 4
-} USER_PS_MODE_T;
+};
 
 typedef enum {
CHIP_WAKEDUP= 0,
@@ -153,7 +153,7 @@ typedef enum {
RELEASE_ALLOW_SLEEP = 1,
 } BUS_RELEASE_T;
 
-typedef enum {
+enum {
NO_SECURITY = 0,
WEP_40  = 0x3,
WEP_104 = 0x7,
@@ -163,7 +163,7 @@ typedef enum {
WPA2_AES= 0x31,
WPA2_TKIP   = 0x51,
WPA2_AES_TKIP   = 0x71, /* Aes or Tkip */
-} SECURITY_T;
+};
 
 enum AUTHTYPE {
OPEN_SYSTEM = 1,
@@ -178,16 +178,16 @@ enum SITESURVEY {
SITE_SURVEY_OFF = 2
 };
 
-typedef enum {
+enum {
NORMAL_ACK  = 0,
NO_ACK,
-} ACK_POLICY_T;
+};
 
-typedef enum {
+enum {
DONT_RESET  = 0,
DO_RESET= 1,
NO_REQUEST  = 2,
-} RESET_REQ_T;
+};
 
 typedef enum {
REKEY_DISABLE   = 1,
-- 
2.7.4




[PATCH v2 6/9] staging: wilc1000: removed enums typedef for BEACON_IE & TX_RATE_T

2018-01-10 Thread Ajay Singh
This patch removed the unnecessary enum typedef for BEACON_IE &
TX_RATE_T
It fix "WARNING: do not add new typedefs" reported by checkpatch.pl

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan_if.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index cf4a44d..068a59d 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -75,7 +75,7 @@ typedef void (*wilc_tx_complete_func_t)(void *, int);
 #define MAX_SSID_LEN33
 #define MAX_RATES_SUPPORTED 12
 
-typedef enum {
+enum {
SUPP_RATES_IE   = 1,
EXT_SUPP_RATES_IE   = 50,
HT_CAPABILITY_IE= 45,
@@ -83,7 +83,7 @@ typedef enum {
WPA_IE  = 221,
WMM_IE  = 221,
P2P_IE  = 221,
-} BEACON_IE;
+};
 
 enum bss_types {
INFRASTRUCTURE  = 0,
@@ -91,7 +91,7 @@ enum bss_types {
AP,
 };
 
-typedef enum {
+enum {
RATE_AUTO   = 0,
RATE_1MB= 1,
RATE_2MB= 2,
@@ -105,7 +105,7 @@ typedef enum {
RATE_26MB   = 36,
RATE_48MB   = 48,
RATE_54MB   = 54
-} TX_RATE_T;
+};
 
 enum {
B_ONLY_MODE = 0,/* 1, 2 M, otherwise 5, 11 M */
-- 
2.7.4




[PATCH v2 9/9] staging: wilc1000: removed enum typedef BUS_RELEASE_T

2018-01-10 Thread Ajay Singh
This patch removes enum typedef BUS_RELEASE_T and define
"enum bus_release" to use instead of typedef.

checkpatch.pl not to add new typedef warning is fixed with this patch.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan.c| 2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 80a5a0b..a2b26ec 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -13,7 +13,7 @@ static inline void acquire_bus(struct wilc *wilc, enum 
bus_acquire acquire)
chip_wakeup(wilc);
 }
 
-static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release)
+static inline void release_bus(struct wilc *wilc, enum bus_release release)
 {
if (release == RELEASE_ALLOW_SLEEP)
chip_allow_sleep(wilc);
diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index 65cb53d..c1483c8 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -148,10 +148,10 @@ enum bus_acquire {
ACQUIRE_AND_WAKEUP  = 1,
 };
 
-typedef enum {
+enum bus_release {
RELEASE_ONLY= 0,
RELEASE_ALLOW_SLEEP = 1,
-} BUS_RELEASE_T;
+};
 
 enum {
NO_SECURITY = 0,
-- 
2.7.4




[PATCH v2 5/9] staging: wilc1000: removed few unnecessary enums typedef

2018-01-10 Thread Ajay Singh
This patch removes following N_OPERATING_MODE_T,N_OBSS_DETECTION_T,
N_PROTECTION_TYPE_T,N_SMPS_MODE_T,TX_ABORT_OPTION_T, typedef enum.
Now, these enums are used as anonymous-enums for constants.

checkpatch.pl warning to not add new typedef is fixes with this patch.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan_if.h | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index eec8760..cf4a44d 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -226,40 +226,40 @@ enum {
G_RTS_CTS_PROT,
 };
 
-typedef enum {
+enum {
HT_MIXED_MODE   = 1,
HT_ONLY_20MHZ_MODE,
HT_ONLY_20_40MHZ_MODE,
-} N_OPERATING_MODE_T;
+};
 
-typedef enum {
+enum {
NO_DETECT   = 0,
DETECT_ONLY = 1,
DETECT_PROTECT  = 2,
DETECT_PROTECT_REPORT   = 3,
-} N_OBSS_DETECTION_T;
+};
 
-typedef enum {
+enum {
RTS_CTS_NONHT_PROT  = 0,/* RTS-CTS at non-HT rate */
FIRST_FRAME_NONHT_PROT, /* First frame at non-HT rate */
LSIG_TXOP_PROT, /* LSIG TXOP Protection */
FIRST_FRAME_MIXED_PROT, /* First frame at Mixed format */
-} N_PROTECTION_TYPE_T;
+};
 
-typedef enum {
+enum {
STATIC_MODE = 1,
DYNAMIC_MODE= 2,
MIMO_MODE   = 3,/* power save disable */
-} N_SMPS_MODE_T;
+};
 
-typedef enum {
+enum {
DISABLE_SELF_CTS,
ENABLE_SELF_CTS,
DISABLE_TX_ABORT,
ENABLE_TX_ABORT,
HW_TRIGGER_ABORT,
SW_TRIGGER_ABORT,
-} TX_ABORT_OPTION_T;
+};
 
 enum wid_type {
WID_CHAR= 0,
-- 
2.7.4




[PATCH v2 7/9] staging: wilc1000: removed enum typedef CHIP_PS_STATE_T

2018-01-10 Thread Ajay Singh
This patch removes enum typedef CHIP_PS_STATE_T and introduce
enum chip_ps_states to use instead of typedef.

checkpatch.pl not to add new typedef warning is fixed with this patch.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan.c| 2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index f49dfa8..3a58a62 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -4,7 +4,7 @@
 #include "wilc_wfi_netdevice.h"
 #include "wilc_wlan_cfg.h"
 
-static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP;
+static enum chip_ps_states chip_ps_state = CHIP_WAKEDUP;
 
 static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire)
 {
diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index 068a59d..70e3558 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -137,11 +137,11 @@ enum {
MAX_PSPOLL_PS   = 4
 };
 
-typedef enum {
+enum chip_ps_states {
CHIP_WAKEDUP= 0,
CHIP_SLEEPING_AUTO  = 1,
CHIP_SLEEPING_MANUAL= 2
-} CHIP_PS_STATE_T;
+};
 
 typedef enum {
ACQUIRE_ONLY= 0,
-- 
2.7.4




[PATCH v2 4/9] staging: wilc1000: removed few unnecessary enums typedef

2018-01-10 Thread Ajay Singh
This patch removes following RSNA_REKEY_POLICY_T,SCAN_CLASS_FITLER_T,
SCAN_PRI_T,CH_FILTER_T,N_PROTECTION_MODE_T,G_PROTECTION_MODE_T typedef
enum.
Now, these enums are used as anonymous-enums for constants.

checkpatch.pl warning to avoid new typedef is fixes with this patch.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan_if.h | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index 598ba9e..eec8760 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -189,42 +189,42 @@ enum {
NO_REQUEST  = 2,
 };
 
-typedef enum {
+enum {
REKEY_DISABLE   = 1,
REKEY_TIME_BASE,
REKEY_PKT_BASE,
REKEY_TIME_PKT_BASE
-} RSNA_REKEY_POLICY_T;
+};
 
-typedef enum {
+enum {
FILTER_NO   = 0x00,
FILTER_AP_ONLY  = 0x01,
FILTER_STA_ONLY = 0x02
-} SCAN_CLASS_FITLER_T;
+};
 
-typedef enum {
+enum {
PRI_HIGH_RSSI   = 0x00,
PRI_LOW_RSSI= 0x04,
PRI_DETECT  = 0x08
-} SCAN_PRI_T;
+};
 
-typedef enum {
+enum {
CH_FILTER_OFF   = 0x00,
CH_FILTER_ON= 0x10
-} CH_FILTER_T;
+};
 
-typedef enum {
+enum {
AUTO_PROT   = 0,/* Auto */
NO_PROT,/* Do not use any protection */
ERP_PROT,   /* Protect all ERP frame exchanges */
HT_PROT,/* Protect all HT frame exchanges  */
GF_PROT,/* Protect all GF frame exchanges  */
-} N_PROTECTION_MODE_T;
+};
 
-typedef enum {
+enum {
G_SELF_CTS_PROT,
G_RTS_CTS_PROT,
-} G_PROTECTION_MODE_T;
+};
 
 typedef enum {
HT_MIXED_MODE   = 1,
-- 
2.7.4




[PATCH v2 8/9] staging: wilc1000: removed enum typedef BUS_ACQUIRE_T

2018-01-10 Thread Ajay Singh
This patch removes enum typedef BUS_ACQUIRE_T and define
enum bus_acquire to use instead of typedef.

checkpatch.pl not to add new typedef warning is fixed with this patch.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan.c| 2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 3a58a62..80a5a0b 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -6,7 +6,7 @@
 
 static enum chip_ps_states chip_ps_state = CHIP_WAKEDUP;
 
-static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire)
+static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
 {
mutex_lock(>hif_cs);
if (acquire == ACQUIRE_AND_WAKEUP)
diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index 70e3558..65cb53d 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -143,10 +143,10 @@ enum chip_ps_states {
CHIP_SLEEPING_MANUAL= 2
 };
 
-typedef enum {
+enum bus_acquire {
ACQUIRE_ONLY= 0,
ACQUIRE_AND_WAKEUP  = 1,
-} BUS_ACQUIRE_T;
+};
 
 typedef enum {
RELEASE_ONLY= 0,
-- 
2.7.4




[PATCH v2 1/9] staging: wilc1000: removed typedef from enum BSSTYPE_T

2018-01-10 Thread Ajay Singh
This patch removes typedef from enum BSSTYPE_T and
rename it to bss_types.

It fixes "WARNING: do not add new typdefs" warning
reported by checkpatch.pl.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index d69248a..4ff1a59 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -202,7 +202,7 @@ struct host_if_msg {
 };
 
 struct join_bss_param {
-   BSSTYPE_T bss_type;
+   enum bss_types bss_type;
u8 dtim_period;
u16 beacon_period;
u16 cap_info;
diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index c1693cf..2baf6c4 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -85,11 +85,11 @@ typedef enum {
P2P_IE  = 221,
 } BEACON_IE;
 
-typedef enum {
+enum bss_types {
INFRASTRUCTURE  = 0,
INDEPENDENT,
AP,
-} BSSTYPE_T;
+};
 
 typedef enum {
RATE_AUTO   = 0,
-- 
2.7.4




[PATCH v2 2/9] staging: wilc1000: remove unnecessary typedef enum G_OPERATING_MODE_T

2018-01-10 Thread Ajay Singh
This patch has removed G_OPERATING_MODE_T typedef enum.
Now, its used as anonymous-enums for constants.
checkpatch.pl warning to avoid new typedef is fixes with this patch.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/wilc_wlan_if.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h 
b/drivers/staging/wilc1000/wilc_wlan_if.h
index 2baf6c4..222bde2 100644
--- a/drivers/staging/wilc1000/wilc_wlan_if.h
+++ b/drivers/staging/wilc1000/wilc_wlan_if.h
@@ -107,12 +107,12 @@ typedef enum {
RATE_54MB   = 54
 } TX_RATE_T;
 
-typedef enum {
+enum {
B_ONLY_MODE = 0,/* 1, 2 M, otherwise 5, 11 M */
G_ONLY_MODE,/* 6,12,24 otherwise 9,18,36,48,54 */
G_MIXED_11B_1_MODE, /* 1,2,5.5,11 otherwise all on */
G_MIXED_11B_2_MODE, /* 1,2,5,11,6,12,24 otherwise all on */
-} G_OPERATING_MODE_T;
+};
 
 typedef enum {
G_SHORT_PREAMBLE= 0,/* Short Preamble */
-- 
2.7.4




[PATCH v2 0/9] fixes to remove enum typedefs

2018-01-10 Thread Ajay Singh
v2: The patch series is created instead of independent patches & 
updated the name for Signed-off-by field. 
  
This patch series fix "WARNING: do not add new typedefs" issues
found by checkpatch.pl

Ajay Singh (9):
  staging: wilc1000: removed typedef from enum BSSTYPE_T
  staging: wilc1000: remove unnecessary typedef enum G_OPERATING_MODE_T
  staging: wilc1000: removed unnecessary enums typedefs
  staging: wilc1000: removed few unnecessary enums typedef
  staging: wilc1000: removed few unnecessary enums typedef
  staging: wilc1000: removed enums typedef for BEACON_IE & TX_RATE_T
  staging: wilc1000: removed enum typedef CHIP_PS_STATE_T
  staging: wilc1000: removed enum typedef BUS_ACQUIRE_T
  staging: wilc1000: removed enum typedef BUS_RELEASE_T

 drivers/staging/wilc1000/host_interface.c |  2 +-
 drivers/staging/wilc1000/wilc_wlan.c  |  6 +-
 drivers/staging/wilc1000/wilc_wlan_if.h   | 96 +++
 3 files changed, 52 insertions(+), 52 deletions(-)

-- 
2.7.4




RE: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS

2018-01-10 Thread Pkshih


> -Original Message-
> From: Arend van Spriel [mailto:arend.vanspr...@broadcom.com]
> Sent: Wednesday, January 10, 2018 4:13 PM
> To: Pkshih; kv...@codeaurora.org
> Cc: larry.fin...@lwfinger.net; 莊彥宣; linux-wireless@vger.kernel.org
> Subject: Re: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS
> 
> On 1/10/2018 6:19 AM, pks...@realtek.com wrote:
> > From: Ping-Ke Shih 
> >
> > If there is no connection, driver will enter IPS state. Meanwhile, it
> > fails to scan channel 1 by the command 'iw dev wlan0 scan freq 2412',
> > because hardware channel setting lose after IPS. Thus, restore channel
> > setting from hw->conf.channel set by last rtl_op_config().
> >
> > Signed-off-by: Tim Lee 
> 
> You need to add your sob here as well as you are submitting them.
> 

I'll add it in v2.

> > ---
> >   drivers/net/wireless/realtek/rtlwifi/ps.c | 6 ++
> >   1 file changed, 6 insertions(+)
> >
> > diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c 
> > b/drivers/net/wireless/realtek/rtlwifi/ps.c
> > index 6a4008845f49..0ffe43772c9a 100644
> > --- a/drivers/net/wireless/realtek/rtlwifi/ps.c
> > +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
> > @@ -51,6 +51,12 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
> > >retry_long);
> > RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
> >
> > +   /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/
> 
> Is this type of comment really helpful? To me it seems the callback
> names provide enough context.
> 

Do you mean the "<2.1>" isn't needed? 
This is because "<1>, <2>, <3>..." exist in the function, so
we want to make it to be consistent.

PK



Re: brcmfmac4329-sdio firmware load failed.

2018-01-10 Thread Arend van Spriel

On 1/9/2018 1:51 PM, Kyle Evans wrote:

This is linux-4.15-rc2 on an ASUS TF101. This device was shipped with
Android and a custom kernel using bcmdhd. I have taken nvram.txt from
/system/etc/ on the stock filesystem and copied to
/lib/firmware/brcm/brcmfmac4329-sdio.txt. Below is the result.


Ok. So far so good as that nvram.txt is indeed what you want to use.

[2.729157] brcmfmac: F1 signature read @0x1800=0x9934329
[2.734313] brcmfmac: brcmf_sdiod_regrw_helper: failed to read data
F1@0x080ac, err: -84


The read failure is a bit concerning, but I ignore it for now.


[2.739952] brcmfmac: brcmf_fw_map_chip_to_name: using
brcm/brcmfmac4329-sdio.bin for chip 0x004329(17193) rev 0x03
[2.965820] brcmfmac mmc0:0001:1: Direct firmware load for
brcm/brcmfmac4329-sdio.clm_blob failed with error -2


Expected as you did not put a clm_blob file in /lib/firmware/brcm/. 
However, ...



[2.969658] brcmfmac mmc0:0001:1: Falling back to user helper
[   64.489695] brcmfmac: brcmf_c_process_clm_blob: request CLM blob file
failed (-11)


...in one of the review cycles for the CLM blob feature it was made 
clear that this should not result in a probe failure...



[   64.489720] brcmfmac: brcmf_c_preinit_dcmds: download CLM blob file
failed, -11
[   64.489739] brcmfmac: brcmf_bus_started: failed: -11


... but it does bail out. Turns out the driver is checking for a 
specific error code -ENOENT (-2) and not -EAGAIN(-11). A patch has been 
submitted for it earlier [1], but it was rejected. I have taken another 
stab at it (see below). Let me know if it works for you.



[   64.489783] brcmfmac: brcmf_sdio_firmware_callback: dongle is not
responding
[   64.596281] [] (device_release_driver_internal) from
[] (brcmf_sdio_firmware_callback+0x244/0x5b8)
[   64.596500] [] (brcmf_sdio_firmware_callback) from
[] (brcmf_fw_request_nvram_done+0x1cc/0x73c)
[   64.596716] [] (brcmf_fw_request_nvram_done) from
[] (request_firmware_work_func+0x3c/0x64)


This stack trace is from a driver bug that has been fixed in later -rc [2].

Regards,
Arend

[1] https://patchwork.kernel.org/patch/10106571/
[2] https://patchwork.kernel.org/patch/10075091/

---
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c 
b/driver

index 6a59d06..f805600 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -182,12 +182,8 @@ static int brcmf_c_process_clm_blob(struct brcmf_if 
*ifp)


err = request_firmware(, clm_name, dev);
if (err) {
-   if (err == -ENOENT) {
-   brcmf_dbg(INFO, "continue with CLM data 
currently prese

-   return 0;
-   }
-   brcmf_err("request CLM blob file failed (%d)\n", err);
-   return err;
+   brcmf_info("no CLM blob. Firmware may still need it.\n");
+   return 0;
}

chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, 
GFP_KERNEL)




Re: [PATCH 05/10] rtlwifi: enable mac80211 fast-tx support

2018-01-10 Thread Arend van Spriel

On 1/10/2018 6:19 AM, pks...@realtek.com wrote:

From: Ping-Ke Shih 

To enable the mac80211 fast-tx feature, the hw/driver needs to support
dynamic power saving and fragmentation. Since our driver does not
need to fragment packet into smaller pieces, we just hook an empty
callback of set_frag_threshold to avoid fragmentation in mac80211.

After this, the mac80211 will not fragment the packets and can transmit
them faster by cache the header information.

Signed-off-by: Yan-Hsuan Chuang 


Your sob is missing here (also in patch 6/10).

Regards,
Arend


Re: [PATCH 02/10] rtlwifi: fix scan channel 1 fail after IPS

2018-01-10 Thread Arend van Spriel

On 1/10/2018 6:19 AM, pks...@realtek.com wrote:

From: Ping-Ke Shih 

If there is no connection, driver will enter IPS state. Meanwhile, it
fails to scan channel 1 by the command 'iw dev wlan0 scan freq 2412',
because hardware channel setting lose after IPS. Thus, restore channel
setting from hw->conf.channel set by last rtl_op_config().

Signed-off-by: Tim Lee 


You need to add your sob here as well as you are submitting them.


---
  drivers/net/wireless/realtek/rtlwifi/ps.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c 
b/drivers/net/wireless/realtek/rtlwifi/ps.c
index 6a4008845f49..0ffe43772c9a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
+++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
@@ -51,6 +51,12 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
>retry_long);
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);

+   /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/


Is this type of comment really helpful? To me it seems the callback 
names provide enough context.


Regards,
Arend


+   rtlpriv->cfg->ops->switch_channel(hw);
+   rtlpriv->cfg->ops->set_channel_access(hw);
+   rtlpriv->cfg->ops->set_bw_mode(hw,
+   cfg80211_get_chandef_type(>conf.chandef));
+
/*<3> Enable Interrupt */
rtlpriv->cfg->ops->enable_interrupt(hw);