diff mbox

[3/3] ath10k: implement mesh support

Message ID 1439738757-29199-4-git-send-email-me@bobcopeland.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Bob Copeland Aug. 16, 2015, 3:25 p.m. UTC
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.

Signed-off-by: Bob Copeland <me@bobcopeland.com>
---
 drivers/net/wireless/ath/ath10k/core.c |  6 ++++++
 drivers/net/wireless/ath/ath10k/mac.c  | 33 ++++++++++++++++++++++++++++-----
 2 files changed, 34 insertions(+), 5 deletions(-)

Comments

Harms, Hannes Aug. 17, 2015, 11:06 a.m. UTC | #1
Hi,

I am trying to set up the latest Kernel (4.2rc6) and firmware 
(10.1.467-ct-14) form Candela for a 5Ghz network.
Unfortunately I am not able to set channels above 100, although 
regulatory domain is set to DE.
Maybe someone has an advice what is going wrong?

Regards
Hannes

My configuration:

Debian with Kernel 4.2-rc6  form Candela (self compiled)
Firmware: 10.1.467-ct-14

iw reg get
country DE: DFS-ETSI
     (2400 - 2483 @ 40), (N/A, 20), (N/A)
     (5150 - 5250 @ 80), (N/A, 20), (N/A), NO-OUTDOOR
     (5250 - 5350 @ 80), (N/A, 20), (0 ms), NO-OUTDOOR, DFS
     (5470 - 5725 @ 160), (N/A, 26), (0 ms), DFS
     (57000 - 66000 @ 2160), (N/A, 40), (N/A)

iw list
     Frequencies:
             * 5180 MHz [36] (17.0 dBm)
             * 5200 MHz [40] (17.0 dBm)
             * 5220 MHz [44] (17.0 dBm)
             * 5240 MHz [48] (17.0 dBm)
             * 5260 MHz [52] (20.0 dBm) (no IR, radar detection)
               DFS state: usable (for 550 sec)
               DFS CAC time: 60000 ms
             * 5280 MHz [56] (20.0 dBm) (no IR, radar detection)
               DFS state: usable (for 550 sec)
               DFS CAC time: 60000 ms
             * 5300 MHz [60] (20.0 dBm) (no IR, radar detection)
               DFS state: usable (for 550 sec)
               DFS CAC time: 60000 ms
             * 5320 MHz [64] (20.0 dBm) (no IR, radar detection)
               DFS state: usable (for 550 sec)
               DFS CAC time: 60000 ms
             * 5500 MHz [100] (disabled)
             * 5520 MHz [104] (disabled)
             * 5540 MHz [108] (disabled)
             * 5560 MHz [112] (disabled)
             * 5580 MHz [116] (disabled)
             * 5600 MHz [120] (disabled)
             * 5620 MHz [124] (disabled)
             * 5640 MHz [128] (disabled)
             * 5660 MHz [132] (disabled)
             * 5680 MHz [136] (disabled)
             * 5700 MHz [140] (disabled)
             * 5720 MHz [144] (disabled)
             * 5745 MHz [149] (disabled)
             * 5765 MHz [153] (disabled)
             * 5785 MHz [157] (disabled)
             * 5805 MHz [161] (disabled)
             * 5825 MHz [165] (disabled)
Kalle Valo Aug. 18, 2015, 11:54 a.m. UTC | #2
"Harms, Hannes" <hannes.harms@tu-bs.de> writes:

> I am trying to set up the latest Kernel (4.2rc6) and firmware
> (10.1.467-ct-14) form Candela for a 5Ghz network.
> Unfortunately I am not able to set channels above 100, although
> regulatory domain is set to DE.
> Maybe someone has an advice what is going wrong?

Btw, please don't hijack threads (ie. reply to an existing thread and
change subject) as it confuses patchwork[1]. Instead start a new thread.

[1] https://patchwork.kernel.org/patch/7023511/
Ben Greear Aug. 18, 2015, 2:52 p.m. UTC | #3
On 08/18/2015 04:54 AM, Kalle Valo wrote:
> "Harms, Hannes" <hannes.harms@tu-bs.de> writes:
>
>> I am trying to set up the latest Kernel (4.2rc6) and firmware
>> (10.1.467-ct-14) form Candela for a 5Ghz network.
>> Unfortunately I am not able to set channels above 100, although
>> regulatory domain is set to DE.
>> Maybe someone has an advice what is going wrong?

This is unlikely to be a firmware issue, as we routinely run on channel 149.

Have you tried an older kernel to see if it is a regression somewhere in
the stack/driver?

Thanks,
Ben

>
> Btw, please don't hijack threads (ie. reply to an existing thread and
> change subject) as it confuses patchwork[1]. Instead start a new thread.
>
> [1] https://patchwork.kernel.org/patch/7023511/
>
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 2551067..e176bb4 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[] = {
 	{
@@ -1101,6 +1104,9 @@  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)
+		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 5c85896..72b0589 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4153,6 +4153,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;
 
@@ -4193,6 +4201,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,
@@ -4527,6 +4536,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) {
@@ -5266,6 +5282,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.
@@ -5301,6 +5318,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.
@@ -6614,14 +6632,16 @@  static const struct ieee80211_iface_limit ath10k_if_limits[] = {
 	},
 	{
 	.max	= 7,
-	.types	= BIT(NL80211_IFTYPE_AP)
+	.types	= BIT(NL80211_IFTYPE_AP) |
+		  BIT(NL80211_IFTYPE_MESH_POINT)
 	},
 };
 
 static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
 	{
 	.max	= 8,
-	.types	= BIT(NL80211_IFTYPE_AP)
+	.types	= BIT(NL80211_IFTYPE_AP) |
+		  BIT(NL80211_IFTYPE_MESH_POINT)
 	},
 };
 
@@ -6660,7 +6680,8 @@  static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
 		.max = 2,
 		.types = BIT(NL80211_IFTYPE_AP) |
 			 BIT(NL80211_IFTYPE_P2P_CLIENT) |
-			 BIT(NL80211_IFTYPE_P2P_GO),
+			 BIT(NL80211_IFTYPE_P2P_GO) |
+			 BIT(NL80211_IFTYPE_MESH_POINT)
 	},
 	{
 		.max = 1,
@@ -6680,7 +6701,8 @@  static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
 	{
 		.max = 1,
 		.types = BIT(NL80211_IFTYPE_AP) |
-			 BIT(NL80211_IFTYPE_P2P_GO),
+			 BIT(NL80211_IFTYPE_P2P_GO) |
+			 BIT(NL80211_IFTYPE_MESH_POINT),
 	},
 	{
 		.max = 1,
@@ -6970,7 +6992,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;