Skip to content

Commit

Permalink
ath10k: Improve PMF/MPF mgt frame check
Browse files Browse the repository at this point in the history
And add a driver for 5.2 (beta, not even tested yet) kernel.
  • Loading branch information
greearb committed Jun 13, 2019
1 parent 8c08f2a commit a045b1c
Show file tree
Hide file tree
Showing 66 changed files with 341 additions and 68 deletions.
42 changes: 39 additions & 3 deletions ath10k-4.16/htt_tx.c
Expand Up @@ -1065,6 +1065,44 @@ static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
}

/* Copied from ieee80211_is_robust_mgmt_frame, but disable the check for has_protected
* since we do tx hw crypt, and it won't actually be encrypted even when this flag is
* set.
*/
bool ieee80211_is_robust_mgmt_frame_tx(struct ieee80211_hdr *hdr)
{
if (ieee80211_is_disassoc(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control))
return true;

if (ieee80211_is_action(hdr->frame_control)) {
u8 *category;

/*
* Action frames, excluding Public Action frames, are Robust
* Management Frames. However, if we are looking at a Protected
* frame, skip the check since the data may be encrypted and
* the frame has already been found to be a Robust Management
* Frame (by the other end).
*/
/*
if (ieee80211_has_protected(hdr->frame_control))
return true;
*/
category = ((u8 *) hdr) + 24;
return *category != WLAN_CATEGORY_PUBLIC &&
*category != WLAN_CATEGORY_HT &&
*category != WLAN_CATEGORY_WNM_UNPROTECTED &&
*category != WLAN_CATEGORY_SELF_PROTECTED &&
*category != WLAN_CATEGORY_UNPROT_DMG &&
*category != WLAN_CATEGORY_VHT &&
*category != WLAN_CATEGORY_VENDOR_SPECIFIC;
}

return false;
}


int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
Expand Down Expand Up @@ -1327,9 +1365,7 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
}

if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)) {
if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
if (ieee80211_is_robust_mgmt_frame_tx(hdr) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (txmode == ATH10K_HW_TXRX_RAW &&
Expand Down
42 changes: 39 additions & 3 deletions ath10k-4.19/htt_tx.c
Expand Up @@ -1065,6 +1065,44 @@ static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
}

/* Copied from ieee80211_is_robust_mgmt_frame, but disable the check for has_protected
* since we do tx hw crypt, and it won't actually be encrypted even when this flag is
* set.
*/
bool ieee80211_is_robust_mgmt_frame_tx(struct ieee80211_hdr *hdr)
{
if (ieee80211_is_disassoc(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control))
return true;

if (ieee80211_is_action(hdr->frame_control)) {
u8 *category;

/*
* Action frames, excluding Public Action frames, are Robust
* Management Frames. However, if we are looking at a Protected
* frame, skip the check since the data may be encrypted and
* the frame has already been found to be a Robust Management
* Frame (by the other end).
*/
/*
if (ieee80211_has_protected(hdr->frame_control))
return true;
*/
category = ((u8 *) hdr) + 24;
return *category != WLAN_CATEGORY_PUBLIC &&
*category != WLAN_CATEGORY_HT &&
*category != WLAN_CATEGORY_WNM_UNPROTECTED &&
*category != WLAN_CATEGORY_SELF_PROTECTED &&
*category != WLAN_CATEGORY_UNPROT_DMG &&
*category != WLAN_CATEGORY_VHT &&
*category != WLAN_CATEGORY_VENDOR_SPECIFIC;
}

return false;
}


int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
Expand Down Expand Up @@ -1323,9 +1361,7 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
}

if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)) {
if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
if (ieee80211_is_robust_mgmt_frame_tx(hdr) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (txmode == ATH10K_HW_TXRX_RAW &&
Expand Down
42 changes: 39 additions & 3 deletions ath10k-4.20/htt_tx.c
Expand Up @@ -1119,6 +1119,44 @@ static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
}

/* Copied from ieee80211_is_robust_mgmt_frame, but disable the check for has_protected
* since we do tx hw crypt, and it won't actually be encrypted even when this flag is
* set.
*/
bool ieee80211_is_robust_mgmt_frame_tx(struct ieee80211_hdr *hdr)
{
if (ieee80211_is_disassoc(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control))
return true;

if (ieee80211_is_action(hdr->frame_control)) {
u8 *category;

/*
* Action frames, excluding Public Action frames, are Robust
* Management Frames. However, if we are looking at a Protected
* frame, skip the check since the data may be encrypted and
* the frame has already been found to be a Robust Management
* Frame (by the other end).
*/
/*
if (ieee80211_has_protected(hdr->frame_control))
return true;
*/
category = ((u8 *) hdr) + 24;
return *category != WLAN_CATEGORY_PUBLIC &&
*category != WLAN_CATEGORY_HT &&
*category != WLAN_CATEGORY_WNM_UNPROTECTED &&
*category != WLAN_CATEGORY_SELF_PROTECTED &&
*category != WLAN_CATEGORY_UNPROT_DMG &&
*category != WLAN_CATEGORY_VHT &&
*category != WLAN_CATEGORY_VENDOR_SPECIFIC;
}

return false;
}


int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
{
struct ath10k *ar = htt->ar;
Expand Down Expand Up @@ -1467,9 +1505,7 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
}

if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)) {
if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
if (ieee80211_is_robust_mgmt_frame_tx(hdr) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (txmode == ATH10K_HW_TXRX_RAW &&
Expand Down
1 change: 1 addition & 0 deletions ath10k-5.1/Kconfig → ath10k-5.2/Kconfig
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
config ATH10K
tristate "Atheros 802.11ac wireless cards support"
depends on MAC80211 && HAS_DMA
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion ath10k-5.1/ce.c → ath10k-5.2/ce.c
Expand Up @@ -1855,7 +1855,7 @@ void ath10k_ce_dump_registers(struct ath10k *ar,
struct ath10k_ce_crash_data ce_data;
u32 addr, id;

lockdep_assert_held(&ar->data_lock);
lockdep_assert_held(&ar->dump_mutex);

ath10k_err(ar, "Copy Engine register dump:\n");

Expand Down
File renamed without changes.
31 changes: 25 additions & 6 deletions ath10k-5.1/core.c → ath10k-5.2/core.c
Expand Up @@ -1751,7 +1751,7 @@ int ath10k_core_fetch_board_file(struct ath10k *ar, int bd_ie_type)
int offset = (ar->hw_params.cal_data_len - (addrs * 4)) / 4; /* Start of configAddr */
/*ath10k_dbg(ar, ATH10K_DBG_BOOT, "Check saving eeprom configAddr from board-data\n");*/
for (i = 0; i<addrs; i++) {
ar->eeprom_configAddrs[i] = e32[offset + i];
ar->eeprom_configAddrs[i] = le32_to_cpu(e32[offset + i]);
if (ar->eeprom_configAddrs[i]) {
ath10k_dbg(ar, ATH10K_DBG_BOOT, "saving eeprom configAddr[%i]: 0x%08x\n",
i, ar->eeprom_configAddrs[i]);
Expand Down Expand Up @@ -3395,6 +3395,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_DISABLE_IBSS_CCA,
ar->eeprom_overrides.disable_ibss_cca);

if (ar->eeprom_overrides.peer_stats_pn)
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_PEER_STATS_PN,
ar->eeprom_overrides.peer_stats_pn);

if (ar->eeprom_overrides.su_sounding_timer_ms)
ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->txbf_sound_period_cmdid,
ar->eeprom_overrides.su_sounding_timer_ms);
Expand All @@ -3409,15 +3413,29 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
ath10k_wmi_pdev_set_fwtest(ar, 20,
ar->eeprom_overrides.rc_txbf_probe);

for (i = 0; i<ARRAY_SIZE(ar->eeprom_configAddrs); i += 2) {
for (i = 0; i<ARRAY_SIZE(ar->eeprom_configAddrs); ) {
if (ar->eeprom_configAddrs[i]) {
ath10k_dbg(ar, ATH10K_DBG_BOOT, "Applying eeprom configAddr[%i]: 0x%08x 0x%08x\n",
i, ar->eeprom_configAddrs[i], ar->eeprom_configAddrs[i+1]);
#define CONFIG_ADDR_MODE_SHIFT 20
int mode = (ar->eeprom_configAddrs[i] >> CONFIG_ADDR_MODE_SHIFT) & 0x3;
int count = 1; /* one value applied to both 2G and 5G modes */
int q;

if (mode == 2) /* 2G, 5G value tuple */
count = 2;
else if (mode == 3) /* 2G_VHT20, 2G_VHT40, 5G_VHT20, 5G_VHT40, 5G_VHT80/160/80+80 */
count = 5;
ath10k_dbg(ar, ATH10K_DBG_BOOT, "Applying eeprom configAddr[%i]: mode: %d count: %d 0x%08x 0x%08x 0x%08x\n",
i, mode, count, ar->eeprom_configAddrs[i], ar->eeprom_configAddrs[i+1],
(count >= 2) ? ar->eeprom_configAddrs[i+2] : 0);

ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_EEPROM_CFG_ADDR_A,
ar->eeprom_configAddrs[i]);
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_EEPROM_CFG_ADDR_V,
ar->eeprom_configAddrs[i+1]);
for (q = 0; q<count; q++) {
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_EEPROM_CFG_ADDR_V,
ar->eeprom_configAddrs[i + q + 1]);
}

i += (count + 1);
}
else {
break;
Expand Down Expand Up @@ -3856,6 +3874,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
goto err_free_wq;

mutex_init(&ar->conf_mutex);
mutex_init(&ar->dump_mutex);
spin_lock_init(&ar->data_lock);

INIT_LIST_HEAD(&ar->peers);
Expand Down
4 changes: 4 additions & 0 deletions ath10k-5.1/core.h → ath10k-5.2/core.h
Expand Up @@ -1337,6 +1337,9 @@ struct ath10k {
/* prevents concurrent FW reconfiguration */
struct mutex conf_mutex;

/* protects coredump data */
struct mutex dump_mutex;

/* protects shared structure data */
spinlock_t data_lock;

Expand Down Expand Up @@ -1500,6 +1503,7 @@ struct ath10k {
bool rx_all_mgt;
bool apply_board_power_ctl_table;
u8 disable_ibss_cca;
u8 peer_stats_pn;
u8 rc_txbf_probe;
#define CT_DISABLE_20MHZ 0x1
#define CT_DISABLE_40MHZ 0x2
Expand Down
7 changes: 4 additions & 3 deletions ath10k-5.1/coredump.c → ath10k-5.2/coredump.c
Expand Up @@ -1102,7 +1102,7 @@ struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar)
{
struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data;

lockdep_assert_held(&ar->data_lock);
lockdep_assert_held(&ar->dump_mutex);

if (ath10k_coredump_mask == 0)
/* coredump disabled */
Expand Down Expand Up @@ -1163,7 +1163,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)
if (!buf)
return NULL;

spin_lock_bh(&ar->data_lock);
mutex_lock(&ar->dump_mutex);

dump_data = (struct ath10k_dump_file_data *)(buf);
strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP",
Expand Down Expand Up @@ -1290,7 +1290,8 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar)

WARN_ON(sofar != len);

spin_unlock_bh(&ar->data_lock);

mutex_unlock(&ar->dump_mutex);

return dump_data;
}
Expand Down
File renamed without changes.
9 changes: 8 additions & 1 deletion ath10k-5.1/debug.c → ath10k-5.2/debug.c
Expand Up @@ -3393,6 +3393,11 @@ static ssize_t ath10k_write_ct_special(struct file *file,
/* Not stored in driver, will not be restored upon FW crash/restart */
ath10k_warn(ar, "Adding EEPROM configAddr value setting 0x08%x.\n", val);
}
else if (id == SET_SPECIAL_ID_PEER_STATS_PN) {
ar->eeprom_overrides.peer_stats_pn = val;
ath10k_warn(ar, "Setting peer-stats-pn to %d\n",
ar->eeprom_overrides.peer_stats_pn);
}
/* Below here are local driver hacks, and not necessarily passed directly to firmware. */
else if (id == 0x1001) {
/* Set station failed-transmit kickout threshold. */
Expand Down Expand Up @@ -3506,7 +3511,9 @@ static ssize_t ath10k_read_ct_special(struct file *file,
"id: 0x11 allow tx-hang logic to try cold resets instead of just warm resets.\n"
"id: 0x12 disable special CCA setting for IBSS queues.\n"
"id: 0x13 set 5-bit antenna-mask for peer, format: (peer-id << 16) | ant_mask\n"
"id: 0x14 Add a 32-bit sticky register / value override to the eeprom."
"id: 0x14 Add a 32-bit sticky register address override to the eeprom."
"id: 0x15 Add a 32-bit sticky register value override to the eeprom."
"id: 0x16 Enable/Disable reporting PN in peer-stats."
"\nBelow here should work with most firmware, including non-CT firmware.\n"
"id: 0x1001 set sta-kickout threshold due to tx-failures (0 means disable. Default is 20 * 16.)\n"
"id: 0x1002 set su-sounding-timer-ms (0 means use defaults next FW reload. Default is 100, max is 500)\n"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit a045b1c

Please sign in to comment.