Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v2] mac80211: implement STA CSA for drivers using channel contexts
From: Arik Nemtsov @ 2013-09-01 14:15 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Arik Nemtsov

Limit the current implementation to a single channel context used by
a single vif, thereby avoiding multi-vif/channel complexities.

Reuse the main function from AP CSA code, but move a portion out in
order to fit the STA scenario.

Add a new mac80211 HW flag so we don't break devices that don't support
channel switch with channel-contexts. The new behavior will be opt-in.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
---
 include/net/mac80211.h |  6 ++++++
 net/mac80211/cfg.c     |  5 +++++
 net/mac80211/chan.c    |  5 -----
 net/mac80211/mlme.c    | 57 +++++++++++++++++++++++++++++++++++++-------------
 4 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 06ffae8..c450644 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1492,6 +1492,11 @@ struct ieee80211_tx_control {
  *
  * @IEEE80211_HW_TIMING_BEACON_ONLY: Use sync timing from beacon frames
  *	only, to allow getting TBTT of a DTIM beacon.
+ *
+ * @IEEE80211_HW_CHANCTX_STA_CSA: Support 802.11H based channel-switch (CSA)
+ *	for a single active channel while using channel contexts. When support
+ *	is not enabled the default action is to disconnect when getting the
+ *	CSA frame.
  */
 enum ieee80211_hw_flags {
 	IEEE80211_HW_HAS_RATE_CONTROL			= 1<<0,
@@ -1522,6 +1527,7 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF		= 1<<25,
 	IEEE80211_HW_TIMING_BEACON_ONLY			= 1<<26,
 	IEEE80211_HW_SUPPORTS_HT_CCK_RATES		= 1<<27,
+	IEEE80211_HW_CHANCTX_STA_CSA			= 1<<28,
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b455e72..ac28af7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2871,6 +2871,11 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
 	if (WARN_ON(err < 0))
 		return;
 
+	if (!local->use_chanctx) {
+		local->_oper_chandef = local->csa_chandef;
+		ieee80211_hw_config(local, 0);
+	}
+
 	ieee80211_bss_info_change_notify(sdata, changed);
 
 	switch (sdata->vif.type) {
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 3a4764b..03ba6b5 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -453,11 +453,6 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
 	chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL;
 	drv_change_chanctx(local, ctx, chanctx_changed);
 
-	if (!local->use_chanctx) {
-		local->_oper_chandef = *chandef;
-		ieee80211_hw_config(local, 0);
-	}
-
 	ieee80211_recalc_chanctx_chantype(local, ctx);
 	ieee80211_recalc_smps_chanctx(local, ctx);
 	ieee80211_recalc_radar_chanctx(local, ctx);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9fce0f4..91cc828 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -876,6 +876,8 @@ static void ieee80211_chswitch_work(struct work_struct *work)
 		container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	u32 changed = 0;
+	int ret;
 
 	if (!ieee80211_sdata_running(sdata))
 		return;
@@ -884,24 +886,39 @@ static void ieee80211_chswitch_work(struct work_struct *work)
 	if (!ifmgd->associated)
 		goto out;
 
-	local->_oper_chandef = local->csa_chandef;
+	ret = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
+					   &changed);
+	if (ret) {
+		sdata_info(sdata,
+			   "vif channel switch failed, disconnecting\n");
+		ieee80211_queue_work(&sdata->local->hw,
+				     &ifmgd->csa_connection_drop_work);
+		goto out;
+	}
 
-	if (!local->ops->channel_switch) {
-		/* call "hw_config" only if doing sw channel switch */
-		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-	} else {
-		/* update the device channel directly */
-		local->hw.conf.chandef = local->_oper_chandef;
+	if (!local->use_chanctx) {
+		local->_oper_chandef = local->csa_chandef;
+		/* Call "hw_config" only if doing sw channel switch.
+		 * Otherwise update the channel directly
+		 */
+		if (!local->ops->channel_switch)
+			ieee80211_hw_config(local, 0);
+		else
+			local->hw.conf.chandef = local->_oper_chandef;
 	}
 
 	/* XXX: shouldn't really modify cfg80211-owned data! */
-	ifmgd->associated->channel = local->_oper_chandef.chan;
+	ifmgd->associated->channel = local->csa_chandef.chan;
 
 	/* XXX: wait for a beacon first? */
 	ieee80211_wake_queues_by_reason(&local->hw,
 					IEEE80211_MAX_QUEUE_MAP,
 					IEEE80211_QUEUE_STOP_REASON_CSA);
+
+	ieee80211_bss_info_change_notify(sdata, changed);
+
  out:
+	sdata->vif.csa_active = false;
 	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
 	sdata_unlock(sdata);
 }
@@ -983,17 +1000,28 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	}
 
 	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
+	sdata->vif.csa_active = true;
 
+	mutex_lock(&local->chanctx_mtx);
 	if (local->use_chanctx) {
-		sdata_info(sdata,
-			   "not handling channel switch with channel contexts\n");
-		ieee80211_queue_work(&local->hw,
-				     &ifmgd->csa_connection_drop_work);
-		return;
+		u32 num_chanctx = 0;
+		list_for_each_entry(chanctx, &local->chanctx_list, list)
+		       num_chanctx++;
+
+		if (num_chanctx > 1 ||
+		    !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
+			sdata_info(sdata,
+				   "not handling chan-switch with channel contexts\n");
+			ieee80211_queue_work(&local->hw,
+					     &ifmgd->csa_connection_drop_work);
+			mutex_unlock(&local->chanctx_mtx);
+			return;
+		}
 	}
 
-	mutex_lock(&local->chanctx_mtx);
 	if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) {
+		ieee80211_queue_work(&local->hw,
+				     &ifmgd->csa_connection_drop_work);
 		mutex_unlock(&local->chanctx_mtx);
 		return;
 	}
@@ -1955,6 +1983,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
 			       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
 			       true, frame_buf);
 	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
+	sdata->vif.csa_active = false;
 	ieee80211_wake_queues_by_reason(&sdata->local->hw,
 					IEEE80211_MAX_QUEUE_MAP,
 					IEEE80211_QUEUE_STOP_REASON_CSA);
-- 
1.8.1.2


^ permalink raw reply related

* Re: linux-next: Tree for Aug 30 (brcmfmac)
From: Arend van Spriel @ 2013-09-01 12:31 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: Geert Uytterhoeven, Randy Dunlap, Stephen Rothwell, Linux-Next,
	linux-kernel@vger.kernel.org, linux-wireless, brcm80211-dev-list,
	linux-kbuild
In-Reply-To: <522238A1.3080008@hauke-m.de>

On 08/31/13 20:40, Hauke Mehrtens wrote:
> On 08/31/2013 08:21 PM, Arend van Spriel wrote:
>> On 08/31/13 19:37, Geert Uytterhoeven wrote:
>>> On Fri, Aug 30, 2013 at 11:12 PM, Randy Dunlap<rdunlap@infradead.org>
>>> wrote:
>>>> This bool kconfig symbol:
>>>>
>>>> config BRCMFMAC_SDIO
>>>>           bool "SDIO bus interface support for FullMAC driver"
>>>>           depends on MMC
>>>>
>>>> allows BRCMFMAC_SDIO to be y even when MMC=m.
>>>>
>>>> Is there a reasonable solution to this?
>>
>> Actually, BRCMFMAC should be built in same form as the MMC and/or USB,
>> but only when BRCMFMAC_SDIO or BRCMFMAC_USB are selected.
>>
>> So valid combinations are:
>> MMC=m, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y =>  BRCMFMAC=m
>> MMC=m, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y =>  BRCMFMAC=m
>> MMC=y, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y =>  BRCMFMAC=m
>> MMC=m, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n =>  BRCMFMAC=m
>> MMC=m, USB=y, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y =>  BRCMFMAC=m|y
>> MMC=y, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n =>  BRCMFMAC=m|y
>> MMC=y, USB=m, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y =>  BRCMFMAC=m
>> MMC=y, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y =>  BRCMFMAC=m|y
>> MMC=y, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n =>  BRCMFMAC=m|y
>> MMC=y, USB=y, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y =>  BRCMFMAC=m|y
>>
>> Not sure how to express the above.
>
> This should be expressed with this Kconfig:
>
> config BRCMFMAC_USB
> 	bool "USB bus interface support for FullMAC driver"
> 	depends on (USB = y || USB = BRCMFMAC)
> 	depends on BRCMFMAC
>
> config BRCMFMAC_SDIO
> 	bool "SDIO bus interface support for FullMAC driver"
> 	depends on (MMC = y || MMC = BRCMFMAC)
> 	depends on BRCMFMAC
> 	select FW_LOADER
>
> I haven't tested it, but we had a similar problem in b43 and fixed it
> like this.

Thanks, Hauke

I will create a patch fixing this.

Regards,
Arend


^ permalink raw reply

* [PATCH v2 2/2] ath10k: add chip_id file to debugfs
From: Kalle Valo @ 2013-09-01  8:22 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901082007.1930.79088.stgit@localhost6.localdomain6>

So that's it's possible to query chip id from ath10k anytime.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/debug.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index fcb40cc..09f535a 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -498,6 +498,25 @@ static const struct file_operations fops_simulate_fw_crash = {
 	.llseek = default_llseek,
 };
 
+static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf,
+				   size_t count, loff_t *ppos)
+{
+	struct ath10k *ar = file->private_data;
+	unsigned int len;
+	char buf[50];
+
+	len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_chip_id = {
+	.read = ath10k_read_chip_id,
+	.open = simple_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
 int ath10k_debug_create(struct ath10k *ar)
 {
 	ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
@@ -517,6 +536,9 @@ int ath10k_debug_create(struct ath10k *ar)
 	debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy,
 			    ar, &fops_simulate_fw_crash);
 
+	debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
+			    ar, &fops_chip_id);
+
 	return 0;
 }
 #endif /* CONFIG_ATH10K_DEBUGFS */


^ permalink raw reply related

* [PATCH v2 1/2] ath10k: check chip id from the soc register during probe
From: Kalle Valo @ 2013-09-01  8:22 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901082007.1930.79088.stgit@localhost6.localdomain6>

ath10k doesn't support qca988x hw1.0 boards anymore. Unfortunately
the PCI id is the same in hw1.0 and hw2.0 so ath10k tries to use
hw1.0 boards anyway. But without hw1.0 workarounds in place
ath10k just crashes horribly.

To avoid using hw1.0 boards at all add a chip id detection
and fail the probe if hw1.0 is detected:

[ 5265.786408] ath10k: ERROR: qca988x hw1.0 is not supported
[ 5265.786497] ath10k: Unsupported chip id 0x043202ff
[ 5265.786574] ath10k: could not register driver core (-95)
[ 5265.793191] ath10k_pci: probe of 0000:02:00.0 failed with error -95

Also add a warning if there's an unknown chip id but continue
the boot process normally anyway.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c |   35 +++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/core.h |    3 ++-
 drivers/net/wireless/ath/ath10k/hw.h   |    8 +++++++
 drivers/net/wireless/ath/ath10k/pci.c  |   15 ++++++++++++--
 4 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 04c132e..2dd39a8 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -706,10 +706,43 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
 	return 0;
 }
 
-int ath10k_core_register(struct ath10k *ar)
+static int ath10k_core_check_chip_id(struct ath10k *ar)
+{
+	u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV);
+
+	/* Check that we are not using hw1.0 (some of them have same pci id
+	 * as hw2.0) before doing anything else as ath10k crashes horribly
+	 * due to missing hw1.0 workarounds. */
+	switch (hw_revision) {
+	case QCA988X_HW_1_0_CHIP_ID_REV:
+		ath10k_err("ERROR: qca988x hw1.0 is not supported\n");
+		return -EOPNOTSUPP;
+
+	case QCA988X_HW_2_0_CHIP_ID_REV:
+		/* known hardware revision, continue normally */
+		return 0;
+
+	default:
+		ath10k_warn("Warning: hardware revision unknown (0x%x), expect problems\n",
+			    ar->chip_id);
+		return 0;
+	}
+
+	return 0;
+}
+
+int ath10k_core_register(struct ath10k *ar, u32 chip_id)
 {
 	int status;
 
+	ar->chip_id = chip_id;
+
+	status = ath10k_core_check_chip_id(ar);
+	if (status) {
+		ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id);
+		return status;
+	}
+
 	status = ath10k_core_probe_fw(ar);
 	if (status) {
 		ath10k_err("could not probe fw (%d)\n", status);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index ab05c4c..174c4b4 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -284,6 +284,7 @@ struct ath10k {
 	struct device *dev;
 	u8 mac_addr[ETH_ALEN];
 
+	u32 chip_id;
 	u32 target_version;
 	u8 fw_version_major;
 	u32 fw_version_minor;
@@ -403,7 +404,7 @@ void ath10k_core_destroy(struct ath10k *ar);
 
 int ath10k_core_start(struct ath10k *ar);
 void ath10k_core_stop(struct ath10k *ar);
-int ath10k_core_register(struct ath10k *ar);
+int ath10k_core_register(struct ath10k *ar, u32 chip_id);
 void ath10k_core_unregister(struct ath10k *ar);
 
 #endif /* _CORE_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 5708888..643f0c9 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -26,8 +26,12 @@
 #define SUPPORTED_FW_RELEASE	0
 #define SUPPORTED_FW_BUILD	636
 
+/* QCA988X 1.0 definitions (unsupported) */
+#define QCA988X_HW_1_0_CHIP_ID_REV	0x0
+
 /* QCA988X 2.0 definitions */
 #define QCA988X_HW_2_0_VERSION		0x4100016c
+#define QCA988X_HW_2_0_CHIP_ID_REV	0x2
 #define QCA988X_HW_2_0_FW_DIR		"ath10k/QCA988X/hw2.0"
 #define QCA988X_HW_2_0_FW_FILE		"firmware.bin"
 #define QCA988X_HW_2_0_OTP_FILE		"otp.bin"
@@ -164,6 +168,10 @@ enum ath10k_mcast2ucast_mode {
 #define SOC_LPO_CAL_ENABLE_LSB			20
 #define SOC_LPO_CAL_ENABLE_MASK			0x00100000
 
+#define SOC_CHIP_ID_ADDRESS			0x000000ec
+#define SOC_CHIP_ID_REV_LSB			8
+#define SOC_CHIP_ID_REV_MASK			0x00000f00
+
 #define WLAN_RESET_CONTROL_COLD_RST_MASK	0x00000008
 #define WLAN_RESET_CONTROL_WARM_RST_MASK	0x00000004
 #define WLAN_SYSTEM_SLEEP_DISABLE_LSB		0
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 29ccd04..622901d 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2390,7 +2390,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
 	int ret = 0;
 	struct ath10k *ar;
 	struct ath10k_pci *ar_pci;
-	u32 lcr_val;
+	u32 lcr_val, chip_id;
 
 	ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__);
 
@@ -2492,7 +2492,18 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
 
 	spin_lock_init(&ar_pci->ce_lock);
 
-	ret = ath10k_core_register(ar);
+	ret = ath10k_do_pci_wake(ar);
+	if (ret) {
+		ath10k_err("Failed to get chip id: %d\n", ret);
+		return ret;
+	}
+
+	chip_id = ath10k_pci_read32(ar,
+				    RTC_SOC_BASE_ADDRESS + SOC_CHIP_ID_ADDRESS);
+
+	ath10k_do_pci_sleep(ar);
+
+	ret = ath10k_core_register(ar, chip_id);
 	if (ret) {
 		ath10k_err("could not register driver core (%d)\n", ret);
 		goto err_iomap;


^ permalink raw reply related

* [PATCH v2 0/2] ath10k: detect hw1.0 boards
From: Kalle Valo @ 2013-09-01  8:22 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless

Here's a patchset which detects hw1.0 from the
chip id register and fails the probe if found.

v2:

o use SOC_CHIP_ID_REV_MASK

o move detection to core.c so that it's not just PCI
  specific

o add debugfs file for reading the chip id

---

Kalle Valo (2):
      ath10k: check chip id from the soc register during probe
      ath10k: add chip_id file to debugfs


 drivers/net/wireless/ath/ath10k/core.c  |   35 ++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath10k/core.h  |    3 ++-
 drivers/net/wireless/ath/ath10k/debug.c |   22 +++++++++++++++++++
 drivers/net/wireless/ath/ath10k/hw.h    |    8 +++++++
 drivers/net/wireless/ath/ath10k/pci.c   |   15 ++++++++++++-
 5 files changed, 79 insertions(+), 4 deletions(-)


^ permalink raw reply

* Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
From: Hin-Tak Leung @ 2013-09-01  7:51 UTC (permalink / raw)
  To: khoroshilov, herton, larry.finger
  Cc: linville, linux-wireless, netdev, linux-kernel, ldv-project

------------------------------
On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote:

>In case of __dev_alloc_skb() failure rtl8187_init_urbs()
>calls usb_free_urb(entry) where 'entry' can points to urb
>allocated at the previous iteration. That means refcnt will be
>decremented incorrectly and the urb can be used after memory
>deallocation.
>
>The patch fixes the issue and implements error handling of init_urbs
>in rtl8187_start().
>
>Found by Linux Driver Verification project (linuxtesting.org).
>
>Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
>---
> drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++++++++++-----
> 1 file changed, 10 insertions(+), 5 deletions(-)
>
>diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>index f49220e..e83d53c 100644
>--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
>+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
>@@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
>         skb_queue_tail(&priv->rx_queue, skb);
>         usb_anchor_urb(entry, &priv->anchored);
>         ret = usb_submit_urb(entry, GFP_KERNEL);
>+        usb_free_urb(entry);
>         if (ret) {
>             skb_unlink(skb, &priv->rx_queue);
>             usb_unanchor_urb(entry);
>             goto err;
>         }
>-        usb_free_urb(entry);
>     }
>     return ret;
>
> err:
>-    usb_free_urb(entry);
>     kfree_skb(skb);
>     usb_kill_anchored_urbs(&priv->anchored);
>     return ret;

This part looks wrong - you free_urb(entry) then unanchor_urb(entry).

>@@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
>                   (RETRY_COUNT < 8  /* short retry limit */) |
>                   (RETRY_COUNT < 0  /* long retry limit */) |
>                   (7 < 21 /* MAX TX DMA */));
>-        rtl8187_init_urbs(dev);
>-        rtl8187b_init_status_urb(dev);
>+        ret = rtl8187_init_urbs(dev);
>+        if (ret)
>+            goto rtl8187_start_exit;
>+        ret = rtl8187b_init_status_urb(dev);
>+        if (ret)
>+            usb_kill_anchored_urbs(&priv->anchored);
>         goto rtl8187_start_exit;
>     }
> 
>@@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
>     rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
>     rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
> 
>-    rtl8187_init_urbs(dev);
>+    ret = rtl8187_init_urbs(dev);
>+    if (ret)
>+        goto rtl8187_start_exit;
> 
>     reg = RTL818X_RX_CONF_ONLYERLPKT |
>           RTL818X_RX_CONF_RX_AUTORESETPHY |
>-- 
>1.8.1.2
>



^ permalink raw reply

* [PATCH v2 7/7] ath10k: simplify ath10k_ce_init() wake up handling
From: Kalle Valo @ 2013-09-01  7:02 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901070020.14695.16694.stgit@localhost6.localdomain6>

ath10k_ce_init() and the functions it calls wakeup
the chip multiple times. Simplify that to call
ath10k_pci_wake() only once. This also makes it
easier to add error handling when wakeup fails.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 19f23a2..afe5df4 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -946,7 +946,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 	src_ring->nentries = nentries;
 	src_ring->nentries_mask = nentries - 1;
 
-	ath10k_pci_wake(ar);
 	src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
 	src_ring->sw_index &= src_ring->nentries_mask;
 	src_ring->hw_index = src_ring->sw_index;
@@ -954,7 +953,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 	src_ring->write_index =
 		ath10k_ce_src_ring_write_index_get(ar, ctrl_addr);
 	src_ring->write_index &= src_ring->nentries_mask;
-	ath10k_pci_sleep(ar);
 
 	src_ring->per_transfer_context = (void **)ptr;
 
@@ -1004,7 +1002,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 			src_ring->shadow_base_unaligned,
 			CE_DESC_RING_ALIGN);
 
-	ath10k_pci_wake(ar);
 	ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr,
 					 src_ring->base_addr_ce_space);
 	ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries);
@@ -1012,7 +1009,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
 	ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0);
 	ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
 	ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
-	ath10k_pci_sleep(ar);
 
 	return 0;
 }
@@ -1049,13 +1045,11 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
 	dest_ring->nentries = nentries;
 	dest_ring->nentries_mask = nentries - 1;
 
-	ath10k_pci_wake(ar);
 	dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr);
 	dest_ring->sw_index &= dest_ring->nentries_mask;
 	dest_ring->write_index =
 		ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
 	dest_ring->write_index &= dest_ring->nentries_mask;
-	ath10k_pci_sleep(ar);
 
 	dest_ring->per_transfer_context = (void **)ptr;
 
@@ -1090,14 +1084,12 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
 			dest_ring->base_addr_ce_space_unaligned,
 			CE_DESC_RING_ALIGN);
 
-	ath10k_pci_wake(ar);
 	ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr,
 					  dest_ring->base_addr_ce_space);
 	ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries);
 	ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0);
 	ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
 	ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
-	ath10k_pci_sleep(ar);
 
 	return 0;
 }
@@ -1138,6 +1130,10 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
 	u32 ctrl_addr = ath10k_ce_base_address(ce_id);
 	int ret;
 
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return NULL;
+
 	ce_state = ath10k_ce_init_state(ar, ce_id, attr);
 	if (!ce_state) {
 		ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id);
@@ -1165,8 +1161,8 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar,
 	}
 
 	/* Enable CE error interrupts */
-	ath10k_pci_wake(ar);
 	ath10k_ce_error_intr_enable(ar, ctrl_addr);
+
 	ath10k_pci_sleep(ar);
 
 	return ce_state;


^ permalink raw reply related

* [PATCH v2 6/7] ath10k: convert ath10k_pci_wake() to return
From: Kalle Valo @ 2013-09-01  7:02 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901070020.14695.16694.stgit@localhost6.localdomain6>

We should not try to access hw if wakeup fails so add
proper error checking for that. Also add the timeout lenght
to the warning message.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c  |   43 ++++++++++++++++++++++++++-------
 drivers/net/wireless/ath/ath10k/pci.c |   11 +++++---
 drivers/net/wireless/ath/ath10k/pci.h |    8 ++++--
 3 files changed, 45 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index 6a80142..19f23a2 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -277,7 +277,9 @@ static int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
 		ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n",
 			    __func__, nbytes, ce_state->src_sz_max);
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return ret;
 
 	if (unlikely(CE_RING_DELTA(nentries_mask,
 				   write_index, sw_index - 1) <= 0)) {
@@ -419,7 +421,9 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
 	write_index = dest_ring->write_index;
 	sw_index = dest_ring->sw_index;
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		goto out;
 
 	if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) {
 		struct ce_desc *base = dest_ring->base_addr_owner_space;
@@ -441,6 +445,8 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
 		ret = -EIO;
 	}
 	ath10k_pci_sleep(ar);
+
+out:
 	spin_unlock_bh(&ar_pci->ce_lock);
 
 	return ret;
@@ -596,6 +602,7 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 	unsigned int sw_index = src_ring->sw_index;
 	struct ce_desc *sdesc, *sbase;
 	unsigned int read_index;
+	int ret;
 
 	if (src_ring->hw_index == sw_index) {
 		/*
@@ -605,10 +612,15 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 		 * the SW has really caught up to the HW, or if the cached
 		 * value of the HW index has become stale.
 		 */
-		ath10k_pci_wake(ar);
+
+		ret = ath10k_pci_wake(ar);
+		if (ret)
+			return ret;
+
 		src_ring->hw_index =
 			ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
 		src_ring->hw_index &= nentries_mask;
+
 		ath10k_pci_sleep(ar);
 	}
 
@@ -735,8 +747,12 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
 	unsigned int nbytes;
 	unsigned int id;
 	unsigned int flags;
+	int ret;
+
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
 
-	ath10k_pci_wake(ar);
 	spin_lock_bh(&ar_pci->ce_lock);
 
 	/* Clear the copy-complete interrupts that will be handled here. */
@@ -795,10 +811,13 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
 void ath10k_ce_per_engine_service_any(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-	int ce_id;
+	int ce_id, ret;
 	u32 intr_summary;
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
+
 	intr_summary = CE_INTERRUPT_SUMMARY(ar);
 
 	for (ce_id = 0; intr_summary && (ce_id < ar_pci->ce_count); ce_id++) {
@@ -826,8 +845,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
 {
 	u32 ctrl_addr = ce_state->ctrl_addr;
 	struct ath10k *ar = ce_state->ar;
+	int ret;
 
-	ath10k_pci_wake(ar);
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
 
 	if ((!disable_copy_compl_intr) &&
 	    (ce_state->send_cb || ce_state->recv_cb))
@@ -843,9 +865,12 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
 void ath10k_ce_disable_interrupts(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-	int ce_id;
+	int ce_id, ret;
+
+	ret = ath10k_pci_wake(ar);
+	if (ret)
+		return;
 
-	ath10k_pci_wake(ar);
 	for (ce_id = 0; ce_id < ar_pci->ce_count; ce_id++) {
 		struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
 		u32 ctrl_addr = ce_state->ctrl_addr;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index e0cf75f..29ccd04 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -537,7 +537,7 @@ static void ath10k_pci_wait(struct ath10k *ar)
 		ath10k_warn("Unable to wakeup target\n");
 }
 
-void ath10k_do_pci_wake(struct ath10k *ar)
+int ath10k_do_pci_wake(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
 	void __iomem *pci_addr = ar_pci->mem;
@@ -553,18 +553,19 @@ void ath10k_do_pci_wake(struct ath10k *ar)
 	atomic_inc(&ar_pci->keep_awake_count);
 
 	if (ar_pci->verified_awake)
-		return;
+		return 0;
 
 	for (;;) {
 		if (ath10k_pci_target_is_awake(ar)) {
 			ar_pci->verified_awake = true;
-			break;
+			return 0;
 		}
 
 		if (tot_delay > PCIE_WAKE_TIMEOUT) {
-			ath10k_warn("target takes too long to wake up (awake count %d)\n",
+			ath10k_warn("target took longer %d us to wake up (awake count %d)\n",
+				    PCIE_WAKE_TIMEOUT,
 				    atomic_read(&ar_pci->keep_awake_count));
-			break;
+			return -ETIMEDOUT;
 		}
 
 		udelay(curr_delay);
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 395f610..7c49f6f 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -321,15 +321,17 @@ static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
 	return ioread32(ar_pci->mem + offset);
 }
 
-void ath10k_do_pci_wake(struct ath10k *ar);
+int ath10k_do_pci_wake(struct ath10k *ar);
 void ath10k_do_pci_sleep(struct ath10k *ar);
 
-static inline void ath10k_pci_wake(struct ath10k *ar)
+static inline int ath10k_pci_wake(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
 
 	if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features))
-		ath10k_do_pci_wake(ar);
+		return ath10k_do_pci_wake(ar);
+
+	return 0;
 }
 
 static inline void ath10k_pci_sleep(struct ath10k *ar)


^ permalink raw reply related

* [PATCH v2 5/7] ath10k: clean up ath10k_ce_completed_send_next_nolock()
From: Kalle Valo @ 2013-09-01  7:02 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901070020.14695.16694.stgit@localhost6.localdomain6>

The error handling was just weird, simplify it.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/ce.c |   41 +++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index dd80c24..6a80142 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -594,8 +594,8 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 	struct ath10k *ar = ce_state->ar;
 	unsigned int nentries_mask = src_ring->nentries_mask;
 	unsigned int sw_index = src_ring->sw_index;
+	struct ce_desc *sdesc, *sbase;
 	unsigned int read_index;
-	int ret = -EIO;
 
 	if (src_ring->hw_index == sw_index) {
 		/*
@@ -611,32 +611,33 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
 		src_ring->hw_index &= nentries_mask;
 		ath10k_pci_sleep(ar);
 	}
+
 	read_index = src_ring->hw_index;
 
-	if ((read_index != sw_index) && (read_index != 0xffffffff)) {
-		struct ce_desc *sbase = src_ring->shadow_base;
-		struct ce_desc *sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index);
+	if ((read_index == sw_index) || (read_index == 0xffffffff))
+		return -EIO;
 
-		/* Return data from completed source descriptor */
-		*bufferp = __le32_to_cpu(sdesc->addr);
-		*nbytesp = __le16_to_cpu(sdesc->nbytes);
-		*transfer_idp = MS(__le16_to_cpu(sdesc->flags),
-						CE_DESC_FLAGS_META_DATA);
+	sbase = src_ring->shadow_base;
+	sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index);
 
-		if (per_transfer_contextp)
-			*per_transfer_contextp =
-				src_ring->per_transfer_context[sw_index];
+	/* Return data from completed source descriptor */
+	*bufferp = __le32_to_cpu(sdesc->addr);
+	*nbytesp = __le16_to_cpu(sdesc->nbytes);
+	*transfer_idp = MS(__le16_to_cpu(sdesc->flags),
+			   CE_DESC_FLAGS_META_DATA);
 
-		/* sanity */
-		src_ring->per_transfer_context[sw_index] = NULL;
+	if (per_transfer_contextp)
+		*per_transfer_contextp =
+			src_ring->per_transfer_context[sw_index];
 
-		/* Update sw_index */
-		sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
-		src_ring->sw_index = sw_index;
-		ret = 0;
-	}
+	/* sanity */
+	src_ring->per_transfer_context[sw_index] = NULL;
 
-	return ret;
+	/* Update sw_index */
+	sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index);
+	src_ring->sw_index = sw_index;
+
+	return 0;
 }
 
 /* NB: Modeled after ath10k_ce_completed_send_next */


^ permalink raw reply related

* [PATCH v2 4/7] ath10k: convert ath10k_pci_reg_read/write32() to take struct ath10k
From: Kalle Valo @ 2013-09-01  7:01 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901070020.14695.16694.stgit@localhost6.localdomain6>

This is consistent with all other functions.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   19 +++++++------------
 drivers/net/wireless/ath/ath10k/pci.h |   12 ++++++++----
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 418de1e..e0cf75f 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2323,18 +2323,13 @@ static int ath10k_pci_reset_target(struct ath10k *ar)
 
 static void ath10k_pci_device_reset(struct ath10k *ar)
 {
-	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-	void __iomem *mem = ar_pci->mem;
 	int i;
 	u32 val;
 
 	if (!SOC_GLOBAL_RESET_ADDRESS)
 		return;
 
-	if (!mem)
-		return;
-
-	ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS,
+	ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS,
 			       PCIE_SOC_WAKE_V_MASK);
 	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
 		if (ath10k_pci_target_is_awake(ar))
@@ -2343,12 +2338,12 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
 	}
 
 	/* Put Target, including PCIe, into RESET. */
-	val = ath10k_pci_reg_read32(mem, SOC_GLOBAL_RESET_ADDRESS);
+	val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS);
 	val |= 1;
-	ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
+	ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
 	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
-		if (ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
+		if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
 					  RTC_STATE_COLD_RESET_MASK)
 			break;
 		msleep(1);
@@ -2356,16 +2351,16 @@ static void ath10k_pci_device_reset(struct ath10k *ar)
 
 	/* Pull Target, including PCIe, out of RESET. */
 	val &= ~1;
-	ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val);
+	ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
 	for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
-		if (!(ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) &
+		if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
 					    RTC_STATE_COLD_RESET_MASK))
 			break;
 		msleep(1);
 	}
 
-	ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
+	ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET);
 }
 
 static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci)
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 2a6cb09..395f610 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -240,14 +240,18 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
 	return ar->hif.priv;
 }
 
-static inline u32 ath10k_pci_reg_read32(void __iomem *mem, u32 addr)
+static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr)
 {
-	return ioread32(mem + PCIE_LOCAL_BASE_ADDRESS + addr);
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr);
 }
 
-static inline void ath10k_pci_reg_write32(void __iomem *mem, u32 addr, u32 val)
+static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val)
 {
-	iowrite32(val, mem + PCIE_LOCAL_BASE_ADDRESS + addr);
+	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+	iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr);
 }
 
 #define ATH_PCI_RESET_WAIT_MAX 10 /* ms */


^ permalink raw reply related

* [PATCH v2 3/7] ath10k: remove void pointer from struct ath10k_pci_compl
From: Kalle Valo @ 2013-09-01  7:01 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901070020.14695.16694.stgit@localhost6.localdomain6>

Void pointers are bad, mmkay.

No functional changes.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   12 ++++++------
 drivers/net/wireless/ath/ath10k/pci.h |    2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 362814a..418de1e 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -643,7 +643,7 @@ static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state,
 		compl->state = ATH10K_PCI_COMPL_SEND;
 		compl->ce_state = ce_state;
 		compl->pipe_info = pipe_info;
-		compl->transfer_context = transfer_context;
+		compl->skb = transfer_context;
 		compl->nbytes = nbytes;
 		compl->transfer_id = transfer_id;
 		compl->flags = 0;
@@ -693,7 +693,7 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state,
 		compl->state = ATH10K_PCI_COMPL_RECV;
 		compl->ce_state = ce_state;
 		compl->pipe_info = pipe_info;
-		compl->transfer_context = transfer_context;
+		compl->skb = transfer_context;
 		compl->nbytes = nbytes;
 		compl->transfer_id = transfer_id;
 		compl->flags = flags;
@@ -939,7 +939,7 @@ static void ath10k_pci_stop_ce(struct ath10k *ar)
 	 * their associated resources */
 	spin_lock_bh(&ar_pci->compl_lock);
 	list_for_each_entry(compl, &ar_pci->compl_process, list) {
-		skb = (struct sk_buff *)compl->transfer_context;
+		skb = compl->skb;
 		ATH10K_SKB_CB(skb)->is_aborted = true;
 	}
 	spin_unlock_bh(&ar_pci->compl_lock);
@@ -960,7 +960,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar)
 
 	list_for_each_entry_safe(compl, tmp, &ar_pci->compl_process, list) {
 		list_del(&compl->list);
-		netbuf = (struct sk_buff *)compl->transfer_context;
+		netbuf = compl->skb;
 		dev_kfree_skb_any(netbuf);
 		kfree(compl);
 	}
@@ -1014,7 +1014,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
 		switch (compl->state) {
 		case ATH10K_PCI_COMPL_SEND:
 			cb->tx_completion(ar,
-					  compl->transfer_context,
+					  compl->skb,
 					  compl->transfer_id);
 			send_done = 1;
 			break;
@@ -1026,7 +1026,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
 				break;
 			}
 
-			skb = (struct sk_buff *)compl->transfer_context;
+			skb = compl->skb;
 			nbytes = compl->nbytes;
 
 			ath10k_dbg(ATH10K_DBG_PCI,
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index 50f3e7b..2a6cb09 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -54,7 +54,7 @@ struct ath10k_pci_compl {
 	enum ath10k_pci_compl_state state;
 	struct ath10k_ce_pipe *ce_state;
 	struct ath10k_pci_pipe *pipe_info;
-	void *transfer_context;
+	struct sk_buff *skb;
 	unsigned int nbytes;
 	unsigned int transfer_id;
 	unsigned int flags;


^ permalink raw reply related

* [PATCH v2 2/7] ath10k: make target_ce_config_wlan more readable
From: Kalle Valo @ 2013-09-01  7:01 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901070020.14695.16694.stgit@localhost6.localdomain6>

It's easier to read t if the field names are visible.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   85 ++++++++++++++++++++++++++++-----
 1 file changed, 71 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index b1709d7..362814a 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -125,21 +125,78 @@ static const struct ce_attr host_ce_config_wlan[] = {
 
 /* Target firmware's Copy Engine configuration. */
 static const struct ce_pipe_config target_ce_config_wlan[] = {
-	/* host->target HTC control and raw streams */
-	{ /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0,},
-	/* target->host HTT + HTC control */
-	{ /* CE1 */ 1, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0,},
-	/* target->host WMI */
-	{ /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,},
-	/* host->target WMI */
-	{ /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
-	/* host->target HTT */
-	{ /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0,},
+	/* CE0: host->target HTC control and raw streams */
+	{
+		.pipenum = 0,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 32,
+		.nbytes_max = 256,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE1: target->host HTT + HTC control */
+	{
+		.pipenum = 1,
+		.pipedir = PIPEDIR_IN,
+		.nentries = 32,
+		.nbytes_max = 512,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE2: target->host WMI */
+	{
+		.pipenum = 2,
+		.pipedir = PIPEDIR_IN,
+		.nentries = 32,
+		.nbytes_max = 2048,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE3: host->target WMI */
+	{
+		.pipenum = 3,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 32,
+		.nbytes_max = 2048,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE4: host->target HTT */
+	{
+		.pipenum = 4,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 256,
+		.nbytes_max = 256,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
 	/* NB: 50% of src nentries, since tx has 2 frags */
-	/* unused */
-	{ /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,},
-	/* Reserved for target autonomous hif_memcpy */
-	{ /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0,},
+
+	/* CE5: unused */
+	{
+		.pipenum = 5,
+		.pipedir = PIPEDIR_OUT,
+		.nentries = 32,
+		.nbytes_max = 2048,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
+	/* CE6: Reserved for target autonomous hif_memcpy */
+	{
+		.pipenum = 6,
+		.pipedir = PIPEDIR_INOUT,
+		.nentries = 32,
+		.nbytes_max = 4096,
+		.flags = CE_ATTR_FLAGS,
+		.reserved = 0,
+	},
+
 	/* CE7 used only by Host */
 };
 


^ permalink raw reply related

* [PATCH v2 1/7] ath10k: pci: make host_ce_config_wlan[] more readable
From: Kalle Valo @ 2013-09-01  7:01 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130901070020.14695.16694.stgit@localhost6.localdomain6>

It's much more readable if struct entries in host_ce_config_wlan
are explicitly set.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   81 ++++++++++++++++++++++++++-------
 1 file changed, 63 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 551fe8c..b1709d7 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -58,24 +58,69 @@ static int ath10k_pci_start_intr(struct ath10k *ar);
 static void ath10k_pci_stop_intr(struct ath10k *ar);
 
 static const struct ce_attr host_ce_config_wlan[] = {
-	/* host->target HTC control and raw streams */
-	{ /* CE0 */ CE_ATTR_FLAGS, 16, 256, 0 },
-	/* could be moved to share CE3 */
-	/* target->host HTT + HTC control */
-	{ /* CE1 */ CE_ATTR_FLAGS, 0, 512, 512 },
-	/* target->host WMI */
-	{ /* CE2 */ CE_ATTR_FLAGS, 0, 2048, 32 },
-	/* host->target WMI */
-	{ /* CE3 */ CE_ATTR_FLAGS, 32, 2048, 0 },
-	/* host->target HTT */
-	{ /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
-		    CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0 },
-	/* unused */
-	{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0 },
-	/* Target autonomous hif_memcpy */
-	{ /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0 },
-	/* ce_diag, the Diagnostic Window */
-	{ /* CE7 */ CE_ATTR_FLAGS, 2, DIAG_TRANSFER_LIMIT, 2 },
+	/* CE0: host->target HTC control and raw streams */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 16,
+		.src_sz_max = 256,
+		.dest_nentries = 0,
+	},
+
+	/* CE1: target->host HTT + HTC control */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 512,
+		.dest_nentries = 512,
+	},
+
+	/* CE2: target->host WMI */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 2048,
+		.dest_nentries = 32,
+	},
+
+	/* CE3: host->target WMI */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 32,
+		.src_sz_max = 2048,
+		.dest_nentries = 0,
+	},
+
+	/* CE4: host->target HTT */
+	{
+		.flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
+		.src_nentries = CE_HTT_H2T_MSG_SRC_NENTRIES,
+		.src_sz_max = 256,
+		.dest_nentries = 0,
+	},
+
+	/* CE5: unused */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 0,
+		.dest_nentries = 0,
+	},
+
+	/* CE6: target autonomous hif_memcpy */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 0,
+		.src_sz_max = 0,
+		.dest_nentries = 0,
+	},
+
+	/* CE7: ce_diag, the Diagnostic Window */
+	{
+		.flags = CE_ATTR_FLAGS,
+		.src_nentries = 2,
+		.src_sz_max = DIAG_TRANSFER_LIMIT,
+		.dest_nentries = 2,
+	},
 };
 
 /* Target firmware's Copy Engine configuration. */


^ permalink raw reply related

* [PATCH v2 0/7] ath10k: pci cleanup
From: Kalle Valo @ 2013-09-01  7:01 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless

Small PCI related code cleanup. Depends on Michal's CE
clean patchset.

v2:

o remove unnecessary cast in patch 3 (from Gabor)

---

Kalle Valo (7):
      ath10k: pci: make host_ce_config_wlan[] more readable
      ath10k: make target_ce_config_wlan more readable
      ath10k: remove void pointer from struct ath10k_pci_compl
      ath10k: convert ath10k_pci_reg_read/write32() to take struct ath10k
      ath10k: clean up ath10k_ce_completed_send_next_nolock()
      ath10k: convert ath10k_pci_wake() to return
      ath10k: simplify ath10k_ce_init() wake up handling


 drivers/net/wireless/ath/ath10k/ce.c  |   98 ++++++++++------
 drivers/net/wireless/ath/ath10k/pci.c |  208 ++++++++++++++++++++++++---------
 drivers/net/wireless/ath/ath10k/pci.h |   22 ++-
 3 files changed, 227 insertions(+), 101 deletions(-)


^ permalink raw reply

* Re: [PATCH] ath10k: remove un ar_pci->cacheline_sz field
From: Kalle Valo @ 2013-09-01  6:44 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130802075601.11114.11607.stgit@localhost6.localdomain6>

Kalle Valo <kvalo@qca.qualcomm.com> writes:

> cacheline_sz is not used anywhere and can be removed.
>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>

I had sent this patch a month ago, but forgot to apply it. It's applied
now (after fixing a simple conflict).

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH v2 0/6] ath10k: CE cleanups
From: Kalle Valo @ 2013-09-01  6:36 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1377601683-12072-1-git-send-email-michal.kazior@tieto.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> This patchset contains non-functional changes
> except patch #1 which changes memory allocation
> from dynamic to static.
>
> There is still some more to clean up in PCI/CE
> but it's probably better to keep patchsets compact
> and more frequent.
>
> v2:
>  * fix checkpatch warning (Kalle)
>
>
> Michal.
>
>
> Michal Kazior (6):
>   ath10k: use inline ce_state structure
>   ath10k: remove ce_op_state
>   ath10k: remove unused ce_attr parameters
>   ath10k: rename hif_ce_pipe_info to ath10k_pci_pipe
>   ath10k: rename ce_state to ath10k_ce_pipe
>   ath10k: rename ce_ring_state to ath10k_ce_ring

Applied all six, thanks.

I dropped the lock addition from patch 1 and patch 5 had a conflict due
to that change. Please double check that I didn't break anything.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH v2 1/6] ath10k: use inline ce_state structure
From: Kalle Valo @ 2013-09-01  6:34 UTC (permalink / raw)
  To: Michal Kazior; +Cc: linux-wireless, ath10k
In-Reply-To: <CA+BoTQ=mBeWQLvaLUL4gnTENRbGUK_fTkj9bP3HP-OSzBwG0Dg@mail.gmail.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> On 28 August 2013 06:12, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> Michal Kazior <michal.kazior@tieto.com> writes:
>>
>>> Simplifies memory managament of ce_state.
>>>
>>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>>
>> Sorry, I noticed this only in my second review round:
>>
>>> --- a/drivers/net/wireless/ath/ath10k/pci.h
>>> +++ b/drivers/net/wireless/ath/ath10k/pci.h
>>> @@ -233,7 +233,10 @@ struct ath10k_pci {
>>>       spinlock_t ce_lock;
>>>
>>>       /* Map CE id to ce_state */
>>> -     struct ce_state *ce_id_to_state[CE_COUNT_MAX];
>>> +     struct ce_state ce_states[CE_COUNT_MAX];
>>> +
>>> +     /* makes sure that dummy reads are atomic */
>>> +     spinlock_t hw_v1_workaround_lock;
>>>  };
>>
>> That lock doesn't look right. Is it a leftover from a rebase?
>
> Oh, good catch. I wonder how it got there..

I had patches pending on this patchset, so I removed the lock from this
patch and applied it.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH 3/7] ath10k: remove void pointer from struct ath10k_pci_compl
From: Kalle Valo @ 2013-09-01  6:16 UTC (permalink / raw)
  To: Gabor Juhos; +Cc: ath10k, linux-wireless
In-Reply-To: <522104B1.2070004@openwrt.org>

Gabor Juhos <juhosg@openwrt.org> writes:

> 2013.08.30. 14:30 keltezéssel, Kalle Valo írta:
>> Void pointers are bad, mmkay.
>> 
>> No functional changes.
>> 
>> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
>> ---
>>  drivers/net/wireless/ath/ath10k/pci.c |   12 ++++++------
>>  drivers/net/wireless/ath/ath10k/pci.h |    2 +-
>>  2 files changed, 7 insertions(+), 7 deletions(-)
>> 
>
> <snip>
>
>> @@ -1026,7 +1026,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
>>  				break;
>>  			}
>>  
>> -			skb = (struct sk_buff *)compl->transfer_context;
>> +			skb = (struct sk_buff *)compl->skb;
>
> The cast can be removed from here as well.

Oh, I had missed that. I'll send v2 to fix that.

Thank you for the review.

-- 
Kalle Valo

^ permalink raw reply

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

From: Bjørn Mork <bjorn@mork.no>
Date: Fri, 30 Aug 2013 18:08:43 +0200

> Copying the dev_addr from a parent device is an operation
> common to a number of drivers. The addr_assign_type should
> be updated accordingly, either by reusing the value from
> the source device or explicitly indicating that the address
> is stolen by setting addr_assign_type to NET_ADDR_STOLEN.
> 
> This patch set adds a helper copying both the dev_addr and
> the addr_assign_type, and use this helper in drivers which
> don't currently set the addr_assign_type. Using NET_ADDR_STOLEN
> might be more appropriate in some of these cases.  Please
> let me know, and I'll update the patch accordingly.
> 
> Changes in v2:
>  - assuming addr_len == ETH_ALEN to allow optimized memcpy
>  - dropped the vt6656 patch due to addr_len being unset in that driver

Looks good, series applied, thanks.

^ permalink raw reply

* [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
From: Alexey Khoroshilov @ 2013-08-31 21:18 UTC (permalink / raw)
  To: Herton Ronaldo Krzesinski, Hin-Tak Leung, Larry Finger
  Cc: Alexey Khoroshilov, John W. Linville, linux-wireless, netdev,
	linux-kernel, ldv-project

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

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

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

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

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


^ permalink raw reply related

* Re: linux-next: Tree for Aug 30 (brcmfmac)
From: Hauke Mehrtens @ 2013-08-31 18:40 UTC (permalink / raw)
  To: Arend van Spriel
  Cc: Geert Uytterhoeven, Randy Dunlap, Stephen Rothwell, Linux-Next,
	linux-kernel@vger.kernel.org, linux-wireless, brcm80211-dev-list,
	linux-kbuild
In-Reply-To: <5222341B.4070205@broadcom.com>

On 08/31/2013 08:21 PM, Arend van Spriel wrote:
> On 08/31/13 19:37, Geert Uytterhoeven wrote:
>> On Fri, Aug 30, 2013 at 11:12 PM, Randy Dunlap<rdunlap@infradead.org> 
>> wrote:
>>> This bool kconfig symbol:
>>>
>>> config BRCMFMAC_SDIO
>>>          bool "SDIO bus interface support for FullMAC driver"
>>>          depends on MMC
>>>
>>> allows BRCMFMAC_SDIO to be y even when MMC=m.
>>>
>>> Is there a reasonable solution to this?
> 
> Actually, BRCMFMAC should be built in same form as the MMC and/or USB,
> but only when BRCMFMAC_SDIO or BRCMFMAC_USB are selected.
> 
> So valid combinations are:
> MMC=m, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m
> MMC=m, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m
> MMC=y, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m
> MMC=m, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n => BRCMFMAC=m
> MMC=m, USB=y, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y => BRCMFMAC=m|y
> MMC=y, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n => BRCMFMAC=m|y
> MMC=y, USB=m, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y => BRCMFMAC=m
> MMC=y, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m|y
> MMC=y, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n => BRCMFMAC=m|y
> MMC=y, USB=y, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y => BRCMFMAC=m|y
> 
> Not sure how to express the above.

This should be expressed with this Kconfig:

config BRCMFMAC_USB
	bool "USB bus interface support for FullMAC driver"
	depends on (USB = y || USB = BRCMFMAC)
	depends on BRCMFMAC

config BRCMFMAC_SDIO
	bool "SDIO bus interface support for FullMAC driver"
	depends on (MMC = y || MMC = BRCMFMAC)
	depends on BRCMFMAC
	select FW_LOADER

I haven't tested it, but we had a similar problem in b43 and fixed it
like this.

Hauke

^ permalink raw reply

* Re: linux-next: Tree for Aug 30 (brcmfmac)
From: Arend van Spriel @ 2013-08-31 18:21 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Randy Dunlap, Stephen Rothwell, Linux-Next,
	linux-kernel@vger.kernel.org, linux-wireless, brcm80211-dev-list,
	linux-kbuild
In-Reply-To: <CAMuHMdXFmWyiUJF+4HbD=6oGPVXHBAVx=rOC7u=motTQFCKn7g@mail.gmail.com>

On 08/31/13 19:37, Geert Uytterhoeven wrote:
> On Fri, Aug 30, 2013 at 11:12 PM, Randy Dunlap<rdunlap@infradead.org>  wrote:
>> This bool kconfig symbol:
>>
>> config BRCMFMAC_SDIO
>>          bool "SDIO bus interface support for FullMAC driver"
>>          depends on MMC
>>
>> allows BRCMFMAC_SDIO to be y even when MMC=m.
>>
>> Is there a reasonable solution to this?

Actually, BRCMFMAC should be built in same form as the MMC and/or USB, 
but only when BRCMFMAC_SDIO or BRCMFMAC_USB are selected.

So valid combinations are:
MMC=m, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m
MMC=m, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m
MMC=y, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m
MMC=m, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n => BRCMFMAC=m
MMC=m, USB=y, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y => BRCMFMAC=m|y
MMC=y, USB=m, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n => BRCMFMAC=m|y
MMC=y, USB=m, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y => BRCMFMAC=m
MMC=y, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=y => BRCMFMAC=m|y
MMC=y, USB=y, BRCMFMAC_SDIO=y, BRCMFMAC_USB=n => BRCMFMAC=m|y
MMC=y, USB=y, BRCMFMAC_SDIO=n, BRCMFMAC_USB=y => BRCMFMAC=m|y

Not sure how to express the above.

Gr. AvS

> In order of preference:
> 1. Make it tristate
> 2. depends on MMC=y
>
> However, the first solution cannot be used as there are several
> "#ifdef CONFIG_BRCMFMAC_SDIO" in the code itself.
>
> Note that there's a similar issue with BRCMFMAC_USB and USB.
>
> Gr{oetje,eeting}s,
>
>                          Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                  -- Linus Torvalds
>



^ permalink raw reply

* Re: linux-next: Tree for Aug 30 (brcmfmac)
From: Geert Uytterhoeven @ 2013-08-31 17:37 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Stephen Rothwell, Linux-Next, linux-kernel@vger.kernel.org,
	linux-wireless, brcm80211-dev-list, linux-kbuild
In-Reply-To: <52210AB9.2090104@infradead.org>

On Fri, Aug 30, 2013 at 11:12 PM, Randy Dunlap <rdunlap@infradead.org> wrote:
> This bool kconfig symbol:
>
> config BRCMFMAC_SDIO
>         bool "SDIO bus interface support for FullMAC driver"
>         depends on MMC
>
> allows BRCMFMAC_SDIO to be y even when MMC=m.
>
> Is there a reasonable solution to this?

In order of preference:
1. Make it tristate
2. depends on MMC=y

However, the first solution cannot be used as there are several
"#ifdef CONFIG_BRCMFMAC_SDIO" in the code itself.

Note that there's a similar issue with BRCMFMAC_USB and USB.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: linux-next: Tree for Aug 30 (brcmfmac)
From: Randy Dunlap @ 2013-08-30 21:12 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: linux-next, linux-kernel, linux-wireless, brcm80211-dev-list,
	linux-kbuild
In-Reply-To: <20130829200013.d9dde1eb64686a32c661b5d3@canb.auug.org.au>

On 08/29/13 03:00, Stephen Rothwell wrote:
> Hi all,
> 

on x86_64:

when
CONFIG_MMC=m
CONFIG_BRCMUTIL=y
CONFIG_BRCMFMAC=y
CONFIG_BRCMFMAC_SDIO=y


This bool kconfig symbol:

config BRCMFMAC_SDIO
	bool "SDIO bus interface support for FullMAC driver"
	depends on MMC

allows BRCMFMAC_SDIO to be y even when MMC=m.

Is there a reasonable solution to this?


This causes many build errors:

drivers/built-in.o: In function `brcmf_sdio_assert_info':
dhd_sdio.c:(.text+0x39609b): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x3960d9): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_readframes':
dhd_sdio.c:(.text+0x396a62): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x396a9b): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x396ae6): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x396b1b): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x396bd9): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x396c03): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x396f76): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x396fcc): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x397115): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x3972d0): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x397632): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x397699): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39770b): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x397731): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x397796): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x3977b6): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x3977ff): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x3978b6): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x397940): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x397963): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x3979c1): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x397a90): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x397ab7): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_txpkt.constprop.16':
dhd_sdio.c:(.text+0x3981d7): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x398213): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x3985d6): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_release':
dhd_sdio.c:(.text+0x398a5e): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x398a85): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_probe':
(.text+0x398d04): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdbrcm_probe':
(.text+0x398d3c): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_probe':
(.text+0x398e91): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_probe':
(.text+0x399087): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdbrcm_probe':
(.text+0x3990d0): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_readshared':
dhd_sdio.c:(.text+0x39953c): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39956e): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_bus_txctl':
dhd_sdio.c:(.text+0x399c14): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x399c2d): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x399cac): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x399cf0): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x399ec8): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x399efe): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x399ff4): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_bus_stop':
dhd_sdio.c:(.text+0x39a0cb): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39a179): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_dataworker':
dhd_sdio.c:(.text+0x39a281): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39a2f1): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39a852): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39a86d): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39aa08): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39aa4a): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39aaa1): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39aac1): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_bus_init':
dhd_sdio.c:(.text+0x39acdb): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39ad05): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39ad29): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39b086): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39b2c7): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdbrcm_watchdog_thread':
dhd_sdio.c:(.text+0x39b6dc): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39b6f7): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39b735): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39b75b): undefined reference to `sdio_release_host'
dhd_sdio.c:(.text+0x39b790): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x39b7ae): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_buffrw':
bcmsdh.c:(.text+0x39bf67): undefined reference to `mmc_set_data_timeout'
bcmsdh.c:(.text+0x39bf76): undefined reference to `mmc_wait_for_req'
bcmsdh.c:(.text+0x39c180): undefined reference to `sdio_readsb'
bcmsdh.c:(.text+0x39c19d): undefined reference to `sdio_memcpy_fromio'
bcmsdh.c:(.text+0x39c211): undefined reference to `sdio_memcpy_toio'
drivers/built-in.o: In function `brcmf_sdio_intr_unregister':
(.text+0x39c6fd): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdio_intr_unregister':
(.text+0x39c706): undefined reference to `sdio_release_irq'
drivers/built-in.o: In function `brcmf_sdio_intr_unregister':
(.text+0x39c70f): undefined reference to `sdio_release_irq'
drivers/built-in.o: In function `brcmf_sdio_intr_unregister':
(.text+0x39c718): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_intr_unregister':
(.text+0x39c72d): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdio_intr_unregister':
(.text+0x39c758): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_intr_register':
(.text+0x39c809): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdio_intr_register':
(.text+0x39c819): undefined reference to `sdio_claim_irq'
drivers/built-in.o: In function `brcmf_sdio_intr_register':
(.text+0x39c829): undefined reference to `sdio_claim_irq'
drivers/built-in.o: In function `brcmf_sdio_intr_register':
(.text+0x39c832): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_intr_register':
(.text+0x39c906): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdio_intr_register':
(.text+0x39c962): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_ramrw':
(.text+0x39ce75): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdio_ramrw':
(.text+0x39cfc1): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_pd_probe':
bcmsdh_sdmmc.c:(.text+0x39d177): undefined reference to `sdio_register_driver'
drivers/built-in.o: In function `brcmf_sdio_suspend':
bcmsdh_sdmmc.c:(.text+0x39d1f5): undefined reference to `sdio_get_host_pm_caps'
bcmsdh_sdmmc.c:(.text+0x39d207): undefined reference to `sdio_set_host_pm_flags'
drivers/built-in.o: In function `brcmf_sdio_pd_remove':
bcmsdh_sdmmc.c:(.text+0x39d268): undefined reference to `sdio_unregister_driver'
drivers/built-in.o: In function `brcmf_sdioh_request_byte':
(.text+0x39d78e): undefined reference to `sdio_f0_readb'
drivers/built-in.o: In function `brcmf_sdioh_request_byte':
(.text+0x39d7c4): undefined reference to `sdio_writeb'
drivers/built-in.o: In function `brcmf_sdioh_request_byte':
(.text+0x39d7fd): undefined reference to `sdio_f0_writeb'
drivers/built-in.o: In function `brcmf_sdioh_request_byte':
(.text+0x39d81c): undefined reference to `sdio_readb'
drivers/built-in.o: In function `brcmf_sdioh_request_byte':
(.text+0x39d844): undefined reference to `sdio_enable_func'
drivers/built-in.o: In function `brcmf_sdioh_request_byte':
(.text+0x39d889): undefined reference to `sdio_writeb'
drivers/built-in.o: In function `brcmf_sdioh_request_byte':
(.text+0x39d8a1): undefined reference to `sdio_disable_func'
drivers/built-in.o: In function `brcmf_sdioh_request_word':
(.text+0x39d96c): undefined reference to `sdio_readw'
drivers/built-in.o: In function `brcmf_sdioh_request_word':
(.text+0x39d9b7): undefined reference to `sdio_writew'
drivers/built-in.o: In function `brcmf_sdioh_request_word':
(.text+0x39d9cc): undefined reference to `sdio_readl'
drivers/built-in.o: In function `brcmf_sdioh_request_word':
(.text+0x39d9f2): undefined reference to `sdio_writel'
drivers/built-in.o: In function `brcmf_sdioh_attach':
(.text+0x39da5a): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdioh_attach':
(.text+0x39da69): undefined reference to `sdio_set_block_size'
drivers/built-in.o: In function `brcmf_sdioh_attach':
(.text+0x39da83): undefined reference to `sdio_set_block_size'
drivers/built-in.o: In function `brcmf_sdioh_attach':
(.text+0x39db3e): undefined reference to `sdio_enable_func'
drivers/built-in.o: In function `brcmf_sdioh_attach':
(.text+0x39db48): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdioh_detach':
(.text+0x39dbab): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdioh_detach':
(.text+0x39dbb4): undefined reference to `sdio_disable_func'
drivers/built-in.o: In function `brcmf_sdioh_detach':
(.text+0x39dbbd): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdioh_detach':
(.text+0x39dbc6): undefined reference to `sdio_claim_host'
drivers/built-in.o: In function `brcmf_sdioh_detach':
(.text+0x39dbcf): undefined reference to `sdio_disable_func'
drivers/built-in.o: In function `brcmf_sdioh_detach':
(.text+0x39dbd8): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_exit':
(.text+0x39dc38): undefined reference to `sdio_unregister_driver'
drivers/built-in.o: In function `brcmf_sdio_init':
(.text+0x39dca2): undefined reference to `sdio_register_driver'


-- 
~Randy

^ permalink raw reply

* Re: [PATCH 3/7] ath10k: remove void pointer from struct ath10k_pci_compl
From: Gabor Juhos @ 2013-08-30 20:46 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <20130830123021.31164.8374.stgit@localhost6.localdomain6>

2013.08.30. 14:30 keltezéssel, Kalle Valo írta:
> Void pointers are bad, mmkay.
> 
> No functional changes.
> 
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
> ---
>  drivers/net/wireless/ath/ath10k/pci.c |   12 ++++++------
>  drivers/net/wireless/ath/ath10k/pci.h |    2 +-
>  2 files changed, 7 insertions(+), 7 deletions(-)
> 

<snip>

> @@ -1026,7 +1026,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar)
>  				break;
>  			}
>  
> -			skb = (struct sk_buff *)compl->transfer_context;
> +			skb = (struct sk_buff *)compl->skb;

The cast can be removed from here as well.

>  			nbytes = compl->nbytes;
>  
>  			ath10k_dbg(ATH10K_DBG_PCI,
> diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
> index c65fe1b..2e1f422 100644
> --- a/drivers/net/wireless/ath/ath10k/pci.h
> +++ b/drivers/net/wireless/ath/ath10k/pci.h
> @@ -54,7 +54,7 @@ struct ath10k_pci_compl {
>  	enum ath10k_pci_compl_state state;
>  	struct ath10k_ce_pipe *ce_state;
>  	struct ath10k_pci_pipe *pipe_info;
> -	void *transfer_context;
> +	struct sk_buff *skb;
>  	unsigned int nbytes;
>  	unsigned int transfer_id;
>  	unsigned int flags;
> 
> 
> _______________________________________________
> ath10k mailing list
> ath10k@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/ath10k
> 


^ 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