Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH] mac80211: allow key deletion for mesh interface
From: Yeoh Chun-Yeow @ 2013-06-18  9:07 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-wireless@vger.kernel.org, John Linville,
	devel@lists.open80211s.org
In-Reply-To: <CAEFj9864ioXkUy3Sg24k6vFTNR8ZfWj=to54J2VS=dvte+ExNA@mail.gmail.com>

In sta_info_get_bss, should it be:

if ((sta->sdata == sdata &&
                     (sta->sdata->bss && sta->sdata->bss == sdata->bss))

in stead of

if ((sta->sdata == sdata ||
                     (sta->sdata->bss && sta->sdata->bss == sdata->bss))

Otherwise, it seems that we still manage to get sta pointer even the
bss is NULL.

---
Chun-Yeow

On Tue, Jun 18, 2013 at 4:14 PM, Yeoh Chun-Yeow <yeohchunyeow@gmail.com> wrote:
> In the ieee80211_free_sta_keys, the key idx 4 is not deleted, since it
> is limited by NUM_DEFAULT_KEYS.
>
> ----
> Chun-Yeow
>
> On Tue, Jun 18, 2013 at 3:56 PM, Yeoh Chun-Yeow <yeohchunyeow@gmail.com> wrote:
>> In authsae, we have a GTK with key index 4 as follow:
>> install_key(&nlcfg, peer, CIPHER_AES_CMAC, NL80211_KEYTYPE_GROUP, 4, peer_mgtk);
>>
>> We may need to delete this key while doing re-authentication for the
>> same peer mesh STA due to accidental reboot. Otherwise, this GTK key
>> is not deleted.
>>
>> ---
>> Chun-Yeow
>>
>> On Tue, Jun 18, 2013 at 3:31 PM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>>> On Tue, 2013-06-18 at 12:07 +0800, Chun-Yeow Yeoh wrote:
>>>> This is to support key deletion for mesh interface, especially
>>>> to be used for key which is not deleted even with the deletion
>>>> of peer mesh station.
>>>
>>> Can you explain which keys in mesh aren't deleted? It seems the
>>> per-station keys would be deleted when the station is deleted, and
>>> something like "GTK" would be deleted when leaving the mesh?
>>>
>>> johannes
>>>

^ permalink raw reply

* Re: [PATCH] mac80211: allow key deletion for mesh interface
From: Johannes Berg @ 2013-06-18  9:36 UTC (permalink / raw)
  To: Yeoh Chun-Yeow
  Cc: linux-wireless@vger.kernel.org, John Linville,
	devel@lists.open80211s.org
In-Reply-To: <CAEFj987DCjNuv+W3oSq6ubHwjnkmKgKvcDThhP8s9ZXBsKmcjg@mail.gmail.com>

On Tue, 2013-06-18 at 17:07 +0800, Yeoh Chun-Yeow wrote:
> In sta_info_get_bss, should it be:
> 
> if ((sta->sdata == sdata &&
>                      (sta->sdata->bss && sta->sdata->bss == sdata->bss))
> 
> in stead of
> 
> if ((sta->sdata == sdata ||
>                      (sta->sdata->bss && sta->sdata->bss == sdata->bss))

What would the point be? Then we could just as well make it *only*
	sta->sdata == sdata
and it'd be the same as sta_info_get(). This is intentional for VLAN
handling.

> Otherwise, it seems that we still manage to get sta pointer even the
> bss is NULL.

What's the problem with that? But if this is a problem maybe we need to
explicitly check for non-NULL?

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: allow key deletion for mesh interface
From: Johannes Berg @ 2013-06-18  9:37 UTC (permalink / raw)
  To: Yeoh Chun-Yeow
  Cc: linux-wireless@vger.kernel.org, John Linville,
	devel@lists.open80211s.org
In-Reply-To: <1371548163.8318.2.camel@jlt4.sipsolutions.net>

On Tue, 2013-06-18 at 11:36 +0200, Johannes Berg wrote:

> > Otherwise, it seems that we still manage to get sta pointer even the
> > bss is NULL.
> 
> What's the problem with that? But if this is a problem maybe we need to
> explicitly check for non-NULL?

I should pay attention ... we already check for non-NULL, so I don't
understand what you're trying to say at all.

Maybe you're looking at old code?

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: allow key deletion for mesh interface
From: Johannes Berg @ 2013-06-18  9:39 UTC (permalink / raw)
  To: Chun-Yeow Yeoh; +Cc: linux-wireless, linville, devel
In-Reply-To: <1371528422-20710-1-git-send-email-yeohchunyeow@gmail.com>

On Tue, 2013-06-18 at 12:07 +0800, Chun-Yeow Yeoh wrote:

> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -239,7 +239,10 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
>  	if (mac_addr) {
>  		ret = -ENOENT;
>  
> -		sta = sta_info_get_bss(sdata, mac_addr);
> +		if (ieee80211_vif_is_mesh(&sdata->vif))
> +			sta = sta_info_get(sdata, mac_addr);
> +		else
> +			sta = sta_info_get_bss(sdata, mac_addr);

I don't see that this actually changes anything. The mesh sdata will
have a NULL bss pointer, so the second condition in sta_info_get_bss()
can't be true.

Therefore, only the first condition can ever be considered, which is
exactly the same as sta_info_get(), no?

johannes


^ permalink raw reply

* [PATCH] initvals: Add rxgain tables for AR9462
From: Sujith Manoharan @ 2013-06-18 10:12 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 tools/initvals/ar9462_2p0_initvals.h | 15 +++++++++++++++
 tools/initvals/checksums.txt         |  2 ++
 tools/initvals/initvals.c            |  4 ++++
 3 files changed, 21 insertions(+)

diff --git a/tools/initvals/ar9462_2p0_initvals.h b/tools/initvals/ar9462_2p0_initvals.h
index bcd0cae..1d6b705 100644
--- a/tools/initvals/ar9462_2p0_initvals.h
+++ b/tools/initvals/ar9462_2p0_initvals.h
@@ -1714,4 +1714,19 @@ static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = {
 	{0x0000b1fc, 0x00000196},
 };
 
+static const u32 ar9462_2p0_baseband_core_mix_rxgain[][2] = {
+	/* Addr      allmodes  */
+	{0x00009fd0, 0x0a2d6b93},
+};
+
+static const u32 ar9462_2p0_baseband_postamble_mix_rxgain[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
+	{0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
+	{0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
+	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
+	{0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
+	{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
+};
+
 #endif /* INITVALS_9462_2P0_H */
diff --git a/tools/initvals/checksums.txt b/tools/initvals/checksums.txt
index 758ff85..c224297 100644
--- a/tools/initvals/checksums.txt
+++ b/tools/initvals/checksums.txt
@@ -158,6 +158,8 @@ c8dc777b012068116cd5282aade8eb460f397d20        ar9462_2p0_mac_postamble
 72675fd0f308e6f31502e283119e12469d262f40        ar9462_common_mixed_rx_gain_table_2p0
 185f0537e40b74dcc4db33c7e111c1bfe79f3104        ar9462_2p0_baseband_postamble_5g_xlna
 72675fd0f308e6f31502e283119e12469d262f40        ar9462_2p0_5g_xlna_only_rxgain
+8f24703571c460bced3d0fea95b5cfeac34a724d        ar9462_2p0_baseband_core_mix_rxgain
+cb83a8c304aae0b6fc937e61d145253a8f470d24        ar9462_2p0_baseband_postamble_mix_rxgain
 c8dc777b012068116cd5282aade8eb460f397d20        ar9485_1_1_mac_postamble
 5d20e4848b97566ad55e0e95458463d622ee5480        ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1
 d9a90632a00a7b417154173b947dfffdeab23e51        ar9485Common_wo_xlna_rx_gain_1_1
diff --git a/tools/initvals/initvals.c b/tools/initvals/initvals.c
index 2d1edba..6b72f29 100644
--- a/tools/initvals/initvals.c
+++ b/tools/initvals/initvals.c
@@ -319,6 +319,8 @@ struct initval_family {
 #define ar9300Common_mixed_rx_gain_table_jupiter_2p0		ar9462_common_mixed_rx_gain_table_2p0
 #define ar9300_jupiter_2p0_baseband_postamble_5g_xlna		ar9462_2p0_baseband_postamble_5g_xlna
 #define ar9300Common_5g_xlna_only_rx_gain_table_jupiter_2p0	ar9462_2p0_5g_xlna_only_rxgain
+#define ar9300_jupiter_2p0_baseband_core_mix_rxgain		ar9462_2p0_baseband_core_mix_rxgain
+#define ar9300_jupiter_2p0_baseband_postamble_mix_rxgain	ar9462_2p0_baseband_postamble_mix_rxgain
 
 #include "ar9300_jupiter20.ini"
 
@@ -906,6 +908,8 @@ static void ar9462_2p0_hw_print_initvals(bool check)
 	INI_PRINT(ar9462_common_mixed_rx_gain_table_2p0);
 	INI_PRINT(ar9462_2p0_baseband_postamble_5g_xlna);
 	INI_PRINT(ar9462_2p0_5g_xlna_only_rxgain);
+	INI_PRINT(ar9462_2p0_baseband_core_mix_rxgain);
+	INI_PRINT(ar9462_2p0_baseband_postamble_mix_rxgain);
 }
 
 static void ar9565_1p0_hw_print_initvals(bool check)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 1/3] ath9k: Add PCI IDs for CUS217
From: Sujith Manoharan @ 2013-06-18 10:12 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

CUS217 is a card based on AR9462.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |  1 +
 drivers/net/wireless/ath/ath9k/init.c  |  2 ++
 drivers/net/wireless/ath/ath9k/pci.c   | 13 +++++++++++++
 3 files changed, 16 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1a0a168..04b2d3e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -633,6 +633,7 @@ void ath_ant_comb_update(struct ath_softc *sc);
 
 #define ATH9K_PCI_CUS198 0x0001
 #define ATH9K_PCI_CUS230 0x0002
+#define ATH9K_PCI_CUS217 0x0004
 
 /*
  * Default cache line size, in bytes.
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 0d17415..1e555d8 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -529,6 +529,8 @@ static void ath9k_init_platform(struct ath_softc *sc)
 		ath_info(common, "Set parameters for %s\n",
 			 (sc->driver_data & ATH9K_PCI_CUS198) ?
 			 "CUS198" : "CUS230");
+	} else if (sc->driver_data & ATH9K_PCI_CUS217) {
+		ath_info(common, "CUS217 card detected\n");
 	}
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index ddf0d78..b096bb2 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -66,6 +66,19 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
 
 	{ PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E  AR9485 */
 	{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E  AR9580 */
+
+	/* PCI-E CUS217 */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 PCI_VENDOR_ID_AZWAVE,
+			 0x2116),
+	  .driver_data = ATH9K_PCI_CUS217 },
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+			 0x0034,
+			 0x11AD, /* LITEON */
+			 0x6661),
+	  .driver_data = ATH9K_PCI_CUS217 },
+
 	{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E  AR9462 */
 	{ PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E  AR1111/AR9485 */
 	{ PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E  AR9565 */
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 2/3] ath9k: Add initvals required for CUS217
From: Sujith Manoharan @ 2013-06-18 10:12 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1371550358-5920-1-git-send-email-sujith@msujith.org>

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index bcd0cae..1d6b705 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -1714,4 +1714,19 @@ static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = {
 	{0x0000b1fc, 0x00000196},
 };
 
+static const u32 ar9462_2p0_baseband_core_mix_rxgain[][2] = {
+	/* Addr      allmodes  */
+	{0x00009fd0, 0x0a2d6b93},
+};
+
+static const u32 ar9462_2p0_baseband_postamble_mix_rxgain[][5] = {
+	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
+	{0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
+	{0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
+	{0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
+	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
+	{0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
+	{0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
+};
+
 #endif /* INITVALS_9462_2P0_H */
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 3/3] ath9k: Program initvals for CUS217
From: Sujith Manoharan @ 2013-06-18 10:12 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless
In-Reply-To: <1371550358-5920-1-git-send-email-sujith@msujith.org>

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_hw.c  |  4 ++++
 drivers/net/wireless/ath/ath9k/ar9003_phy.c | 10 ++++++++++
 drivers/net/wireless/ath/ath9k/hw.h         |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index ce748af..671aaa7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -630,6 +630,10 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
 	if (AR_SREV_9462_20(ah)) {
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			       ar9462_common_mixed_rx_gain_table_2p0);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
+			       ar9462_2p0_baseband_core_mix_rxgain);
+		INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
+			       ar9462_2p0_baseband_postamble_mix_rxgain);
 		INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
 			       ar9462_2p0_baseband_postamble_5g_xlna);
 	}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index df919e2..df84d20 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -756,6 +756,16 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
 
 	if (AR_SREV_9462_20(ah)) {
 		/*
+		 * CUS217 mix LNA mode.
+		 */
+		if (ar9003_hw_get_rx_gain_idx(ah) == 2) {
+			REG_WRITE_ARRAY(&ah->ini_modes_rxgain_bb_core,
+					1, regWrites);
+			REG_WRITE_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
+					modesIndex, regWrites);
+		}
+
+		/*
 		 * 5G-XLNA
 		 */
 		if ((ar9003_hw_get_rx_gain_idx(ah) == 2) ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e076639..cd74b3a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -893,6 +893,8 @@ struct ath_hw {
 	struct ar5416IniArray iniModes_9271_ANI_reg;
 	struct ar5416IniArray ini_radio_post_sys2ant;
 	struct ar5416IniArray ini_modes_rxgain_5g_xlna;
+	struct ar5416IniArray ini_modes_rxgain_bb_core;
+	struct ar5416IniArray ini_modes_rxgain_bb_postamble;
 
 	struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
 	struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Revert "mac80211: in IBSS use the Auth frame to trigger STA reinsertion"
From: Antonio Quartulli @ 2013-06-18 10:45 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

This reverts commit 6d810f10325522cfcf498dc6d64b9f96e1f5153f

In this way an IBSS station will not use the AUTH messages
to trigger a state reinitialisation anymore.

The behaviour was racy and was not working properly.
It has been introduced to help wpa_supplicant to support
IBSS/RSN, however all the logic is now getting moved into
wpa_s itself which will also be in charge of handling the
AUTH messages thanks to the mgmt frame registration.

If userspace does not register for receiving AUTH frames
then mac80211 will still reply by itself.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/mac80211/ibss.c | 41 +++++++----------------------------------
 1 file changed, 7 insertions(+), 34 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index caa4b4f..6c9d21a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -298,8 +298,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 				  tsf, false);
 }
 
-static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
-						  bool auth)
+static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
 	__acquires(RCU)
 {
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -321,20 +320,12 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
 	/* If it fails, maybe we raced another insertion? */
 	if (sta_info_insert_rcu(sta))
 		return sta_info_get(sdata, addr);
-	if (auth && !sdata->u.ibss.auth_frame_registrations) {
-		ibss_dbg(sdata,
-			 "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
-			 sdata->vif.addr, addr, sdata->u.ibss.bssid);
-		ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0,
-				    addr, sdata->u.ibss.bssid, NULL, 0, 0, 0);
-	}
 	return sta;
 }
 
 static struct sta_info *
-ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
-		       const u8 *bssid, const u8 *addr,
-		       u32 supp_rates, bool auth)
+ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
+		       const u8 *addr, u32 supp_rates)
 	__acquires(RCU)
 {
 	struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -385,7 +376,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 	sta->sta.supp_rates[band] = supp_rates |
 			ieee80211_mandatory_rates(sband);
 
-	return ieee80211_ibss_finish_sta(sta, auth);
+	return ieee80211_ibss_finish_sta(sta);
 }
 
 static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
@@ -407,8 +398,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
 					size_t len)
 {
 	u16 auth_alg, auth_transaction;
-	struct sta_info *sta;
-	u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
 
 	sdata_assert_lock(sdata);
 
@@ -425,22 +414,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
 	if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
 		return;
 
-	sta_info_destroy_addr(sdata, mgmt->sa);
-	sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
-	rcu_read_unlock();
-
-	/*
-	 * if we have any problem in allocating the new station, we reply with a
-	 * DEAUTH frame to tell the other end that we had a problem
-	 */
-	if (!sta) {
-		ieee80211_send_deauth_disassoc(sdata, sdata->u.ibss.bssid,
-					       IEEE80211_STYPE_DEAUTH,
-					       WLAN_REASON_UNSPECIFIED, true,
-					       deauth_frame_buf);
-		return;
-	}
-
 	/*
 	 * IEEE 802.11 standard does not require authentication in IBSS
 	 * networks and most implementations do not seem to use it.
@@ -506,7 +479,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 			} else {
 				rcu_read_unlock();
 				sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
-						mgmt->sa, supp_rates, true);
+						mgmt->sa, supp_rates);
 			}
 		}
 
@@ -610,7 +583,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 		ieee80211_sta_join_ibss(sdata, bss);
 		supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL);
 		ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
-				       supp_rates, true);
+				       supp_rates);
 		rcu_read_unlock();
 	}
 
@@ -982,7 +955,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
 		list_del(&sta->list);
 		spin_unlock_bh(&ifibss->incomplete_lock);
 
-		ieee80211_ibss_finish_sta(sta, true);
+		ieee80211_ibss_finish_sta(sta);
 		rcu_read_unlock();
 		spin_lock_bh(&ifibss->incomplete_lock);
 	}
-- 
1.8.1.5


^ permalink raw reply related

* wl12xx.git tree has been rebased (3.10)
From: Luciano Coelho @ 2013-06-18 10:54 UTC (permalink / raw)
  To: linux-wireless

Hi,

I have rebased the master branch of the wl12xx.git tree to sync with
John's latest tree (based on 3.10-rc5). 

I have also rebased the wl12xx-next branch, to reflect the rebases
John's latest in wireless-next.

Please update your local copies.

-- 
Cheers,
Luca.


^ permalink raw reply

* pull request: TI wireless drivers 2013-06-18 (for 3.11)
From: Luciano Coelho @ 2013-06-18 10:55 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

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

Hi John,

Here are a few patches intended for 3.11.  There's nothing major.  A
bunch of bug fixes here and there, a hardware bug workaround and some
small clean-ups.

Please let me know if you have any problems with it!

The following changes since commit 1105a13bb8ad29cf83d46989ee462d196038be87:

  orinoco_usb: fix memory leak in ezusb_access_ltv() when device disconnected (2013-06-14 13:37:16 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git for-linville

for you to fetch changes up to 789e90e567d7d93edc1b2001d17209c21cc37850:

  net: wireless: wl1251: Fix commenting style (2013-06-17 12:24:09 +0300)

----------------------------------------------------------------
Arik Nemtsov (2):
      wlcore: cancel channel switch work on interface removal
      wlcore: hold jiffies in unsigned long

Eliad Peller (1):
      wlcore: configure rates in multiple cases

Ido Reis (1):
      wl18xx: FDSP Code RAM Corruption fix

Luciano Coelho (3):
      wlcore: some non-functional clean-ups in main.c
      wlcore: move sysfs handling to a separate file
      wl18xx: use locally administered MAC address if not available from fuse

Peter Huewe (1):
      net/wireless/ti/wlcore/spi: Use module_spi_driver to register driver

Sachin Kamat (2):
      net: wireless: wl1251: Use module_spi_driver macro
      net: wireless: wl1251: Fix commenting style

Victor Goldenshtein (1):
      wlcore: fix occasional AP TX stop after recovery

Yoni Divinsky (1):
      wlcore: set default_wep_key when configured

 drivers/net/wireless/ti/wl1251/spi.c    |   30 +------
 drivers/net/wireless/ti/wl18xx/main.c   |   47 +++++++++-
 drivers/net/wireless/ti/wl18xx/reg.h    |   15 ++++
 drivers/net/wireless/ti/wlcore/Makefile |    2 +-
 drivers/net/wireless/ti/wlcore/main.c   |  265 ++++++++++++--------------------------------------------
 drivers/net/wireless/ti/wlcore/ps.c     |    2 +-
 drivers/net/wireless/ti/wlcore/spi.c    |   14 +--
 drivers/net/wireless/ti/wlcore/sysfs.c  |  216 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ti/wlcore/sysfs.h  |   28 ++++++
 drivers/net/wireless/ti/wlcore/tx.c     |    2 +-
 10 files changed, 367 insertions(+), 254 deletions(-)
 create mode 100644 drivers/net/wireless/ti/wlcore/sysfs.c
 create mode 100644 drivers/net/wireless/ti/wlcore/sysfs.h

-- 
Cheers,
Luca.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH] Revert "mac80211: in IBSS use the Auth frame to trigger STA reinsertion"
From: Nicolas Cavallari @ 2013-06-18 11:26 UTC (permalink / raw)
  To: Antonio Quartulli; +Cc: linux-wireless
In-Reply-To: <1371552313-3581-1-git-send-email-ordex@autistici.org>

On 18/06/2013 12:45, Antonio Quartulli wrote:
> -	if (auth && !sdata->u.ibss.auth_frame_registrations) {

The sole purpose of the auth_frame_registrations field is to be checked by this code.
The field and the code maintaining this field can be removed now.

^ permalink raw reply

* [PATCH 8/8] brcmfmac: add sdio sg list support
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

From: Franky Lin <frankyl@broadcom.com>

Add scatter gather list support for better rx glom performance.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |  149 +++++++++++++++++---
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   73 ----------
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |   82 +----------
 .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |    7 -
 4 files changed, 137 insertions(+), 174 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 32a205e..3f8e69c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -22,9 +22,11 @@
 #include <linux/pci_ids.h>
 #include <linux/sched.h>
 #include <linux/completion.h>
+#include <linux/scatterlist.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
 #include <linux/platform_data/brcmfmac-sdio.h>
 
 #include <defs.h>
@@ -316,34 +318,138 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
  * caller has already been padded and aligned.
  */
 static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
-			     bool write, u32 addr, struct sk_buff *pkt)
+			     bool write, u32 addr, struct sk_buff_head *pktlist)
 {
-	uint len;
+	unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
+	unsigned int max_blks, max_req_sz;
+	unsigned short max_seg_sz, seg_sz;
+	unsigned char *pkt_data;
+	struct sk_buff *pkt_next = NULL;
+	struct mmc_request mmc_req;
+	struct mmc_command mmc_cmd;
+	struct mmc_data mmc_dat;
+	struct sg_table st;
+	struct scatterlist *sgl;
+	struct mmc_host *host;
+	int ret = 0;
+
+	if (!pktlist->qlen)
+		return -EINVAL;
 
 	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
 	if (brcmf_pm_resume_error(sdiodev))
 		return -EIO;
 
 	/* Single skb use the standard mmc interface */
-	if (!pkt->next) {
-		len = pkt->len + 3;
-		len &= (uint)~3;
+	if (pktlist->qlen == 1) {
+		pkt_next = pktlist->next;
+		req_sz = pkt_next->len + 3;
+		req_sz &= (uint)~3;
 
 		if (write)
 			return sdio_memcpy_toio(sdiodev->func[fn], addr,
-						((u8 *)(pkt->data)), len);
+						((u8 *)(pkt_next->data)),
+						req_sz);
 		else if (fn == 1)
 			return sdio_memcpy_fromio(sdiodev->func[fn],
-						  ((u8 *)(pkt->data)), addr,
-						  len);
+						  ((u8 *)(pkt_next->data)),
+						  addr, req_sz);
 		else
 			/* function 2 read is FIFO operation */
 			return sdio_readsb(sdiodev->func[fn],
-					   ((u8 *)(pkt->data)), addr, len);
+					   ((u8 *)(pkt_next->data)), addr,
+					   req_sz);
 	}
 
-	brcmf_err("skb chain is not supported yet.\n");
-	return -EOPNOTSUPP;
+	host = sdiodev->func[fn]->card->host;
+	func_blk_sz = sdiodev->func[fn]->cur_blksize;
+	/* Blocks per command is limited by host count, host transfer
+	 * size and the maximum for IO_RW_EXTENDED of 511 blocks.
+	 */
+	max_blks = min_t(unsigned int, host->max_blk_count, 511u);
+	max_req_sz = min_t(unsigned int, host->max_req_size,
+			   max_blks * func_blk_sz);
+	max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC);
+	max_seg_sz = min_t(unsigned short, max_seg_sz, pktlist->qlen);
+	seg_sz = pktlist->qlen;
+	pkt_offset = 0;
+	pkt_next = pktlist->next;
+
+	if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL))
+		return -ENOMEM;
+
+	while (seg_sz) {
+		req_sz = 0;
+		sg_cnt = 0;
+		memset(&mmc_req, 0, sizeof(struct mmc_request));
+		memset(&mmc_cmd, 0, sizeof(struct mmc_command));
+		memset(&mmc_dat, 0, sizeof(struct mmc_data));
+		sgl = st.sgl;
+		/* prep sg table */
+		while (pkt_next != (struct sk_buff *)pktlist) {
+			pkt_data = pkt_next->data + pkt_offset;
+			sg_data_sz = pkt_next->len - pkt_offset;
+			if (sg_data_sz > host->max_seg_size)
+				sg_data_sz = host->max_seg_size;
+			if (sg_data_sz > max_req_sz - req_sz)
+				sg_data_sz = max_req_sz - req_sz;
+
+			sg_set_buf(sgl, pkt_data, sg_data_sz);
+
+			sg_cnt++;
+			sgl = sg_next(sgl);
+			req_sz += sg_data_sz;
+			pkt_offset += sg_data_sz;
+			if (pkt_offset == pkt_next->len) {
+				pkt_offset = 0;
+				pkt_next = pkt_next->next;
+			}
+
+			if (req_sz >= max_req_sz || sg_cnt >= max_seg_sz)
+				break;
+		}
+		seg_sz -= sg_cnt;
+
+		if (req_sz % func_blk_sz != 0) {
+			brcmf_err("sg request length %u is not %u aligned\n",
+				  req_sz, func_blk_sz);
+			sg_free_table(&st);
+			return -ENOTBLK;
+		}
+		mmc_dat.sg = st.sgl;
+		mmc_dat.sg_len = sg_cnt;
+		mmc_dat.blksz = func_blk_sz;
+		mmc_dat.blocks = req_sz / func_blk_sz;
+		mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+		mmc_cmd.opcode = SD_IO_RW_EXTENDED;
+		mmc_cmd.arg = write ? 1<<31 : 0;	/* write flag  */
+		mmc_cmd.arg |= (fn & 0x7) << 28;	/* SDIO func num */
+		mmc_cmd.arg |= 1<<27;			/* block mode */
+		/* incrementing addr for function 1 */
+		mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
+		mmc_cmd.arg |= (addr & 0x1FFFF) << 9;	/* address */
+		mmc_cmd.arg |= mmc_dat.blocks & 0x1FF;	/* block count */
+		mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+		mmc_req.cmd = &mmc_cmd;
+		mmc_req.data = &mmc_dat;
+		if (fn == 1)
+			addr += req_sz;
+
+		mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card);
+		mmc_wait_for_req(host, &mmc_req);
+
+		ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
+		if (ret != 0) {
+			brcmf_err("CMD53 sg block %s failed %d\n",
+				  write ? "write" : "read", ret);
+			ret = -EIO;
+			break;
+		}
+	}
+
+	sg_free_table(&st);
+
+	return ret;
 }
 
 static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
@@ -400,6 +506,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 {
 	uint width;
 	int err = 0;
+	struct sk_buff_head pkt_list;
 
 	brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
 		  fn, addr, pkt->len);
@@ -409,7 +516,10 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	if (err)
 		goto done;
 
-	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt);
+	skb_queue_head_init(&pkt_list);
+	skb_queue_tail(&pkt_list, pkt);
+	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, &pkt_list);
+	skb_dequeue_tail(&pkt_list);
 
 done:
 	return err;
@@ -431,8 +541,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		goto done;
 
 	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
-	err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr,
-					pktq);
+	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq);
 
 done:
 	return err;
@@ -467,6 +576,7 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	uint width;
 	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
 	int err = 0;
+	struct sk_buff_head pkt_list;
 
 	brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
 		  fn, addr, pkt->len);
@@ -489,7 +599,10 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	if (width == 4)
 		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-	err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, pkt);
+	skb_queue_head_init(&pkt_list);
+	skb_queue_tail(&pkt_list, pkt);
+	err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list);
+	skb_dequeue_tail(&pkt_list);
 
 done:
 	return err;
@@ -503,6 +616,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 	struct sk_buff *pkt;
 	u32 sdaddr;
 	uint dsize;
+	struct sk_buff_head pkt_list;
 
 	dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
 	pkt = dev_alloc_skb(dsize);
@@ -511,6 +625,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 		return -EIO;
 	}
 	pkt->priority = 0;
+	skb_queue_head_init(&pkt_list);
 
 	/* Determine initial transfer parameters */
 	sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
@@ -538,8 +653,10 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 		skb_put(pkt, dsize);
 		if (write)
 			memcpy(pkt->data, data, dsize);
+		skb_queue_tail(&pkt_list, pkt);
 		bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write,
-					     sdaddr, pkt);
+					     sdaddr, &pkt_list);
+		skb_dequeue_tail(&pkt_list);
 		if (bcmerror) {
 			brcmf_err("membytes transfer failed\n");
 			break;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 7a3c5bf..289e386 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -211,78 +211,6 @@ int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
 	return err_ret;
 }
 
-/* precondition: host controller is claimed */
-static int
-brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo,
-			 uint func, uint addr, struct sk_buff *pkt, uint pktlen)
-{
-	int err_ret = 0;
-
-	if ((write) && (!fifo)) {
-		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
-					   ((u8 *) (pkt->data)), pktlen);
-	} else if (write) {
-		err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
-					   ((u8 *) (pkt->data)), pktlen);
-	} else if (fifo) {
-		err_ret = sdio_readsb(sdiodev->func[func],
-				      ((u8 *) (pkt->data)), addr, pktlen);
-	} else {
-		err_ret = sdio_memcpy_fromio(sdiodev->func[func],
-					     ((u8 *) (pkt->data)),
-					     addr, pktlen);
-	}
-
-	return err_ret;
-}
-
-/*
- * This function takes a queue of packets. The packets on the queue
- * are assumed to be properly aligned by the caller.
- */
-int
-brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
-			  uint write, uint func, uint addr,
-			  struct sk_buff_head *pktq)
-{
-	bool fifo = (fix_inc == SDIOH_DATA_FIX);
-	u32 SGCount = 0;
-	int err_ret = 0;
-
-	struct sk_buff *pkt;
-
-	brcmf_dbg(SDIO, "Enter\n");
-
-	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_chain_wait);
-	if (brcmf_pm_resume_error(sdiodev))
-		return -EIO;
-
-	skb_queue_walk(pktq, pkt) {
-		uint pkt_len = pkt->len;
-		pkt_len += 3;
-		pkt_len &= 0xFFFFFFFC;
-
-		err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
-						   addr, pkt, pkt_len);
-		if (err_ret) {
-			brcmf_err("%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
-				  write ? "TX" : "RX", pkt, SGCount, addr,
-				  pkt_len, err_ret);
-		} else {
-			brcmf_dbg(SDIO, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
-				  write ? "TX" : "RX", pkt, SGCount, addr,
-				  pkt_len);
-		}
-		if (!fifo)
-			addr += pkt_len;
-
-		SGCount++;
-	}
-
-	brcmf_dbg(SDIO, "Exit\n");
-	return err_ret;
-}
-
 static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
 {
 	/* read 24 bits and return valid 17 bit addr */
@@ -431,7 +359,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
 	atomic_set(&sdiodev->suspend, false);
 	init_waitqueue_head(&sdiodev->request_byte_wait);
 	init_waitqueue_head(&sdiodev->request_word_wait);
-	init_waitqueue_head(&sdiodev->request_chain_wait);
 	init_waitqueue_head(&sdiodev->request_buffer_wait);
 
 	brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n");
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index cb22f2f..2641119 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -448,8 +448,6 @@ struct brcmf_sdio {
 	uint rxblen;		/* Allocated length of rxbuf */
 	u8 *rxctl;		/* Aligned pointer into rxbuf */
 	u8 *rxctl_orig;		/* pointer for freeing rxctl */
-	u8 *databuf;		/* Buffer for receiving big glom packet */
-	u8 *dataptr;		/* Aligned pointer into databuf */
 	uint rxlen;		/* Length of valid data in buffer */
 	spinlock_t rxctl_lock;	/* protection lock for ctrl frame resources */
 
@@ -473,8 +471,6 @@ struct brcmf_sdio {
 	s32 idletime;		/* Control for activity timeout */
 	s32 idlecount;	/* Activity timeout counter */
 	s32 idleclock;	/* How to set bus driver when idle */
-	s32 sd_rxchain;
-	bool use_rxchain;	/* If brcmf should use PKT chains */
 	bool rxflow_mode;	/* Rx flow control mode */
 	bool rxflow;		/* Is rx flow control on */
 	bool alp_only;		/* Don't use HT clock (ALP only) */
@@ -1025,29 +1021,6 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
 		bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 }
 
-/* copy a buffer into a pkt buffer chain */
-static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_sdio *bus, uint len)
-{
-	uint n, ret = 0;
-	struct sk_buff *p;
-	u8 *buf;
-
-	buf = bus->dataptr;
-
-	/* copy the data */
-	skb_queue_walk(&bus->glom, p) {
-		n = min_t(uint, p->len, len);
-		memcpy(p->data, buf, n);
-		buf += n;
-		len -= n;
-		ret += n;
-		if (!len)
-			break;
-	}
-
-	return ret;
-}
-
 /* return total length of buffer chain */
 static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus)
 {
@@ -1201,8 +1174,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 	int errcode;
 	u8 doff, sfdoff;
 
-	bool usechain = bus->use_rxchain;
-
 	struct brcmf_sdio_read rd_new;
 
 	/* If packets, issue read(s) and send up packet chain */
@@ -1237,7 +1208,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 			if (sublen % BRCMF_SDALIGN) {
 				brcmf_err("sublen %d not multiple of %d\n",
 					  sublen, BRCMF_SDALIGN);
-				usechain = false;
 			}
 			totlen += sublen;
 
@@ -1304,27 +1274,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 		 * packet and and copy into the chain.
 		 */
 		sdio_claim_host(bus->sdiodev->func[1]);
-		if (usechain) {
-			errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
-					bus->sdiodev->sbwad,
-					SDIO_FUNC_2, F2SYNC, &bus->glom);
-		} else if (bus->dataptr) {
-			errcode = brcmf_sdcard_recv_buf(bus->sdiodev,
-					bus->sdiodev->sbwad,
-					SDIO_FUNC_2, F2SYNC,
-					bus->dataptr, dlen);
-			sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen);
-			if (sublen != dlen) {
-				brcmf_err("FAILED TO COPY, dlen %d sublen %d\n",
-					  dlen, sublen);
-				errcode = -1;
-			}
-			pnext = NULL;
-		} else {
-			brcmf_err("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n",
-				  dlen);
-			errcode = -1;
-		}
+		errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
+				bus->sdiodev->sbwad,
+				SDIO_FUNC_2, F2SYNC, &bus->glom);
 		sdio_release_host(bus->sdiodev->func[1]);
 		bus->sdcnt.f2rxdata++;
 
@@ -3527,9 +3479,6 @@ static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
 	kfree(bus->rxbuf);
 	bus->rxctl = bus->rxbuf = NULL;
 	bus->rxlen = 0;
-
-	kfree(bus->databuf);
-	bus->databuf = NULL;
 }
 
 static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
@@ -3542,29 +3491,10 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
 			    ALIGNMENT) + BRCMF_SDALIGN;
 		bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
 		if (!(bus->rxbuf))
-			goto fail;
-	}
-
-	/* Allocate buffer to receive glomed packet */
-	bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC);
-	if (!(bus->databuf)) {
-		/* release rxbuf which was already located as above */
-		if (!bus->rxblen)
-			kfree(bus->rxbuf);
-		goto fail;
+			return false;
 	}
 
-	/* Align the buffer */
-	if ((unsigned long)bus->databuf % BRCMF_SDALIGN)
-		bus->dataptr = bus->databuf + (BRCMF_SDALIGN -
-			       ((unsigned long)bus->databuf % BRCMF_SDALIGN));
-	else
-		bus->dataptr = bus->databuf;
-
 	return true;
-
-fail:
-	return false;
 }
 
 static bool
@@ -3703,10 +3633,6 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
 	bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
 	bus->roundup = min(max_roundup, bus->blocksize);
 
-	/* bus module does not support packet chaining */
-	bus->use_rxchain = false;
-	bus->sd_rxchain = false;
-
 	/* SR state */
 	bus->sleeping = false;
 	bus->sr_enabled = false;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 991c1501..793df66 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -170,7 +170,6 @@ struct brcmf_sdio_dev {
 	atomic_t suspend;		/* suspend flag */
 	wait_queue_head_t request_byte_wait;
 	wait_queue_head_t request_word_wait;
-	wait_queue_head_t request_chain_wait;
 	wait_queue_head_t request_buffer_wait;
 	struct device *dev;
 	struct brcmf_bus *bus_if;
@@ -272,12 +271,6 @@ brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
 			 uint rw, uint fnc, uint addr,
 			 u32 *word, uint nbyte);
 
-/* read or write any buffer using cmd53 */
-extern int
-brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
-			  uint write, uint func, uint addr,
-			  struct sk_buff_head *pktq);
-
 /* Watchdog timer interface for pm ops */
 extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
 				    bool enable);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 6/8] brcmfmac: remove redundant chip ID check in dhd_sdio
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

From: Franky Lin <frankyl@broadcom.com>

There is an ID table registered to SDIO stack which consists of all SDIO devices
supported by brcmfmac. It is not necessary to have an extra check.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |   22 --------------------
 1 file changed, 22 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index d4db0c7..cb22f2f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3509,23 +3509,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 	return (atomic_read(&bus->ipend) > 0);
 }
 
-static bool brcmf_sdbrcm_chipmatch(u16 chipid)
-{
-	if (chipid == BCM43143_CHIP_ID)
-		return true;
-	if (chipid == BCM43241_CHIP_ID)
-		return true;
-	if (chipid == BCM4329_CHIP_ID)
-		return true;
-	if (chipid == BCM4330_CHIP_ID)
-		return true;
-	if (chipid == BCM4334_CHIP_ID)
-		return true;
-	if (chipid == BCM4335_CHIP_ID)
-		return true;
-	return false;
-}
-
 static void brcmf_sdio_dataworker(struct work_struct *work)
 {
 	struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
@@ -3622,11 +3605,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
 		goto fail;
 	}
 
-	if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) {
-		brcmf_err("unsupported chip: 0x%04x\n", bus->ci->chip);
-		goto fail;
-	}
-
 	if (brcmf_sdbrcm_kso_init(bus)) {
 		brcmf_err("error enabling KSO\n");
 		goto fail;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 2/8] brcmfmac: rename variable prec to more appropriate name, ie. fifo
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

The term prec (precedence) is different from the fifo number. Rename
use of prec with fifo to be consistent and clear.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 1d8fa7d..e66b723 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -839,7 +839,7 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
 
 static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
 				 struct brcmf_fws_mac_descriptor *entry,
-				 int prec, bool send_immediately)
+				 int fifo, bool send_immediately)
 {
 	struct sk_buff *skb;
 	struct brcmf_bus *bus;
@@ -848,10 +848,10 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
 	u32 len;
 
 	/* check delayedQ and suppressQ in one call using bitmap */
-	if (brcmu_pktq_mlen(&entry->psq, 3 << (prec * 2)) == 0)
-		entry->traffic_pending_bmp &= ~NBITVAL(prec);
+	if (brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0)
+		entry->traffic_pending_bmp &= ~NBITVAL(fifo);
 	else
-		entry->traffic_pending_bmp |= NBITVAL(prec);
+		entry->traffic_pending_bmp |= NBITVAL(fifo);
 
 	entry->send_tim_signal = false;
 	if (entry->traffic_lastreported_bmp != entry->traffic_pending_bmp)
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 4/8] brcmfmac: consolidate mac_descriptor related function names
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

Just cleaning up and being consistent in naming operations
related to struct brcmf_fws_mac_descriptor objects.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |   53 ++++++++++----------
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index b702f3e..13e75c4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -631,8 +631,8 @@ static void brcmf_fws_macdesc_set_name(struct brcmf_fws_info *fws,
 			  desc->interface_id);
 }
 
-static void brcmf_fws_init_mac_descriptor(struct brcmf_fws_mac_descriptor *desc,
-					  u8 *addr, u8 ifidx)
+static void brcmf_fws_macdesc_init(struct brcmf_fws_mac_descriptor *desc,
+				   u8 *addr, u8 ifidx)
 {
 	brcmf_dbg(TRACE,
 		  "enter: desc %p ea=%pM, ifidx=%u\n", desc, addr, ifidx);
@@ -648,7 +648,7 @@ static void brcmf_fws_init_mac_descriptor(struct brcmf_fws_mac_descriptor *desc,
 }
 
 static
-void brcmf_fws_clear_mac_descriptor(struct brcmf_fws_mac_descriptor *desc)
+void brcmf_fws_macdesc_deinit(struct brcmf_fws_mac_descriptor *desc)
 {
 	brcmf_dbg(TRACE,
 		  "enter: ea=%pM, ifidx=%u\n", desc->ea, desc->interface_id);
@@ -659,7 +659,7 @@ void brcmf_fws_clear_mac_descriptor(struct brcmf_fws_mac_descriptor *desc)
 }
 
 static struct brcmf_fws_mac_descriptor *
-brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea)
+brcmf_fws_macdesc_lookup(struct brcmf_fws_info *fws, u8 *ea)
 {
 	struct brcmf_fws_mac_descriptor *entry;
 	int i;
@@ -678,8 +678,7 @@ brcmf_fws_mac_descriptor_lookup(struct brcmf_fws_info *fws, u8 *ea)
 }
 
 static struct brcmf_fws_mac_descriptor*
-brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, struct brcmf_if *ifp,
-			u8 *da)
+brcmf_fws_macdesc_find(struct brcmf_fws_info *fws, struct brcmf_if *ifp, u8 *da)
 {
 	struct brcmf_fws_mac_descriptor *entry = &fws->desc.other;
 	bool multicast;
@@ -695,7 +694,7 @@ brcmf_fws_find_mac_desc(struct brcmf_fws_info *fws, struct brcmf_if *ifp,
 		goto done;
 	}
 
-	entry = brcmf_fws_mac_descriptor_lookup(fws, da);
+	entry = brcmf_fws_macdesc_lookup(fws, da);
 	if (IS_ERR(entry))
 		entry = ifp->fws_desc;
 
@@ -703,9 +702,9 @@ done:
 	return entry;
 }
 
-static bool brcmf_fws_mac_desc_closed(struct brcmf_fws_info *fws,
-				      struct brcmf_fws_mac_descriptor *entry,
-				      int fifo)
+static bool brcmf_fws_macdesc_closed(struct brcmf_fws_info *fws,
+				     struct brcmf_fws_mac_descriptor *entry,
+				     int fifo)
 {
 	struct brcmf_fws_mac_descriptor *if_entry;
 	bool closed;
@@ -728,9 +727,9 @@ static bool brcmf_fws_mac_desc_closed(struct brcmf_fws_info *fws,
 	return closed || !(entry->ac_bitmap & BIT(fifo));
 }
 
-static void brcmf_fws_mac_desc_cleanup(struct brcmf_fws_info *fws,
-				       struct brcmf_fws_mac_descriptor *entry,
-				       int ifidx)
+static void brcmf_fws_macdesc_cleanup(struct brcmf_fws_info *fws,
+				      struct brcmf_fws_mac_descriptor *entry,
+				      int ifidx)
 {
 	if (entry->occupied && (ifidx == -1 || ifidx == entry->interface_id)) {
 		brcmf_fws_psq_flush(fws, &entry->psq, ifidx);
@@ -782,9 +781,9 @@ static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx)
 	/* cleanup individual nodes */
 	table = &fws->desc.nodes[0];
 	for (i = 0; i < ARRAY_SIZE(fws->desc.nodes); i++)
-		brcmf_fws_mac_desc_cleanup(fws, &table[i], ifidx);
+		brcmf_fws_macdesc_cleanup(fws, &table[i], ifidx);
 
-	brcmf_fws_mac_desc_cleanup(fws, &fws->desc.other, ifidx);
+	brcmf_fws_macdesc_cleanup(fws, &fws->desc.other, ifidx);
 	brcmf_fws_bus_txq_cleanup(fws, matchfn, ifidx);
 	brcmf_fws_hanger_cleanup(fws, matchfn, ifidx);
 }
@@ -924,18 +923,18 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
 		if (entry->occupied) {
 			brcmf_dbg(TRACE, "deleting %s mac %pM\n",
 				  entry->name, addr);
-			brcmf_fws_mac_desc_cleanup(fws, entry, -1);
-			brcmf_fws_clear_mac_descriptor(entry);
+			brcmf_fws_macdesc_cleanup(fws, entry, -1);
+			brcmf_fws_macdesc_deinit(entry);
 		} else
 			fws->stats.mac_update_failed++;
 		return 0;
 	}
 
-	existing = brcmf_fws_mac_descriptor_lookup(fws, addr);
+	existing = brcmf_fws_macdesc_lookup(fws, addr);
 	if (IS_ERR(existing)) {
 		if (!entry->occupied) {
 			entry->mac_handle = mac_handle;
-			brcmf_fws_init_mac_descriptor(entry, addr, ifidx);
+			brcmf_fws_macdesc_init(entry, addr, ifidx);
 			brcmf_fws_macdesc_set_name(fws, entry);
 			brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
 					BRCMF_FWS_PSQ_LEN);
@@ -949,7 +948,7 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
 			memcpy(entry, existing,
 			       offsetof(struct brcmf_fws_mac_descriptor, psq));
 			entry->mac_handle = mac_handle;
-			brcmf_fws_clear_mac_descriptor(existing);
+			brcmf_fws_macdesc_deinit(existing);
 			brcmf_fws_macdesc_set_name(fws, entry);
 			brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name,
 				  addr);
@@ -1189,7 +1188,7 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
 	for (i = 0; i < num_nodes; i++) {
 		entry = &table[(node_pos + i) % num_nodes];
 		if (!entry->occupied ||
-		    brcmf_fws_mac_desc_closed(fws, entry, fifo))
+		    brcmf_fws_macdesc_closed(fws, entry, fifo))
 			continue;
 
 		if (entry->suppressed)
@@ -1810,7 +1809,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
 
 	/* set control buffer information */
 	skcb->if_flags = 0;
-	skcb->mac = brcmf_fws_find_mac_desc(fws, ifp, eh->h_dest);
+	skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
 	skcb->state = BRCMF_FWS_SKBSTATE_NEW;
 	brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx);
 	if (!multicast)
@@ -1828,7 +1827,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
 
 	if (skcb->mac->suppressed ||
 	    fws->bus_flow_blocked ||
-	    brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) ||
+	    brcmf_fws_macdesc_closed(fws, skcb->mac, fifo) ||
 	    brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) ||
 	    (!multicast &&
 	     brcmf_fws_consume_credit(fws, fifo, skb) < 0)) {
@@ -1850,7 +1849,7 @@ void brcmf_fws_reset_interface(struct brcmf_if *ifp)
 	if (!entry)
 		return;
 
-	brcmf_fws_init_mac_descriptor(entry, ifp->mac_addr, ifp->ifidx);
+	brcmf_fws_macdesc_init(entry, ifp->mac_addr, ifp->ifidx);
 }
 
 void brcmf_fws_add_interface(struct brcmf_if *ifp)
@@ -1863,7 +1862,7 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp)
 
 	entry = &fws->desc.iface[ifp->ifidx];
 	ifp->fws_desc = entry;
-	brcmf_fws_init_mac_descriptor(entry, ifp->mac_addr, ifp->ifidx);
+	brcmf_fws_macdesc_init(entry, ifp->mac_addr, ifp->ifidx);
 	brcmf_fws_macdesc_set_name(fws, entry);
 	brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
 			BRCMF_FWS_PSQ_LEN);
@@ -1881,7 +1880,7 @@ void brcmf_fws_del_interface(struct brcmf_if *ifp)
 	brcmf_fws_lock(ifp->drvr, flags);
 	ifp->fws_desc = NULL;
 	brcmf_dbg(TRACE, "deleting %s\n", entry->name);
-	brcmf_fws_clear_mac_descriptor(entry);
+	brcmf_fws_macdesc_deinit(entry);
 	brcmf_fws_cleanup(ifp->drvr->fws, ifp->ifidx);
 	brcmf_fws_unlock(ifp->drvr, flags);
 }
@@ -1986,7 +1985,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
 	}
 
 	brcmf_fws_hanger_init(&drvr->fws->hanger);
-	brcmf_fws_init_mac_descriptor(&drvr->fws->desc.other, NULL, 0);
+	brcmf_fws_macdesc_init(&drvr->fws->desc.other, NULL, 0);
 	brcmf_fws_macdesc_set_name(drvr->fws, &drvr->fws->desc.other);
 	brcmu_pktq_init(&drvr->fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT,
 			BRCMF_FWS_PSQ_LEN);
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 7/8] brcmfmac: replace brcmf_sdioh_request_buffer with brcmf_sdio_buffrw
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

From: Franky Lin <frankyl@broadcom.com>

Introducing a new SDIO block data access interface function
brcmf_sdio_buffrw. It will act as a unified interface function for any block
data access to WiFi dongle through SDIO interface. This patch enables
the support for single skb transmission.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |   58 ++++++++++++++++----
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |   41 +-------------
 .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |    8 +--
 3 files changed, 53 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 4891e3d..32a205e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -303,6 +303,49 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
 		*ret = retval;
 }
 
+/**
+ * brcmf_sdio_buffrw - SDIO interface function for block data access
+ * @sdiodev: brcmfmac sdio device
+ * @fn: SDIO function number
+ * @write: direction flag
+ * @addr: dongle memory address as source/destination
+ * @pkt: skb pointer
+ *
+ * This function takes the respbonsibility as the interface function to MMC
+ * stack for block data access. It assumes that the skb passed down by the
+ * caller has already been padded and aligned.
+ */
+static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
+			     bool write, u32 addr, struct sk_buff *pkt)
+{
+	uint len;
+
+	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
+	if (brcmf_pm_resume_error(sdiodev))
+		return -EIO;
+
+	/* Single skb use the standard mmc interface */
+	if (!pkt->next) {
+		len = pkt->len + 3;
+		len &= (uint)~3;
+
+		if (write)
+			return sdio_memcpy_toio(sdiodev->func[fn], addr,
+						((u8 *)(pkt->data)), len);
+		else if (fn == 1)
+			return sdio_memcpy_fromio(sdiodev->func[fn],
+						  ((u8 *)(pkt->data)), addr,
+						  len);
+		else
+			/* function 2 read is FIFO operation */
+			return sdio_readsb(sdiodev->func[fn],
+					   ((u8 *)(pkt->data)), addr, len);
+	}
+
+	brcmf_err("skb chain is not supported yet.\n");
+	return -EOPNOTSUPP;
+}
+
 static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
 				     uint flags, uint width, u32 *addr)
 {
@@ -355,7 +398,6 @@ int
 brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, struct sk_buff *pkt)
 {
-	uint incr_fix;
 	uint width;
 	int err = 0;
 
@@ -367,9 +409,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 	if (err)
 		goto done;
 
-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
-	err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
-					 fn, addr, pkt);
+	err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt);
 
 done:
 	return err;
@@ -424,7 +464,6 @@ int
 brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 		      uint flags, struct sk_buff *pkt)
 {
-	uint incr_fix;
 	uint width;
 	uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
 	int err = 0;
@@ -446,13 +485,11 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
 
 	addr &= SBSDIO_SB_OFT_ADDR_MASK;
 
-	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
 	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
 	if (width == 4)
 		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
 
-	err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
-					 addr, pkt);
+	err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, pkt);
 
 done:
 	return err;
@@ -501,9 +538,8 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
 		skb_put(pkt, dsize);
 		if (write)
 			memcpy(pkt->data, data, dsize);
-		bcmerror = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
-						      write, SDIO_FUNC_1,
-						      sdaddr, pkt);
+		bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write,
+					     sdaddr, pkt);
 		if (bcmerror) {
 			brcmf_err("membytes transfer failed\n");
 			break;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 11400b3..7a3c5bf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -66,7 +66,7 @@ MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
 static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
 
 
-static bool
+bool
 brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
 {
 	bool is_err = false;
@@ -76,7 +76,7 @@ brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
 	return is_err;
 }
 
-static void
+void
 brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
 {
 #ifdef CONFIG_PM_SLEEP
@@ -283,43 +283,6 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
 	return err_ret;
 }
 
-/*
- * This function takes a single DMA-able packet.
- */
-int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
-			       uint fix_inc, uint write, uint func, uint addr,
-			       struct sk_buff *pkt)
-{
-	int status;
-	uint pkt_len;
-	bool fifo = (fix_inc == SDIOH_DATA_FIX);
-
-	brcmf_dbg(SDIO, "Enter\n");
-
-	if (pkt == NULL)
-		return -EINVAL;
-	pkt_len = pkt->len;
-
-	brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
-	if (brcmf_pm_resume_error(sdiodev))
-		return -EIO;
-
-	pkt_len += 3;
-	pkt_len &= (uint)~3;
-
-	status = brcmf_sdioh_request_data(sdiodev, write, fifo, func,
-					   addr, pkt, pkt_len);
-	if (status) {
-		brcmf_err("%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
-			  write ? "TX" : "RX", pkt, addr, pkt_len, status);
-	} else {
-		brcmf_dbg(SDIO, "%s xfr'd %p, addr=0x%05x, len=%d\n",
-			  write ? "TX" : "RX", pkt, addr, pkt_len);
-	}
-
-	return status;
-}
-
 static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
 {
 	/* read 24 bits and return valid 17 bit addr */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 7c1b633..991c1501 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -274,10 +274,6 @@ brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
 
 /* read or write any buffer using cmd53 */
 extern int
-brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
-			   uint fix_inc, uint rw, uint fnc_num, u32 addr,
-			   struct sk_buff *pkt);
-extern int
 brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
 			  uint write, uint func, uint addr,
 			  struct sk_buff_head *pktq);
@@ -291,4 +287,8 @@ extern void brcmf_sdbrcm_disconnect(void *ptr);
 extern void brcmf_sdbrcm_isr(void *arg);
 
 extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick);
+
+extern void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev,
+				 wait_queue_head_t *wq);
+extern bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev);
 #endif				/* _BRCM_SDH_H_ */
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 5/8] brcmfmac: simplify dpc handling using atomic operations
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

Instead of allocating an empty list item and queue that for
the dpc data worker to dequeue an atomic counter is used.

Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |   70 ++++----------------
 1 file changed, 12 insertions(+), 58 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 6f3d181..d4db0c7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -495,8 +495,7 @@ struct brcmf_sdio {
 
 	struct workqueue_struct *brcmf_wq;
 	struct work_struct datawork;
-	struct list_head dpc_tsklst;
-	spinlock_t dpc_tl_lock;
+	atomic_t dpc_tskcnt;
 
 	const struct firmware *firmware;
 	u32 fw_ptr;
@@ -2061,23 +2060,6 @@ static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
 	}
 }
 
-static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
-{
-	struct list_head *new_hd;
-	unsigned long flags;
-
-	if (in_interrupt())
-		new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
-	else
-		new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
-	if (new_hd == NULL)
-		return;
-
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-	list_add_tail(new_hd, &bus->dpc_tsklst);
-	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
-}
-
 static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
 {
 	u8 idx;
@@ -2312,7 +2294,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 		   (!atomic_read(&bus->fcstate) &&
 		    brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
 		    data_ok(bus)) || PKT_AVAILABLE()) {
-		brcmf_sdbrcm_adddpctsk(bus);
+		atomic_inc(&bus->dpc_tskcnt);
 	}
 
 	/* If we're done for now, turn off clock request. */
@@ -2342,7 +2324,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 	struct brcmf_sdio *bus = sdiodev->bus;
-	unsigned long flags;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -2381,14 +2362,9 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
 		qcount[prec] = pktq_plen(&bus->txq, prec);
 #endif
 
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-	if (list_empty(&bus->dpc_tsklst)) {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
-
-		brcmf_sdbrcm_adddpctsk(bus);
+	if (atomic_read(&bus->dpc_tskcnt) == 0) {
+		atomic_inc(&bus->dpc_tskcnt);
 		queue_work(bus->brcmf_wq, &bus->datawork);
-	} else {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 	}
 
 	return ret;
@@ -2525,7 +2501,6 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
 	struct brcmf_sdio *bus = sdiodev->bus;
-	unsigned long flags;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -2612,18 +2587,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
 		} while (ret < 0 && retries++ < TXRETRIES);
 	}
 
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
 	if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
-	    list_empty(&bus->dpc_tsklst)) {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
-
+	    atomic_read(&bus->dpc_tskcnt) == 0) {
 		bus->activity = false;
 		sdio_claim_host(bus->sdiodev->func[1]);
 		brcmf_dbg(INFO, "idle\n");
 		brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
 		sdio_release_host(bus->sdiodev->func[1]);
-	} else {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 	}
 
 	if (ret)
@@ -3451,7 +3421,7 @@ void brcmf_sdbrcm_isr(void *arg)
 	if (!bus->intr)
 		brcmf_err("isr w/o interrupt configured!\n");
 
-	brcmf_sdbrcm_adddpctsk(bus);
+	atomic_inc(&bus->dpc_tskcnt);
 	queue_work(bus->brcmf_wq, &bus->datawork);
 }
 
@@ -3460,7 +3430,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 #ifdef DEBUG
 	struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
 #endif	/* DEBUG */
-	unsigned long flags;
 
 	brcmf_dbg(TIMER, "Enter\n");
 
@@ -3476,11 +3445,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 		if (!bus->intr ||
 		    (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
 
-			spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-			if (list_empty(&bus->dpc_tsklst)) {
+			if (atomic_read(&bus->dpc_tskcnt) == 0) {
 				u8 devpend;
-				spin_unlock_irqrestore(&bus->dpc_tl_lock,
-						       flags);
+
 				sdio_claim_host(bus->sdiodev->func[1]);
 				devpend = brcmf_sdio_regrb(bus->sdiodev,
 							   SDIO_CCCR_INTx,
@@ -3489,9 +3456,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 				intstatus =
 				    devpend & (INTR_STATUS_FUNC1 |
 					       INTR_STATUS_FUNC2);
-			} else {
-				spin_unlock_irqrestore(&bus->dpc_tl_lock,
-						       flags);
 			}
 
 			/* If there is something, make like the ISR and
@@ -3500,7 +3464,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 				bus->sdcnt.pollcnt++;
 				atomic_set(&bus->ipend, 1);
 
-				brcmf_sdbrcm_adddpctsk(bus);
+				atomic_inc(&bus->dpc_tskcnt);
 				queue_work(bus->brcmf_wq, &bus->datawork);
 			}
 		}
@@ -3566,20 +3530,11 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
 {
 	struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
 					      datawork);
-	struct list_head *cur_hd, *tmp_hd;
-	unsigned long flags;
-
-	spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-	list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
-		spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 
+	while (atomic_read(&bus->dpc_tskcnt)) {
 		brcmf_sdbrcm_dpc(bus);
-
-		spin_lock_irqsave(&bus->dpc_tl_lock, flags);
-		list_del(cur_hd);
-		kfree(cur_hd);
+		atomic_dec(&bus->dpc_tskcnt);
 	}
-	spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
 }
 
 static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
@@ -3927,8 +3882,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 		bus->watchdog_tsk = NULL;
 	}
 	/* Initialize DPC thread */
-	INIT_LIST_HEAD(&bus->dpc_tsklst);
-	spin_lock_init(&bus->dpc_tl_lock);
+	atomic_set(&bus->dpc_tskcnt, 0);
 
 	/* Assign bus interface call back */
 	bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 0/8] brcmfmac: scatterlist support in sdio and cleanup
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel

This series contains mostly cleanup patches. The main change is the
support for scatterlist api in sdio part of the brcmfmac driver.

The series is intended for v3.11 and applies to the master branch
of the wireless-next repository.

Arend van Spriel (4):
  brcmfmac: rename variable prec to more appropriate name, ie. fifo
  brcmfmac: remove dependency with nl80211.h
  brcmfmac: consolidate mac_descriptor related function names
  brcmfmac: simplify dpc handling using atomic operations

Franky Lin (3):
  brcmfmac: remove redundant chip ID check in dhd_sdio
  brcmfmac: replace brcmf_sdioh_request_buffer with brcmf_sdio_buffrw
  brcmfmac: add sdio sg list support

Hante Meuleman (1):
  brcmfmac: Only use credits for bcmc when firmware indicates it.

 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |  179 ++++++++++++++++++--
 .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |  114 +------------
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |  174 ++-----------------
 drivers/net/wireless/brcm80211/brcmfmac/fweh.h     |    3 +-
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |   96 +++++++----
 .../net/wireless/brcm80211/brcmfmac/sdio_host.h    |   15 +-
 6 files changed, 252 insertions(+), 329 deletions(-)

-- 
1.7.10.4



^ permalink raw reply

* [PATCH 3/8] brcmfmac: remove dependency with nl80211.h
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

The firmware-signalling code used NL80211_NUM_ACS, but it has
its own definition enum brcmf_fws_fifo, which is more appropriate
to use. This effectively removes the need to include nl80211.h.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index e66b723..b702f3e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -22,7 +22,6 @@
 #include <linux/etherdevice.h>
 #include <linux/err.h>
 #include <linux/jiffies.h>
-#include <uapi/linux/nl80211.h>
 #include <net/cfg80211.h>
 
 #include <brcmu_utils.h>
@@ -142,7 +141,7 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
 #define BRCMF_FWS_FLOWCONTROL_HIWATER			128
 #define BRCMF_FWS_FLOWCONTROL_LOWATER			64
 
-#define BRCMF_FWS_PSQ_PREC_COUNT		((NL80211_NUM_ACS + 1) * 2)
+#define BRCMF_FWS_PSQ_PREC_COUNT		((BRCMF_FWS_FIFO_COUNT + 1) * 2)
 #define BRCMF_FWS_PSQ_LEN				256
 
 #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST			0x01
-- 
1.7.10.4



^ permalink raw reply related

* [PATCH 1/8] brcmfmac: Only use credits for bcmc when firmware indicates it.
From: Arend van Spriel @ 2013-06-18 11:29 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Hante Meuleman, Arend van Spriel
In-Reply-To: <1371554970-23495-1-git-send-email-arend@broadcom.com>

From: Hante Meuleman <meuleman@broadcom.com>

The firmware will sent an event message when bc/mc traffic should
be sent to the device using credit mechanism.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/fweh.h     |    3 +-
 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c |   32 +++++++++++++++++++-
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 6ec5db9..e679214 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -101,7 +101,8 @@ struct brcmf_event;
 	BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \
 	BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
 	BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
-	BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75)
+	BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
+	BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
 
 #define BRCMF_ENUM_DEF(id, val) \
 	BRCMF_E_##id = (val),
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 70f70ce..1d8fa7d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -426,6 +426,7 @@ struct brcmf_fws_info {
 	struct brcmf_fws_stats stats;
 	struct brcmf_fws_hanger hanger;
 	enum brcmf_fws_fcmode fcmode;
+	bool bcmc_credit_check;
 	struct brcmf_fws_macdesc_table desc;
 	struct workqueue_struct *fws_wq;
 	struct work_struct fws_dequeue_work;
@@ -1438,6 +1439,20 @@ static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
 	return 0;
 }
 
+static int brcmf_fws_notify_bcmc_credit_support(struct brcmf_if *ifp,
+						const struct brcmf_event_msg *e,
+						void *data)
+{
+	struct brcmf_fws_info *fws = ifp->drvr->fws;
+	ulong flags;
+
+	brcmf_fws_lock(ifp->drvr, flags);
+	if (fws)
+		fws->bcmc_credit_check = true;
+	brcmf_fws_unlock(ifp->drvr, flags);
+	return 0;
+}
+
 int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
 		      struct sk_buff *skb)
 {
@@ -1806,6 +1821,12 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
 		  eh->h_dest, multicast, fifo);
 
 	brcmf_fws_lock(drvr, flags);
+	/* multicast credit support is conditional, setting
+	 * flag to false to assure credit is consumed below.
+	 */
+	if (fws->bcmc_credit_check)
+		multicast = false;
+
 	if (skcb->mac->suppressed ||
 	    fws->bus_flow_blocked ||
 	    brcmf_fws_mac_desc_closed(fws, skcb->mac, fifo) ||
@@ -1878,7 +1899,8 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
 	brcmf_fws_lock(fws->drvr, flags);
 	for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked;
 	     fifo--) {
-		while (fws->fifo_credit[fifo]) {
+		while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
+		       (fifo == BRCMF_FWS_FIFO_BCMC))) {
 			skb = brcmf_fws_deq(fws, fifo);
 			if (!skb)
 				break;
@@ -1947,6 +1969,13 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
 		brcmf_err("register credit map handler failed\n");
 		goto fail;
 	}
+	rc = brcmf_fweh_register(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT,
+				 brcmf_fws_notify_bcmc_credit_support);
+	if (rc < 0) {
+		brcmf_err("register bcmc credit handler failed\n");
+		brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
+		goto fail;
+	}
 
 	/* setting the iovar may fail if feature is unsupported
 	 * so leave the rc as is so driver initialization can
@@ -1971,6 +2000,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
 	return 0;
 
 fail_event:
+	brcmf_fweh_unregister(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT);
 	brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP);
 fail:
 	brcmf_fws_deinit(drvr);
-- 
1.7.10.4



^ permalink raw reply related

* Re: [PATCH] Revert "mac80211: in IBSS use the Auth frame to trigger STA reinsertion"
From: Antonio Quartulli @ 2013-06-18 11:43 UTC (permalink / raw)
  To: Nicolas Cavallari; +Cc: linux-wireless
In-Reply-To: <51C043FE.6050108@lri.fr>

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

On Tue, Jun 18, 2013 at 01:26:54PM +0200, Nicolas Cavallari wrote:
> On 18/06/2013 12:45, Antonio Quartulli wrote:
> > -	if (auth && !sdata->u.ibss.auth_frame_registrations) {
> 
> The sole purpose of the auth_frame_registrations field is to be checked by this code.
> The field and the code maintaining this field can be removed now.

Oh ok.
I was just looking around to understand how that field was used.

I'll send v2.

Cheers,

-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto "Che" Guevara

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH] mac80211: allow key deletion for mesh interface
From: Yeoh Chun-Yeow @ 2013-06-18 12:05 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-wireless@vger.kernel.org, John Linville,
	devel@lists.open80211s.org
In-Reply-To: <1371548362.8318.5.camel@jlt4.sipsolutions.net>

> I don't see that this actually changes anything. The mesh sdata will
> have a NULL bss pointer, so the second condition in sta_info_get_bss()
> can't be true.
>
> Therefore, only the first condition can ever be considered, which is
> exactly the same as sta_info_get(), no?

Yes. My current patch does not make sense since I see no difference
calling sta_info_get or sta_info_get_bss in my case.

The same applies to ieee80211_add_key.

---
Chun-Yeow

^ permalink raw reply

* Re: [PATCH] mac80211: Fix VHT bandwidth change event
From: Johannes Berg @ 2013-06-18 12:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ilan Peer
In-Reply-To: <1370974919-6117-1-git-send-email-johannes@sipsolutions.net>

Applied.

johannes


^ permalink raw reply

* Re: [PATCH] mac80211: track AP's beacon rate and give it to the driver
From: Johannes Berg @ 2013-06-18 12:06 UTC (permalink / raw)
  To: linux-wireless; +Cc: Alexander Bondar
In-Reply-To: <1370974911-6074-1-git-send-email-johannes@sipsolutions.net>

On Tue, 2013-06-11 at 20:21 +0200, Johannes Berg wrote:
> From: Alexander Bondar <alexander.bondar@intel.com>
> 
> Track the AP's beacon rate in the scan BSS data and in the
> interface configuration to let the drivers know which rate
> the AP is using. This information may be used by drivers,
> in our case to let the firmware optimise beacon RX.

Applied.

johannes


^ permalink raw reply


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