Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 2/2] wl12xx: configure probe-resp template according to notification
From: Guy Eilam @ 2011-10-22 13:14 UTC (permalink / raw)
  To: coelho; +Cc: linux-wireless
In-Reply-To: <1319289279-21950-1-git-send-email-guy@wizery.com>

When operating in AP-mode, replace probe-response template when a
notification is recieved from mac80211. We preserve the "legacy" way of
configuring a probe-response according to beacon for IBSS mode and for
versions of hostapd that do not support this feature.

Signed-off-by: Guy Eilam <guy@wizery.com>
---
 drivers/net/wireless/wl12xx/main.c   |   57 +++++++++++++++++++++++++++++----
 drivers/net/wireless/wl12xx/wl12xx.h |    1 +
 2 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 0a7d020..d91842d 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -3311,11 +3311,33 @@ static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
 	skb_trim(skb, skb->len - len);
 }
 
-static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl,
-					 struct ieee80211_vif *vif,
-					 u8 *probe_rsp_data,
-					 size_t probe_rsp_len,
-					 u32 rates)
+static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates)
+{
+	struct sk_buff *skb;
+	int ret;
+
+	skb = ieee80211_proberesp_get(wl->hw, wl->vif);
+	if (!skb)
+		return -EINVAL;
+
+	ret = wl1271_cmd_template_set(wl,
+				      CMD_TEMPL_AP_PROBE_RESPONSE,
+				      skb->data,
+				      skb->len, 0,
+				      rates);
+
+	if (!ret)
+		set_bit(WL1271_FLAG_PROBE_RESP_SET, &wl->flags);
+
+	dev_kfree_skb(skb);
+	return ret;
+}
+
+static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,
+					     struct ieee80211_vif *vif,
+					     u8 *probe_rsp_data,
+					     size_t probe_rsp_len,
+					     u32 rates)
 {
 	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
@@ -3428,6 +3450,13 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
 		wlvif->beacon_int = bss_conf->beacon_int;
 	}
 
+	if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) {
+		ret = wl1271_ap_set_probe_resp_tmpl(wl,
+			wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set));
+		if (ret < 0)
+			goto out;
+	}
+
 	if ((changed & BSS_CHANGED_BEACON)) {
 		struct ieee80211_hdr *hdr;
 		u32 min_rate;
@@ -3436,8 +3465,10 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
 		struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
 		u16 tmpl_id;
 
-		if (!beacon)
+		if (!beacon) {
+			ret = -EINVAL;
 			goto out;
+		}
 
 		wl1271_debug(DEBUG_MASTER, "beacon updated");
 
@@ -3458,6 +3489,13 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
 			goto out;
 		}
 
+		/*
+		 * In case we already have a probe-resp beacon set explicitly
+		 * by usermode, don't use the beacon data.
+		 */
+		if (test_bit(WL1271_FLAG_PROBE_RESP_SET, &wl->flags))
+			goto end_bcn;
+
 		/* remove TIM ie from probe response */
 		wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset);
 
@@ -3476,7 +3514,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
 		hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 						 IEEE80211_STYPE_PROBE_RESP);
 		if (is_ap)
-			ret = wl1271_ap_set_probe_resp_tmpl(wl, vif,
+			ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif,
 						beacon->data,
 						beacon->len,
 						min_rate);
@@ -3486,12 +3524,15 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
 						beacon->data,
 						beacon->len, 0,
 						min_rate);
+end_bcn:
 		dev_kfree_skb(beacon);
 		if (ret < 0)
 			goto out;
 	}
 
 out:
+	if (ret != 0)
+		wl1271_error("beacon info change failed: %d", ret);
 	return ret;
 }
 
@@ -3548,6 +3589,8 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
 					goto out;
 
 				clear_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
+				clear_bit(WL1271_FLAG_PROBE_RESP_SET,
+					    &wl->flags);
 				wl1271_debug(DEBUG_AP, "stopped AP");
 			}
 		}
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index b7036df..a117c9d 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -255,6 +255,7 @@ enum wl12xx_flags {
 	WL1271_FLAG_PENDING_WORK,
 	WL1271_FLAG_SOFT_GEMINI,
 	WL1271_FLAG_RECOVERY_IN_PROGRESS,
+	WL1271_FLAG_PROBE_RESP_SET,
 };
 
 enum wl12xx_vif_flags {
-- 
1.7.4.1


^ permalink raw reply related

* Re: Setting negative value in dBm for power output (txpower)
From: Johannes Berg @ 2011-10-22 13:30 UTC (permalink / raw)
  To: Gábor Stefanik; +Cc: Patryk Żółtowski, linux-wireless
In-Reply-To: <CA+XFjiq6EJNczcotbk3R5YQXa-iY_2FY8KK4UN69XxSTm8LtoQ@mail.gmail.com>

On Sat, 2011-10-22 at 00:02 +0200, Gábor Stefanik wrote:
> 2011/10/21 Patryk Żółtowski <patryk.zoltowski@gmail.com>:
> > I'm doing a research and I'm wondering if it's possible to hack
> > wireless drivers to allow setting  txpower to smaller value than 1mW
> > (e.g. 0.1mW = -10dBM, or even 0.01mW). I've checked source code and in
> > net/mac80211/cfg.c there is the following check:
> >
> >  if (mbm < 0 || (mbm % 100))
> >                     return -EOPNOTSUPP;
> 
> The "mbm % 100" part is even weirder; why do we even use millibels if
> we only allow whole-decibel values?

This is really just historic -- nobody has so far cared about TX power
enough to clean up the APIs for it etc. The distinction between
"automatic", "fixed" and "limited" (auto <= some value) is also not
really done very well here.

johannes


^ permalink raw reply

* Re: [PATCH 1/4] nl80211: Add probe response offload attribute
From: Johannes Berg @ 2011-10-22 13:34 UTC (permalink / raw)
  To: Guy Eilam; +Cc: linux-wireless
In-Reply-To: <1319289112-21896-1-git-send-email-guy@wizery.com>

On Sat, 2011-10-22 at 15:11 +0200, Guy Eilam wrote:

> +enum nl80211_probe_resp_offload_support_attr {
> +	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS,
> +	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2,
> +	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P,
> +};

I think doing = 1<<N here would be nicer to use in drivers & userspace.

> + * @get_probe_resp_offload: Get probe response offload support from driver.

and this seems unnecessary -- why not just put a u32 value into struct
wiphy?

johannes


^ permalink raw reply

* Re: [PATCH 1/4] nl80211: Add probe response offload attribute
From: Johannes Berg @ 2011-10-22 13:36 UTC (permalink / raw)
  To: Guy Eilam; +Cc: linux-wireless
In-Reply-To: <1319290457.3956.3.camel@jlt3.sipsolutions.net>

On Sat, 2011-10-22 at 15:34 +0200, Johannes Berg wrote:
> On Sat, 2011-10-22 at 15:11 +0200, Guy Eilam wrote:
> 
> > +enum nl80211_probe_resp_offload_support_attr {
> > +	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS,
> > +	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2,
> > +	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P,
> > +};
> 
> I think doing = 1<<N here would be nicer to use in drivers & userspace.

Hm, also: should we call this WPS or WSC, and do we need to distinguish
WPS and WPS2? My AP mode patch called it WSC in a different context but
I can change, we just should be consistent.

> > + * @get_probe_resp_offload: Get probe response offload support from driver.
> 
> and this seems unnecessary -- why not just put a u32 value into struct
> wiphy?

Oh, and probably a regular WIPHY flag that indicates whether the
attribute should be added at all so that it can also be 0 but present
(presence with 0 value indicates something other than not present).

johannes


^ permalink raw reply

* [PATCH] nl80211: clean up genlmsg_end uses
From: Johannes Berg @ 2011-10-22 17:05 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

From: Johannes Berg <johannes.berg@intel.com>

genlmsg_end() cannot fail, it just returns the length
of the message. Thus, error handling for it is useless.
While removing it, I also noticed a useless variable
and removed this it as well.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wireless/nl80211.c |   97 +++++++++----------------------------------------
 1 file changed, 19 insertions(+), 78 deletions(-)

--- a/net/wireless/nl80211.c	2011-10-22 19:00:10.000000000 +0200
+++ b/net/wireless/nl80211.c	2011-10-22 19:03:05.000000000 +0200
@@ -6634,10 +6634,7 @@ void nl80211_send_reg_change_event(struc
 	if (wiphy_idx_valid(request->wiphy_idx))
 		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	rcu_read_lock();
 	genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
@@ -6673,10 +6670,7 @@ static void nl80211_send_mlme_event(stru
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
 	NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -6757,10 +6751,7 @@ static void nl80211_send_mlme_timeout(st
 	NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -6816,10 +6807,7 @@ void nl80211_send_connect_result(struct
 	if (resp_ie)
 		NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -6857,10 +6845,7 @@ void nl80211_send_roamed(struct cfg80211
 	if (resp_ie)
 		NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -6898,10 +6883,7 @@ void nl80211_send_disconnected(struct cf
 	if (ie)
 		NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, GFP_KERNEL);
@@ -6934,10 +6916,7 @@ void nl80211_send_ibss_bssid(struct cfg8
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -6972,10 +6951,7 @@ void nl80211_send_new_peer_candidate(str
 	if (ie_len && ie)
 		NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -7014,10 +6990,7 @@ void nl80211_michael_mic_failure(struct
 	if (tsc)
 		NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -7068,10 +7041,7 @@ void nl80211_send_beacon_hint_event(stru
 		goto nla_put_failure;
 	nla_nest_end(msg, nl_freq);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	rcu_read_lock();
 	genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
@@ -7114,10 +7084,7 @@ static void nl80211_send_remain_on_chan_
 	if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL)
 		NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -7188,10 +7155,7 @@ void nl80211_send_sta_del_event(struct c
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -7208,7 +7172,6 @@ int nl80211_send_mgmt(struct cfg80211_re
 {
 	struct sk_buff *msg;
 	void *hdr;
-	int err;
 
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
 	if (!msg)
@@ -7225,16 +7188,9 @@ int nl80211_send_mgmt(struct cfg80211_re
 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
 	NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
 
-	err = genlmsg_end(msg, hdr);
-	if (err < 0) {
-		nlmsg_free(msg);
-		return err;
-	}
+	genlmsg_end(msg, hdr);
 
-	err = genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
-	if (err < 0)
-		return err;
-	return 0;
+	return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
 
  nla_put_failure:
 	genlmsg_cancel(msg, hdr);
@@ -7267,10 +7223,7 @@ void nl80211_send_mgmt_tx_status(struct
 	if (ack)
 		NLA_PUT_FLAG(msg, NL80211_ATTR_ACK);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
 	return;
@@ -7312,10 +7265,7 @@ nl80211_send_cqm_rssi_notify(struct cfg8
 
 	nla_nest_end(msg, pinfoattr);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -7357,10 +7307,7 @@ void nl80211_gtk_rekey_notify(struct cfg
 
 	nla_nest_end(msg, rekey_attr);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -7403,10 +7350,7 @@ void nl80211_pmksa_candidate_notify(stru
 
 	nla_nest_end(msg, attr);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);
@@ -7448,10 +7392,7 @@ nl80211_send_cqm_pktloss_notify(struct c
 
 	nla_nest_end(msg, pinfoattr);
 
-	if (genlmsg_end(msg, hdr) < 0) {
-		nlmsg_free(msg);
-		return;
-	}
+	genlmsg_end(msg, hdr);
 
 	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
 				nl80211_mlme_mcgrp.id, gfp);



^ permalink raw reply

* Re: [PATCH 1/4] nl80211: Add probe response offload attribute
From: Guy Eilam @ 2011-10-22 17:26 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1319290618.3956.6.camel@jlt3.sipsolutions.net>

On Sat, Oct 22, 2011 at 3:36 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Sat, 2011-10-22 at 15:34 +0200, Johannes Berg wrote:
>> On Sat, 2011-10-22 at 15:11 +0200, Guy Eilam wrote:
>>
>> > +enum nl80211_probe_resp_offload_support_attr {
>> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS,
>> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2,
>> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P,
>> > +};
>>
>> I think doing = 1<<N here would be nicer to use in drivers & userspace.
>
> Hm, also: should we call this WPS or WSC, and do we need to distinguish
> WPS and WPS2? My AP mode patch called it WSC in a different context but
> I can change, we just should be consistent.
>
>> > + * @get_probe_resp_offload: Get probe response offload support from driver.
>>
>> and this seems unnecessary -- why not just put a u32 value into struct
>> wiphy?
>
> Oh, and probably a regular WIPHY flag that indicates whether the
> attribute should be added at all so that it can also be 0 but present
> (presence with 0 value indicates something other than not present).

When this is not supported a -EOPNOTSUPP should be returned.
A 0 return means that it is supported.
I now see that I have a small mistake in the patch regarding this.
The check should be (res >= 0) and not (!res).
I'll fix it.

>
> johannes
>
>

^ permalink raw reply

* Re: [PATCH 1/4] nl80211: Add probe response offload attribute
From: Johannes Berg @ 2011-10-22 17:39 UTC (permalink / raw)
  To: Guy Eilam; +Cc: linux-wireless
In-Reply-To: <CAA038468Y7T4BSAycqmNc0q+Ph1wSh07B57tV--O00kvDEp-wg@mail.gmail.com>

On Sat, 2011-10-22 at 19:26 +0200, Guy Eilam wrote:

> >> > +enum nl80211_probe_resp_offload_support_attr {
> >> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS,
> >> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2,
> >> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P,
> >> > +};
> >>
> >> I think doing = 1<<N here would be nicer to use in drivers & userspace.
> >
> > Hm, also: should we call this WPS or WSC, and do we need to distinguish
> > WPS and WPS2? My AP mode patch called it WSC in a different context but
> > I can change, we just should be consistent.
> >
> >> > + * @get_probe_resp_offload: Get probe response offload support from driver.
> >>
> >> and this seems unnecessary -- why not just put a u32 value into struct
> >> wiphy?
> >
> > Oh, and probably a regular WIPHY flag that indicates whether the
> > attribute should be added at all so that it can also be 0 but present
> > (presence with 0 value indicates something other than not present).
> 
> When this is not supported a -EOPNOTSUPP should be returned.
> A 0 return means that it is supported.

Yeah but if you add a wiphy flag and the bits into struct wiphy, then
you can save the function pointer which seems nicer?

johannes


^ permalink raw reply

* Re: [PATCH 1/4] nl80211: Add probe response offload attribute
From: Guy Eilam @ 2011-10-22 17:42 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1319305186.3956.11.camel@jlt3.sipsolutions.net>

On Sat, Oct 22, 2011 at 7:39 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Sat, 2011-10-22 at 19:26 +0200, Guy Eilam wrote:
>
>> >> > +enum nl80211_probe_resp_offload_support_attr {
>> >> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS,
>> >> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2,
>> >> > +   NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P,
>> >> > +};
>> >>
>> >> I think doing = 1<<N here would be nicer to use in drivers & userspace.
>> >
>> > Hm, also: should we call this WPS or WSC, and do we need to distinguish
>> > WPS and WPS2? My AP mode patch called it WSC in a different context but
>> > I can change, we just should be consistent.
>> >
>> >> > + * @get_probe_resp_offload: Get probe response offload support from driver.
>> >>
>> >> and this seems unnecessary -- why not just put a u32 value into struct
>> >> wiphy?
>> >
>> > Oh, and probably a regular WIPHY flag that indicates whether the
>> > attribute should be added at all so that it can also be 0 but present
>> > (presence with 0 value indicates something other than not present).
>>
>> When this is not supported a -EOPNOTSUPP should be returned.
>> A 0 return means that it is supported.
>
> Yeah but if you add a wiphy flag and the bits into struct wiphy, then
> you can save the function pointer which seems nicer?

You're absolutely right.
I'll send another version of the patch that will have a flag and
bitmap in the wiphy struct.

>
> johannes
>
>

Guy.

^ permalink raw reply

* Re: [PATCH 1/4] nl80211: Add probe response offload attribute
From: Johannes Berg @ 2011-10-22 17:44 UTC (permalink / raw)
  To: Guy Eilam; +Cc: linux-wireless
In-Reply-To: <CAA03845twSZjJHN-MygjLvK8VsQk+_S6qNqdM7JgZA9GS9LPWQ@mail.gmail.com>

On Sat, 2011-10-22 at 19:42 +0200, Guy Eilam wrote:

> > Yeah but if you add a wiphy flag and the bits into struct wiphy, then
> > you can save the function pointer which seems nicer?
> 
> You're absolutely right.
> I'll send another version of the patch that will have a flag and
> bitmap in the wiphy struct.

Also I believe that means you don't need patch 2 at all so that's kinda
nice :-)

johannes


^ permalink raw reply

* Compat-wireless release for 2011-10-22 is baked
From: Compat-wireless cronjob account @ 2011-10-22 19:03 UTC (permalink / raw)
  To: linux-wireless


compat-wireless code metrics

    814119 - Total upstream lines of code being pulled
      2431 - backport code changes
      2113 - backport code additions
       318 - backport code deletions
      8588 - backport from compat module
     11019 - total backport code
    1.3535 - % of code consists of backport work

^ permalink raw reply

* [PATCH v2 1/3] nl80211: Add probe response offload attribute
From: Guy Eilam @ 2011-10-22 19:51 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless

Notify the userspace of the probe response offloading
support by the driver.

Signed-off-by: Guy Eilam <guy@wizery.com>
---
v2:
use struct wiphy instead of a function pointer
this change made the previous second PATCH:
"Get the probe response offloading support from the driver" irrelevant
changed WPS to WSC

 include/linux/nl80211.h |   24 ++++++++++++++++++++++++
 include/net/cfg80211.h  |    5 +++++
 net/wireless/nl80211.c  |    5 +++++
 3 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 9d797f2..c1f0a3d 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1109,6 +1109,11 @@ enum nl80211_commands {
  *	%NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
  *	used for asking the driver to perform a TDLS operation.
  *
+ * @NL80211_ATTR_PROBE_RESP_OFFLOAD_SUPPORT: Indicates the support
+ *	of probe response offloading by the driver/firmware.
+ *	In addition this attribute holds a bitmap of the supported protocols
+ *	for offloading using &enum nl80211_probe_resp_offload_support_attr.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1337,6 +1342,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_TDLS_SUPPORT,
 	NL80211_ATTR_TDLS_EXTERNAL_SETUP,
 
+	NL80211_ATTR_PROBE_RESP_OFFLOAD_SUPPORT,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -2648,4 +2655,21 @@ enum nl80211_tdls_operation {
 	NL80211_TDLS_DISABLE_LINK,
 };
 
+/**
+ * enum nl80211_probe_resp_offload_support_attr - definition of optional
+ *	supported protocols for probe response offloading by the driver/firmware
+ *	to be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD_SUPPORT
+ *	attribute. Each enum value represents a bit in the bitmap of
+ *	supported protocols.
+ *
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WSC: Support for WSC ver. 1
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WSC2: Support for WSC ver. 2
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P
+ */
+enum nl80211_probe_resp_offload_support_attr {
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WSC =	1<<0,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WSC2 =	1<<1,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P =	1<<2,
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 74f4f85..c9f69a6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1690,6 +1690,7 @@ enum wiphy_flags {
 	WIPHY_FLAG_AP_UAPSD			= BIT(14),
 	WIPHY_FLAG_SUPPORTS_TDLS		= BIT(15),
 	WIPHY_FLAG_TDLS_EXTERNAL_SETUP		= BIT(16),
+	WIPHY_FLAG_SUPPORT_PROBE_RESP_OFFLOAD	= BIT(17),
 };
 
 /**
@@ -1953,6 +1954,10 @@ struct wiphy {
 	u32 available_antennas_tx;
 	u32 available_antennas_rx;
 
+	/* bitmap of supported protocols for probe response offloading
+	 * see enum nl80211_probe_resp_offload_support_attr */
+	u32 probe_resp_offload;
+
 	/* If multiple wiphys are registered and you're handed e.g.
 	 * a regular netdev with assigned ieee80211_ptr, you won't
 	 * know whether it points to a wiphy your driver has registered
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index edf655a..71d36ed 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -759,6 +759,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
 		    dev->wiphy.available_antennas_rx);
 
+	if (dev->wiphy.flags & WIPHY_FLAG_SUPPORT_PROBE_RESP_OFFLOAD)
+		NLA_PUT_U32(msg,
+			NL80211_ATTR_PROBE_RESP_OFFLOAD_SUPPORT,
+			dev->wiphy.probe_resp_offload);
+
 	if ((dev->wiphy.available_antennas_tx ||
 	     dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
 		u32 tx_ant = 0, rx_ant = 0;
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH v2 1/2] wl12xx: configure the probe response offloading support
From: Guy Eilam @ 2011-10-22 19:55 UTC (permalink / raw)
  To: coelho; +Cc: linux-wireless

Configure the probe response offload wiphy struct with
the relevant protocols supported currently by the driver.

Signed-off-by: Guy Eilam <guy@wizery.com>
---
v2:
now using the wiphy struct instead of a function and the conf_drv_settings

 drivers/net/wireless/wl12xx/main.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index f76be5a..833f3e7 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -4965,6 +4965,12 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
 
 	wl->hw->wiphy->reg_notifier = wl1271_reg_notify;
 
+	wl->hw->wiphy->flags |= WIPHY_FLAG_SUPPORT_PROBE_RESP_OFFLOAD;
+	wl->hw->wiphy->probe_resp_offload =
+		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WSC |
+		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WSC2 |
+		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
+
 	SET_IEEE80211_DEV(wl->hw, wl->dev);
 
 	wl->hw->sta_data_size = sizeof(struct wl1271_station);
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCH v2 1/3] nl80211: Add probe response offload attribute
From: Johannes Berg @ 2011-10-22 20:00 UTC (permalink / raw)
  To: Guy Eilam; +Cc: linux-wireless
In-Reply-To: <1319313081-28722-1-git-send-email-guy@wizery.com>

On Sat, 2011-10-22 at 21:51 +0200, Guy Eilam wrote:

> +/**
> + * enum nl80211_probe_resp_offload_support_attr - definition of optional
> + *	supported protocols for probe response offloading by the driver/firmware
> + *	to be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD_SUPPORT
> + *	attribute. Each enum value represents a bit in the bitmap of
> + *	supported protocols.

Oops I should have pointed that out before -- that's not valid
kernel-doc.

Also, maybe this should say how it'll be supported (i.e. by passing the
frame up for userspace to reply to, I think?)

johannes


^ permalink raw reply

* [PATCH] mac80211: support adding IV-room in the skb for CCMP keys
From: Arik Nemtsov @ 2011-10-23  6:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Arik Nemtsov

Some cards can generate CCMP IVs in HW, but require the space for the IV
to be pre-allocated in the frame at the correct offset. Add a key flag
that allows us to achieve this.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
---
 include/net/mac80211.h |    5 +++++
 net/mac80211/key.c     |    9 +++++++--
 net/mac80211/wpa.c     |    8 +++++++-
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index cd108df..a3ea227 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -899,6 +899,10 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
  * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a
  *	CCMP key if it requires CCMP encryption of management frames (MFP) to
  *	be done in software.
+ * @IEEE80211_KEY_FLAG_PUT_IV_SPACE: This flag should be set by the driver
+ *	for a CCMP key if space should be prepared for the IV, but the IV
+ *	itself should not be generated. Do not set together with
+ *	@IEEE80211_KEY_FLAG_GENERATE_IV on the same key.
  */
 enum ieee80211_key_flags {
 	IEEE80211_KEY_FLAG_WMM_STA	= 1<<0,
@@ -906,6 +910,7 @@ enum ieee80211_key_flags {
 	IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
 	IEEE80211_KEY_FLAG_PAIRWISE	= 1<<3,
 	IEEE80211_KEY_FLAG_SW_MGMT	= 1<<4,
+	IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5,
 };
 
 /**
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 756b157..17a5220 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -133,9 +133,13 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
 
 		if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
-		      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
+		      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
+		      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
 			sdata->crypto_tx_tailroom_needed_cnt--;
 
+		WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
+			(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV));
+
 		return 0;
 	}
 
@@ -178,7 +182,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 	sdata = key->sdata;
 
 	if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
-	      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)))
+	      (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
+	      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
 		increment_tailroom_need_count(sdata);
 
 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 7bc8702..ae58f4d 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -389,7 +389,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 	u8 scratch[6 * AES_BLOCK_SIZE];
 
 	if (info->control.hw_key &&
-	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
+	    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
 		/*
 		 * hwaccel has no need for preallocated room for CCMP
 		 * header or MIC fields
@@ -411,6 +412,11 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 
 	pos = skb_push(skb, CCMP_HDR_LEN);
 	memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
+
+	/* the HW only needs room for the IV, but not the actual IV */
+	if (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)
+		return 0;
+
 	hdr = (struct ieee80211_hdr *) pos;
 	pos += hdrlen;
 
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH 1/2] wl12xx: leave IV calculation to HW for CCMP
From: Arik Nemtsov @ 2011-10-23  6:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luciano Coelho, Arik Nemtsov

Use an appropriate mac80211 flags in CCMP keys to indicate we are
calculating the CCMP IV in HW, but require room for the IV to be reserved
in the skb. The space is reserved by mac80211.

depends on "mac80211: support adding IV-room in the skb for CCMP keys".

Signed-off-by: Arik Nemtsov <arik@wizery.com>
---
 drivers/net/wireless/wl12xx/main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index f76be5a..75adc76 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2992,7 +2992,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	case WLAN_CIPHER_SUITE_CCMP:
 		key_type = KEY_AES;
 
-		key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
 		tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
 		tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
 		break;
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH 2/2] wl12xx: handle idle changes per-interface
From: Arik Nemtsov @ 2011-10-23  6:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luciano Coelho, Eliad Peller, Arik Nemtsov
In-Reply-To: <1319350915-31222-1-git-send-email-arik@wizery.com>

From: Eliad Peller <eliad@wizery.com>

Idle changes are currently handled per hardware.
However, some operations should be done only per-interface.

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
---
 drivers/net/wireless/wl12xx/main.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 75adc76..b65816d 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2540,13 +2540,6 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 		}
 	}
 
-	if (changed & IEEE80211_CONF_CHANGE_IDLE && !is_ap) {
-		ret = wl1271_sta_handle_idle(wl, wlvif,
-					conf->flags & IEEE80211_CONF_IDLE);
-		if (ret < 0)
-			wl1271_warning("idle mode change failed %d", ret);
-	}
-
 	/*
 	 * if mac80211 changes the PSM mode, make sure the mode is not
 	 * incorrectly changed after the pspoll failure active window.
@@ -3619,6 +3612,12 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
 		do_join = true;
 	}
 
+	if (changed & BSS_CHANGED_IDLE) {
+		ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
+		if (ret < 0)
+			wl1271_warning("idle mode change failed %d", ret);
+	}
+
 	if ((changed & BSS_CHANGED_CQM)) {
 		bool enable = false;
 		if (bss_conf->cqm_rssi_thold)
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH] NFC: update to NCI spec 1.0 draft 18
From: ilanelias78 @ 2011-10-23  7:46 UTC (permalink / raw)
  To: aloisio.almeida, lauro.venancio, samuel, linville
  Cc: linux-wireless, Ilan Elias

From: Ilan Elias <ilane@ti.com>

Signed-off-by: Ilan Elias <ilane@ti.com>
---
 include/net/nfc/nci.h      |  208 ++++++++++++++++++++++---------------------
 include/net/nfc/nci_core.h |   13 +--
 net/nfc/nci/core.c         |   17 ++--
 net/nfc/nci/data.c         |    5 +-
 net/nfc/nci/lib.c          |    8 +--
 net/nfc/nci/ntf.c          |  152 +++++++++++++++++++-------------
 net/nfc/nci/rsp.c          |  149 ++++++++++++++-----------------
 7 files changed, 281 insertions(+), 271 deletions(-)

diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h
index 39b85bc..e4a2632 100644
--- a/include/net/nfc/nci.h
+++ b/include/net/nfc/nci.h
@@ -33,47 +33,49 @@
 #define NCI_MAX_NUM_RF_CONFIGS					10
 #define NCI_MAX_NUM_CONN					10
 
-/* NCI Status Codes */
-#define	NCI_STATUS_OK						0x00
-#define	NCI_STATUS_REJECTED					0x01
-#define	NCI_STATUS_MESSAGE_CORRUPTED				0x02
-#define	NCI_STATUS_BUFFER_FULL					0x03
-#define	NCI_STATUS_FAILED					0x04
-#define	NCI_STATUS_NOT_INITIALIZED				0x05
-#define	NCI_STATUS_SYNTAX_ERROR					0x06
-#define	NCI_STATUS_SEMANTIC_ERROR				0x07
-#define	NCI_STATUS_UNKNOWN_GID					0x08
-#define	NCI_STATUS_UNKNOWN_OID					0x09
-#define	NCI_STATUS_INVALID_PARAM				0x0a
-#define	NCI_STATUS_MESSAGE_SIZE_EXCEEDED			0x0b
-/* Discovery Specific Status Codes */
-#define	NCI_STATUS_DISCOVERY_ALREADY_STARTED			0xa0
-#define	NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED		0xa1
+/* Generic Status Codes */
+#define NCI_STATUS_OK						0x00
+#define NCI_STATUS_REJECTED					0x01
+#define NCI_STATUS_RF_FRAME_CORRUPTED				0x02
+#define NCI_STATUS_FAILED					0x03
+#define NCI_STATUS_NOT_INITIALIZED				0x04
+#define NCI_STATUS_SYNTAX_ERROR					0x05
+#define NCI_STATUS_SEMANTIC_ERROR				0x06
+#define NCI_STATUS_UNKNOWN_GID					0x07
+#define NCI_STATUS_UNKNOWN_OID					0x08
+#define NCI_STATUS_INVALID_PARAM				0x09
+#define NCI_STATUS_MESSAGE_SIZE_EXCEEDED			0x0a
+/* RF Discovery Specific Status Codes */
+#define NCI_STATUS_DISCOVERY_ALREADY_STARTED			0xa0
+#define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED		0xa1
+#define NCI_STATUS_DISCOVERY_TEAR_DOWN				0xa2
 /* RF Interface Specific Status Codes */
-#define	NCI_STATUS_RF_TRANSMISSION_ERROR			0xb0
-#define	NCI_STATUS_RF_PROTOCOL_ERROR				0xb1
-#define	NCI_STATUS_RF_TIMEOUT_ERROR				0xb2
-#define	NCI_STATUS_RF_LINK_LOSS_ERROR				0xb3
+#define NCI_STATUS_RF_TRANSMISSION_ERROR			0xb0
+#define NCI_STATUS_RF_PROTOCOL_ERROR				0xb1
+#define NCI_STATUS_RF_TIMEOUT_ERROR				0xb2
 /* NFCEE Interface Specific Status Codes */
-#define	NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED		0xc0
-#define	NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED		0xc1
-#define	NCI_STATUS_NFCEE_TRANSMISSION_ERROR			0xc2
-#define	NCI_STATUS_NFCEE_PROTOCOL_ERROR				0xc3
+#define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED		0xc0
+#define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED		0xc1
+#define NCI_STATUS_NFCEE_TRANSMISSION_ERROR			0xc2
+#define NCI_STATUS_NFCEE_PROTOCOL_ERROR				0xc3
 #define NCI_STATUS_NFCEE_TIMEOUT_ERROR				0xc4
 
-/* NCI RF Technology and Mode */
-#define NCI_NFC_A_PASSIVE_POLL_MODE				0x00
-#define NCI_NFC_B_PASSIVE_POLL_MODE				0x01
-#define NCI_NFC_F_PASSIVE_POLL_MODE				0x02
-#define NCI_NFC_A_ACTIVE_POLL_MODE				0x03
-#define NCI_NFC_F_ACTIVE_POLL_MODE				0x05
-#define NCI_NFC_A_PASSIVE_LISTEN_MODE				0x80
-#define NCI_NFC_B_PASSIVE_LISTEN_MODE				0x81
-#define NCI_NFC_F_PASSIVE_LISTEN_MODE				0x82
-#define NCI_NFC_A_ACTIVE_LISTEN_MODE				0x83
-#define NCI_NFC_F_ACTIVE_LISTEN_MODE				0x85
-
-/* NCI RF Protocols */
+/* RF Technologies */
+#define NCI_NFC_RF_TECHNOLOGY_A					0x00
+#define NCI_NFC_RF_TECHNOLOGY_B					0x01
+#define NCI_NFC_RF_TECHNOLOGY_F					0x02
+#define NCI_NFC_RF_TECHNOLOGY_15693				0x03
+
+/* Bit Rates */
+#define NCI_NFC_BIT_RATE_106					0x00
+#define NCI_NFC_BIT_RATE_212					0x01
+#define NCI_NFC_BIT_RATE_424					0x02
+#define NCI_NFC_BIT_RATE_848					0x03
+#define NCI_NFC_BIT_RATE_1696					0x04
+#define NCI_NFC_BIT_RATE_3392					0x05
+#define NCI_NFC_BIT_RATE_6784					0x06
+
+/* RF Protocols */
 #define NCI_RF_PROTOCOL_UNKNOWN					0x00
 #define NCI_RF_PROTOCOL_T1T					0x01
 #define NCI_RF_PROTOCOL_T2T					0x02
@@ -81,38 +83,54 @@
 #define NCI_RF_PROTOCOL_ISO_DEP					0x04
 #define NCI_RF_PROTOCOL_NFC_DEP					0x05
 
-/* NCI RF Interfaces */
-#define NCI_RF_INTERFACE_RFU					0x00
-#define	NCI_RF_INTERFACE_FRAME					0x01
-#define	NCI_RF_INTERFACE_ISO_DEP				0x02
-#define	NCI_RF_INTERFACE_NFC_DEP				0x03
+/* RF Interfaces */
+#define NCI_RF_INTERFACE_NFCEE_DIRECT				0x00
+#define NCI_RF_INTERFACE_FRAME					0x01
+#define NCI_RF_INTERFACE_ISO_DEP				0x02
+#define NCI_RF_INTERFACE_NFC_DEP				0x03
 
-/* NCI RF_DISCOVER_MAP_CMD modes */
+/* Reset types */
+#define NCI_RESET_TYPE_KEEP_CONFIG				0x00
+#define NCI_RESET_TYPE_RESET_CONFIG				0x01
+
+/* Static RF connection ID */
+#define NCI_STATIC_RF_CONN_ID					0x00
+
+/* RF_DISCOVER_MAP_CMD modes */
 #define NCI_DISC_MAP_MODE_POLL					0x01
 #define NCI_DISC_MAP_MODE_LISTEN				0x02
 #define NCI_DISC_MAP_MODE_BOTH					0x03
 
-/* NCI Discovery Types */
+/* Discovery Types */
 #define NCI_DISCOVERY_TYPE_POLL_A_PASSIVE			0x00
-#define	NCI_DISCOVERY_TYPE_POLL_B_PASSIVE			0x01
-#define	NCI_DISCOVERY_TYPE_POLL_F_PASSIVE			0x02
-#define	NCI_DISCOVERY_TYPE_POLL_A_ACTIVE			0x03
-#define	NCI_DISCOVERY_TYPE_POLL_F_ACTIVE			0x05
-#define	NCI_DISCOVERY_TYPE_WAKEUP_A_PASSIVE			0x06
-#define	NCI_DISCOVERY_TYPE_WAKEUP_B_PASSIVE			0x07
-#define	NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE			0x09
-#define	NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE			0x80
-#define	NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE			0x81
-#define	NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE			0x82
-#define	NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE			0x83
-#define	NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE			0x85
-
-/* NCI Deactivation Type */
-#define	NCI_DEACTIVATE_TYPE_IDLE_MODE				0x00
-#define	NCI_DEACTIVATE_TYPE_SLEEP_MODE				0x01
-#define	NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE			0x02
-#define	NCI_DEACTIVATE_TYPE_RF_LINK_LOSS			0x03
-#define	NCI_DEACTIVATE_TYPE_DISCOVERY_ERROR			0x04
+#define NCI_DISCOVERY_TYPE_POLL_B_PASSIVE			0x01
+#define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE			0x02
+#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE			0x03
+#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE			0x05
+#define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE			0x09
+#define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE			0x80
+#define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE			0x81
+#define NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE			0x82
+#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE			0x83
+#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE			0x85
+
+/* RF Technology and Mode */
+#define NCI_NFC_A_PASSIVE_POLL_MODE				0x00
+#define NCI_NFC_B_PASSIVE_POLL_MODE				0x01
+#define NCI_NFC_F_PASSIVE_POLL_MODE				0x02
+#define NCI_NFC_A_ACTIVE_POLL_MODE				0x03
+#define NCI_NFC_F_ACTIVE_POLL_MODE				0x05
+#define NCI_NFC_A_PASSIVE_LISTEN_MODE				0x80
+#define NCI_NFC_B_PASSIVE_LISTEN_MODE				0x81
+#define NCI_NFC_F_PASSIVE_LISTEN_MODE				0x82
+#define NCI_NFC_A_ACTIVE_LISTEN_MODE				0x83
+#define NCI_NFC_F_ACTIVE_LISTEN_MODE				0x85
+
+/* Deactivation Type */
+#define NCI_DEACTIVATE_TYPE_IDLE_MODE				0x00
+#define NCI_DEACTIVATE_TYPE_SLEEP_MODE				0x01
+#define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE			0x02
+#define NCI_DEACTIVATE_TYPE_DISCOVERY				0x03
 
 /* Message Type (MT) */
 #define NCI_MT_DATA_PKT						0x00
@@ -144,10 +162,10 @@
 #define nci_conn_id(hdr)		(__u8)(((hdr)[0])&0x0f)
 
 /* GID values */
-#define	NCI_GID_CORE						0x0
-#define	NCI_GID_RF_MGMT						0x1
-#define	NCI_GID_NFCEE_MGMT					0x2
-#define	NCI_GID_PROPRIETARY					0xf
+#define NCI_GID_CORE						0x0
+#define NCI_GID_RF_MGMT						0x1
+#define NCI_GID_NFCEE_MGMT					0x2
+#define NCI_GID_PROPRIETARY					0xf
 
 /* ---- NCI Packet structures ---- */
 #define NCI_CTRL_HDR_SIZE					3
@@ -169,18 +187,11 @@ struct nci_data_hdr {
 /* -----  NCI Commands ---- */
 /* ------------------------ */
 #define NCI_OP_CORE_RESET_CMD		nci_opcode_pack(NCI_GID_CORE, 0x00)
-
-#define NCI_OP_CORE_INIT_CMD		nci_opcode_pack(NCI_GID_CORE, 0x01)
-
-#define NCI_OP_CORE_SET_CONFIG_CMD	nci_opcode_pack(NCI_GID_CORE, 0x02)
-
-#define NCI_OP_CORE_CONN_CREATE_CMD	nci_opcode_pack(NCI_GID_CORE, 0x04)
-struct nci_core_conn_create_cmd {
-	__u8	target_handle;
-	__u8	num_target_specific_params;
+struct nci_core_reset_cmd {
+	__u8	reset_type;
 } __packed;
 
-#define NCI_OP_CORE_CONN_CLOSE_CMD	nci_opcode_pack(NCI_GID_CORE, 0x06)
+#define NCI_OP_CORE_INIT_CMD		nci_opcode_pack(NCI_GID_CORE, 0x01)
 
 #define NCI_OP_RF_DISCOVER_MAP_CMD	nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)
 struct disc_map_config {
@@ -218,6 +229,7 @@ struct nci_rf_deactivate_cmd {
 struct nci_core_reset_rsp {
 	__u8	status;
 	__u8	nci_ver;
+	__u8	config_status;
 } __packed;
 
 #define NCI_OP_CORE_INIT_RSP		nci_opcode_pack(NCI_GID_CORE, 0x01)
@@ -232,24 +244,14 @@ struct nci_core_init_rsp_1 {
 struct nci_core_init_rsp_2 {
 	__u8	max_logical_connections;
 	__le16	max_routing_table_size;
-	__u8	max_control_packet_payload_length;
-	__le16	rf_sending_buffer_size;
-	__le16	rf_receiving_buffer_size;
-	__le16	manufacturer_id;
-} __packed;
-
-#define NCI_OP_CORE_SET_CONFIG_RSP	nci_opcode_pack(NCI_GID_CORE, 0x02)
-
-#define NCI_OP_CORE_CONN_CREATE_RSP	nci_opcode_pack(NCI_GID_CORE, 0x04)
-struct nci_core_conn_create_rsp {
-	__u8	status;
-	__u8	max_pkt_payload_size;
+	__u8	max_control_pkt_payload_len;
+	__le16	max_size_for_large_params;
+	__u8	max_data_pkt_payload_size;
 	__u8	initial_num_credits;
-	__u8	conn_id;
+	__u8	manufacturer_id;
+	__le32	manufacturer_specific_info;
 } __packed;
 
-#define NCI_OP_CORE_CONN_CLOSE_RSP	nci_opcode_pack(NCI_GID_CORE, 0x06)
-
 #define NCI_OP_RF_DISCOVER_MAP_RSP	nci_opcode_pack(NCI_GID_RF_MGMT, 0x00)
 
 #define NCI_OP_RF_DISCOVER_RSP		nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
@@ -270,12 +272,7 @@ struct nci_core_conn_credit_ntf {
 	struct conn_credit_entry	conn_entries[NCI_MAX_NUM_CONN];
 } __packed;
 
-#define NCI_OP_RF_FIELD_INFO_NTF	nci_opcode_pack(NCI_GID_CORE, 0x08)
-struct nci_rf_field_info_ntf {
-	__u8	rf_field_status;
-} __packed;
-
-#define NCI_OP_RF_ACTIVATE_NTF		nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
+#define NCI_OP_RF_INTF_ACTIVATED_NTF	nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
 struct rf_tech_specific_params_nfca_poll {
 	__u16	sens_res;
 	__u8	nfcid1_len;	/* 0, 4, 7, or 10 Bytes */
@@ -289,17 +286,20 @@ struct activation_params_nfca_poll_iso_dep {
 	__u8	rats_res[20];
 };
 
-struct nci_rf_activate_ntf {
-	__u8	target_handle;
+struct nci_rf_intf_activated_ntf {
+	__u8	rf_discovery_id;
+	__u8	rf_interface_type;
 	__u8	rf_protocol;
-	__u8	rf_tech_and_mode;
+	__u8	activation_rf_tech_and_mode;
 	__u8	rf_tech_specific_params_len;
 
 	union {
 		struct rf_tech_specific_params_nfca_poll nfca_poll;
 	} rf_tech_specific_params;
 
-	__u8	rf_interface_type;
+	__u8	data_exchange_rf_tech_and_mode;
+	__u8	data_exchange_tx_bit_rate;
+	__u8	data_exchange_rx_bit_rate;
 	__u8	activation_params_len;
 
 	union {
@@ -309,5 +309,9 @@ struct nci_rf_activate_ntf {
 } __packed;
 
 #define NCI_OP_RF_DEACTIVATE_NTF	nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
+struct nci_rf_deactivate_ntf {
+	__u8	type;
+	__u8	reason;
+} __packed;
 
 #endif /* __NCI_H */
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index b8b4bbd..77b7c9e 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -109,15 +109,12 @@ struct nci_dev {
 				[NCI_MAX_SUPPORTED_RF_INTERFACES];
 	__u8			max_logical_connections;
 	__u16			max_routing_table_size;
-	__u8			max_control_packet_payload_length;
-	__u16			rf_sending_buffer_size;
-	__u16			rf_receiving_buffer_size;
-	__u16			manufacturer_id;
-
-	/* received during NCI_OP_CORE_CONN_CREATE_RSP for static conn 0 */
-	__u8			max_pkt_payload_size;
+	__u8			max_control_pkt_payload_len;
+	__u16			max_size_for_large_params;
+	__u8			max_data_pkt_payload_size;
 	__u8			initial_num_credits;
-	__u8			conn_id;
+	__u8			manufacturer_id;
+	__u32			manufacturer_specific_info;
 
 	/* stored during nci_data_exchange */
 	data_exchange_cb_t	data_exchange_cb;
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index 4047e29..056cd37 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -125,7 +125,10 @@ static inline int nci_request(struct nci_dev *ndev,
 
 static void nci_reset_req(struct nci_dev *ndev, unsigned long opt)
 {
-	nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 0, NULL);
+	struct nci_core_reset_cmd cmd;
+
+	cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG;
+	nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd);
 }
 
 static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
@@ -135,17 +138,11 @@ static void nci_init_req(struct nci_dev *ndev, unsigned long opt)
 
 static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
 {
-	struct nci_core_conn_create_cmd conn_cmd;
 	struct nci_rf_disc_map_cmd cmd;
 	struct disc_map_config *cfg = cmd.mapping_configs;
 	__u8 *num = &cmd.num_mapping_configs;
 	int i;
 
-	/* create static rf connection */
-	conn_cmd.target_handle = 0;
-	conn_cmd.num_target_specific_params = 0;
-	nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd);
-
 	/* set rf mapping configurations */
 	*num = 0;
 
@@ -469,7 +466,7 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx,
 	ndev->data_exchange_cb = cb;
 	ndev->data_exchange_cb_context = cb_context;
 
-	rc = nci_send_data(ndev, ndev->conn_id, skb);
+	rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);
 	if (rc)
 		clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
 
@@ -725,7 +722,9 @@ static void nci_tx_work(struct work_struct *work)
 		if (!skb)
 			return;
 
-		atomic_dec(&ndev->credits_cnt);
+		/* Check if data flow control is used */
+		if (atomic_read(&ndev->credits_cnt) != 0xff)
+			atomic_dec(&ndev->credits_cnt);
 
 		nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d",
 				nci_pbf(skb->data),
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
index e5ed90f..511fb96 100644
--- a/net/nfc/nci/data.c
+++ b/net/nfc/nci/data.c
@@ -95,7 +95,8 @@ static int nci_queue_tx_data_frags(struct nci_dev *ndev,
 	__skb_queue_head_init(&frags_q);
 
 	while (total_len) {
-		frag_len = min_t(int, total_len, ndev->max_pkt_payload_size);
+		frag_len =
+			min_t(int, total_len, ndev->max_data_pkt_payload_size);
 
 		skb_frag = nci_skb_alloc(ndev,
 					(NCI_DATA_HDR_SIZE + frag_len),
@@ -151,7 +152,7 @@ int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb)
 	nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len);
 
 	/* check if the packet need to be fragmented */
-	if (skb->len <= ndev->max_pkt_payload_size) {
+	if (skb->len <= ndev->max_data_pkt_payload_size) {
 		/* no need to fragment packet */
 		nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST);
 
diff --git a/net/nfc/nci/lib.c b/net/nfc/nci/lib.c
index b19dc2f..e99adcf 100644
--- a/net/nfc/nci/lib.c
+++ b/net/nfc/nci/lib.c
@@ -42,12 +42,9 @@ int nci_to_errno(__u8 code)
 	case NCI_STATUS_REJECTED:
 		return -EBUSY;
 
-	case NCI_STATUS_MESSAGE_CORRUPTED:
+	case NCI_STATUS_RF_FRAME_CORRUPTED:
 		return -EBADMSG;
 
-	case NCI_STATUS_BUFFER_FULL:
-		return -ENOBUFS;
-
 	case NCI_STATUS_NOT_INITIALIZED:
 		return -EHOSTDOWN;
 
@@ -80,9 +77,6 @@ int nci_to_errno(__u8 code)
 	case NCI_STATUS_NFCEE_TIMEOUT_ERROR:
 		return -ETIMEDOUT;
 
-	case NCI_STATUS_RF_LINK_LOSS_ERROR:
-		return -ENOLINK;
-
 	case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED:
 		return -EDQUOT;
 
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index 96633f5..770dfc8 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -54,7 +54,7 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
 			ntf->conn_entries[i].conn_id,
 			ntf->conn_entries[i].credits);
 
-		if (ntf->conn_entries[i].conn_id == ndev->conn_id) {
+		if (ntf->conn_entries[i].conn_id == NCI_STATIC_RF_CONN_ID) {
 			/* found static rf connection */
 			atomic_add(ntf->conn_entries[i].credits,
 				&ndev->credits_cnt);
@@ -66,22 +66,12 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
 		queue_work(ndev->tx_wq, &ndev->tx_work);
 }
 
-static void nci_rf_field_info_ntf_packet(struct nci_dev *ndev,
-					struct sk_buff *skb)
-{
-	struct nci_rf_field_info_ntf *ntf = (void *) skb->data;
-
-	nfc_dbg("entry, rf_field_status %d", ntf->rf_field_status);
-}
-
-static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
-			struct nci_rf_activate_ntf *ntf, __u8 *data)
+static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
+			struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
 {
 	struct rf_tech_specific_params_nfca_poll *nfca_poll;
-	struct activation_params_nfca_poll_iso_dep *nfca_poll_iso_dep;
 
 	nfca_poll = &ntf->rf_tech_specific_params.nfca_poll;
-	nfca_poll_iso_dep = &ntf->activation_params.nfca_poll_iso_dep;
 
 	nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
 	data += 2;
@@ -100,32 +90,32 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
 	if (nfca_poll->sel_res_len != 0)
 		nfca_poll->sel_res = *data++;
 
-	ntf->rf_interface_type = *data++;
-	ntf->activation_params_len = *data++;
-
-	nfc_dbg("sel_res_len %d, sel_res 0x%x, rf_interface_type %d, activation_params_len %d",
+	nfc_dbg("sel_res_len %d, sel_res 0x%x",
 		nfca_poll->sel_res_len,
-		nfca_poll->sel_res,
-		ntf->rf_interface_type,
-		ntf->activation_params_len);
-
-	switch (ntf->rf_interface_type) {
-	case NCI_RF_INTERFACE_ISO_DEP:
-		nfca_poll_iso_dep->rats_res_len = *data++;
-		if (nfca_poll_iso_dep->rats_res_len > 0) {
-			memcpy(nfca_poll_iso_dep->rats_res,
+		nfca_poll->sel_res);
+
+	return data;
+}
+
+static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
+			struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
+{
+	struct activation_params_nfca_poll_iso_dep *nfca_poll;
+
+	switch (ntf->activation_rf_tech_and_mode) {
+	case NCI_NFC_A_PASSIVE_POLL_MODE:
+		nfca_poll = &ntf->activation_params.nfca_poll_iso_dep;
+		nfca_poll->rats_res_len = *data++;
+		if (nfca_poll->rats_res_len > 0) {
+			memcpy(nfca_poll->rats_res,
 				data,
-				nfca_poll_iso_dep->rats_res_len);
+				nfca_poll->rats_res_len);
 		}
 		break;
 
-	case NCI_RF_INTERFACE_FRAME:
-		/* no activation params */
-		break;
-
 	default:
-		nfc_err("unsupported rf_interface_type 0x%x",
-			ntf->rf_interface_type);
+		nfc_err("unsupported activation_rf_tech_and_mode 0x%x",
+			ntf->activation_rf_tech_and_mode);
 		return -EPROTO;
 	}
 
@@ -133,7 +123,7 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev,
 }
 
 static void nci_target_found(struct nci_dev *ndev,
-				struct nci_rf_activate_ntf *ntf)
+				struct nci_rf_intf_activated_ntf *ntf)
 {
 	struct nfc_target nfc_tgt;
 
@@ -141,6 +131,8 @@ static void nci_target_found(struct nci_dev *ndev,
 		nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK;
 	else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP)	/* 4A */
 		nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK;
+	else
+		nfc_tgt.supported_protocols = 0;
 
 	nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res;
 	nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res;
@@ -158,49 +150,86 @@ static void nci_target_found(struct nci_dev *ndev,
 	nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);
 }
 
-static void nci_rf_activate_ntf_packet(struct nci_dev *ndev,
-					struct sk_buff *skb)
+static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
+						struct sk_buff *skb)
 {
-	struct nci_rf_activate_ntf ntf;
+	struct nci_rf_intf_activated_ntf ntf;
 	__u8 *data = skb->data;
-	int rc = -1;
+	int err = 0;
 
 	clear_bit(NCI_DISCOVERY, &ndev->flags);
 	set_bit(NCI_POLL_ACTIVE, &ndev->flags);
 
-	ntf.target_handle = *data++;
+	ntf.rf_discovery_id = *data++;
+	ntf.rf_interface_type = *data++;
 	ntf.rf_protocol = *data++;
-	ntf.rf_tech_and_mode = *data++;
+	ntf.activation_rf_tech_and_mode = *data++;
 	ntf.rf_tech_specific_params_len = *data++;
 
-	nfc_dbg("target_handle %d, rf_protocol 0x%x, rf_tech_and_mode 0x%x, rf_tech_specific_params_len %d",
-		ntf.target_handle,
-		ntf.rf_protocol,
-		ntf.rf_tech_and_mode,
+	nfc_dbg("rf_discovery_id %d", ntf.rf_discovery_id);
+	nfc_dbg("rf_interface_type 0x%x", ntf.rf_interface_type);
+	nfc_dbg("rf_protocol 0x%x", ntf.rf_protocol);
+	nfc_dbg("activation_rf_tech_and_mode 0x%x",
+		ntf.activation_rf_tech_and_mode);
+	nfc_dbg("rf_tech_specific_params_len %d",
 		ntf.rf_tech_specific_params_len);
 
-	switch (ntf.rf_tech_and_mode) {
-	case NCI_NFC_A_PASSIVE_POLL_MODE:
-		rc = nci_rf_activate_nfca_passive_poll(ndev, &ntf,
-			data);
-		break;
+	if (ntf.rf_tech_specific_params_len > 0) {
+		switch (ntf.activation_rf_tech_and_mode) {
+		case NCI_NFC_A_PASSIVE_POLL_MODE:
+			data = nci_extract_rf_params_nfca_passive_poll(ndev,
+				&ntf, data);
+			break;
+
+		default:
+			nfc_err("unsupported activation_rf_tech_and_mode 0x%x",
+				ntf.activation_rf_tech_and_mode);
+			return;
+		}
+	}
 
-	default:
-		nfc_err("unsupported rf_tech_and_mode 0x%x",
-			ntf.rf_tech_and_mode);
-		return;
+	ntf.data_exchange_rf_tech_and_mode = *data++;
+	ntf.data_exchange_tx_bit_rate = *data++;
+	ntf.data_exchange_rx_bit_rate = *data++;
+	ntf.activation_params_len = *data++;
+
+	nfc_dbg("data_exchange_rf_tech_and_mode 0x%x",
+		ntf.data_exchange_rf_tech_and_mode);
+	nfc_dbg("data_exchange_tx_bit_rate 0x%x",
+		ntf.data_exchange_tx_bit_rate);
+	nfc_dbg("data_exchange_rx_bit_rate 0x%x",
+		ntf.data_exchange_rx_bit_rate);
+	nfc_dbg("activation_params_len %d",
+		ntf.activation_params_len);
+
+	if (ntf.activation_params_len > 0) {
+		switch (ntf.rf_interface_type) {
+		case NCI_RF_INTERFACE_ISO_DEP:
+			err = nci_extract_activation_params_iso_dep(ndev,
+				&ntf, data);
+			break;
+
+		case NCI_RF_INTERFACE_FRAME:
+			/* no activation params */
+			break;
+
+		default:
+			nfc_err("unsupported rf_interface_type 0x%x",
+				ntf.rf_interface_type);
+			return;
+		}
 	}
 
-	if (!rc)
+	if (!err)
 		nci_target_found(ndev, &ntf);
 }
 
 static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
 					struct sk_buff *skb)
 {
-	__u8 type = skb->data[0];
+	struct nci_rf_deactivate_ntf *ntf = (void *) skb->data;
 
-	nfc_dbg("entry, type 0x%x", type);
+	nfc_dbg("entry, type 0x%x, reason 0x%x", ntf->type, ntf->reason);
 
 	clear_bit(NCI_POLL_ACTIVE, &ndev->flags);
 	ndev->target_active_prot = 0;
@@ -214,6 +243,9 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
 		ndev->rx_data_reassembly = 0;
 	}
 
+	/* set the available credits to initial value */
+	atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
+
 	/* complete the data exchange transaction, if exists */
 	if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
 		nci_data_exchange_complete(ndev, NULL, -EIO);
@@ -237,12 +269,8 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
 		nci_core_conn_credits_ntf_packet(ndev, skb);
 		break;
 
-	case NCI_OP_RF_FIELD_INFO_NTF:
-		nci_rf_field_info_ntf_packet(ndev, skb);
-		break;
-
-	case NCI_OP_RF_ACTIVATE_NTF:
-		nci_rf_activate_ntf_packet(ndev, skb);
+	case NCI_OP_RF_INTF_ACTIVATED_NTF:
+		nci_rf_intf_activated_ntf_packet(ndev, skb);
 		break;
 
 	case NCI_OP_RF_DEACTIVATE_NTF:
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c
index 0403d4c..1d2a1ce 100644
--- a/net/nfc/nci/rsp.c
+++ b/net/nfc/nci/rsp.c
@@ -42,10 +42,11 @@ static void nci_core_reset_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
 
 	nfc_dbg("entry, status 0x%x", rsp->status);
 
-	if (rsp->status == NCI_STATUS_OK)
+	if (rsp->status == NCI_STATUS_OK) {
 		ndev->nci_ver = rsp->nci_ver;
-
-	nfc_dbg("nci_ver 0x%x", ndev->nci_ver);
+		nfc_dbg("nci_ver 0x%x, config_status 0x%x",
+			rsp->nci_ver, rsp->config_status);
+	}
 
 	nci_req_complete(ndev, rsp->status);
 }
@@ -57,86 +58,76 @@ static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
 
 	nfc_dbg("entry, status 0x%x", rsp_1->status);
 
-	if (rsp_1->status != NCI_STATUS_OK)
-		return;
-
-	ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features);
-	ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces;
-
-	if (ndev->num_supported_rf_interfaces >
-		NCI_MAX_SUPPORTED_RF_INTERFACES) {
+	if (rsp_1->status == NCI_STATUS_OK) {
+		ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features);
 		ndev->num_supported_rf_interfaces =
-			NCI_MAX_SUPPORTED_RF_INTERFACES;
+			rsp_1->num_supported_rf_interfaces;
+
+		if (ndev->num_supported_rf_interfaces >
+			NCI_MAX_SUPPORTED_RF_INTERFACES) {
+			ndev->num_supported_rf_interfaces =
+				NCI_MAX_SUPPORTED_RF_INTERFACES;
+		}
+
+		memcpy(ndev->supported_rf_interfaces,
+			rsp_1->supported_rf_interfaces,
+			ndev->num_supported_rf_interfaces);
+
+		rsp_2 =
+		(void *) (skb->data + 6 + rsp_1->num_supported_rf_interfaces);
+
+		ndev->max_logical_connections =
+			rsp_2->max_logical_connections;
+		ndev->max_routing_table_size =
+			__le16_to_cpu(rsp_2->max_routing_table_size);
+		ndev->max_control_pkt_payload_len =
+			rsp_2->max_control_pkt_payload_len;
+		ndev->max_size_for_large_params =
+			__le16_to_cpu(rsp_2->max_size_for_large_params);
+		ndev->max_data_pkt_payload_size =
+			rsp_2->max_data_pkt_payload_size;
+		ndev->initial_num_credits =
+			rsp_2->initial_num_credits;
+		ndev->manufacturer_id =
+			rsp_2->manufacturer_id;
+		ndev->manufacturer_specific_info =
+			__le32_to_cpu(rsp_2->manufacturer_specific_info);
+
+		atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
+
+		nfc_dbg("nfcc_features 0x%x",
+			ndev->nfcc_features);
+		nfc_dbg("num_supported_rf_interfaces %d",
+			ndev->num_supported_rf_interfaces);
+		nfc_dbg("supported_rf_interfaces[0] 0x%x",
+			ndev->supported_rf_interfaces[0]);
+		nfc_dbg("supported_rf_interfaces[1] 0x%x",
+			ndev->supported_rf_interfaces[1]);
+		nfc_dbg("supported_rf_interfaces[2] 0x%x",
+			ndev->supported_rf_interfaces[2]);
+		nfc_dbg("supported_rf_interfaces[3] 0x%x",
+			ndev->supported_rf_interfaces[3]);
+		nfc_dbg("max_logical_connections %d",
+			ndev->max_logical_connections);
+		nfc_dbg("max_routing_table_size %d",
+			ndev->max_routing_table_size);
+		nfc_dbg("max_control_pkt_payload_len %d",
+			ndev->max_control_pkt_payload_len);
+		nfc_dbg("max_size_for_large_params %d",
+			ndev->max_size_for_large_params);
+		nfc_dbg("max_data_pkt_payload_size %d",
+			ndev->max_data_pkt_payload_size);
+		nfc_dbg("initial_num_credits %d",
+			ndev->initial_num_credits);
+		nfc_dbg("manufacturer_id 0x%x",
+			ndev->manufacturer_id);
+		nfc_dbg("manufacturer_specific_info 0x%x",
+			ndev->manufacturer_specific_info);
 	}
 
-	memcpy(ndev->supported_rf_interfaces,
-		rsp_1->supported_rf_interfaces,
-		ndev->num_supported_rf_interfaces);
-
-	rsp_2 = (void *) (skb->data + 6 + ndev->num_supported_rf_interfaces);
-
-	ndev->max_logical_connections =
-		rsp_2->max_logical_connections;
-	ndev->max_routing_table_size =
-		__le16_to_cpu(rsp_2->max_routing_table_size);
-	ndev->max_control_packet_payload_length =
-		rsp_2->max_control_packet_payload_length;
-	ndev->rf_sending_buffer_size =
-		__le16_to_cpu(rsp_2->rf_sending_buffer_size);
-	ndev->rf_receiving_buffer_size =
-		__le16_to_cpu(rsp_2->rf_receiving_buffer_size);
-	ndev->manufacturer_id =
-		__le16_to_cpu(rsp_2->manufacturer_id);
-
-	nfc_dbg("nfcc_features 0x%x",
-		ndev->nfcc_features);
-	nfc_dbg("num_supported_rf_interfaces %d",
-		ndev->num_supported_rf_interfaces);
-	nfc_dbg("supported_rf_interfaces[0] 0x%x",
-		ndev->supported_rf_interfaces[0]);
-	nfc_dbg("supported_rf_interfaces[1] 0x%x",
-		ndev->supported_rf_interfaces[1]);
-	nfc_dbg("supported_rf_interfaces[2] 0x%x",
-		ndev->supported_rf_interfaces[2]);
-	nfc_dbg("supported_rf_interfaces[3] 0x%x",
-		ndev->supported_rf_interfaces[3]);
-	nfc_dbg("max_logical_connections %d",
-		ndev->max_logical_connections);
-	nfc_dbg("max_routing_table_size %d",
-		ndev->max_routing_table_size);
-	nfc_dbg("max_control_packet_payload_length %d",
-		ndev->max_control_packet_payload_length);
-	nfc_dbg("rf_sending_buffer_size %d",
-		ndev->rf_sending_buffer_size);
-	nfc_dbg("rf_receiving_buffer_size %d",
-		ndev->rf_receiving_buffer_size);
-	nfc_dbg("manufacturer_id 0x%x",
-		ndev->manufacturer_id);
-
 	nci_req_complete(ndev, rsp_1->status);
 }
 
-static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev,
-						struct sk_buff *skb)
-{
-	struct nci_core_conn_create_rsp *rsp = (void *) skb->data;
-
-	nfc_dbg("entry, status 0x%x", rsp->status);
-
-	if (rsp->status != NCI_STATUS_OK)
-		return;
-
-	ndev->max_pkt_payload_size = rsp->max_pkt_payload_size;
-	ndev->initial_num_credits = rsp->initial_num_credits;
-	ndev->conn_id = rsp->conn_id;
-
-	atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
-
-	nfc_dbg("max_pkt_payload_size %d", ndev->max_pkt_payload_size);
-	nfc_dbg("initial_num_credits %d", ndev->initial_num_credits);
-	nfc_dbg("conn_id %d", ndev->conn_id);
-}
-
 static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev,
 					struct sk_buff *skb)
 {
@@ -196,10 +187,6 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
 		nci_core_init_rsp_packet(ndev, skb);
 		break;
 
-	case NCI_OP_CORE_CONN_CREATE_RSP:
-		nci_core_conn_create_rsp_packet(ndev, skb);
-		break;
-
 	case NCI_OP_RF_DISCOVER_MAP_RSP:
 		nci_rf_disc_map_rsp_packet(ndev, skb);
 		break;
-- 
1.7.0.4


^ permalink raw reply related

* Re: BUG: All network processes hang (brcmsmac/wpa_supplicant)
From: Arend van Spriel @ 2011-10-23 10:04 UTC (permalink / raw)
  To: Nico Schottelius, Eric Dumazet, linux-wireless@vger.kernel.org
In-Reply-To: <20111022015945.GC26186@ethz.ch>

On 10/22/2011 03:59 AM, Nico Schottelius wrote:
> Hey Arend,
> 
> it seems that your patch really solves this problem.
> 
> I've got a new one now, though :-)
> 
> After several suspend/resume cycles, my card often reconnects to my AP
> that is only several meters (2) away. If the connection is established,
> I've a very laggy connection to the AP:
> 
> 64 bytes from 192.168.42.1: icmp_req=1154 ttl=64 time=10839 ms
> 64 bytes from 192.168.42.1: icmp_req=1155 ttl=64 time=9841 ms
> ...
> 64 bytes from 192.168.42.1: icmp_req=1164 ttl=64 time=2814 ms
> 64 bytes from 192.168.42.1: icmp_req=1165 ttl=64 time=16785 ms
> 64 bytes from 192.168.42.1: icmp_req=1166 ttl=64 time=20767 ms
> 
> Attached are the usual suspect outputs.
> This time I'm on 2.432 Ghz.
> 
> Cheers,
> 
> Nico
> 

Hi Nico,

I see three different AP's in this log. Could you indicate what AP you
have issues with.

[13087.196234] wlan0: RX AssocResp from 00:03:52:e3:0e:10 (capab=0x11
status=0 aid=3)
[13087.196238] wlan0: associated

[17148.068771] wlan0: RX AssocResp from 00:18:39:50:07:f3 (capab=0x421
status=0 aid=4)
[17148.068776] wlan0: associated

[19010.367351] wlan0: RX AssocResp from 00:14:6c:67:9c:32 (capab=0x611
status=0 aid=2)
[19010.367355] wlan0: associated

With the suspend/resume cycles early in the dmesg log it seems brcmsmac
gets disassoc/deauth before going to sleep. When things start to get
flaky this does not seem to happen and I see a lot of deauth reason=2 in
the log. If I am correct that would mean previousAuthNotValid. Not sure
why we see that. Will try to reproduce this tomorrow.

Gr. AvS


^ permalink raw reply

* [RFC] ipv6 over wireless classification issue?
From: David Täht @ 2011-10-23 10:23 UTC (permalink / raw)
  To: bloat-devel, linux-wireless@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 1932 bytes --]

After slowly working my way down from verifying the apps to ECN handling 
and up from the drivers... I've been (also) slowly working on getting 
wireless qos/aqms to work better, on ipv6. (I need to get to having a 
spectrum analyzer or better instrumentation...) I was puzzled about dscp 
marked ipv6 packets responding differently.

Perhaps this is it. I'm not making this a commit yet (untested code!)

d@cruithne:~/git/linux-2.6/include$ git diff
diff --git a/net/wireless/util.c b/net/wireless/util.c
index be75a3a..a11c5f2 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -658,6 +658,12 @@ unsigned int cfg80211_classify8021d(struct sk_buff 
*skb)
         case htons(ETH_P_IP):
                 dscp = ip_hdr(skb)->tos & 0xfc;
                 break;
+       case htons(ETH_P_IPV6):
+               dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc;
+               break;
+       case htons(ETH_P_ARP):
+               dscp = 4<<5;
+               break;
         default:
                 return 0;
         }


A) Elsewhere in the stack ipv4_get_dsfield is the equivalent of the 
ip_hdr(skb)->tos & 0xfc line
B) It appears ipv6_get_dsfield is safe to call from non-ipv6 enabled 
systems

So my thought would be to also harmonize this with ipv4_get_dsfield...

C) And I doubt that slamming arp packets into the VI queue would be 
acceptable yet (as per the ANTs discussion of a few months back, ARP, 
ND, RA, RS, DHCP, and possibly DNS, ssh (marked interactive), etc might 
do better in the VI queue)
(however this part of the patch is not relevant to the IPv6 issue, it's 
just the patch I wanted to try)

D) Lastly, Later on in this function only dscp's first 3 bits (CS0 - 
CS7) are used to classify packets into the queues, where a mildly saner 
version would use a lookup table to also do sane things with the 
'immediate' bit, perhaps settable via userspace from via sysfs, sysctl, 
or proc.

-- 
Dave Täht


[-- Attachment #2: dave_taht.vcf --]
[-- Type: text/x-vcard, Size: 204 bytes --]

begin:vcard
fn;quoted-printable:Dave T=C3=A4ht
n;quoted-printable:T=C3=A4ht;Dave
email;internet:dave.taht@gmail.com
tel;home:1-239-829-5608
tel;cell:0638645374
x-mozilla-html:FALSE
version:2.1
end:vcard


^ permalink raw reply related

* Re: BUG: All network processes hang (brcmsmac/wpa_supplicant)
From: Nico Schottelius @ 2011-10-23 10:53 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Nico Schottelius, Eric Dumazet, linux-wireless@vger.kernel.org
In-Reply-To: <4EA3E6AD.4030701@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 1564 bytes --]

Hey Arend,

Arend van Spriel [Sun, Oct 23, 2011 at 12:04:29PM +0200]:
> I see three different AP's in this log. Could you indicate what AP you
> have issues with.

Sure, it's this one:

> [19010.367351] wlan0: RX AssocResp from 00:14:6c:67:9c:32 (capab=0x611
> status=0 aid=2)
> [19010.367355] wlan0: associated

It's a WPNT384 (Netgear), an early pre-draft-n ap.

> With the suspend/resume cycles early in the dmesg log it seems brcmsmac
> gets disassoc/deauth before going to sleep. When things start to get
> flaky this does not seem to happen and I see a lot of deauth reason=2 in
> the log. If I am correct that would mean previousAuthNotValid. Not sure
> why we see that. Will try to reproduce this tomorrow.

Thanks for digging in there. I've to update my report: After another two
suspend/resume cycles, the connection works fine again:

64 bytes from 192.168.42.1: icmp_req=38950 ttl=64 time=103 ms
64 bytes from 192.168.42.1: icmp_req=38951 ttl=64 time=47.4 ms
64 bytes from 192.168.42.1: icmp_req=38952 ttl=64 time=34.1 ms
64 bytes from 192.168.42.1: icmp_req=38953 ttl=64 time=3.57 ms
64 bytes from 192.168.42.1: icmp_req=38954 ttl=64 time=10.6 ms
64 bytes from 192.168.42.1: icmp_req=38955 ttl=64 time=1.24 ms
64 bytes from 192.168.42.1: icmp_req=38956 ttl=64 time=64.8 ms
[...]

I'm watching this problem for the next time and as soon it happens
again, I'll test with other wifi devices to verify that the problem
is not within the AP.

I've attached the updated dmesg.

Cheers,

Nico

-- 
PGP key: 7ED9 F7D3 6B10 81D7 0EC5  5C09 D7DC C8E4 3187 7DF0

[-- Attachment #2: dmesg.gz --]
[-- Type: application/octet-stream, Size: 69222 bytes --]

^ permalink raw reply

* Re: [RFC 1/7] mac80211: mesh power mode indication in QoS frames
From: Ivan Bezyazychnyy @ 2011-10-23 13:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1319190767.3964.8.camel@jlt3.sipsolutions.net>

On 21 October 2011 13:52, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Fri, 2011-10-21 at 12:36 +0400, Ivan Bezyazychnyy wrote:
>
>> +/* mesh power save level subfield mask */
>> +#define IEEE80211_QOS_CTL_PS_LEVEL      0x0200
>
> That looks like it could use a better name?

Do you mean something like IEEE80211_QOS_CTL_MESH_POWER_SAVE_LEVEL?
The first half is similar to previous constants.

Thanks,
Ivan

^ permalink raw reply

* Re: [RFC 4/7] mac80211: setting link-specific mesh power modes when plink open
From: Ivan Bezyazychnyy @ 2011-10-23 13:12 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1319191502.3964.11.camel@jlt3.sipsolutions.net>

On 21 October 2011 14:05, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Fri, 2011-10-21 at 12:37 +0400, Ivan Bezyazychnyy wrote:
>> Setting peer link-specific power mode equal to peer non-peer power mode
>> value and local link-specific power mode equal to local non-peer value
>
> You really need more verbose changelogs, I can't even parse that
> properly. How about mentioning why, what it means, etc?

Yes, I understand.

> You should also extend your cover letter to explain how the power save
> stuff works.
OK. Thank you very much for all comments.

--Ivan

^ permalink raw reply

* Re: lockdep in mac80211
From: Arik Nemtsov @ 2011-10-23 15:12 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg
In-Reply-To: <CA+XVXffT6pq0bKZrVmrYDqustkTFt_ot99BPK_Q5JmXU3wE0iQ@mail.gmail.com>

On Wed, Oct 19, 2011 at 00:12, Arik Nemtsov <arik@wizery.com> wrote:
> http://pastebin.com/qX3SLy2H
>
> This appears to be a legitimate lockdep (when trying to re-connect to
> an AP whose password I just changed).
> These take the locks in reverse order:
>
> ieee80211_work_work() -> ieee80211_authenticate() (Inlined in the
> lockdep print).
> ieee80211_sta_rx_queued_mgmt() -> ieee80211_rx_mgmt_disassoc()
>

Please disregard this one. The problem was with an internal patch I
was using for testing (as can be seen in the stack trace as well).

Arik

^ permalink raw reply

* Compat-wireless release for 2011-10-23 is baked
From: Compat-wireless cronjob account @ 2011-10-23 19:02 UTC (permalink / raw)
  To: linux-wireless


compat-wireless code metrics

    814119 - Total upstream lines of code being pulled
      2431 - backport code changes
      2113 - backport code additions
       318 - backport code deletions
      8588 - backport from compat module
     11019 - total backport code
    1.3535 - % of code consists of backport work

^ permalink raw reply

* [PATCH] mac80211: Fix TDLS support validation in add_station handler
From: Jouni Malinen @ 2011-10-23 19:36 UTC (permalink / raw)
  To: John W. Linville, Johannes Berg; +Cc: linux-wireless, Arik Nemtsov

We need to verify whether the command is successful before allocating
the station entry to avoid extra processing. This also fixes a memory
leak on the error path.

Signed-off-by: Jouni Malinen <j@w1.fi>
---
 net/mac80211/cfg.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e253afa..a9ded52 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -832,6 +832,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
 	if (is_multicast_ether_addr(mac))
 		return -EINVAL;
 
+	/* Only TDLS-supporting stations can add TDLS peers */
+	if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
+	    !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
+	      sdata->vif.type == NL80211_IFTYPE_STATION))
+		return -ENOTSUPP;
+
 	sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
 	if (!sta)
 		return -ENOMEM;
@@ -841,12 +847,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
 
 	sta_apply_parameters(local, sta, params);
 
-	/* Only TDLS-supporting stations can add TDLS peers */
-	if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
-	    !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
-	      sdata->vif.type == NL80211_IFTYPE_STATION))
-		return -ENOTSUPP;
-
 	rate_control_rate_init(sta);
 
 	layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
-- 
1.7.4.1


-- 
Jouni Malinen                                            PGP id EFC895FA

^ 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