2015-08-05 16:18:48

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 0/7] Make changes in rtlwifi and dependent drivers

The Realtek engineers have suggested several improvements to this family
of drivers. The changes include:

1. Fix the 5G channel assignments to remove unused channels.
2. Fix a potential race condition when updating CAM.
3. Change retry limits to depend on vif type.
4. Fix a race condition that could allow a change in the APOL key
before packet 4 of the handshaking sequence has been transmitted.
This problem affects rtl8192ee, rtl8723be, and rtl8821ae.

Larry
---

V2 - Fix a merge error

pkshih (6):
rtlwifi: Fix programming of CAM content
rtlwifi: Make retry limits depend on vif type
rtlwifi: Force disable key to wait until TX acked.
rtlwifi: rtl8192ee: Implement new rekey logic
rtlwifi: rtl8723be: Implement new rekey logic
rtlwifi: rtl8821ae: Implement new rekey logic

timlee (1):
rtlwifi: rtl8821ae: Remove unsupported 5G channels

drivers/net/wireless/rtlwifi/base.c | 183 ++++++++++++++++++++++-----
drivers/net/wireless/rtlwifi/base.h | 7 +
drivers/net/wireless/rtlwifi/cam.c | 6 +-
drivers/net/wireless/rtlwifi/core.c | 22 +++-
drivers/net/wireless/rtlwifi/debug.h | 1 +
drivers/net/wireless/rtlwifi/pci.c | 8 +-
drivers/net/wireless/rtlwifi/ps.c | 3 +
drivers/net/wireless/rtlwifi/rtl8192ee/fw.c | 1 +
drivers/net/wireless/rtlwifi/rtl8192ee/trx.c | 8 ++
drivers/net/wireless/rtlwifi/rtl8723be/fw.c | 1 +
drivers/net/wireless/rtlwifi/rtl8723be/trx.c | 8 ++
drivers/net/wireless/rtlwifi/rtl8723be/trx.h | 12 ++
drivers/net/wireless/rtlwifi/rtl8821ae/hw.c | 14 +-
drivers/net/wireless/rtlwifi/rtl8821ae/trx.c | 8 ++
drivers/net/wireless/rtlwifi/rtl8821ae/trx.h | 13 ++
drivers/net/wireless/rtlwifi/wifi.h | 9 ++
16 files changed, 255 insertions(+), 49 deletions(-)

--
2.1.4



2015-08-05 16:18:50

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 1/7] rtlwifi: rtl8821ae: Remove unsupported 5G channels

From: timlee <[email protected]>

The 5G channel list contains channels that are not supported.

Signed-off-by: timlee <[email protected]>
Signed-off-by: shaofu <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---
V2 - unchanged
---
drivers/net/wireless/rtlwifi/rtl8821ae/hw.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
index b7f18e21..53d67a9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
@@ -2856,13 +2856,13 @@ static void _rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
struct txpower_info_2g pwrinfo24g;
struct txpower_info_5g pwrinfo5g;
u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {
- 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
- 56, 58, 60, 62, 64, 100, 102, 104, 106,
- 108, 110, 112, 114, 116, 118, 120, 122,
- 124, 126, 128, 130, 132, 134, 136, 138,
- 140, 142, 144, 149, 151, 153, 155, 157,
- 159, 161, 163, 165, 167, 168, 169, 171,
- 173, 175, 177};
+ 36, 38, 40, 42, 44, 46, 48, /* Band 1 */
+ 52, 54, 56, 58, 60, 62, 64, /* Band 2 */
+ 100, 102, 104, 106, 108, 110, 112, /* Band 3 */
+ 116, 118, 120, 122, 124, 126, 128, /* Band 3 */
+ 132, 134, 136, 138, 140, 142, 144, /* Band 3 */
+ 149, 151, 153, 155, 157, 159, 161, /* Band 4 */
+ 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */
u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
42, 58, 106, 122, 138, 155, 171};
u8 rf_path, index;
--
2.1.4


2015-08-05 16:18:55

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 4/7] rtlwifi: Force disable key to wait until TX acked.

From: pkshih <[email protected]>

When connected, the drivers will use EAPOL to do PTK rekey. When msg 3/4 is
received, the supplicant will send msg 4/4 and install new key immediately.
However, the driver must make sure that msg 4/4 is sent before it installs
the new key. A new routine is created to ensure that msg 4/4 has been sent.

This patch modifies rtlwifi to support the new logic. Subsequent patches
will implement it in the drivers.

Signed-off-by: pkshih <[email protected]>
Signed-off-by: shaofu <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---
V2 - no changes
---
drivers/net/wireless/rtlwifi/base.c | 183 ++++++++++++++++++++++++++++-------
drivers/net/wireless/rtlwifi/base.h | 7 ++
drivers/net/wireless/rtlwifi/core.c | 3 +
drivers/net/wireless/rtlwifi/debug.h | 1 +
drivers/net/wireless/rtlwifi/wifi.h | 9 ++
5 files changed, 168 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 0517a4f..01a6ed4 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1105,6 +1105,9 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
if (txrate)
tcb_desc->hw_rate = txrate->hw_value;

+ if (rtl_is_tx_report_skb(hw, skb))
+ tcb_desc->use_spe_rpt = 1;
+
if (ieee80211_is_data(fc)) {
/*
*we set data rate INX 0
@@ -1312,45 +1315,69 @@ static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc)
ppsc->last_delaylps_stamp_jiffies = jiffies;
}

-/*should call before software enc*/
-u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
- bool is_enc)
+static const u8 *rtl_skb_ether_type_ptr(struct ieee80211_hw *hw,
+ struct sk_buff *skb,
+ bool with_encrypt_header)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
+ u8 encrypt_header_len = 0;
+
+ if (with_encrypt_header && mac->link_state >= MAC80211_LINKED) {
+ switch (rtlpriv->sec.pairwise_enc_algorithm) {
+ case WEP40_ENCRYPTION:
+ case WEP104_ENCRYPTION:
+ encrypt_header_len = 4;/*WEP_IV_LEN*/
+ break;
+ case TKIP_ENCRYPTION:
+ encrypt_header_len = 8;/*TKIP_IV_LEN*/
+ break;
+ case AESCCMP_ENCRYPTION:
+ encrypt_header_len = 8;/*CCMP_HDR_LEN;*/
+ break;
+ default:
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
+ DBG_LOUD, "encrypt not set!\n");
+ break;
+ }
+ }
+
+ return skb->data + mac_hdr_len + SNAP_SIZE + encrypt_header_len;
+}
+
+/* This function is called by 3 routines:
+ * 1.RX
+ * 2.rtl_tx_status
+ * 3._rtl_rc_get_highest_rix
+ *
+ * 1 and 2 have encryption header
+ * 3 does not
+ *
+ * data in 2 and 3 are same.
+ *
+ * if we return false to _rtl_rc_get_highest_rix(), this will cause the rate
+ * to be too high when EAPOL. After a while, the connection will fail
+ */
+
+u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb,
+ u8 is_tx, bool with_encrypt_header)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
__le16 fc = rtl_get_fc(skb);
u16 ether_type;
- u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
- u8 encrypt_header_len = 0;
- u8 offset;
+ const u8 *ether_type_ptr;
const struct iphdr *ip;

if (!ieee80211_is_data(fc))
goto end;

- switch (rtlpriv->sec.pairwise_enc_algorithm) {
- case WEP40_ENCRYPTION:
- case WEP104_ENCRYPTION:
- encrypt_header_len = 4;/*WEP_IV_LEN*/
- break;
- case TKIP_ENCRYPTION:
- encrypt_header_len = 8;/*TKIP_IV_LEN*/
- break;
- case AESCCMP_ENCRYPTION:
- encrypt_header_len = 8;/*CCMP_HDR_LEN;*/
- break;
- default:
- break;
- }
-
- offset = mac_hdr_len + SNAP_SIZE;
- if (is_enc)
- offset += encrypt_header_len;
- ether_type = be16_to_cpup((__be16 *)(skb->data + offset));
+ ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, with_encrypt_header);
+ ether_type = be16_to_cpup((__be16 *)ether_type_ptr);

if (ETH_P_IP == ether_type) {
- ip = (struct iphdr *)((u8 *)skb->data + offset +
- PROTOC_TYPE_SIZE);
+ ip = (struct iphdr *)((u8 *)ether_type_ptr + PROTOC_TYPE_SIZE);
if (IPPROTO_UDP == ip->protocol) {
struct udphdr *udp = (struct udphdr *)((u8 *)ip +
(ip->ihl << 2));
@@ -1361,37 +1388,43 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
/* 68 : UDP BOOTP client
* 67 : UDP BOOTP server
*/
+ if (!with_encrypt_header)
+ return true;
+
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
DBG_DMESG, "dhcp %s !!\n",
(is_tx) ? "Tx" : "Rx");

if (is_tx)
setup_arp_tx(rtlpriv, ppsc);
+
return true;
}
}
} else if (ETH_P_ARP == ether_type) {
+ if (!with_encrypt_header)
+ return true;
+
if (is_tx)
setup_arp_tx(rtlpriv, ppsc);
-
+ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
+ DBG_DMESG, "ARP %s !!\n", (is_tx) ? "Tx" : "Rx");
return true;
} else if (ETH_P_PAE == ether_type) {
+ if (!with_encrypt_header)
+ return true;
RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
"802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx");

if (is_tx) {
rtlpriv->ra.is_special_data = true;
- rtlpriv->enter_ps = false;
- schedule_work(&rtlpriv->works.lps_change_work);
+ rtl_lps_leave(hw);
ppsc->last_delaylps_stamp_jiffies = jiffies;
}

return true;
- } else if (ETH_P_IPV6 == ether_type) {
- /* TODO: Handle any IPv6 cases that need special handling.
- * For now, always return false
- */
- goto end;
+ } else if (0x86DD == ether_type) {
+ return true;
}

end:
@@ -1400,6 +1433,86 @@ end:
}
EXPORT_SYMBOL_GPL(rtl_is_special_data);

+bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ u16 ether_type;
+ const u8 *ether_type_ptr;
+
+ ether_type_ptr = rtl_skb_ether_type_ptr(hw, skb, true);
+ ether_type = be16_to_cpup((__be16 *)ether_type_ptr);
+
+ /* EAPOL */
+ if (ETH_P_PAE == ether_type)
+ return true;
+
+ return false;
+}
+
+u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
+ u16 sn;
+
+ sn = atomic_inc_return(&tx_report->sn) & 0x0FFF;
+
+ tx_report->last_sent_sn = sn;
+ tx_report->last_sent_time = jiffies;
+
+ RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG,
+ "Send TX-Report sn=0x%X\n", sn);
+
+ return sn;
+}
+EXPORT_SYMBOL_GPL(rtl_get_tx_report_sn);
+
+void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf, u8 c2h_cmd_len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
+ u16 sn;
+
+ sn = ((tmp_buf[7] & 0x0F) << 8) | tmp_buf[6];
+
+ tx_report->last_recv_sn = sn;
+
+ RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG,
+ "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n",
+ tmp_buf[0], sn, tmp_buf[2]);
+}
+EXPORT_SYMBOL_GPL(rtl_tx_report_handler);
+
+bool rtl_check_tx_report_acked(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tx_report *tx_report = &rtlpriv->tx_report;
+
+ if (tx_report->last_sent_sn == tx_report->last_recv_sn)
+ return true;
+
+ if (time_before(tx_report->last_sent_time + 3 * HZ, jiffies)) {
+ RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_WARNING,
+ "Check TX-Report timeout!!\n");
+ return true; /* 3 sec. (timeout) seen as acked */
+ }
+
+ return false;
+}
+
+void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int i;
+
+ for (i = 0; i < wait_ms; i++) {
+ if (rtl_check_tx_report_acked(hw))
+ break;
+ usleep_range(1000, 1500);
+ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+ "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms);
+ }
+}
+
/*********************************************************
*
* functions called by core.c
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index 74233d6..05a69f7 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -123,6 +123,13 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
bool is_enc);

+bool rtl_is_tx_report_skb(struct ieee80211_hw *hw, struct sk_buff *skb);
+u16 rtl_get_tx_report_sn(struct ieee80211_hw *hw);
+void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf,
+ u8 c2h_cmd_len);
+bool rtl_check_tx_report_acked(struct ieee80211_hw *hw);
+void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms);
+
void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 19729ed..086c1ad 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1671,6 +1671,9 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
*so don't use rtl_cam_reset_all_entry
*or clear all entry here.
*/
+ key_idx = key->keyidx;
+
+ rtl_wait_tx_report_acked(hw, 500); /* wait 500ms for TX ack */
rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
break;
default:
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
index fc794b3..e23f2d5 100644
--- a/drivers/net/wireless/rtlwifi/debug.h
+++ b/drivers/net/wireless/rtlwifi/debug.h
@@ -105,6 +105,7 @@
#define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */
#define COMP_BT_COEXIST BIT(30)
#define COMP_IQK BIT(31)
+#define COMP_TX_REPORT BIT_ULL(32)

/*--------------------------------------------------------------
Define the rt_print components
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 2b770b5..ca734bb 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1860,6 +1860,13 @@ struct rtl_efuse {
u8 channel_plan;
};

+struct rtl_tx_report {
+ atomic_t sn;
+ u16 last_sent_sn;
+ unsigned long last_sent_time;
+ u16 last_recv_sn;
+};
+
struct rtl_ps_ctl {
bool pwrdomain_protect;
bool in_powersavemode;
@@ -2048,6 +2055,7 @@ struct rtl_tcb_desc {
u8 use_shortpreamble:1;
u8 use_driver_rate:1;
u8 disable_ratefallback:1;
+ u8 use_spe_rpt:1;

u8 ratr_index;
u8 mac_id;
@@ -2557,6 +2565,7 @@ struct rtl_priv {
struct rtl_dm dm;
struct rtl_security sec;
struct rtl_efuse efuse;
+ struct rtl_tx_report tx_report;

struct rtl_ps_ctl psc;
struct rate_adaptive ra;
--
2.1.4


2015-08-05 16:18:59

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 7/7] rtlwifi: rtl8821ae: Implement new rekey logic

From: pkshih <[email protected]>

Use the new capability in rtlwifi to prevent rekeying before EAPOL msg 4/4
has been sent.

Signed-off-by: pkshih <[email protected]>
Signed-off-by: shaofu <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---
V2 - no changes
---
drivers/net/wireless/rtlwifi/rtl8821ae/trx.c | 8 ++++++++
drivers/net/wireless/rtlwifi/rtl8821ae/trx.h | 13 +++++++++++++
2 files changed, 21 insertions(+)

diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
index 174743a..a03015c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
@@ -740,6 +740,14 @@ void rtl8821ae_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
}

+ /* tx report */
+ if (ptcb_desc->use_spe_rpt) {
+ u16 sn = rtl_get_tx_report_sn(hw);
+
+ SET_TX_DESC_SPE_RPT(pdesc, 1);
+ SET_TX_DESC_SW_DEFINE(pdesc, sn);
+ }
+
/* ptcb_desc->use_driver_rate = true; */
SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
if (ptcb_desc->hw_rate > DESC_RATEMCS0)
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.h b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.h
index 3140904..4717801 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.h
@@ -185,6 +185,19 @@
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)

+#define SET_TX_DESC_SW_DEFINE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 0, 12, __val)
+#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 16, 3, __val)
+#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 19, 3, __val)
+#define SET_TX_DESC_ANTSEL_C(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 22, 3, __val)
+#define SET_TX_DESC_ANTSEL_D(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 25, 3, __val)
+#define SET_TX_DESC_MBSSID(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 12, 4, __val)
+
#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)

--
2.1.4


2015-08-05 16:18:51

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 2/7] rtlwifi: Fix programming of CAM content

From: pkshih <[email protected]>

There is a potential race condition when the control byte of a CAM entry
is written first.

Signed-off-by: pkshih <[email protected]>
Signed-off-by: shaofu <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---
V2 - Removed a udelay() statement introduced because of a merge error

---
drivers/net/wireless/rtlwifi/cam.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
index 8fe8b4c..cc7acbf 100644
--- a/drivers/net/wireless/rtlwifi/cam.c
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -45,12 +45,13 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,

u32 target_command;
u32 target_content = 0;
- u8 entry_i;
+ s8 entry_i;

RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_DMESG, "Key content :",
key_cont_128, 16);

- for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
+ /* 2-5 fill 128key,6-7 are reserved */
+ for (entry_i = CAM_CONTENT_COUNT - 3; entry_i >= 0; entry_i--) {
target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
target_command = target_command | BIT(31) | BIT(16);

--
2.1.4


2015-08-05 16:18:58

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 6/7] rtlwifi: rtl8723be: Implement new rekey logic

From: pkshih <[email protected]>

Use the new capability in rtlwifi to prevent rekeying before EAPOL msg 4/4
has been sent.

Signed-off-by: pkshih <[email protected]>
Signed-off-by: shaofu <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---
V2 - no changes
---
drivers/net/wireless/rtlwifi/rtl8723be/fw.c | 1 +
drivers/net/wireless/rtlwifi/rtl8723be/trx.c | 8 ++++++++
drivers/net/wireless/rtlwifi/rtl8723be/trx.h | 12 ++++++++++++
3 files changed, 21 insertions(+)

diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
index d5da0f3..be15d3d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/fw.c
@@ -600,6 +600,7 @@ static void _rtl8723be_c2h_content_parsing(struct ieee80211_hw *hw,
case C2H_8723B_TX_REPORT:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
"[C2H], C2H_8723BE_TX_REPORT!\n");
+ rtl_tx_report_handler(hw, tmp_buf, c2h_cmd_len);
break;
case C2H_8723B_BT_INFO:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
index 338ec9a..fe8e3f4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
@@ -488,6 +488,14 @@ void rtl8723be_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
}

+ /* tx report */
+ if (ptcb_desc->use_spe_rpt) {
+ u16 sn = rtl_get_tx_report_sn(hw);
+
+ SET_TX_DESC_SPE_RPT(pdesc, 1);
+ SET_TX_DESC_SW_DEFINE(pdesc, sn);
+ }
+
/* ptcb_desc->use_driver_rate = true; */
SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
if (ptcb_desc->hw_rate > DESC92C_RATEMCS0)
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/trx.h b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
index 45949ac..c20fb45 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.h
@@ -187,6 +187,18 @@
#define SET_TX_DESC_RTS_SC(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val)

+#define SET_TX_DESC_SW_DEFINE(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 0, 12, __val)
+#define SET_TX_DESC_MBSSID(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 12, 4, __val)
+#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 16, 3, __val)
+#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 19, 3, __val)
+#define SET_TX_DESC_ANTSEL_C(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 22, 3, __val)
+#define SET_TX_DESC_ANTSEL_D(__pdesc, __val) \
+ SET_BITS_TO_LE_4BYTE(__pdesc + 24, 25, 3, __val)

#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val)
--
2.1.4


2015-08-05 16:18:57

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 5/7] rtlwifi: rtl8192ee: Implement new rekey logic

From: pkshih <[email protected]>

Use the new capability in rtlwifi to prevent rekeying before EAPOL msg 4/4
has been sent.

Signed-off-by: pkshih <[email protected]>
Signed-off-by: shaofu <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---
V2 - no changes
---
drivers/net/wireless/rtlwifi/rtl8192ee/fw.c | 1 +
drivers/net/wireless/rtlwifi/rtl8192ee/trx.c | 8 ++++++++
2 files changed, 9 insertions(+)

diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
index 232865c..4091430 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
@@ -859,6 +859,7 @@ static void _rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id,
case C2H_8192E_TX_REPORT:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE ,
"[C2H], C2H_8723BE_TX_REPORT!\n");
+ rtl_tx_report_handler(hw, tmp_buf, c2h_cmd_len);
break;
case C2H_8192E_BT_INFO:
RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
index d39ee67..49aec97 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
@@ -731,6 +731,14 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
}

+ /* tx report */
+ if (ptcb_desc->use_spe_rpt) {
+ u16 sn = rtl_get_tx_report_sn(hw);
+
+ SET_TX_DESC_SPE_RPT(pdesc, 1);
+ SET_TX_DESC_SW_DEFINE(pdesc, sn);
+ }
+
SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);

if (ieee80211_is_mgmt(fc)) {
--
2.1.4


2015-08-05 16:18:53

by Larry Finger

[permalink] [raw]
Subject: [PATCH V2 NEXT 3/7] rtlwifi: Make retry limits depend on vif type

From: pkshih <[email protected]>

Making the retry limits depend on the vif type can boost performance.

Signed-off-by: pkshih <[email protected]>
Signed-off-by: shaofu <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
---
V2 - no changes
---
drivers/net/wireless/rtlwifi/core.c | 19 +++++++++++++++----
drivers/net/wireless/rtlwifi/pci.c | 8 +++++++-
drivers/net/wireless/rtlwifi/ps.c | 3 +++
3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 3b3a88b..19729ed 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -238,6 +238,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
int err = 0;
+ u8 retry_limit = 0x30;

if (mac->vif) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
@@ -275,7 +276,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
mac->basic_rates = 0xff0;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
(u8 *)(&mac->basic_rates));
-
+ retry_limit = 0x07;
break;
case NL80211_IFTYPE_P2P_GO:
mac->p2p = P2P_ROLE_GO;
@@ -292,6 +293,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
mac->basic_rates = 0xff0;
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
(u8 *)(&mac->basic_rates));
+ retry_limit = 0x07;
break;
case NL80211_IFTYPE_MESH_POINT:
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
@@ -326,6 +328,10 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
memcpy(mac->mac_addr, vif->addr, ETH_ALEN);
rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);

+ mac->retry_long = retry_limit;
+ mac->retry_short = retry_limit;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ (u8 *)(&retry_limit));
out:
mutex_unlock(&rtlpriv->locks.conf_mutex);
return err;
@@ -650,10 +656,15 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
"IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
hw->conf.long_frame_max_tx_count);
- mac->retry_long = hw->conf.long_frame_max_tx_count;
- mac->retry_short = hw->conf.long_frame_max_tx_count;
- rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ /* On first open, everything changes (changed == ~0),
+ * so use our default value instead of wiphy's one.
+ */
+ if (changed != ~0) {
+ mac->retry_long = hw->conf.long_frame_max_tx_count;
+ mac->retry_short = hw->conf.long_frame_max_tx_count;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
(u8 *)(&hw->conf.long_frame_max_tx_count));
+ }
}

if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index f46c9d7..a621d7d 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1227,6 +1227,10 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw,
mac->current_ampdu_density = 7;
mac->current_ampdu_factor = 3;

+ /* Retry Limit */
+ mac->retry_short = 7;
+ mac->retry_long = 7;
+
/*QOS*/
rtlpci->acm_method = EACMWAY2_SW;

@@ -1833,7 +1837,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
-
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
int err;

rtl_pci_reset_trx_ring(hw);
@@ -1850,6 +1854,8 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
"Failed to config hardware!\n");
return err;
}
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ &rtlmac->retry_long);

rtlpriv->cfg->ops->enable_interrupt(hw);
RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n");
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index b69321d..b6b6834 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -34,6 +34,7 @@ bool rtl_ps_enable_nic(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));
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));

/*<1> reset trx ring */
if (rtlhal->interface == INTF_PCI)
@@ -46,6 +47,8 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
/*<2> Enable Adapter */
if (rtlpriv->cfg->ops->hw_init(hw))
return false;
+ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+ &rtlmac->retry_long);
RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);

/*<3> Enable Interrupt */
--
2.1.4