Linux wireless drivers development
 help / color / mirror / Atom feed
* merge window warning
From: David Miller @ 2013-09-04 17:10 UTC (permalink / raw)
  To: netdev; +Cc: linux-wireless, netfilter-devel


The merge window is now open.

This means if a feature patch isn't in patchwork already, and
completely ready to apply, you should not submit it at this time.

I will just automatically reject any inappropriate patches sent from
now until the net-next tree opens again after the merge window closes,
in order to assist with my ability to process the current backlog
efficiently.

Thanks.


^ permalink raw reply

* Re: [PATCH net-hext] wireless: scan: Remove comment to compare_ether_addr
From: David Miller @ 2013-09-04  2:35 UTC (permalink / raw)
  To: joe; +Cc: johannes, linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <1378075707.1953.29.camel@joe-AO722>

From: Joe Perches <joe@perches.com>
Date: Sun, 01 Sep 2013 15:48:27 -0700

> This function is being removed, so remove the reference to it.
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next] drivers/net: Convert uses of compare_ether_addr to ether_addr_equal
From: David Miller @ 2013-09-04  2:28 UTC (permalink / raw)
  To: joe; +Cc: netdev, e1000-devel, linux-kernel, linux-wireless, users
In-Reply-To: <1378061483.1953.3.camel@joe-AO722>

From: Joe Perches <joe@perches.com>
Date: Sun, 01 Sep 2013 11:51:23 -0700

> Use the new bool function ether_addr_equal to add
> some clarity and reduce the likelihood for misuse
> of compare_ether_addr for sorting.
> 
> Done via cocci script: (and a little typing)
 ...
> Signed-off-by: Joe Perches <joe@perches.com>

Applied, thanks Joe.

^ permalink raw reply

* Re: pull request: wireless-next 2013-08-29
From: David Miller @ 2013-09-04  1:46 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev
In-Reply-To: <20130829185352.GB2300@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Thu, 29 Aug 2013 14:53:53 -0400

> Please accept this batch of updates intended for the 3.12 stream.

Pulled, thanks John.

^ permalink raw reply

* Re: [PATCH v2 net-next 0/9] set addr_assign_type when inheriting a dev_addr
From: David Miller @ 2013-09-04  1:41 UTC (permalink / raw)
  To: bjorn
  Cc: netdev, kaber, jiri, linville, linux-wireless, j, libertas-dev,
	gregkh, devel, forest, stephen, dan.carpenter
In-Reply-To: <87mwnuqrrx.fsf@nemi.mork.no>

From: Bjørn Mork <bjorn@mork.no>
Date: Tue, 03 Sep 2013 09:38:10 +0200

> But it doesn't look like it ended up in net-next?  Or am I missing
> something (again)?

I forgot to push it out from my workstation before going away for the
holiday weekend, this has now been fixed :-)

^ permalink raw reply

* [PATCH v2] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
From: Alexey Khoroshilov @ 2013-09-03 20:37 UTC (permalink / raw)
  To: Hin-Tak Leung, Larry Finger
  Cc: Alexey Khoroshilov, John W. Linville, linux-wireless, netdev,
	linux-kernel, ldv-project

In case of __dev_alloc_skb() failure rtl8187_init_urbs()
calls usb_free_urb(entry) where 'entry' can points to urb
allocated at the previous iteration. That means refcnt will be
decremented incorrectly and the urb can be used after memory
deallocation.

The patch fixes the issue and implements error handling of init_urbs
in rtl8187_start().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
 drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index f49220e..a668c0e 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
 		skb_queue_tail(&priv->rx_queue, skb);
 		usb_anchor_urb(entry, &priv->anchored);
 		ret = usb_submit_urb(entry, GFP_KERNEL);
+		usb_put_urb(entry);
 		if (ret) {
 			skb_unlink(skb, &priv->rx_queue);
 			usb_unanchor_urb(entry);
 			goto err;
 		}
-		usb_free_urb(entry);
 	}
 	return ret;
 
 err:
-	usb_free_urb(entry);
 	kfree_skb(skb);
 	usb_kill_anchored_urbs(&priv->anchored);
 	return ret;
@@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 				  (RETRY_COUNT << 8  /* short retry limit */) |
 				  (RETRY_COUNT << 0  /* long retry limit */) |
 				  (7 << 21 /* MAX TX DMA */));
-		rtl8187_init_urbs(dev);
-		rtl8187b_init_status_urb(dev);
+		ret = rtl8187_init_urbs(dev);
+		if (ret)
+			goto rtl8187_start_exit;
+		ret = rtl8187b_init_status_urb(dev);
+		if (ret)
+			usb_kill_anchored_urbs(&priv->anchored);
 		goto rtl8187_start_exit;
 	}
 
@@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 	rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
 	rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
 
-	rtl8187_init_urbs(dev);
+	ret = rtl8187_init_urbs(dev);
+	if (ret)
+		goto rtl8187_start_exit;
 
 	reg = RTL818X_RX_CONF_ONLYERLPKT |
 	      RTL818X_RX_CONF_RX_AUTORESETPHY |
-- 
1.8.1.2


^ permalink raw reply related

* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
From: Alexey Khoroshilov @ 2013-09-03 20:09 UTC (permalink / raw)
  To: htl10
  Cc: larry.finger, linville, linux-wireless, netdev, linux-kernel,
	ldv-project, gregkh
In-Reply-To: <1378103685.43571.YahooMailBasic@web172301.mail.ir2.yahoo.com>

On 02.09.2013 10:34, Hin-Tak Leung wrote:
> ------------------------------
> On Mon, Sep 2, 2013 05:06 BST Alexey Khoroshilov wrote:
>
>> On 01.09.2013 10:51, Hin-Tak Leung wrote:
>>> ------------------------------
>>> On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:
>>>
>>> In case of __dev_alloc_skb() failure rtl8187_init_urbs()
>>> calls usb_free_urb(entry) where 'entry' can points to urb
>>> allocated at the previous iteration. That means refcnt will be
>>> decremented incorrectly and the urb can be used after memory
>>> deallocation.
>>>
>>> The patch fixes the issue and implements error handling of init_urbs
>>> in rtl8187_start().
>>>
>>> Found by Linux Driver Verification project (linuxtesting.org).
>>>
>>> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
>>> ---
>>> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
>>> 1 file changed, 10 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>>> index f49220e..e83d53c 100644
>>> --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>>> +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>>> @@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
>>>            skb_queue_tail(&priv->rx_queue, skb);
>>>            usb_anchor_urb(entry, &priv->anchored);
>>>            ret = usb_submit_urb(entry, GFP_KERNEL);
>>> +        usb_free_urb(entry);
>>>            if (ret) {
>>>                skb_unlink(skb, &priv->rx_queue);
>>>                usb_unanchor_urb(entry);
>>>                goto err;
>>>            }
>>> -        usb_free_urb(entry);
>>>        }
>>>        return ret;
>>>
>>> err:
>>> -    usb_free_urb(entry);
>>>        kfree_skb(skb);
>>>        usb_kill_anchored_urbs(&priv->anchored);
>>>        return ret;
>>> This part looks wrong - you free_urb(entry) then unanchor_urb(entry).
>> I do not see any problems here.
>> usb_free_urb() just decrements refcnt of the urb.
>> While usb_anchor_urb() and usb_unanchor_urb() increment and decrement it
>> as well.
>> So actual memory deallocation will happen in usb_unanchor_urb().
> If the routines work as you say, they probably are misnamed, and/or prototyped wrongly?
> Also, you are making assumptions about how they are implemented, and relying
> on the implementation details to be fixed for eternity.
>
> I am just saying,
>
> XXX_free(some_entity);
> if(condtion)
>       do_stuff(some_entity);
>
> looks wrong, and if that's intentional, those routines really shouldn't be named as such.
There is an alias for usb_free_urb() named usb_put_urb().
I will resend the patch with such substitution.

--
Alexey

^ permalink raw reply

* Re: [PATCH] brcmfmac: fix bus interface selection in Kconfig
From: Randy Dunlap @ 2013-09-03 19:43 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: John W. Linville, linux-wireless, Hauke Mehrtens
In-Reply-To: <1378212369-17166-1-git-send-email-arend@broadcom.com>

On 09/03/13 05:46, Arend van Spriel wrote:
> The kernel configuration for the driver could result in
> compilation issues as reported by Randy Dunlap. His results
> are show below:
> 
> "on x86_64:
> 
> when
> CONFIG_MMC=m
> CONFIG_BRCMUTIL=y
> CONFIG_BRCMFMAC=y
> CONFIG_BRCMFMAC_SDIO=y
> 
> This bool kconfig symbol:
> 
> config BRCMFMAC_SDIO
> 	bool "SDIO bus interface support for FullMAC driver"
> 	depends on MMC
> 
> allows BRCMFMAC_SDIO to be y even when MMC=m.
> 
> Is there a reasonable solution to this?
> 
> This causes many build errors:
> 
> drivers/built-in.o: In function `brcmf_sdio_assert_info':
> dhd_sdio.c:(.text+0x39609b): undefined reference to `sdio_claim_host'
> dhd_sdio.c:(.text+0x3960d9): undefined reference to `sdio_release_host'
> drivers/built-in.o: In function `brcmf_sdio_readframes':
> dhd_sdio.c:(.text+0x396a62): undefined reference to `sdio_claim_host'
> dhd_sdio.c:(.text+0x396a9b): undefined reference to `sdio_release_host'
> ..."
> 
> This patch adds the appropriate logic in Kconfig to resolve
> these issues. The solution was provided by Hauke Mehrtens.
> 
> Reported-by: Randy Dunlap <rdunlap@infradead.org>
> Cc: Hauke Mehrtens <hauke@hauke-m.de>
> Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
> Signed-off-by: Arend van Spriel <arend@broadcom.com>

Acked-by: Randy Dunlap <rdunlap@infradead.org>

Thanks.


> ---
> Hi John,
> 
> Probably the merge window has already been started after the surpirse release
> of 3.11, but this one was reported by Randy Dunlap on linux-next tree and
> earlier today by Fenguang Wu. Maybe good to take it in the wireless-next tree.
> 
> Regards,
> Arend
> ---
>  drivers/net/wireless/brcm80211/Kconfig |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
> index fc8a0fa..b00a7e9 100644
> --- a/drivers/net/wireless/brcm80211/Kconfig
> +++ b/drivers/net/wireless/brcm80211/Kconfig
> @@ -28,7 +28,7 @@ config BRCMFMAC
>  
>  config BRCMFMAC_SDIO
>  	bool "SDIO bus interface support for FullMAC driver"
> -	depends on MMC
> +	depends on (MMC = y || MMC = BRCMFMAC)
>  	depends on BRCMFMAC
>  	select FW_LOADER
>  	default y
> @@ -39,7 +39,7 @@ config BRCMFMAC_SDIO
>  
>  config BRCMFMAC_USB
>  	bool "USB bus interface support for FullMAC driver"
> -	depends on USB
> +	depends on (USB = y || USB = BRCMFMAC)
>  	depends on BRCMFMAC
>  	select FW_LOADER
>  	---help---
> 


-- 
~Randy

^ permalink raw reply

* [PATCH 3/4] mac80211: enable DFS for IBSS mode
From: Simon Wunderlich @ 2013-09-03 17:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1378230201-25446-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Allow changing to DFS channels if the channel is available for
beaconing and a control program is available.

Channel switch announcement on DFS channels will trigger a radar event
and mark these channels as unavailable.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 net/mac80211/ibss.c        |   50 +++++++++++++++++++++++++++++++++++++++-----
 net/mac80211/ieee80211_i.h |    1 +
 2 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 5ea9b3a..c3bf369 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -229,6 +229,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 	struct beacon_data *presp;
 	enum nl80211_bss_scan_width scan_width;
 	bool have_higher_than_11mbit;
+	bool radar_required = false;
+	int err;
 
 	sdata_assert_lock(sdata);
 
@@ -271,6 +273,23 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		}
 		chandef.width = NL80211_CHAN_WIDTH_20;
 		chandef.center_freq1 = chan->center_freq;
+		/* check again for downgraded chandef */
+		if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+			sdata_info(sdata,
+				   "Failed to join IBSS, beacons forbidden\n");
+			return;
+		}
+	}
+
+	err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
+					    &chandef);
+	if (err > 0) {
+		if (!ifibss->control_port_dfs) {
+			sdata_info(sdata,
+				   "Failed to join IBSS, DFS channel without control program\n");
+			return;
+		}
+		radar_required = true;
 	}
 
 	ieee80211_vif_release_channel(sdata);
@@ -295,6 +314,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 	rcu_assign_pointer(ifibss->presp, presp);
 	mgmt = (void *)presp->head;
 
+	sdata->radar_required = radar_required;
 	sdata->vif.bss_conf.enable_beacon = true;
 	sdata->vif.bss_conf.beacon_int = beacon_int;
 	sdata->vif.bss_conf.basic_rates = basic_rates;
@@ -778,6 +798,21 @@ static void ieee80211_csa_connection_drop_work(struct work_struct *work)
 	ieee80211_queue_work(&sdata->local->hw, &sdata->work);
 }
 
+static void ieee80211_ibss_csa_mark_radar(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+	int err;
+
+	/* if the current channel is a DFS channel, mark the channel as
+	 * unavailable.
+	 */
+	err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
+					    &ifibss->chandef);
+	if (err > 0)
+		cfg80211_radar_event(sdata->local->hw.wiphy, &ifibss->chandef,
+				     GFP_ATOMIC);
+}
+
 static bool
 ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 				  struct ieee802_11_elems *elems,
@@ -862,8 +897,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 		goto disconnect;
 	}
 
-	if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, &params.chandef,
-				     IEEE80211_CHAN_DISABLED)) {
+	if (!cfg80211_reg_can_beacon(sdata->local->hw.wiphy, &params.chandef)) {
 		sdata_info(sdata,
 			   "IBSS %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
 			   ifibss->bssid,
@@ -879,10 +913,11 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	if (err < 0)
 		goto disconnect;
 	if (err) {
+		/* IBSS-DFS only allowed with a control program */
+		if (!ifibss->control_port_dfs)
+			goto disconnect;
+
 		params.radar_required = true;
-
-		/* TODO: IBSS-DFS not (yet) supported, disconnect. */
-		goto disconnect;
 	}
 
 	rcu_read_lock();
@@ -929,12 +964,16 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	ieee80211_bss_info_change_notify(sdata, err);
 	drv_channel_switch_beacon(sdata, &params.chandef);
 
+	ieee80211_ibss_csa_mark_radar(sdata);
+
 	return true;
 disconnect:
 	ibss_dbg(sdata, "Can't handle channel switch, disconnect\n");
 	ieee80211_queue_work(&sdata->local->hw,
 			     &ifibss->csa_connection_drop_work);
 
+	ieee80211_ibss_csa_mark_radar(sdata);
+
 	return true;
 }
 
@@ -1670,6 +1709,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 
 	sdata->u.ibss.privacy = params->privacy;
 	sdata->u.ibss.control_port = params->control_port;
+	sdata->u.ibss.control_port_dfs = params->control_port_dfs;
 	sdata->u.ibss.basic_rates = params->basic_rates;
 
 	/* fix basic_rates if channel does not support these rates */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3a87c89..2bb01b6 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -497,6 +497,7 @@ struct ieee80211_if_ibss {
 	bool privacy;
 
 	bool control_port;
+	bool control_port_dfs;
 
 	u8 bssid[ETH_ALEN] __aligned(2);
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 2/4] nl80211/cfg80211: enable DFS for IBSS mode
From: Simon Wunderlich @ 2013-09-03 17:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1378230201-25446-1-git-send-email-siwu@hrz.tu-chemnitz.de>

To use DFS in IBSS mode, userspace is required to react to radar events.
It can inform nl80211 that it is capable of doing so by adding a
NL80211_ATTR_CONTROL_PORT_DFS attribute when joining the IBSS.

If this attribute is supplied, DFS channels may be used if the driver
supports it. Support will be checked even if a channel without DFS will
be joined, as the channel might change later due to scan activity or
channel switch announcements.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 include/net/cfg80211.h       |    6 ++++++
 include/uapi/linux/nl80211.h |    7 +++++++
 net/wireless/chan.c          |    3 ++-
 net/wireless/ibss.c          |   24 ++++++++++++++++++++----
 net/wireless/nl80211.c       |    8 ++++++--
 net/wireless/util.c          |   11 +++++++++--
 6 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0a2aafe..b20e8ca 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1656,6 +1656,9 @@ struct cfg80211_disassoc_request {
  *	sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
  *	required to assume that the port is unauthorized until authorized by
  *	user space. Otherwise, port is marked authorized by default.
+ * @control_port_dfs: whether user space controls DFS operation, i.e.
+ *	changes the channel when a radar is detected. This is required
+ *	to operate on DFS channels.
  * @basic_rates: bitmap of basic rates to use when creating the IBSS
  * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
  * @ht_capa:  HT Capabilities over-rides.  Values set in ht_capa_mask
@@ -1673,6 +1676,7 @@ struct cfg80211_ibss_params {
 	bool channel_fixed;
 	bool privacy;
 	bool control_port;
+	bool control_port_dfs;
 	int mcast_rate[IEEE80211_NUM_BANDS];
 	struct ieee80211_ht_cap ht_capa;
 	struct ieee80211_ht_cap ht_capa_mask;
@@ -3053,6 +3057,7 @@ struct cfg80211_cached_keys;
  * @conn: (private) cfg80211 software SME connection state machine data
  * @connect_keys: (private) keys to set after connection is established
  * @ibss_fixed: (private) IBSS is using fixed BSSID
+ * @ibss_dfs_possible: (private) IBSS may change to a DFS channel
  * @event_list: (private) list for internal event processing
  * @event_lock: (private) lock for event list
  */
@@ -3091,6 +3096,7 @@ struct wireless_dev {
 	struct ieee80211_channel *channel;
 
 	bool ibss_fixed;
+	bool ibss_dfs_possible;
 
 	bool ps;
 	int ps_timeout;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index fde2c02..80e68e0 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1496,6 +1496,11 @@ enum nl80211_commands {
  * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
  *	As specified in the &enum nl80211_rxmgmt_flags.
  *
+ * @NL80211_ATTR_CONTROL_PORT_DFS: A flag indicating whether user space
+ *	controls DFS operation in IBSS mode. If the flag is included in
+ *	%NL80211_CMD_JOIN_IBSS request, the driver will allow use of DFS
+ *	channels and reports radar events to userspace.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1806,6 +1811,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_RXMGMT_FLAGS,
 
+	NL80211_ATTR_CONTROL_PORT_DFS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 80504e6..92cf75f 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -504,7 +504,8 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
 	case NL80211_IFTYPE_ADHOC:
 		if (wdev->current_bss) {
 			*chan = wdev->current_bss->pub.channel;
-			*chanmode = wdev->ibss_fixed
+			*chanmode = (wdev->ibss_fixed &&
+				     !wdev->ibss_dfs_possible)
 				  ? CHAN_MODE_SHARED
 				  : CHAN_MODE_EXCLUSIVE;
 			return;
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 39bff7d..5edd69e 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -83,6 +83,8 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 			 struct cfg80211_cached_keys *connkeys)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct ieee80211_channel *check_chan;
+	u8 radar_detect_width = 0;
 	int err;
 
 	ASSERT_WDEV_LOCK(wdev);
@@ -114,14 +116,28 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 	wdev->connect_keys = connkeys;
 
 	wdev->ibss_fixed = params->channel_fixed;
+	wdev->ibss_dfs_possible = params->control_port_dfs;
 #ifdef CONFIG_CFG80211_WEXT
 	wdev->wext.ibss.chandef = params->chandef;
 #endif
+	check_chan = params->chandef.chan;
+	if (params->control_port_dfs) {
+		/* use channel NULL to check for radar even if the current
+		 * channel is not a radar channel - it might decide to change
+		 * to DFS channel later.
+		 */
+		radar_detect_width = BIT(params->chandef.width);
+		check_chan = NULL;
+	}
+
+	err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
+					   check_chan,
+					   (params->channel_fixed &&
+					    !radar_detect_width)
+					   ? CHAN_MODE_SHARED
+					   : CHAN_MODE_EXCLUSIVE,
+					   radar_detect_width);
 
-	err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan,
-				    params->channel_fixed
-				    ? CHAN_MODE_SHARED
-				    : CHAN_MODE_EXCLUSIVE);
 	if (err) {
 		wdev->connect_keys = NULL;
 		return err;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cbbef88..d10410a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -354,6 +354,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 	[NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
 	[NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_U16 },
 	[NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_U16 },
+	[NL80211_ATTR_CONTROL_PORT_DFS] = { .type = NLA_FLAG },
 };
 
 /* policy for the key attributes */
@@ -5722,9 +5723,9 @@ skip_beacons:
 	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
 		return -EINVAL;
 
-	/* DFS channels are only supported for AP/P2P GO ... for now. */
 	if (dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
-	    dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) {
+	    dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO ||
+	    dev->ieee80211_ptr->iftype == NL80211_IFTYPE_ADHOC) {
 		err = cfg80211_chandef_dfs_required(wdev->wiphy,
 						    &params.chandef);
 		if (err < 0) {
@@ -6556,6 +6557,9 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 	ibss.control_port =
 		nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
 
+	ibss.control_port_dfs =
+		nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_DFS]);
+
 	err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
 	if (err)
 		kfree(connkeys);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index ce090c1..beee988 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1255,8 +1255,15 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_P2P_GO:
 	case NL80211_IFTYPE_WDS:
-		radar_required = !!(chan &&
-				    (chan->flags & IEEE80211_CHAN_RADAR));
+		/* if the interface could potentially choose a DFS channel,
+		 * then mark DFS as required.
+		 */
+		if (!chan) {
+			if (chanmode != CHAN_MODE_UNDEFINED && radar_detect)
+				radar_required = true;
+			break;
+		}
+		radar_required = !!(chan->flags & IEEE80211_CHAN_RADAR);
 		break;
 	case NL80211_IFTYPE_P2P_CLIENT:
 	case NL80211_IFTYPE_STATION:
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/4] nl80211: allow CAC only if no operation is going on
From: Simon Wunderlich @ 2013-09-03 17:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1378230201-25446-1-git-send-email-siwu@hrz.tu-chemnitz.de>

A CAC should fail if it is triggered while the interface is already
running.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 net/wireless/nl80211.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index da8de5b..cbbef88 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5591,6 +5591,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
 	if (err)
 		return err;
 
+	if (netif_carrier_ok(dev))
+		return -EBUSY;
+
 	if (wdev->cac_started)
 		return -EBUSY;
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 4/4] ath9k: enable DFS for IBSS mode
From: Simon Wunderlich @ 2013-09-03 17:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1378230201-25446-1-git-send-email-siwu@hrz.tu-chemnitz.de>

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
 drivers/net/wireless/ath/ath9k/init.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 9a1f349..bcc5698 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -791,7 +791,8 @@ static const struct ieee80211_iface_limit if_limits[] = {
 
 
 static const struct ieee80211_iface_limit if_dfs_limits[] = {
-	{ .max = 1,	.types = BIT(NL80211_IFTYPE_AP) },
+	{ .max = 1,	.types = BIT(NL80211_IFTYPE_AP) |
+				 BIT(NL80211_IFTYPE_ADHOC) },
 };
 
 static const struct ieee80211_iface_combination if_comb[] = {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 0/4] add IBSS-DFS support
From: Simon Wunderlich @ 2013-09-03 17:43 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich

This patchset adds DFS support for the IBSS mode. It builds on top of
the previously sent AP DFS mode and channel switch announcement support.

The implementation differs from the DFS support as described in IEEE 802.11.
It does not implement the DFS owner service or uses IBSS DFS elements as
described in IEEE 802.11-2012 10.9.8.3. The DFS owner service has various
shortcomings:

 * it requires synchronization to find one central IBSS owner
 * citation: "The potential for hidden nodes within an IBSS means that the
   IBSS channel switch protocol is best effort."
 * the mechanism does not provide any way to handle big adhoc cells like
   mesh networks (which is a major target).

Therefore, a stripped down approach is implemented:

 * userspace must announce that it wants support for DFS and will handle
   events using a flag for the ibss_join command.
 * if a radar is detected, inform userspace. Userspace should then select
   a channel (e.g. decide on it with the peers on higher level protocols
   before, or wait a random backoff time) and start a channel switch process.
 * if a channel switch announcement from another peeris received, adopt it
   and re-transmit it (this has been implemented in the IBSS-CSA patchset
   before)
 * channel switch announcements on DFS channels are interpreted as
   radar signals and will mark the channel as unusable.

As always, any comments are appreciated.

Cheers,
        Simon

Simon Wunderlich (4):
  nl80211: allow CAC only if no operation is going on
  nl80211/cfg80211: enable DFS for IBSS mode
  mac80211: enable DFS for IBSS mode
  ath9k: enable DFS for IBSS mode

 drivers/net/wireless/ath/ath9k/init.c |    3 +-
 include/net/cfg80211.h                |    6 ++++
 include/uapi/linux/nl80211.h          |    7 +++++
 net/mac80211/ibss.c                   |   50 +++++++++++++++++++++++++++++----
 net/mac80211/ieee80211_i.h            |    1 +
 net/wireless/chan.c                   |    3 +-
 net/wireless/ibss.c                   |   24 +++++++++++++---
 net/wireless/nl80211.c                |   11 ++++++--
 net/wireless/util.c                   |   11 ++++++--
 9 files changed, 101 insertions(+), 15 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* Hidden SSIDs on DFS channels
From: Blaise Gassend @ 2013-09-03 17:24 UTC (permalink / raw)
  To: linux-wireless

(Reposting this as my original post went out without a subject.)

Hi,

Tracking down a customer problem, I recently discovered that Linux
does not currently support hidden SSIDs on DFS channels. As far as I
can tell, there isn't a fundamental reason for this. You could switch
to a frequency, listen for a beacon, once you see the beacon send a
directed probe, and listen for responses. I'm sure there are folks on
this list who have thought about this issue...

- Are there any reasons you know of why my proposed strategy would not
work from a regulatory point of view?

- If a patch were prepared, is this something that would be considered
for mainstream inclusion?

I know that hidden SSIDs are a bad idea. But some customers can be
hard to convince, and dealing with customers who have hidden SSIDs on
DFS channels can be a support burden. If we can make it just work for
them then our life is that much easier.

Regards,
Blaise

^ permalink raw reply

* Re: ACS compile to hostapd 2.0
From: Bartosz Markowski @ 2013-09-03 15:44 UTC (permalink / raw)
  To: Andrew Delamare; +Cc: Michal Kazior, linux-wireless@vger.kernel.org
In-Reply-To: <2ce6e0837f3c48d39e72cd07b5cdd491@THHSTE15D1BE3.hs20.net>

On 3 September 2013 16:26, Andrew Delamare
<andrew.delamare@powerethernet.com> wrote:

[...]

> Which repository is that in?
>
> If you could point me to the right Git repository or ftp download that would be great.

http://hostap.epitest.fi/cvs.html
master branch

-- 
Bartosz

^ permalink raw reply

* [PATCH 12/12] wlcore: always register dummy hardirq
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Arik Nemtsov <arik@wizery.com>

This keeps the kernel happy when using edge-irqs and requesting a
threaded irq.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/main.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index d952593..a537483 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5997,6 +5997,11 @@ static const struct wiphy_wowlan_support wlcore_wowlan_support = {
 };
 #endif
 
+static irqreturn_t wlcore_hardirq(int irq, void *cookie)
+{
+	return IRQ_WAKE_THREAD;
+}
+
 static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 {
 	struct wl1271 *wl = context;
@@ -6005,6 +6010,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
 	unsigned long irqflags;
 	int ret;
+	irq_handler_t hardirq_fn = NULL;
 
 	if (fw) {
 		wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
@@ -6033,12 +6039,14 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
 	wl->platform_quirks = pdata->platform_quirks;
 	wl->if_ops = pdev_data->if_ops;
 
-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) {
 		irqflags = IRQF_TRIGGER_RISING;
-	else
+		hardirq_fn = wlcore_hardirq;
+	} else {
 		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+	}
 
-	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
+	ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
 				   irqflags, pdev->name, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 11/12] wl18xx: print new RDL versions during boot
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Victor Goldenshtein <victorg@ti.com>

Extract and print info for the new RDL 5, 6, 7 and 8.
Replace const struct with function which translates
the RDL number to string.

Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Barak Bercovitz <barak@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wl18xx/main.c | 40 +++++++++++++++++++++++++++++------
 drivers/net/wireless/ti/wl18xx/reg.h  | 20 +++++++++---------
 2 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index b47eb62..aef0c91 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -1228,16 +1228,46 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
 	}
 }
 
+static const char *wl18xx_rdl_name(enum wl18xx_rdl_num rdl_num)
+{
+	switch (rdl_num) {
+	case RDL_1_HP:
+	    return "183xH";
+	case RDL_2_SP:
+	    return "183x or 180x";
+	case RDL_3_HP:
+	    return "187xH";
+	case RDL_4_SP:
+	    return "187x";
+	case RDL_5_SP:
+	    return "RDL11 - Not Supported";
+	case RDL_6_SP:
+	    return "180xD";
+	case RDL_7_SP:
+	    return "RDL13 - Not Supported (1893Q)";
+	case RDL_8_SP:
+	    return "18xxQ";
+	default:
+	    return "UNTRIMMED";
+	}
+}
+
 static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
 {
 	u32 fuse;
-	s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0;
+	s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0, package_type = 0;
 	int ret;
 
 	ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
 	if (ret < 0)
 		goto out;
 
+	ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse);
+	if (ret < 0)
+		goto out;
+
+	package_type = (fuse >> WL18XX_PACKAGE_TYPE_OFFSET) & 1;
+
 	ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
 	if (ret < 0)
 		goto out;
@@ -1245,7 +1275,7 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
 	pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
 	rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET;
 
-	if (rom <= 0xE)
+	if ((rom <= 0xE) && (package_type == WL18XX_PACKAGE_TYPE_WSP))
 		metal = (fuse & WL18XX_METAL_VER_MASK) >>
 			WL18XX_METAL_VER_OFFSET;
 	else
@@ -1257,11 +1287,9 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
 		goto out;
 
 	rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET;
-	if (rdl_ver > RDL_MAX)
-		rdl_ver = RDL_NONE;
 
-	wl1271_info("wl18xx HW: RDL %d, %s, PG %x.%x (ROM %x)",
-		    rdl_ver, rdl_names[rdl_ver], pg_ver, metal, rom);
+	wl1271_info("wl18xx HW: %s, PG %d.%d (ROM 0x%x)",
+		    wl18xx_rdl_name(rdl_ver), pg_ver, metal, rom);
 
 	if (ver)
 		*ver = pg_ver;
diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h
index 88de3f2..a433a75 100644
--- a/drivers/net/wireless/ti/wl18xx/reg.h
+++ b/drivers/net/wireless/ti/wl18xx/reg.h
@@ -147,13 +147,16 @@
 #define WL18XX_REG_FUSE_DATA_1_3	0xA0260C
 #define WL18XX_PG_VER_MASK		0x70
 #define WL18XX_PG_VER_OFFSET		4
-#define WL18XX_ROM_VER_MASK		0x3
-#define WL18XX_ROM_VER_OFFSET		0
+#define WL18XX_ROM_VER_MASK		0x3e00
+#define WL18XX_ROM_VER_OFFSET		9
 #define WL18XX_METAL_VER_MASK		0xC
 #define WL18XX_METAL_VER_OFFSET		2
 #define WL18XX_NEW_METAL_VER_MASK	0x180
 #define WL18XX_NEW_METAL_VER_OFFSET	7
 
+#define WL18XX_PACKAGE_TYPE_OFFSET	13
+#define WL18XX_PACKAGE_TYPE_WSP		0
+
 #define WL18XX_REG_FUSE_DATA_2_3	0xA02614
 #define WL18XX_RDL_VER_MASK		0x1f00
 #define WL18XX_RDL_VER_OFFSET		8
@@ -214,24 +217,21 @@ enum {
 	NUM_BOARD_TYPES,
 };
 
-enum {
+enum wl18xx_rdl_num {
 	RDL_NONE	= 0,
 	RDL_1_HP	= 1,
 	RDL_2_SP	= 2,
 	RDL_3_HP	= 3,
 	RDL_4_SP	= 4,
+	RDL_5_SP	= 0x11,
+	RDL_6_SP	= 0x12,
+	RDL_7_SP	= 0x13,
+	RDL_8_SP	= 0x14,
 
 	_RDL_LAST,
 	RDL_MAX = _RDL_LAST - 1,
 };
 
-static const char * const rdl_names[] = {
-	[RDL_NONE]	= "",
-	[RDL_1_HP]	= "1853 SISO",
-	[RDL_2_SP]	= "1857 MIMO",
-	[RDL_3_HP]	= "1893 SISO",
-	[RDL_4_SP]	= "1897 MIMO",
-};
 
 /* FPGA_SPARE_1 register - used to change the PHY ATPG clock at boot time */
 #define WL18XX_PHY_FPGA_SPARE_1		0x8093CA40
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 10/12] wl18xx: fix boot process in high temperature environment
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Victor Goldenshtein <victorg@ti.com>

In addition to existing WCS PLL configuration add and enable
also the coex PLL during init phase. This fixes boot failures
due to silicon latchup in high temperature environment (>85c).

Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Nadim Zubidat <nadimz@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wl18xx/main.c | 53 +++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ti/wl18xx/reg.h  | 13 +++++++++
 2 files changed, 66 insertions(+)

diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 7aa0eb8..b47eb62 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -623,6 +623,18 @@ static const int wl18xx_rtable[REG_TABLE_LEN] = {
 	[REG_RAW_FW_STATUS_ADDR]	= WL18XX_FW_STATUS_ADDR,
 };
 
+static const struct wl18xx_clk_cfg wl18xx_clk_table_coex[NUM_CLOCK_CONFIGS] = {
+	[CLOCK_CONFIG_16_2_M]	= { 8,  121, 0, 0, false },
+	[CLOCK_CONFIG_16_368_M]	= { 8,  120, 0, 0, false },
+	[CLOCK_CONFIG_16_8_M]	= { 8,  117, 0, 0, false },
+	[CLOCK_CONFIG_19_2_M]	= { 10, 128, 0, 0, false },
+	[CLOCK_CONFIG_26_M]	= { 11, 104, 0, 0, false },
+	[CLOCK_CONFIG_32_736_M]	= { 8,  120, 0, 0, false },
+	[CLOCK_CONFIG_33_6_M]	= { 8,  117, 0, 0, false },
+	[CLOCK_CONFIG_38_468_M]	= { 10, 128, 0, 0, false },
+	[CLOCK_CONFIG_52_M]	= { 11, 104, 0, 0, false },
+};
+
 static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
 	[CLOCK_CONFIG_16_2_M]	= { 7,  104,  801, 4,  true },
 	[CLOCK_CONFIG_16_368_M]	= { 9,  132, 3751, 4,  true },
@@ -704,6 +716,23 @@ static int wl18xx_set_clk(struct wl1271 *wl)
 		     wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q,
 		     wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit");
 
+	/* coex PLL configuration */
+	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_N,
+				   wl18xx_clk_table_coex[clk_freq].n);
+	if (ret < 0)
+		goto out;
+
+	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_M,
+				   wl18xx_clk_table_coex[clk_freq].m);
+	if (ret < 0)
+		goto out;
+
+	/* bypass the swallowing logic */
+	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
+				   PLLSH_COEX_PLL_SWALLOW_EN_VAL1);
+	if (ret < 0)
+		goto out;
+
 	ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N,
 				   wl18xx_clk_table[clk_freq].n);
 	if (ret < 0)
@@ -745,6 +774,30 @@ static int wl18xx_set_clk(struct wl1271 *wl)
 					   PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
 	}
 
+	/* choose WCS PLL */
+	ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_SEL,
+				   PLLSH_WL_PLL_SEL_WCS_PLL);
+	if (ret < 0)
+		goto out;
+
+	/* enable both PLLs */
+	ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL1);
+	if (ret < 0)
+		goto out;
+
+	udelay(1000);
+
+	/* disable coex PLL */
+	ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL2);
+	if (ret < 0)
+		goto out;
+
+	/* reset the swallowing logic */
+	ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN,
+				   PLLSH_COEX_PLL_SWALLOW_EN_VAL2);
+	if (ret < 0)
+		goto out;
+
 out:
 	return ret;
 }
diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h
index 05dd8ba..88de3f2 100644
--- a/drivers/net/wireless/ti/wl18xx/reg.h
+++ b/drivers/net/wireless/ti/wl18xx/reg.h
@@ -114,6 +114,11 @@
 #define PLATFORM_DETECTION		0xA0E3E0
 #define OCS_EN				0xA02080
 #define PRIMARY_CLK_DETECT		0xA020A6
+#define PLLSH_COEX_PLL_N		0xA02384
+#define PLLSH_COEX_PLL_M		0xA02382
+#define PLLSH_COEX_PLL_SWALLOW_EN	0xA0238E
+#define PLLSH_WL_PLL_SEL		0xA02398
+
 #define PLLSH_WCS_PLL_N			0xA02362
 #define PLLSH_WCS_PLL_M			0xA02360
 #define PLLSH_WCS_PLL_Q_FACTOR_CFG_1	0xA02364
@@ -128,9 +133,17 @@
 #define PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK	0xFFFF
 #define PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK	0x000F
 
+#define PLLSH_WL_PLL_EN_VAL1		0x7
+#define PLLSH_WL_PLL_EN_VAL2		0x2
+#define PLLSH_COEX_PLL_SWALLOW_EN_VAL1	0x2
+#define PLLSH_COEX_PLL_SWALLOW_EN_VAL2	0x11
+
 #define PLLSH_WCS_PLL_SWALLOW_EN_VAL1	0x1
 #define PLLSH_WCS_PLL_SWALLOW_EN_VAL2	0x12
 
+#define PLLSH_WL_PLL_SEL_WCS_PLL	0x0
+#define PLLSH_WL_PLL_SEL_COEX_PLL	0x1
+
 #define WL18XX_REG_FUSE_DATA_1_3	0xA0260C
 #define WL18XX_PG_VER_MASK		0x70
 #define WL18XX_PG_VER_OFFSET		4
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 09/12] wlcore: fix regulatory domain bit translation
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Ido Reis <idor@ti.com>

This is a fix for channels 52,56,60,64 bit translation.

Reported-by: Yaniv Machani <yanivma@ti.com>
Signed-off-by: Ido Reis <idor@ti.com>
Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/cmd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index e3ae425..1cb3296 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1613,8 +1613,10 @@ static int wlcore_get_reg_conf_ch_idx(enum ieee80211_band band, u16 ch)
 	case IEEE80211_BAND_5GHZ:
 		if (ch >= 8 && ch <= 16)
 			idx = ((ch-8)/4 + 18);
-		else if (ch >= 34 && ch <= 64)
+		else if (ch >= 34 && ch <= 48)
 			idx = ((ch-34)/2 + 3 + 18);
+		else if (ch >= 52 && ch <= 64)
+			idx = ((ch-52)/4 + 11 + 18);
 		else if (ch >= 100 && ch <= 140)
 			idx = ((ch-100)/4 + 15 + 18);
 		else if (ch >= 149 && ch <= 165)
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 08/12] wlcore: fix unsafe dereference of the wlvif
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Victor Goldenshtein <victorg@ti.com>

wlvif could be passed as NULL from the wlcore_tx_work_locked()
to the wl1271_prepare_tx_frame() and to wl1271_skb_queue_head()
functions. This may lead to a Kernel panic, fix this by
validating that wlvif != NULL.

Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/tx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 3c02023..aa11a17 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -405,7 +405,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 		is_wep = (cipher == WLAN_CIPHER_SUITE_WEP40) ||
 			 (cipher == WLAN_CIPHER_SUITE_WEP104);
 
-		if (WARN_ON(is_wep && wlvif->default_key != idx)) {
+		if (WARN_ON(is_wep && wlvif && wlvif->default_key != idx)) {
 			ret = wl1271_set_default_wep_key(wl, wlvif, idx);
 			if (ret < 0)
 				return ret;
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 07/12] wlcore: cleanup scan debug prints
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Victor Goldenshtein <victorg@ti.com>

Remove scan debug dumps which are rarely used.
Make scan debug prints more clear and short.

Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/cmd.c  |  6 +++---
 drivers/net/wireless/ti/wlcore/scan.c | 28 ++++++++++++++--------------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index c9e0607..e3ae425 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1126,6 +1126,8 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 	u16 template_id_2_4 = wl->scan_templ_id_2_4;
 	u16 template_id_5 = wl->scan_templ_id_5;
 
+	wl1271_debug(DEBUG_SCAN, "build probe request band %d", band);
+
 	skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
 				     ie_len);
 	if (!skb) {
@@ -1135,8 +1137,6 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 	if (ie_len)
 		memcpy(skb_put(skb, ie_len), ie, ie_len);
 
-	wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
-
 	if (sched_scan &&
 	    (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) {
 		template_id_2_4 = wl->sched_scan_templ_id_2_4;
@@ -1172,7 +1172,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
 	if (!skb)
 		goto out;
 
-	wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
+	wl1271_debug(DEBUG_SCAN, "set ap probe request template");
 
 	rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]);
 	if (wlvif->band == IEEE80211_BAND_2GHZ)
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index f407101..bbe0bc4 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -174,17 +174,7 @@ wlcore_scan_get_channels(struct wl1271 *wl,
 		    /* if radar is set, we ignore the passive flag */
 		    (radar ||
 		     !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
-			wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
-				     req_channels[i]->band,
-				     req_channels[i]->center_freq);
-			wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
-				     req_channels[i]->hw_value,
-				     req_channels[i]->flags);
-			wl1271_debug(DEBUG_SCAN, "max_power %d",
-				     req_channels[i]->max_power);
-			wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d",
-				     min_dwell_time_active,
-				     max_dwell_time_active);
+
 
 			if (flags & IEEE80211_CHAN_RADAR) {
 				channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
@@ -222,6 +212,18 @@ wlcore_scan_get_channels(struct wl1271 *wl,
 					     *n_pactive_ch);
 			}
 
+			wl1271_debug(DEBUG_SCAN, "freq %04d, ch. %03d, flags 0x%02X, power %02d, min/max_dwell %02d/%02d%s%s",
+				     req_channels[i]->center_freq,
+				     req_channels[i]->hw_value,
+				     req_channels[i]->flags,
+				     req_channels[i]->max_power,
+				     min_dwell_time_active,
+				     max_dwell_time_active,
+				     flags & IEEE80211_CHAN_RADAR ?
+					", DFS" : "",
+				     flags & IEEE80211_CHAN_PASSIVE_SCAN ?
+					", PASSIVE" : "");
+
 			j++;
 		}
 	}
@@ -364,7 +366,7 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
 	struct cfg80211_ssid *ssids = req->ssids;
 	int ret = 0, type, i, j, n_match_ssids = 0;
 
-	wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list");
+	wl1271_debug((DEBUG_CMD | DEBUG_SCAN), "cmd sched scan ssid list");
 
 	/* count the match sets that contain SSIDs */
 	for (i = 0; i < req->n_match_sets; i++)
@@ -442,8 +444,6 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
 		}
 	}
 
-	wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd));
-
 	ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd,
 			      sizeof(*cmd), 0);
 	if (ret < 0) {
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 06/12] wlcore: send EAPOL frames with voice priority
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Igal Chernobelsky <igalc@ti.com>

Send EAPOL frames with voice priority by setting TX_HW_ATTR_EAPOL_FRAME
new bit in tx attribute. Sending EAPOL with voice priority fixes
re-key timeout during heavy traffic issue.

Signed-off-by: Igal Chernobelsky <igalc@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/tx.c | 4 ++++
 drivers/net/wireless/ti/wlcore/tx.h | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 03249da..3c02023 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -357,6 +357,10 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 	    ieee80211_has_protected(frame_control))
 		tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
 
+	/* send EAPOL frames as voice */
+	if (control->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
+		tx_attr |= TX_HW_ATTR_EAPOL_FRAME;
+
 	desc->tx_attr = cpu_to_le16(tx_attr);
 
 	wlcore_hw_set_tx_desc_csum(wl, desc, skb);
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 35489c3..79cb3ff 100644
--- a/drivers/net/wireless/ti/wlcore/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -37,6 +37,7 @@
 #define TX_HW_ATTR_TX_CMPLT_REQ          BIT(12)
 #define TX_HW_ATTR_TX_DUMMY_REQ          BIT(13)
 #define TX_HW_ATTR_HOST_ENCRYPT          BIT(14)
+#define TX_HW_ATTR_EAPOL_FRAME           BIT(15)
 
 #define TX_HW_ATTR_OFST_SAVE_RETRIES     0
 #define TX_HW_ATTR_OFST_HEADER_PAD       1
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 05/12] wl18xx: increase the number of allowed BA sessions
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Victor Goldenshtein <victorg@ti.com>

The current fw (actually starting from fw 8.5.0.0.58)
supports 8 rx BA sessions.

Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wl18xx/wl18xx.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index 9204e07..f700c4de 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -40,7 +40,7 @@
 
 #define WL18XX_NUM_MAC_ADDRESSES 3
 
-#define WL18XX_RX_BA_MAX_SESSIONS 5
+#define WL18XX_RX_BA_MAX_SESSIONS 8
 
 struct wl18xx_priv {
 	/* buffer for sending commands to FW */
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 04/12] wlcore: re-enable idle handling
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Arik Nemtsov <arik@wizery.com>

We need some stuff done on idle change, most notably we have to stop
sched-scanning. Take care of this by reintroducing idle handling.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/main.c     | 22 ++++++++++++++++++++++
 drivers/net/wireless/ti/wlcore/wlcore_i.h |  1 +
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 611e81d..d952593 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2927,6 +2927,25 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 	wlvif->rate_set = wlvif->basic_rate_set;
 }
 
+static void wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+				   bool idle)
+{
+	bool cur_idle = !test_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+
+	if (idle == cur_idle)
+		return;
+
+	if (idle) {
+		clear_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+	} else {
+		/* The current firmware only supports sched_scan in idle */
+		if (wl->sched_vif == wlvif)
+			wl->ops->sched_scan_stop(wl, wlvif);
+
+		set_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+	}
+}
+
 static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 			     struct ieee80211_conf *conf, u32 changed)
 {
@@ -4179,6 +4198,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
 		do_join = true;
 	}
 
+	if (changed & BSS_CHANGED_IDLE && !is_ibss)
+		wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
+
 	if (changed & BSS_CHANGED_CQM) {
 		bool enable = false;
 		if (bss_conf->cqm_rssi_thold)
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 3f4f08b..2a50e08 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -255,6 +255,7 @@ enum wl12xx_vif_flags {
 	WLVIF_FLAG_CS_PROGRESS,
 	WLVIF_FLAG_AP_PROBE_RESP_SET,
 	WLVIF_FLAG_IN_USE,
+	WLVIF_FLAG_ACTIVE,
 };
 
 struct wl12xx_vif;
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH 03/12] wlcore: disable elp sleep while in plt mode
From: Eliad Peller @ 2013-09-03 14:33 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>

From: Yair Shapira <yair.shapira@ti.com>

We now disable elp sleep during plt mode to allow normal operation of
plt tools such as calibrator.

Having elp_sleep enabled during plt mode is actually not required and
in fact it disrupt plt operations such as rx statistics etc.

Signed-off-by: Yair Shapira <yair.shapira@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/ps.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 98066d4..26bfc36 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -83,6 +83,10 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
 	struct wl12xx_vif *wlvif;
 	u32 timeout;
 
+	/* We do not enter elp sleep in PLT mode */
+	if (wl->plt)
+		return;
+
 	if (wl->sleep_auth != WL1271_PSM_ELP)
 		return;
 
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox