2015-09-09 16:48:05

by Bob Copeland

[permalink] [raw]
Subject: [PATCH v3 1/3] ath10k: enable monitor when OTHER_BSS requested

By default, ath10k restricts received frames to those matching BSSID.
When other BSS frames are requested (e.g. in mesh mode), add an internal
monitor device so those frames are not filtered.

Signed-off-by: Bob Copeland <[email protected]>
---
drivers/net/wireless/ath/ath10k/mac.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 989d2a1..80efcc8 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1070,6 +1070,7 @@ static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
return false;

return ar->monitor ||
+ ar->filter_flags & FIF_OTHER_BSS ||
test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
}

--
2.1.4



2015-09-09 16:48:12

by Bob Copeland

[permalink] [raw]
Subject: [PATCH v3 2/3] ath10k: check for encryption before adding MIC_LEN

In the case of raw mode without nohwcrypt parameter, we
should still make sure the frame is protected before
adding MIC_LEN to avoid skb_under_panic errors.

Signed-off-by: Bob Copeland <[email protected]>
---
drivers/net/wireless/ath/ath10k/htt_tx.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index ea53c21..eb5ba9b 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -564,7 +564,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!skb_cb->htt.nohwcrypt &&
- skb_cb->txmode == ATH10K_HW_TXRX_RAW) {
+ skb_cb->txmode == ATH10K_HW_TXRX_RAW &&
+ ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}

--
2.1.4


2015-09-09 16:48:05

by Bob Copeland

[permalink] [raw]
Subject: [PATCH v3 3/3] ath10k: implement mesh support

Add support for mesh to ath10k. We simply use an AP virtual interface
in the firmware in order to enable beaconing without TSF adoption, and
use the raw (802.11) transmit mode.

Due to firmware limitations, the firmware must operate in raw
(non-native 802.11) mode. As this is configured at firmware init time,
a new "rawmode" modparam is added, and mesh interfaces are available
only if rawmode=true. The firmware must advertise support for rawmode;
tested successfully with firmware 10.2.4.70-2.

When the module is loaded with (newly implemented) modparam rawmode=1, it
will enable operating an open mesh STA via something like the following:

ip link set wlan0 down
iw dev wlan0 set type mp
ip link set wlan0 up
iw dev wlan0 set freq 5745 80 5775
iw dev wlan0 mesh join mesh-vht

Signed-off-by: Bob Copeland <[email protected]>
---
v3:
* fix cfg80211 interface combinations warning when
CONFIG_MAC80211_MESH=n or when using 10.4 FW (Kalle Valo)
v2:
* added raw mode feature flag check
* usage and firmware notes in commit log

drivers/net/wireless/ath/ath10k/core.c | 12 ++++++++++++
drivers/net/wireless/ath/ath10k/mac.c | 36 +++++++++++++++++++++++++++++++++-
2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 6e5033b..09a74a8 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -34,16 +34,19 @@ unsigned int ath10k_debug_mask;
static unsigned int ath10k_cryptmode_param;
static bool uart_print;
static bool skip_otp;
+static bool rawmode;

module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
module_param(uart_print, bool, 0644);
module_param(skip_otp, bool, 0644);
+module_param(rawmode, bool, 0644);

MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
+MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");

static const struct ath10k_hw_params ath10k_hw_params_list[] = {
{
@@ -1122,6 +1125,15 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;

+ if (rawmode) {
+ if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
+ ar->fw_features)) {
+ ath10k_err(ar, "rawmode = 1 requires support from firmware");
+ return -EINVAL;
+ }
+ set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
+ }
+
if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW;

diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 80efcc8..1cda4f9 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4211,6 +4211,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
case NL80211_IFTYPE_ADHOC:
arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
+ ret = -EINVAL;
+ ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
+ goto err;
+ }
+ arvif->vdev_type = WMI_VDEV_TYPE_AP;
+ break;
case NL80211_IFTYPE_AP:
arvif->vdev_type = WMI_VDEV_TYPE_AP;

@@ -4251,6 +4259,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
* become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
*/
if (vif->type == NL80211_IFTYPE_ADHOC ||
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
vif->type == NL80211_IFTYPE_AP) {
arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
IEEE80211_MAX_FRAME_LEN,
@@ -4590,6 +4599,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
if (ret)
ath10k_warn(ar, "failed to update beacon template: %d\n",
ret);
+
+ if (ieee80211_vif_is_mesh(vif)) {
+ /* mesh doesn't use SSID but firmware needs it */
+ strncpy(arvif->u.ap.ssid, "mesh",
+ sizeof(arvif->u.ap.ssid));
+ arvif->u.ap.ssid_len = 4;
+ }
}

if (changed & BSS_CHANGED_AP_PROBE_RESP) {
@@ -5329,6 +5345,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
} else if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC &&
(vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
vif->type == NL80211_IFTYPE_ADHOC)) {
/*
* New association.
@@ -5364,6 +5381,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
} else if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTH &&
(vif->type == NL80211_IFTYPE_AP ||
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
vif->type == NL80211_IFTYPE_ADHOC)) {
/*
* Disassociation.
@@ -6678,6 +6696,9 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
{
.max = 7,
.types = BIT(NL80211_IFTYPE_AP)
+#ifdef CONFIG_MAC80211_MESH
+ | BIT(NL80211_IFTYPE_MESH_POINT)
+#endif
},
};

@@ -6685,6 +6706,9 @@ static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
{
.max = 8,
.types = BIT(NL80211_IFTYPE_AP)
+#ifdef CONFIG_MAC80211_MESH
+ | BIT(NL80211_IFTYPE_MESH_POINT)
+#endif
},
};

@@ -6722,6 +6746,9 @@ static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
{
.max = 2,
.types = BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO),
},
@@ -6743,6 +6770,9 @@ static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
{
.max = 1,
.types = BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
BIT(NL80211_IFTYPE_P2P_GO),
},
{
@@ -6809,6 +6839,9 @@ static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
{
.max = 16,
.types = BIT(NL80211_IFTYPE_AP)
+#ifdef CONFIG_MAC80211_MESH
+ | BIT(NL80211_IFTYPE_MESH_POINT)
+#endif
},
};

@@ -7033,7 +7066,8 @@ int ath10k_mac_register(struct ath10k *ar)

ar->hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP);
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_MESH_POINT);

ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;
ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;
--
2.1.4


2015-09-17 10:58:04

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v3 1/3] ath10k: enable monitor when OTHER_BSS requested

Bob Copeland <[email protected]> writes:

> By default, ath10k restricts received frames to those matching BSSID.
> When other BSS frames are requested (e.g. in mesh mode), add an internal
> monitor device so those frames are not filtered.
>
> Signed-off-by: Bob Copeland <[email protected]>

Thanks, all three patches applied. In patch 3 I just changed the
firmware version in commit log to 10.2.4.70.6-2 as that one has the raw
mode feature flag enabled.

I also tested this myself and I was able to join to a mesh network I
created with ath9k and ping each other. In case someone cherry picks
these patches please take into account that these patches need quite a
few recent mac80211 patches from mac80211-next. The patches are also in
wireless-testing and ath.git master branch. Safest is to test with
ath.git master branch.

--
Kalle Valo