Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 2/2] cfg80211: add an option to disable processing country IEs
From: Mihir Shete @ 2013-10-13  3:30 UTC (permalink / raw)
  To: linux-wireless
  Cc: Mihir Shete, Henri Bahini, Tushnim Bhattacharyya,
	Luis R. Rodriguez
In-Reply-To: <1381635046-15123-1-git-send-email-smihir@qti.qualcomm.com>

Certain vendors may want to disable the processing of
country IEs so that they can continue using the regulatory
domain the driver or user has set.  Currently there is no
way to stop the core from processing country IEs, so add
support to the core to ignore country IE hints.

Cc: Henri Bahini <hbahini@qca.qualcomm.com>
Cc: Tushnim Bhattacharyya <tushnimb@qca.qualcomm.com>
Cc: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Signed-off-by: Mihir Shete <smihir@qti.qualcomm.com>
---
 include/uapi/linux/nl80211.h | 5 +++++
 net/wireless/reg.c           | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 977c487..2a6ba5c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2343,10 +2343,15 @@ enum nl80211_reg_type {
  *	domain. The regulatory domain used will be based on the
  *	ISO3166-alpha2 from country IE provided through
  *	regulatory_hint_country_ie()
+ * @NL80211_COUNTRY_IE_IGNORE_CORE - for devices that have a preference to
+ *	to ignore all country IE information processed by the core. This will
+ *	override %NL80211_COUNTRY_IE_FOLLOW_POWER if the country IE hint is
+ *	issued by the core
  */
 enum nl80211_country_ie_pref {
 	NL80211_COUNTRY_IE_FOLLOW_CORE,
 	NL80211_COUNTRY_IE_FOLLOW_POWER = BIT(0),
+	NL80211_COUNTRY_IE_IGNORE_CORE = BIT(1),
 };
 
 /**
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 87b4ee3..699c4dc 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1322,6 +1322,9 @@ get_reg_request_treatment(struct wiphy *wiphy,
 	case NL80211_REGDOM_SET_BY_CORE:
 		return REG_REQ_OK;
 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+		if (wiphy->country_ie_pref & NL80211_COUNTRY_IE_IGNORE_CORE)
+			return REG_REQ_IGNORE;
+
 		if (reg_request_cell_base(lr)) {
 			/* Trust a Cell base station over the AP's country IE */
 			if (regdom_changes(pending_request->alpha2))
-- 
1.8.2.1


^ permalink raw reply related

* [PATCH 1/2] cfg80211: add flags to define country IE processing rules
From: Mihir Shete @ 2013-10-13  3:30 UTC (permalink / raw)
  To: linux-wireless
  Cc: Mihir Shete, Henri Bahini, Tushnim Bhattacharyya,
	Luis R. Rodriguez
In-Reply-To: <1381635046-15123-1-git-send-email-smihir@qti.qualcomm.com>

802.11 cards may have different country IE parsing behavioural
preferences and vendors may want to support these. These preferences
were managed by the WIPHY_FLAG_CUSTOM_REGULATORY and the
WIPHY_FLAG_STRICT_REGULATORY flags and their combination.
Instead of using this existing notation, split out the country
IE behavioural preferences to a new flag. This will allow
us to add more customizations easily and make the code more
maintainable

Cc: Henri Bahini <hbahini@qca.qualcomm.com>
Cc: Tushnim Bhattacharyya <tushnimb@qca.qualcomm.com>
Cc: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Signed-off-by: Mihir Shete <smihir@qti.qualcomm.com>
---
 drivers/net/wireless/ath/regd.c |  1 +
 include/net/cfg80211.h          | 36 +++++++++++++++++++++++-------------
 include/uapi/linux/nl80211.h    | 29 +++++++++++++++++++++++++++++
 net/wireless/reg.c              |  8 +++-----
 4 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 7d077c7..cbf074c 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -513,6 +513,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
 		 */
 		regd = ath_world_regdomain(reg);
 		wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+		wiphy->country_ie_pref = NL80211_COUNTRY_IE_FOLLOW_POWER;
 	} else {
 		/*
 		 * This gets applied in the case of the absence of CRDA,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 45f6bf5..9dd71f2 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2430,19 +2430,25 @@ struct cfg80211_ops {
  * 	has its own custom regulatory domain and cannot identify the
  * 	ISO / IEC 3166 alpha2 it belongs to. When this is enabled
  * 	we will disregard the first regulatory hint (when the
- * 	initiator is %REGDOM_SET_BY_CORE).
- * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will
- *	ignore regulatory domain settings until it gets its own regulatory
- *	domain via its regulatory_hint() unless the regulatory hint is
- *	from a country IE. After its gets its own regulatory domain it will
- *	only allow further regulatory domain settings to further enhance
- *	compliance. For example if channel 13 and 14 are disabled by this
- *	regulatory domain no user regulatory domain can enable these channels
- *	at a later time. This can be used for devices which do not have
- *	calibration information guaranteed for frequencies or settings
- *	outside of its regulatory domain. If used in combination with
- *	WIPHY_FLAG_CUSTOM_REGULATORY the inspected country IE power settings
- *	will be followed.
+ * 	initiator is %REGDOM_SET_BY_CORE). wiphys can set the custom
+ * 	regulatory domain using wiphy_apply_custom_regulatory()
+ * 	prior to wiphy registration.
+ * @WIPHY_FLAG_STRICT_REGULATORY: tells us that the wiphy for this device
+ * 	has regulatory domain that it wishes to be considered as the
+ * 	superset for regulatory rules. After this device gets its regulatory
+ * 	domain programmed further regulatory hints shall only be considered
+ * 	for this device to enhance regulatory compliance, forcing the
+ * 	device to only possibly use subsets of the original regulatory
+ * 	rules. For example if channel 13 and 14 are disabled by this
+ * 	device's regulatory domain no user specified regulatory hint which
+ * 	has these channels enabled would enable them for this wiphy,
+ * 	the device's original regulatory domain will be trusted as the
+ * 	base. You can program the superset of regulatory rules for this
+ * 	wiphy with regulatory_hint() for cards programmed with an
+ * 	ISO3166-alpha2 country code. wiphys that use regulatory_hint()
+ * 	will have their wiphy->regd programmed once the regulatory
+ * 	domain is set, and all other regulatory hints will be ignored
+ * 	until their own regulatory domain gets programmed.
  * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure
  *	that passive scan flags and beaconing flags may not be lifted by
  *	cfg80211 due to regulatory beacon hints. For more information on beacon
@@ -2773,6 +2779,8 @@ struct wiphy_coalesce_support {
  *	802.11-2012 8.4.2.29 for the defined fields.
  * @extended_capabilities_mask: mask of the valid values
  * @extended_capabilities_len: length of the extended capabilities
+ * @country_ie_pref: country IE processing preferences specified
+ *	by enum nl80211_country_ie_pref
  * @coalesce: packet coalescing support information
  */
 struct wiphy {
@@ -2844,6 +2852,8 @@ struct wiphy {
 	const u8 *extended_capabilities, *extended_capabilities_mask;
 	u8 extended_capabilities_len;
 
+	u8 country_ie_pref;
+
 	/* If multiple wiphys are registered and you're handed e.g.
 	 * a regular netdev with assigned ieee80211_ptr, you won't
 	 * know whether it points to a wiphy your driver has registered
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index fde2c02..977c487 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2321,6 +2321,35 @@ enum nl80211_reg_type {
 };
 
 /**
+ * enum nl80211_country_ie_pref - country IE processing preferences
+ *
+ * enumerates the different preferences an 802.11 card can advertize
+ * for parsing the country IEs. As per the current implementation
+ * country IEs are only used to derive the ISO3166-apha2, the
+ * information for power settings that comes with the country IE is
+ * ignored and we use the power settings from regdb.
+ *
+ * @NL80211_COUNTRY_IE_FOLLOW_CORE - This is the default behaviour
+ *	for drivers that do not advertize any preference to handle
+ *	the country IE. It allows the core to update channel flags
+ *	according to the ISO3166-alpha2 in the country IE.
+ *	The applied power is -
+ *	MIN(power specified by custom domain, power obtained from regdb)
+ * @NL80211_COUNTRY_IE_FOLLOW_POWER - for devices that have a
+ *	preference that even though they may have programmed their own
+ *	custom power setting prior to wiphy registration, they want
+ *	to ensure their channel power settings are updated for this
+ *	connection with the power settings derived from the regulatory
+ *	domain. The regulatory domain used will be based on the
+ *	ISO3166-alpha2 from country IE provided through
+ *	regulatory_hint_country_ie()
+ */
+enum nl80211_country_ie_pref {
+	NL80211_COUNTRY_IE_FOLLOW_CORE,
+	NL80211_COUNTRY_IE_FOLLOW_POWER = BIT(0),
+};
+
+/**
  * enum nl80211_reg_rule_attr - regulatory rule attributes
  * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved
  * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index d62cb1e..87b4ee3 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -898,13 +898,11 @@ static void handle_channel(struct wiphy *wiphy,
 	chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
 	if (chan->orig_mpwr) {
 		/*
-		 * Devices that have their own custom regulatory domain
-		 * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
-		 * passed country IE power settings.
+		 * Devices that use NL80211_COUNTRY_IE_FOLLOW_POWER will always
+		 * follow the passed country IE power settings.
 		 */
 		if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
-		    wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
-		    wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
+		    wiphy->country_ie_pref & NL80211_COUNTRY_IE_FOLLOW_POWER)
 			chan->max_power = chan->max_reg_power;
 		else
 			chan->max_power = min(chan->orig_mpwr,
-- 
1.8.2.1


^ permalink raw reply related

* [PATCH 0/2] cfg80211: changes to add the country IE preferences
From: Mihir Shete @ 2013-10-13  3:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: Mihir Shete

802.11 cards may have different country IE parsing preferences
and vendors have to support these. We currently provide support
for country IE behavioural preferences by using the flags
WIPHY_FLAG_STRICT_REGULATORY, WIPHY_FLAG_CUSTOM_REGULATORY and
their combination.

Instead of extending the definition by using the existing
regulatory flags, split out the desired behaviours into a new
wiphy flag. This will allow us to add more customizations in a
more easily maintainable fashion.

Mihir Shete (2):
  cfg80211: add flags to define country IE processing rules
  cfg80211: add an option to disable processing country IEs

 drivers/net/wireless/ath/regd.c |  1 +
 include/net/cfg80211.h          | 36 +++++++++++++++++++++++-------------
 include/uapi/linux/nl80211.h    | 34 ++++++++++++++++++++++++++++++++++
 net/wireless/reg.c              | 11 ++++++-----
 4 files changed, 64 insertions(+), 18 deletions(-)

-- 
1.8.2.1


^ permalink raw reply

* Re: [Patch 1/1]: libertas/sdio: fix releasing memory twice.
From: Dan Williams @ 2013-10-12 19:58 UTC (permalink / raw)
  To: Dr. H. Nikolaus Schaller
  Cc: John W. Linville, Bing Zhao, Harro Haan, libertas-dev,
	linux-wireless, netdev, LKML, Belisko Marek, NeilBrown Brown
In-Reply-To: <D5BD8103-A6A6-4070-878B-99FC5883725F@goldelico.com>

On Sat, 2013-10-12 at 18:02 +0200, Dr. H. Nikolaus Schaller wrote:
> While upgrading the GTA04 kernel to 3.12-rc4 we came across
> an issue with libertas/sdio referencing stale memory on ifconfig up
> when trying to load the firmware (for a second time).
> 
> I am not at all sure if the patch is how it should be done and the right
> location, but it appears to work for us with resetting priv->helper_fw to NULL
> before asynchronously loading the firmware again.

How about we go even simpler?  helper_fw is *only* used inside
firmware.c anyway, and that's probably where its lifetime should be
handled.  Same for the main firmware.  I have no idea why the bus code
is responsible for releasing the firmware anyway, when it originates
from firmware.c and control returns back there after the firmware loaded
callback is done.  Does the following patch fix your problem too?

Dan

---
diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c
index c0f9e7e..51b92b5 100644
--- a/drivers/net/wireless/libertas/firmware.c
+++ b/drivers/net/wireless/libertas/firmware.c
@@ -49,14 +49,19 @@ static void main_firmware_cb(const struct firmware *firmware, void *context)
 		/* Failed to find firmware: try next table entry */
 		load_next_firmware_from_table(priv);
 		return;
 	}
 
 	/* Firmware found! */
 	lbs_fw_loaded(priv, 0, priv->helper_fw, firmware);
+	if (priv->helper_fw) {
+		release_firmware (priv->helper_fw);
+		priv->helper_fw = NULL;
+	}
+	release_firmware (firmware);
 }
 
 static void helper_firmware_cb(const struct firmware *firmware, void *context)
 {
 	struct lbs_private *priv = context;
 
 	if (!firmware) {
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index c94dd68..ef8c98e 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -750,22 +750,22 @@ static void if_cs_prog_firmware(struct lbs_private *priv, int ret,
 	}
 
 	/* Load the firmware */
 	ret = if_cs_prog_helper(card, helper);
 	if (ret == 0 && (card->model != MODEL_8305))
 		ret = if_cs_prog_real(card, mainfw);
 	if (ret)
-		goto out;
+		return;
 
 	/* Now actually get the IRQ */
 	ret = request_irq(card->p_dev->irq, if_cs_interrupt,
 		IRQF_SHARED, DRV_NAME, card);
 	if (ret) {
 		pr_err("error in request_irq\n");
-		goto out;
+		return;
 	}
 
 	/*
 	 * Clear any interrupt cause that happened while sending
 	 * firmware/initializing card
 	 */
 	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
@@ -773,18 +773,14 @@ static void if_cs_prog_firmware(struct lbs_private *priv, int ret,
 
 	/* And finally bring the card up */
 	priv->fw_ready = 1;
 	if (lbs_start_card(priv) != 0) {
 		pr_err("could not activate card\n");
 		free_irq(card->p_dev->irq, card);
 	}
-
-out:
-	release_firmware(helper);
-	release_firmware(mainfw);
 }
 
 
 /********************************************************************/
 /* Callback functions for libertas.ko                               */
 /********************************************************************/
 
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 4557833..991238a 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -704,28 +704,24 @@ static void if_sdio_do_prog_firmware(struct lbs_private *priv, int ret,
 	if (ret) {
 		pr_err("failed to find firmware (%d)\n", ret);
 		return;
 	}
 
 	ret = if_sdio_prog_helper(card, helper);
 	if (ret)
-		goto out;
+		return;
 
 	lbs_deb_sdio("Helper firmware loaded\n");
 
 	ret = if_sdio_prog_real(card, mainfw);
 	if (ret)
-		goto out;
+		return;
 
 	lbs_deb_sdio("Firmware loaded\n");
 	if_sdio_finish_power_on(card);
-
-out:
-	release_firmware(helper);
-	release_firmware(mainfw);
 }
 
 static int if_sdio_prog_firmware(struct if_sdio_card *card)
 {
 	int ret;
 	u16 scratch;
 
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 4bb6574..87ff0ca 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -1090,19 +1090,15 @@ static int if_spi_init_card(struct if_spi_card *card)
 	}
 
 	err = spu_set_interrupt_mode(card, 0, 1);
 	if (err)
 		goto out;
 
 out:
-	release_firmware(helper);
-	release_firmware(mainfw);
-
 	lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
-
 	return err;
 }
 
 static void if_spi_resume_worker(struct work_struct *work)
 {
 	struct if_spi_card *card;
 
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 2798077..dff08a2 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -840,15 +840,15 @@ static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
 		pr_err("failed to find firmware (%d)\n", ret);
 		goto done;
 	}
 
 	cardp->fw = fw;
 	if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
 		ret = -EINVAL;
-		goto release_fw;
+		goto done;
 	}
 
 	/* Cancel any pending usb business */
 	usb_kill_urb(cardp->rx_urb);
 	usb_kill_urb(cardp->tx_urb);
 
 	cardp->fwlastblksent = 0;
@@ -857,15 +857,15 @@ static void if_usb_prog_firmware(struct lbs_private *priv, int ret,
 	cardp->fwfinalblk = 0;
 	cardp->bootcmdresp = 0;
 
 restart:
 	if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
 		lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
 		ret = -EIO;
-		goto release_fw;
+		goto done;
 	}
 
 	cardp->bootcmdresp = 0;
 	do {
 		int j = 0;
 		i++;
 		if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
@@ -879,22 +879,22 @@ restart:
 	if (cardp->bootcmdresp == BOOT_CMD_RESP_NOT_SUPPORTED) {
 		/* Return to normal operation */
 		ret = -EOPNOTSUPP;
 		usb_kill_urb(cardp->rx_urb);
 		usb_kill_urb(cardp->tx_urb);
 		if (if_usb_submit_rx_urb(cardp) < 0)
 			ret = -EIO;
-		goto release_fw;
+		goto done;
 	} else if (cardp->bootcmdresp <= 0) {
 		if (--reset_count >= 0) {
 			if_usb_reset_device(cardp);
 			goto restart;
 		}
 		ret = -EIO;
-		goto release_fw;
+		goto done;
 	}
 
 	i = 0;
 
 	cardp->totalbytes = 0;
 	cardp->fwlastblksent = 0;
 	cardp->CRC_OK = 1;
@@ -917,37 +917,34 @@ restart:
 		if (--reset_count >= 0) {
 			if_usb_reset_device(cardp);
 			goto restart;
 		}
 
 		pr_info("FW download failure, time = %d ms\n", i * 100);
 		ret = -EIO;
-		goto release_fw;
+		goto done;
 	}
 
 	cardp->priv->fw_ready = 1;
 	if_usb_submit_rx_urb(cardp);
 
 	if (lbs_start_card(priv))
-		goto release_fw;
+		goto done;
 
 	if_usb_setup_firmware(priv);
 
 	/*
 	 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
 	 */
 	priv->wol_criteria = EHS_REMOVE_WAKEUP;
 	if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL))
 		priv->ehs_remove_supported = false;
 
- release_fw:
-	release_firmware(cardp->fw);
-	cardp->fw = NULL;
-
  done:
+	cardp->fw = NULL;
 	lbs_deb_leave(LBS_DEB_USB);
 }
 
 
 #ifdef CONFIG_PM
 static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 {



^ permalink raw reply related

* Re: [wireless-next:master 82/98] drivers/net/wireless/ath/wcn36xx/wcn36xx.h:88:24: sparse: incorrect type in assignment (different base types)
From: Eugene Krasnikov @ 2013-10-12 19:17 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Fengguang Wu, kbuild-all, John W. Linville, linux-wireless,
	wcn36xx
In-Reply-To: <1381602356.14243.4.camel@jlt4.sipsolutions.net>

> $ sparse --version
> v0.4.4-133-g5449cfb

My is: sparse --version
v0.4.5-rc1


> Hard to believe - did you pass the CF= on the command line? I suggest
>
> ccflags-y += -D__CHECK_ENDIAN__

Agree that it's not a version difference :) Yes , i set check endian.
Weird, will try to modify makefile and see if that helps.


> Also, code might be fine, but buff_to_be() is still not a good idea
> since it breaks all endian annotation.

Could you please explain in more details how does buff_to_be break
endian annotation?


> Also, I suggested to run smatch, I guess you never did:

I ran it and even fixed some of the errors. These errors i might just
missed because of the output is flooded with messages like:
drivers/net/wireless/ath/wcn36xx/main.c:24 (null)() info: ignoring
unreachable code.

Thanx for pointing to these warnings.

On Sat, Oct 12, 2013 at 7:25 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Fri, 2013-10-11 at 21:39 +0100, Eugene Krasnikov wrote:
>
>> Do you see the same warning?
>
> Yes
>
>> With the latest sparse i do not see this
>> warning.
>
> $ sparse --version
> v0.4.4-133-g5449cfb
>
>> I assume this warning depends on sparse version since with my
>> environment it does not pop up. Also from code perspective it looks
>> fine. Any ideas?:)
>
> Hard to believe - did you pass the CF= on the command line? I suggest
>
> ccflags-y += -D__CHECK_ENDIAN__
>
> in your Makefile.
>
> Also, code might be fine, but buff_to_be() is still not a good idea
> since it breaks all endian annotation.
>
> Also, I suggested to run smatch, I guess you never did:
> drivers/net/wireless/ath/wcn36xx/smd.c:1314 wcn36xx_smd_send_beacon() warn: inconsistent returns mutex:&wcn->hal_mutex: locked (1289 [(-12)]) unlocked (1314 [0], 1314 [s32min-(-1),1-s32max])
> drivers/net/wireless/ath/wcn36xx/smd.c:1357 wcn36xx_smd_update_proberesp_tmpl() warn: inconsistent returns mutex:&wcn->hal_mutex: locked (1330 [(-7)]) unlocked (1357 [0], 1357 [s32min-(-1),1-s32max])
> drivers/net/wireless/ath/wcn36xx/smd.c:1626 wcn36xx_smd_keep_alive_req() warn: inconsistent returns mutex:&wcn->hal_mutex: locked (1609 [(-22)]) unlocked (1626 [0], 1626 [s32min-(-1),1-s32max])
> drivers/net/wireless/ath/wcn36xx/smd.c:2041 wcn36xx_smd_rsp_process() error: potential null dereference 'msg_ind'.  (kmalloc returns null)
>
> johannes
>



-- 
Best regards,
Eugene

^ permalink raw reply

* Re: [wireless-next:master 82/98] drivers/net/wireless/ath/wcn36xx/wcn36xx.h:88:24: sparse: incorrect type in assignment (different base types)
From: Johannes Berg @ 2013-10-12 18:25 UTC (permalink / raw)
  To: Eugene Krasnikov
  Cc: Fengguang Wu, kbuild-all, John W. Linville, linux-wireless,
	wcn36xx
In-Reply-To: <CAFSJ42Y3x9bzKO8jo-n8Vn7ei38FkYVqW5Gog+_pa_j83ZUXhw@mail.gmail.com>

On Fri, 2013-10-11 at 21:39 +0100, Eugene Krasnikov wrote:

> Do you see the same warning? 

Yes

> With the latest sparse i do not see this
> warning. 

$ sparse --version
v0.4.4-133-g5449cfb

> I assume this warning depends on sparse version since with my
> environment it does not pop up. Also from code perspective it looks
> fine. Any ideas?:)

Hard to believe - did you pass the CF= on the command line? I suggest

ccflags-y += -D__CHECK_ENDIAN__

in your Makefile.

Also, code might be fine, but buff_to_be() is still not a good idea
since it breaks all endian annotation.

Also, I suggested to run smatch, I guess you never did:
drivers/net/wireless/ath/wcn36xx/smd.c:1314 wcn36xx_smd_send_beacon() warn: inconsistent returns mutex:&wcn->hal_mutex: locked (1289 [(-12)]) unlocked (1314 [0], 1314 [s32min-(-1),1-s32max])
drivers/net/wireless/ath/wcn36xx/smd.c:1357 wcn36xx_smd_update_proberesp_tmpl() warn: inconsistent returns mutex:&wcn->hal_mutex: locked (1330 [(-7)]) unlocked (1357 [0], 1357 [s32min-(-1),1-s32max])
drivers/net/wireless/ath/wcn36xx/smd.c:1626 wcn36xx_smd_keep_alive_req() warn: inconsistent returns mutex:&wcn->hal_mutex: locked (1609 [(-22)]) unlocked (1626 [0], 1626 [s32min-(-1),1-s32max])
drivers/net/wireless/ath/wcn36xx/smd.c:2041 wcn36xx_smd_rsp_process() error: potential null dereference 'msg_ind'.  (kmalloc returns null)

johannes


^ permalink raw reply

* Re: [PATCH v3] rt2x00: rt2800lib: remove duplicate rf_vals for RF3053
From: Gabor Juhos @ 2013-10-12 16:20 UTC (permalink / raw)
  To: Kevin Lo; +Cc: John Linville, linux-wireless, users
In-Reply-To: <20131012152735.GB4156@ns.kevlo.org>

2013.10.12. 17:27 keltezéssel, Kevin Lo írta:
> We already have rf_vals_3x with same values.  Hence rf_vals_3053 is removed
> in this patch.
> 
> Signed-off-by: Kevin Lo <kevlo@kevlo.org>
> Acked-by: Paul Menzel <paulepanter@users.sourceforge.net>
> Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
> ---
> Changes since v1:
>   - update comment of rf_vals_3x to indicate that it also supports RF3053
>   - add Paul's Acked-by tag
> ---
> Changes since v2:
>  - the previous patch was malformed
>  - add Stanislaw's Acked-by tag
> ---
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c

<...>

>  	struct hw_mode_spec *spec = &rt2x00dev->spec;
> @@ -7599,14 +7533,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>  		   rt2x00_rf(rt2x00dev, RF5392)) {
>  		spec->num_channels = 14;
>  		spec->channels = rf_vals_3x;
> -	} else if (rt2x00_rf(rt2x00dev, RF3052)) {
> +	} else if (rt2x00_rf(rt2x00dev, RF3052) ||
> +		   rt2x00_rf(rt2x00dev, RF3053)) { 

checpatch.pl says this:

ERROR: trailing whitespace
#127: FILE: drivers/net/wireless/rt2x00/rt2800lib.c:7537:
+^I^I   rt2x00_rf(rt2x00dev, RF3053)) { $

total: 1 errors, 0 warnings, 96 lines checked

Otherwise the patch is ok.

-Gabor

^ permalink raw reply

* [Patch 1/1]: libertas/sdio: fix releasing memory twice.
From: Dr. H. Nikolaus Schaller @ 2013-10-12 16:02 UTC (permalink / raw)
  To: John W. Linville, Bing Zhao, H. Nikolaus Schaller, Dan Williams,
	Harro Haan, libertas-dev, linux-wireless, netdev, LKML,
	Belisko Marek, NeilBrown Brown

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

While upgrading the GTA04 kernel to 3.12-rc4 we came across
an issue with libertas/sdio referencing stale memory on ifconfig up
when trying to load the firmware (for a second time).

I am not at all sure if the patch is how it should be done and the right
location, but it appears to work for us with resetting priv->helper_fw to NULL
before asynchronously loading the firmware again.




[-- Attachment #2: 0001-libertas-sdio-fix-releasing-memory-twice.patch --]
[-- Type: application/octet-stream, Size: 1850 bytes --]

From f6864491ea45d2bd877a37fbb4a618e42fe03fbe Mon Sep 17 00:00:00 2001
From: "H. Nikolaus Schaller" <hns@goldelico.com>
Date: Sat, 12 Oct 2013 17:49:31 +0200
Subject: [PATCH] libertas/sdio: fix releasing memory twice. We have connected
 a Wi2Wi W2CBW003 to an OMAP3 using SDIO. We have seen an
 issue (not related with this patch) that sometimes power is
 not turned off. This did lead to a kernel Oops if an
 ifconfig up / down / up when the chip was not powered down.
 This leads to a second call to lbs_get_firmware_async()
 with the same priv data - and that tries to
 release_firmware(priv->helper_fw); This appears to be
 wrong, since it was alredy released in the
 if_sdio_do_prog_firmware.

Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
 drivers/net/wireless/libertas/if_sdio.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 4557833..a04eb41 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -769,6 +769,19 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
 		return 0;
 	}
 
+	/* This is missing in lbs_get_firmware_async()
+	 * and therefore a second call using the same priv structure
+	 * may find a stale helper_fw entry that has already been
+	 * released by release_firmware(helper) in
+	 * if_sdio_do_prog_firmware().
+	 * Or doing that release in if_sdio_do_prog_firmware()
+	 * is a duplicate and should not be there.
+	 * Anyways, this can happen if a ifconfig up / down / up
+	 * sequence is issued.
+	 */
+
+	card->priv->helper_fw = NULL;
+
 	ret = lbs_get_firmware_async(card->priv, &card->func->dev, card->model,
 				     fw_table, if_sdio_do_prog_firmware);
 
-- 
1.7.7.4


^ permalink raw reply related

* [PATCH v3] rt2x00: rt2800lib: remove duplicate rf_vals for RF3053
From: Kevin Lo @ 2013-10-12 15:27 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, users

We already have rf_vals_3x with same values.  Hence rf_vals_3053 is removed
in this patch.

Signed-off-by: Kevin Lo <kevlo@kevlo.org>
Acked-by: Paul Menzel <paulepanter@users.sourceforge.net>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
Changes since v1:
  - update comment of rf_vals_3x to indicate that it also supports RF3053
  - add Paul's Acked-by tag
---
Changes since v2:
 - the previous patch was malformed
 - add Stanislaw's Acked-by tag
---

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index a114cab..c755309 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7248,7 +7248,7 @@ static const struct rf_channel rf_vals[] = {
 
 /*
  * RF value list for rt3xxx
- * Supports: 2.4 GHz (all) & 5.2 GHz (RF3052)
+ * Supports: 2.4 GHz (all) & 5.2 GHz (RF3052 & RF3053)
  */
 static const struct rf_channel rf_vals_3x[] = {
 	{1,  241, 2, 2 },
@@ -7444,72 +7444,6 @@ static const struct rf_channel rf_vals_5592_xtal40[] = {
 	{196, 83, 0, 12, 1},
 };
 
-static const struct rf_channel rf_vals_3053[] = {
-	/* Channel, N, R, K */
-	{1, 241, 2, 2},
-	{2, 241, 2, 7},
-	{3, 242, 2, 2},
-	{4, 242, 2, 7},
-	{5, 243, 2, 2},
-	{6, 243, 2, 7},
-	{7, 244, 2, 2},
-	{8, 244, 2, 7},
-	{9, 245, 2, 2},
-	{10, 245, 2, 7},
-	{11, 246, 2, 2},
-	{12, 246, 2, 7},
-	{13, 247, 2, 2},
-	{14, 248, 2, 4},
-
-	{36, 0x56, 0, 4},
-	{38, 0x56, 0, 6},
-	{40, 0x56, 0, 8},
-	{44, 0x57, 0, 0},
-	{46, 0x57, 0, 2},
-	{48, 0x57, 0, 4},
-	{52, 0x57, 0, 8},
-	{54, 0x57, 0, 10},
-	{56, 0x58, 0, 0},
-	{60, 0x58, 0, 4},
-	{62, 0x58, 0, 6},
-	{64, 0x58, 0, 8},
-
-	{100, 0x5B, 0, 8},
-	{102, 0x5B, 0, 10},
-	{104, 0x5C, 0, 0},
-	{108, 0x5C, 0, 4},
-	{110, 0x5C, 0, 6},
-	{112, 0x5C, 0, 8},
-
-	/* NOTE: Channel 114 has been removed intentionally.
-	 * The EEPROM contains no TX power values for that,
-	 * and it is disabled in the vendor driver as well.
-	 */
-
-	{116, 0x5D, 0, 0},
-	{118, 0x5D, 0, 2},
-	{120, 0x5D, 0, 4},
-	{124, 0x5D, 0, 8},
-	{126, 0x5D, 0, 10},
-	{128, 0x5E, 0, 0},
-	{132, 0x5E, 0, 4},
-	{134, 0x5E, 0, 6},
-	{136, 0x5E, 0, 8},
-	{140, 0x5F, 0, 0},
-
-	{149, 0x5F, 0, 9},
-	{151, 0x5F, 0, 11},
-	{153, 0x60, 0, 1},
-	{157, 0x60, 0, 5},
-	{159, 0x60, 0, 7},
-	{161, 0x60, 0, 9},
-	{165, 0x61, 0, 1},
-	{167, 0x61, 0, 3},
-	{169, 0x61, 0, 5},
-	{171, 0x61, 0, 7},
-	{173, 0x61, 0, 9},
-};
-
 static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 {
 	struct hw_mode_spec *spec = &rt2x00dev->spec;
@@ -7599,14 +7533,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 		   rt2x00_rf(rt2x00dev, RF5392)) {
 		spec->num_channels = 14;
 		spec->channels = rf_vals_3x;
-	} else if (rt2x00_rf(rt2x00dev, RF3052)) {
+	} else if (rt2x00_rf(rt2x00dev, RF3052) ||
+		   rt2x00_rf(rt2x00dev, RF3053)) { 
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 		spec->num_channels = ARRAY_SIZE(rf_vals_3x);
 		spec->channels = rf_vals_3x;
-	} else if (rt2x00_rf(rt2x00dev, RF3053)) {
-		spec->supported_bands |= SUPPORT_BAND_5GHZ;
-		spec->num_channels = ARRAY_SIZE(rf_vals_3053);
-		spec->channels = rf_vals_3053;
 	} else if (rt2x00_rf(rt2x00dev, RF5592)) {
 		spec->supported_bands |= SUPPORT_BAND_5GHZ;
 

^ permalink raw reply related

* [PATCH v2] rt2x00: rt2800lib: fix RF registers for RT5390/RT5392
From: Kevin Lo @ 2013-10-12 15:25 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless, users

Update rf registers to use the same values that the MediaTek/Ralink
reference driver DPO_RT5572_LinuxSTA_2.6.1.3_20121022 uses.

References:
  RF5390RegTable in chips/rt5390.c
  RF5392RegTable in chips/rt5390.c

Tested on TP-Link TL-WN727N and D-Link DWA-140 Rev.b3 usb wifi dongles.

Signed-off-by: Kevin Lo <kevlo@kevlo.org>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>
---
Changes since v1:
  - the previous patch was malformed
  - add Stanislaw's Acked-by tag
--- 

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index a114cab..373efde 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -6476,7 +6476,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
 	rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
 	rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
 
-	rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
+	rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
 	rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
 	rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
 	rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
@@ -6514,7 +6514,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
 	rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
 	rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
 	rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
-	rt2800_rfcsr_write(rt2x00dev, 59, 0x63);
+	rt2800_rfcsr_write(rt2x00dev, 59, 0x8f);
 
 	rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
 	if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
@@ -6534,7 +6534,6 @@ static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev)
 	rt2800_rf_init_calibration(rt2x00dev, 2);
 
 	rt2800_rfcsr_write(rt2x00dev, 1, 0x17);
-	rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
 	rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
 	rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
 	rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);

^ permalink raw reply related

* Re: [PATCH 2/2] ath9k: add HT40 spectral scan capability
From: Luis R. Rodriguez @ 2013-10-12 14:25 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Simon Wunderlich, John Linville, linux-wireless,
	Luis R. Rodriguez
In-Reply-To: <CAA2SeNJk2JxRfMzZd1VR=nA+e3gNoa+jdfcU8rZAUbsdGrHJ2g@mail.gmail.com>

On Fri, Oct 11, 2013 at 01:33:49PM +0200, Lorenzo Bianconi wrote:
> Hi Simon,
> 
> > Hello Lorenzo,
> >
> > I've reviewed and tested your patch, this looks good! The old format still works, and
> > for a HT40+ channel I get your new format. Please find a few minor comments inline,
> > and feel free to add my Tested-by/Reviewed-by in the next round.
> >
> 
> Perfect, I will send a new patchset with changes you suggested me
> 
> > BTW, i failed to compile your UI[1]. I'm not familiar with QT, maybe you can add some
> > installation document (or Makefile or whatever)? :)
> 
> Sorry, I forgot to commit main.c :)
> You should install Qwt libraries (http://qwt.sourceforge.net/) since
> they are not compiled statically into the program and then run qmake
> and make. I tested UI with Qwt-6.1.0 and Qt-5.0.1
> Anyway, I will write a README

Please also extend the ath9k wiki with informatoin
referncing your project and feel free to also use the
wiki to even document your project as this is very ath9k
specific.

  Luis

^ permalink raw reply

* Re: [rt2x00-users] [PATCH] rt2x00: cleanup indentation in rt2800.h
From: Gabor Juhos @ 2013-10-12 10:15 UTC (permalink / raw)
  To: Paul Menzel; +Cc: John Linville, linux-wireless, users
In-Reply-To: <1381570876.22335.13.camel@mattotaupa>

2013.10.12. 11:41 keltezéssel, Paul Menzel írta:
> Am Freitag, den 11.10.2013, 12:50 +0200 schrieb Gabor Juhos:
>> Adjust whitespaces to move badly aligned constants
>> to the right column.
> 
> Did you use a tool for that or did you do it manually?

I did that manually.

-Gabor


^ permalink raw reply

* Re: [rt2x00-users] [PATCH] rt2x00: cleanup indentation in rt2800.h
From: Paul Menzel @ 2013-10-12  9:41 UTC (permalink / raw)
  To: Gabor Juhos; +Cc: John Linville, linux-wireless, users
In-Reply-To: <1381488608-23315-1-git-send-email-juhosg@openwrt.org>

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

Am Freitag, den 11.10.2013, 12:50 +0200 schrieb Gabor Juhos:
> Adjust whitespaces to move badly aligned constants
> to the right column.

Did you use a tool for that or did you do it manually?

[…]


Thanks,

Paul


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

^ permalink raw reply

* [PATCH] mwifiex: use alloc_workqueue() function
From: Bing Zhao @ 2013-10-12  1:33 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Amitkumar Karwar, Avinash Patil,
	Nishant Sarmukadam, Frank Huang, Bing Zhao

From: Amitkumar Karwar <akarwar@marvell.com>

It replaces deprecated create_workqueue().

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index c2b91f5..9d7c9d3 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -882,7 +882,9 @@ mwifiex_add_card(void *card, struct semaphore *sem,
 	adapter->cmd_wait_q.status = 0;
 	adapter->scan_wait_q_woken = false;
 
-	adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
+	adapter->workqueue =
+		alloc_workqueue("MWIFIEX_WORK_QUEUE",
+				WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
 	if (!adapter->workqueue)
 		goto err_kmalloc;
 
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 3.12 1/2] mwifiex: inform cfg80211 about disconnect if device is removed
From: Bing Zhao @ 2013-10-12  1:31 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Avinash Patil, Amitkumar Karwar,
	Nishant Sarmukadam, Frank Huang, Bing Zhao

From: Avinash Patil <patila@marvell.com>

If device is surprise removed, commands sent to FW including
deauthenticate command fail as bus writes fail.
We update our media_connected status to false and inform cfg80211
about disconnection only when command is successful. Since cfg80211
assumes device is still connected, it results into following
WARN_ON during unload:

WARNING: CPU: 0 PID: 18245 at net/wireless/core.c:937
         cfg80211_netdev_notifier_call+0x175/0x4d0 [cfg80211]()

Avoid this by emitting cfg80211_disconnected event even if the
deauthenticate command fails.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/join.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 717fbe2..4e4686e 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1422,13 +1422,19 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
  */
 int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
 {
+	int ret = 0;
+
 	if (!priv->media_connected)
 		return 0;
 
 	switch (priv->bss_mode) {
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_P2P_CLIENT:
-		return mwifiex_deauthenticate_infra(priv, mac);
+		ret = mwifiex_deauthenticate_infra(priv, mac);
+		if (ret)
+			cfg80211_disconnected(priv->netdev, 0, NULL, 0,
+					      GFP_KERNEL);
+		break;
 	case NL80211_IFTYPE_ADHOC:
 		return mwifiex_send_cmd_sync(priv,
 					     HostCmd_CMD_802_11_AD_HOC_STOP,
@@ -1440,7 +1446,7 @@ int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
 		break;
 	}
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
 
-- 
1.8.2.3


^ permalink raw reply related

* [PATCH 3.12 2/2] mwifiex: inform cfg80211 about disconnect for P2P client interface
From: Bing Zhao @ 2013-10-12  1:31 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Avinash Patil, Amitkumar Karwar,
	Nishant Sarmukadam, Frank Huang, Bing Zhao
In-Reply-To: <1381541492-28226-1-git-send-email-bzhao@marvell.com>

From: Avinash Patil <patila@marvell.com>

This patch adds missing cfg80211_disconnected event for P2P client
interface upon successful deauthenticate command, deauthenticate
event or disassociate event from FW.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
---
 drivers/net/wireless/mwifiex/sta_event.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 8b05752..8c351f7 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -118,7 +118,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
 	dev_dbg(adapter->dev,
 		"info: successfully disconnected from %pM: reason code %d\n",
 		priv->cfg_bssid, reason_code);
-	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+	    priv->bss_mode == NL80211_IFTYPE_P2P_CLIENT) {
 		cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
 				      GFP_KERNEL);
 	}
-- 
1.8.2.3


^ permalink raw reply related

* ath10k related kernel crash in wireless-testing (3.12.0-rc3-wl+)
From: Ben Greear @ 2013-10-11 23:51 UTC (permalink / raw)
  To: ath9k-devel@lists.ath9k.org; +Cc: linux-wireless@vger.kernel.org

My kernel is lightly patched, no patches to ath10k.

Looks like something is not checking a NULL pointer, but I did
not dig into the code.  I'm not actually running any traffic on
the ath10k device.


ath10k: Completion buffers are full
ath10k: Completion buffers are full
ath10k: MSI-X interrupt handling (8 intrs)
e1000e: eth1 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx
ath10k: UART prints disabled
ath10k: firmware 1.0.0.636 booted
ath10k: htt target version 2.1

...

ath10k: Completion buffers are full
ath10k: Completion buffers are full
IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready
8021q: adding VLAN 0 to HW filter on device eth1
IPv6: ADDRCONF(NETDEV_UP): sta0: link is not ready
IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
IPv6: ADDRCONF(NETDEV_UP): wlan1: link is not ready
IPv6: ADDRCONF(NETDEV_UP): sta0: link is not ready
IPv6: ADDRCONF(NETDEV_UP): sta0: link is not ready
ath10k: MSI-X interrupt handling (8 intrs)
ath10k: Unable to wakeup target
ath10k: target took longer 5000 us to wake up (awake count 1)
ath10k: Failed to get pcie state addr: -16
ath10k: early firmware event indicated
BUG: unable to handle kernel NULL pointer dereference at 0000000000000004
IP: [<ffffffffa06ae46c>] ath10k_ce_completed_send_next+0x47/0x122 [ath10k_pci]
PGD d1f5b067 PUD d9c1c067 PMD 0
Oops: 0000 [#1] PREEMPT SMP
Modules linked in: rpcsec_gss_krb5 auth_rpcgss oid_registry nfsv4 nfs fscache nf_nat_ipv4 nf_nat 8021q ga]
CPU: 1 PID: 17 Comm: ksoftirqd/1 Tainted: G         C   3.12.0-rc3-wl+ #10
Hardware name: To be filled by O.E.M. To be filled by O.E.M./HURONRIVER, BIOS 4.6.5 05/02/2012
task: ffff8802160fdd80 ti: ffff880216306000 task.ti: ffff880216306000
RIP: 0010:[<ffffffffa06ae46c>]  [<ffffffffa06ae46c>] ath10k_ce_completed_send_next+0x47/0x122 [ath10k_pci]
RSP: 0018:ffff880216307c98  EFLAGS: 00010246
RAX: 0000000000005b5b RBX: ffff88020bfbfc50 RCX: 0000000000057400
RDX: ffff88020c7e5f20 RSI: ffff880216307d10 RDI: ffff88020bfbfc48
RBP: ffff880216307cf8 R08: ffff880216307d1c R09: ffff8800d967d438
R10: ffff88021fa92ff0 R11: 0000000000000001 R12: ffff880216307d10
R13: ffff880216307d24 R14: ffff880216307d20 R15: 0000000000000000
FS:  0000000000000000(0000) GS:ffff88021fa80000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000004 CR3: 00000000d1c76000 CR4: 00000000000407e0
Stack:
  ffff880216307cc8 ffff8802160fdde8 ffff88021fa92ff0 ffff880216307d1c
  ffff88020bfbfc48 ffff88021fa92ff0 ffff880216307d08 ffff88020c7e5f20
  ffff88020bfbf800 0000000000000000 ffff88020bfbfc48 0000000000057430
Call Trace:
  [<ffffffffa06ab568>] ath10k_pci_bmi_send_done+0x1d/0x32 [ath10k_pci]
  [<ffffffff810a4915>] ? local_bh_enable_ip+0x9/0xb
  [<ffffffff8158e801>] ? _raw_spin_unlock_bh+0x1f/0x21
  [<ffffffffa06ae357>] ath10k_ce_per_engine_service+0xab/0xea [ath10k_pci]
  [<ffffffffa06ab3b4>] ath10k_pci_ce_tasklet+0x15/0x17 [ath10k_pci]
  [<ffffffff810a3e3e>] tasklet_action+0x78/0xc6
  [<ffffffff810a463c>] __do_softirq+0xc4/0x19d
  [<ffffffff810a4738>] run_ksoftirqd+0x23/0x42
  [<ffffffff810c0ea3>] smpboot_thread_fn+0x21e/0x223
  [<ffffffff810c0c85>] ? smpboot_create_threads+0x61/0x61
  [<ffffffff810ba54d>] kthread+0xb0/0xb8
  [<ffffffff810ba49d>] ? kthread_freezable_should_stop+0x5b/0x5b
  [<ffffffff815939cc>] ret_from_fork+0x7c/0xb0
  [<ffffffff810ba49d>] ? kthread_freezable_should_stop+0x5b/0x5b
Code: 38 4c 89 45 b8 48 8b 07 48 8b 80 a0 01 00 00 48 05 48 04 00 00 48 89 c7 48 89 45 c0 e8 b6 07 ee e0
RIP  [<ffffffffa06ae46c>] ath10k_ce_completed_send_next+0x47/0x122 [ath10k_pci]
  RSP <ffff880216307c98>
CR2: 0000000000000004
---[ end trace 6b10a0163cca0cc3 ]---

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* [PATCH] wireless-regdb: NO, Norway - enable VHT80
From: Bjørn Mork @ 2013-10-11 23:27 UTC (permalink / raw)
  To: John W. Linville
  Cc: linux-wireless, wireless-regdb, Bjørn Mork,
	Luis R. Rodriguez

This enables 80 MHz bandwidth usage on all 5 GHz
frequencies.

This is a country that belongs to CEPT [0] and an available
regulatory source is ECC/DEC/(04)08 [1].

Quoting:

considering [...]
   e. that the systems covered by this ECC Decision operate
   typically in a 20 MHz channel bandwidth, other values for
   the channel bandwidth are also feasible provided they
   comply with the relevant maximum mean e.i.r.p. and the
   corresponding maximum mean e.i.r.p. density limits;

[0] https://en.wikipedia.org/wiki/European_Conference_of_Postal_and_Telecommunications_Administrations
[1] http://www.erodocdb.dk/Docs/doc98/official/pdf/ECCDEC0408.PDF

Cc: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
I have no idea why this was left out of the big CEPT VHT80 batch...

 db.txt |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/db.txt b/db.txt
index d0d1a3f..8c61b14 100644
--- a/db.txt
+++ b/db.txt
@@ -569,9 +569,9 @@ country NL: DFS-ETSI
 
 country NO: DFS-ETSI
 	(2402 - 2482 @ 40), (N/A, 20)
-	(5170 - 5250 @ 40), (N/A, 20)
-	(5250 - 5330 @ 40), (N/A, 20), DFS
-	(5490 - 5710 @ 40), (N/A, 27), DFS
+	(5170 - 5250 @ 80), (N/A, 20)
+	(5250 - 5330 @ 80), (N/A, 20), DFS
+	(5490 - 5710 @ 80), (N/A, 27), DFS
 	# 60 gHz band channels 1-4, ref: Etsi En 302 567
 	(57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH v3 tip/core/rcu 10/14] mac80211: Apply ACCESS_ONCE() to avoid sparse false positive
From: Paul E. McKenney @ 2013-10-11 23:17 UTC (permalink / raw)
  To: linux-kernel
  Cc: mingo, laijs, dipankar, akpm, mathieu.desnoyers, josh, niv, tglx,
	peterz, rostedt, dhowells, edumazet, darren, fweisbec, sbw,
	Paul E. McKenney, John W. Linville, Johannes Berg,
	David S. Miller, linux-wireless, netdev
In-Reply-To: <1381533451-29018-1-git-send-email-paulmck@linux.vnet.ibm.com>

From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>

The sparse checking for rcu_assign_pointer() was recently upgraded
to reject non-__kernel address spaces.  This also rejects __rcu,
which is almost always the right thing to do.  However, the uses in
sta_info_hash_del() are legitimate: They are assigning a pointer to an
element from an RCU-protected list, and all elements of this list are
already visible to caller.

This commit therefore silences this false positive by laundering the
pointer using ACCESS_ONCE() as suggested by Eric Dumazet and Josh
Triplett.

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 net/mac80211/sta_info.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index aeb967a0aeed..494f03c0831f 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -74,8 +74,8 @@ static int sta_info_hash_del(struct ieee80211_local *local,
 	if (!s)
 		return -ENOENT;
 	if (s == sta) {
-		rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)],
-				   s->hnext);
+		/* Both --rcu and visible, so ACCESS_ONCE() is OK. */
+		ACCESS_ONCE(local->sta_hash[STA_HASH(sta->sta.addr)]) = s->hnext;
 		return 0;
 	}
 
@@ -84,7 +84,8 @@ static int sta_info_hash_del(struct ieee80211_local *local,
 		s = rcu_dereference_protected(s->hnext,
 					lockdep_is_held(&local->sta_mtx));
 	if (rcu_access_pointer(s->hnext)) {
-		rcu_assign_pointer(s->hnext, sta->hnext);
+		/* Both --rcu and visible, so ACCESS_ONCE() is OK. */
+		ACCESS_ONCE(s->hnext) = sta->hnext;
 		return 0;
 	}
 
-- 
1.8.1.5


^ permalink raw reply related

* Re: [PATCH] mac80211:  Add rate-control name to station debugfs.
From: Ben Greear @ 2013-10-11 21:40 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless
In-Reply-To: <52586DA9.5050204@openwrt.org>

On 10/11/2013 02:29 PM, Felix Fietkau wrote:
> On 2013-10-11 11:04 PM, greearb@candelatech.com wrote:
>> From: Ben Greear <greearb@candelatech.com>
>>
>> Nice to see what algorithm it's actually using.
> No need for that, you can use this:
> # cat /sys/kernel/debug/ieee80211/phy0/rc/name

Ok, that should work for me.  But, is there any reason we cannot
have a different rate control alg for different stations on same
phy?

I am thinking of allowing such configuration if possible...the
better to compare various rate ctrl algorithms...

Thanks,
Ben

>
> - Felix
>


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* [PATCH v2 02/10] ath9k_hw: remove direct accesses to channel mode flags
From: Felix Fietkau @ 2013-10-11 21:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville
In-Reply-To: <1381527061-43758-1-git-send-email-nbd@openwrt.org>

Use wrappers where available. Simplifies code and helps with further
improvements to the channel data structure

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ani.c          |   6 +-
 drivers/net/wireless/ath/ath9k/ar5008_phy.c   |  35 ++-------
 drivers/net/wireless/ath/ath9k/ar9002_hw.c    |  26 +------
 drivers/net/wireless/ath/ath9k/ar9003_phy.c   | 105 ++++++--------------------
 drivers/net/wireless/ath/ath9k/htc_drv_main.c |  26 +------
 drivers/net/wireless/ath/ath9k/hw.c           |   7 +-
 drivers/net/wireless/ath/ath9k/hw.h           |   2 +
 drivers/net/wireless/ath/ath9k/mci.c          |   8 +-
 drivers/net/wireless/ath/ath9k/xmit.c         |   3 +-
 9 files changed, 49 insertions(+), 169 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index be466b0..d28923b 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -338,10 +338,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
 		    aniState->cckNoiseImmunityLevel !=
 		    ATH9K_ANI_CCK_DEF_LEVEL) {
 			ath_dbg(common, ANI,
-				"Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+				"Restore defaults: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
 				ah->opmode,
 				chan->channel,
-				chan->channelFlags,
 				is_scanning,
 				aniState->ofdmNoiseImmunityLevel,
 				aniState->cckNoiseImmunityLevel);
@@ -354,10 +353,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
 		 * restore historical levels for this channel
 		 */
 		ath_dbg(common, ANI,
-			"Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
+			"Restore history: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
 			ah->opmode,
 			chan->channel,
-			chan->channelFlags,
 			is_scanning,
 			aniState->ofdmNoiseImmunityLevel,
 			aniState->cckNoiseImmunityLevel);
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index cb6435e..2bfa6fb 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -666,8 +666,7 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
 	if (IS_CHAN_HT40(chan)) {
 		phymode |= AR_PHY_FC_DYN2040_EN;
 
-		if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-		    (chan->chanmode == CHANNEL_G_HT40PLUS))
+		if (IS_CHAN_HT40PLUS(chan))
 			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
 
 	}
@@ -691,31 +690,12 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
 	int i, regWrites = 0;
 	u32 modesIndex, freqIndex;
 
-	switch (chan->chanmode) {
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-		modesIndex = 1;
+	if (IS_CHAN_5GHZ(chan)) {
 		freqIndex = 1;
-		break;
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		modesIndex = 2;
-		freqIndex = 1;
-		break;
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_B:
-		modesIndex = 4;
-		freqIndex = 2;
-		break;
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		modesIndex = 3;
+		modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
+	} else {
 		freqIndex = 2;
-		break;
-
-	default:
-		return -EINVAL;
+		modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
 	}
 
 	/*
@@ -1218,12 +1198,11 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
 
 	iniDef = &aniState->iniDef;
 
-	ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
+	ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n",
 		ah->hw_version.macVersion,
 		ah->hw_version.macRev,
 		ah->opmode,
-		chan->channel,
-		chan->channelFlags);
+		chan->channel);
 
 	val = REG_READ(ah, AR_PHY_SFCORR);
 	iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index fb61b08..5c95fd9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -419,28 +419,10 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
 	u32 modesIndex;
 	int i;
 
-	switch (chan->chanmode) {
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-		modesIndex = 1;
-		break;
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		modesIndex = 2;
-		break;
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_B:
-		modesIndex = 4;
-		break;
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		modesIndex = 3;
-		break;
-
-	default:
-		return;
-	}
+	if (IS_CHAN_5GHZ(chan))
+		modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
+	else
+		modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
 
 	ENABLE_REGWRITE_BUFFER(ah);
 
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 0131ba2..7249844 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -551,8 +551,7 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
 	if (IS_CHAN_HT40(chan)) {
 		phymode |= AR_PHY_GC_DYN2040_EN;
 		/* Configure control (primary) channel at +-10MHz */
-		if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-		    (chan->chanmode == CHANNEL_G_HT40PLUS))
+		if (IS_CHAN_HT40PLUS(chan))
 			phymode |= AR_PHY_GC_DYN2040_PRI_CH;
 
 	}
@@ -682,41 +681,22 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
 {
 	int ret;
 
-	switch (chan->chanmode) {
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-		if (chan->channel <= 5350)
-			ret = 1;
-		else if ((chan->channel > 5350) && (chan->channel <= 5600))
-			ret = 3;
+	if (IS_CHAN_2GHZ(chan)) {
+		if (IS_CHAN_HT40(chan))
+			return 7;
 		else
-			ret = 5;
-		break;
-
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		if (chan->channel <= 5350)
-			ret = 2;
-		else if ((chan->channel > 5350) && (chan->channel <= 5600))
-			ret = 4;
-		else
-			ret = 6;
-		break;
-
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_B:
-		ret = 8;
-		break;
+			return 8;
+	}
 
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		ret = 7;
-		break;
+	if (chan->channel <= 5350)
+		ret = 1;
+	else if ((chan->channel > 5350) && (chan->channel <= 5600))
+		ret = 3;
+	else
+		ret = 5;
 
-	default:
-		ret = -EINVAL;
-	}
+	if (IS_CHAN_HT40(chan))
+		ret++;
 
 	return ret;
 }
@@ -727,28 +707,10 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
 	unsigned int regWrites = 0, i;
 	u32 modesIndex;
 
-	switch (chan->chanmode) {
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-		modesIndex = 1;
-		break;
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		modesIndex = 2;
-		break;
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_B:
-		modesIndex = 4;
-		break;
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		modesIndex = 3;
-		break;
-
-	default:
-		return -EINVAL;
-	}
+	if (IS_CHAN_5GHZ(chan))
+		modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
+	else
+		modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
 
 	/*
 	 * SOC, MAC, BB, RADIO initvals.
@@ -1273,12 +1235,11 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
 	aniState = &ah->ani;
 	iniDef = &aniState->iniDef;
 
-	ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
+	ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n",
 		ah->hw_version.macVersion,
 		ah->hw_version.macRev,
 		ah->opmode,
-		chan->channel,
-		chan->channelFlags);
+		chan->channel);
 
 	val = REG_READ(ah, AR_PHY_SFCORR);
 	iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
@@ -1536,28 +1497,10 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
 	unsigned int regWrites = 0;
 	u32 modesIndex;
 
-	switch (chan->chanmode) {
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-		modesIndex = 1;
-		break;
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		modesIndex = 2;
-		break;
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_B:
-		modesIndex = 4;
-		break;
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		modesIndex = 3;
-		break;
-
-	default:
-		return -EINVAL;
-	}
+	if (IS_CHAN_5GHZ(chan))
+		modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
+	else
+		modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
 
 	if (modesIndex == ah->modes_index) {
 		*ini_reloaded = false;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index d442581..fa71af1 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -24,30 +24,10 @@
 static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
 					      struct ath9k_channel *ichan)
 {
-	enum htc_phymode mode;
-
-	mode = -EINVAL;
-
-	switch (ichan->chanmode) {
-	case CHANNEL_G:
-	case CHANNEL_G_HT20:
-	case CHANNEL_G_HT40PLUS:
-	case CHANNEL_G_HT40MINUS:
-		mode = HTC_MODE_11NG;
-		break;
-	case CHANNEL_A:
-	case CHANNEL_A_HT20:
-	case CHANNEL_A_HT40PLUS:
-	case CHANNEL_A_HT40MINUS:
-		mode = HTC_MODE_11NA;
-		break;
-	default:
-		break;
-	}
-
-	WARN_ON(mode < 0);
+	if (IS_CHAN_5GHZ(ichan))
+		return HTC_MODE_11NA;
 
-	return mode;
+	return HTC_MODE_11NG;
 }
 
 bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f11e838..7c4d600 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -294,8 +294,7 @@ void ath9k_hw_get_channel_centers(struct ath_hw *ah,
 		return;
 	}
 
-	if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-	    (chan->chanmode == CHANNEL_G_HT40PLUS)) {
+	if (IS_CHAN_HT40PLUS(chan)) {
 		centers->synth_center =
 			chan->channel + HT40_CHANNEL_CENTER_SHIFT;
 		extoff = 1;
@@ -1510,9 +1509,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	int r;
 
 	if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
-		u32 cur = ah->curchan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
-		u32 new = chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
-		band_switch = (cur != new);
+		band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan);
 		mode_diff = (chan->chanmode != ah->curchan->chanmode);
 	}
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 2babf93..102b3b6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -463,6 +463,8 @@ struct ath9k_channel {
 			  ((_c)->chanmode == CHANNEL_G_HT40PLUS) ||	\
 			  ((_c)->chanmode == CHANNEL_G_HT40MINUS))
 #define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
+#define IS_CHAN_HT40PLUS(_c) ((_c)->chanmode & CHANNEL_HT40PLUS)
+#define IS_CHAN_HT40MINUS(_c) ((_c)->chanmode & CHANNEL_HT40MINUS)
 
 enum ath9k_power_mode {
 	ATH9K_PM_AWAKE = 0,
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 815bee2..0ac1b5f 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -661,9 +661,9 @@ void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all)
 	chan_start = wlan_chan - 10;
 	chan_end = wlan_chan + 10;
 
-	if (chan->chanmode == CHANNEL_G_HT40PLUS)
+	if (IS_CHAN_HT40PLUS(chan))
 		chan_end += 20;
-	else if (chan->chanmode == CHANNEL_G_HT40MINUS)
+	else if (IS_CHAN_HT40MINUS(chan))
 		chan_start -= 20;
 
 	/* adjust side band */
@@ -707,11 +707,11 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
 
 	if (setchannel) {
 		struct ath9k_hw_cal_data *caldata = &sc->caldata;
-		if ((caldata->chanmode == CHANNEL_G_HT40PLUS) &&
+		if (IS_CHAN_HT40PLUS(ah->curchan) &&
 		    (ah->curchan->channel > caldata->channel) &&
 		    (ah->curchan->channel <= caldata->channel + 20))
 			return;
-		if ((caldata->chanmode == CHANNEL_G_HT40MINUS) &&
+		if (IS_CHAN_HT40MINUS(ah->curchan) &&
 		    (ah->curchan->channel < caldata->channel) &&
 		    (ah->curchan->channel >= caldata->channel - 20))
 			return;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 1ce8af2..08ba590 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2037,8 +2037,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath9k_channel *curchan = ah->curchan;
 
-	if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) &&
-	    (curchan->channelFlags & CHANNEL_5GHZ) &&
+	if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && IS_CHAN_5GHZ(curchan) &&
 	    (chainmask == 0x7) && (rate < 0x90))
 		return 0x3;
 	else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) &&
-- 
1.8.0.2


^ permalink raw reply related

* [PATCH v2 07/10] ath9k: move channel change code to ath_set_channel
From: Felix Fietkau @ 2013-10-11 21:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville
In-Reply-To: <1381527061-43758-1-git-send-email-nbd@openwrt.org>

Preparation for adding the scanning state machine to ath9k

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/main.c | 150 ++++++++++++++++++----------------
 1 file changed, 78 insertions(+), 72 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 2a86047..bc89823 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -312,17 +312,91 @@ out:
  * by reseting the chip.  To accomplish this we must first cleanup any pending
  * DMA, then restart stuff.
 */
-static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-		    struct ath9k_channel *hchan)
+static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chandef)
 {
+	struct ath_hw *ah = sc->sc_ah;
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ieee80211_hw *hw = sc->hw;
+	struct ath9k_channel *hchan;
+	struct ieee80211_channel *chan = chandef->chan;
+	unsigned long flags;
+	bool offchannel;
+	int pos = chan->hw_value;
+	int old_pos = -1;
 	int r;
 
 	if (test_bit(SC_OP_INVALID, &sc->sc_flags))
 		return -EIO;
 
+	offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
+
+	if (ah->curchan)
+		old_pos = ah->curchan - &ah->channels[0];
+
+	ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
+		chan->center_freq, chandef->width);
+
+	/* update survey stats for the old channel before switching */
+	spin_lock_irqsave(&common->cc_lock, flags);
+	ath_update_survey_stats(sc);
+	spin_unlock_irqrestore(&common->cc_lock, flags);
+
+	ath9k_cmn_get_channel(hw, ah, chandef);
+
+	/*
+	 * If the operating channel changes, change the survey in-use flags
+	 * along with it.
+	 * Reset the survey data for the new channel, unless we're switching
+	 * back to the operating channel from an off-channel operation.
+	 */
+	if (!offchannel && sc->cur_survey != &sc->survey[pos]) {
+		if (sc->cur_survey)
+			sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
+
+		sc->cur_survey = &sc->survey[pos];
+
+		memset(sc->cur_survey, 0, sizeof(struct survey_info));
+		sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
+	} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
+		memset(&sc->survey[pos], 0, sizeof(struct survey_info));
+	}
+
+	hchan = &sc->sc_ah->channels[pos];
 	r = ath_reset_internal(sc, hchan);
+	if (r)
+		return r;
 
-	return r;
+	/*
+	 * The most recent snapshot of channel->noisefloor for the old
+	 * channel is only available after the hardware reset. Copy it to
+	 * the survey stats now.
+	 */
+	if (old_pos >= 0)
+		ath_update_survey_nf(sc, old_pos);
+
+	/*
+	 * Enable radar pulse detection if on a DFS channel. Spectral
+	 * scanning and radar detection can not be used concurrently.
+	 */
+	if (hw->conf.radar_enabled) {
+		u32 rxfilter;
+
+		/* set HW specific DFS configuration */
+		ath9k_hw_set_radar_params(ah);
+		rxfilter = ath9k_hw_getrxfilter(ah);
+		rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
+				ATH9K_RX_FILTER_PHYERR;
+		ath9k_hw_setrxfilter(ah, rxfilter);
+		ath_dbg(common, DFS, "DFS enabled at freq %d\n",
+			chan->center_freq);
+	} else {
+		/* perform spectral scan if requested. */
+		if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
+			sc->spectral_mode == SPECTRAL_CHANSCAN)
+			ath9k_spectral_scan_trigger(hw);
+	}
+
+	return 0;
 }
 
 static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -1207,80 +1281,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 	}
 
 	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
-		struct ieee80211_channel *curchan = hw->conf.chandef.chan;
-		int pos = curchan->hw_value;
-		int old_pos = -1;
-		unsigned long flags;
-
-		if (ah->curchan)
-			old_pos = ah->curchan - &ah->channels[0];
-
-		ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
-			curchan->center_freq, hw->conf.chandef.width);
-
-		/* update survey stats for the old channel before switching */
-		spin_lock_irqsave(&common->cc_lock, flags);
-		ath_update_survey_stats(sc);
-		spin_unlock_irqrestore(&common->cc_lock, flags);
-
-		ath9k_cmn_get_channel(hw, ah, &conf->chandef);
-
-		/*
-		 * If the operating channel changes, change the survey in-use flags
-		 * along with it.
-		 * Reset the survey data for the new channel, unless we're switching
-		 * back to the operating channel from an off-channel operation.
-		 */
-		if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
-		    sc->cur_survey != &sc->survey[pos]) {
-
-			if (sc->cur_survey)
-				sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
-
-			sc->cur_survey = &sc->survey[pos];
-
-			memset(sc->cur_survey, 0, sizeof(struct survey_info));
-			sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
-		} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
-			memset(&sc->survey[pos], 0, sizeof(struct survey_info));
-		}
-
-		if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
+		if (ath_set_channel(sc, &hw->conf.chandef) < 0) {
 			ath_err(common, "Unable to set channel\n");
 			mutex_unlock(&sc->mutex);
 			ath9k_ps_restore(sc);
 			return -EINVAL;
 		}
-
-		/*
-		 * The most recent snapshot of channel->noisefloor for the old
-		 * channel is only available after the hardware reset. Copy it to
-		 * the survey stats now.
-		 */
-		if (old_pos >= 0)
-			ath_update_survey_nf(sc, old_pos);
-
-		/*
-		 * Enable radar pulse detection if on a DFS channel. Spectral
-		 * scanning and radar detection can not be used concurrently.
-		 */
-		if (hw->conf.radar_enabled) {
-			u32 rxfilter;
-
-			/* set HW specific DFS configuration */
-			ath9k_hw_set_radar_params(ah);
-			rxfilter = ath9k_hw_getrxfilter(ah);
-			rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
-				    ATH9K_RX_FILTER_PHYERR;
-			ath9k_hw_setrxfilter(ah, rxfilter);
-			ath_dbg(common, DFS, "DFS enabled at freq %d\n",
-				curchan->center_freq);
-		} else {
-			/* perform spectral scan if requested. */
-			if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
-			    sc->spectral_mode == SPECTRAL_CHANSCAN)
-				ath9k_spectral_scan_trigger(hw);
-		}
 	}
 
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-- 
1.8.0.2


^ permalink raw reply related

* [PATCH v2 01/10] ath9k: use a separate data structure for rx buffers
From: Felix Fietkau @ 2013-10-11 21:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

There's no shared code for handling both rx and tx buffers, and tx
buffers require a lot more metadata than rx buffers.
Using a separate data structure for rx reduces memory usage and improves
cache footprint.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h | 10 +++-
 drivers/net/wireless/ath/ath9k/init.c  | 84 ++++++++++++++++++++++++----------
 drivers/net/wireless/ath/ath9k/recv.c  | 48 +++++++++----------
 3 files changed, 92 insertions(+), 50 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8878f2d..83c0455 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -207,6 +207,14 @@ struct ath_frame_info {
 	u8 baw_tracked : 1;
 };
 
+struct ath_rxbuf {
+	struct list_head list;
+	struct sk_buff *bf_mpdu;
+	void *bf_desc;
+	dma_addr_t bf_daddr;
+	dma_addr_t bf_buf_addr;
+};
+
 struct ath_buf_state {
 	u8 bf_type;
 	u8 bfs_paprd;
@@ -307,7 +315,7 @@ struct ath_rx {
 	struct ath_descdma rxdma;
 	struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
 
-	struct ath_buf *buf_hold;
+	struct ath_rxbuf *buf_hold;
 	struct sk_buff *frag;
 
 	u32 ampdu_ref;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index e3d11c4..2306f57 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -347,7 +347,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 {
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	u8 *ds;
-	struct ath_buf *bf;
 	int i, bsize, desc_len;
 
 	ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n",
@@ -399,33 +398,68 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
 		ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
 
 	/* allocate buffers */
-	bsize = sizeof(struct ath_buf) * nbuf;
-	bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
-	if (!bf)
-		return -ENOMEM;
+	if (is_tx) {
+		struct ath_buf *bf;
+
+		bsize = sizeof(struct ath_buf) * nbuf;
+		bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
+		if (!bf)
+			return -ENOMEM;
+
+		for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
+			bf->bf_desc = ds;
+			bf->bf_daddr = DS2PHYS(dd, ds);
+
+			if (!(sc->sc_ah->caps.hw_caps &
+				  ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+				/*
+				 * Skip descriptor addresses which can cause 4KB
+				 * boundary crossing (addr + length) with a 32 dword
+				 * descriptor fetch.
+				 */
+				while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
+					BUG_ON((caddr_t) bf->bf_desc >=
+						   ((caddr_t) dd->dd_desc +
+						dd->dd_desc_len));
+
+					ds += (desc_len * ndesc);
+					bf->bf_desc = ds;
+					bf->bf_daddr = DS2PHYS(dd, ds);
+				}
+			}
+			list_add_tail(&bf->list, head);
+		}
+	} else {
+		struct ath_rxbuf *bf;
+
+		bsize = sizeof(struct ath_rxbuf) * nbuf;
+		bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
+		if (!bf)
+			return -ENOMEM;
 
-	for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
-		bf->bf_desc = ds;
-		bf->bf_daddr = DS2PHYS(dd, ds);
-
-		if (!(sc->sc_ah->caps.hw_caps &
-		      ATH9K_HW_CAP_4KB_SPLITTRANS)) {
-			/*
-			 * Skip descriptor addresses which can cause 4KB
-			 * boundary crossing (addr + length) with a 32 dword
-			 * descriptor fetch.
-			 */
-			while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
-				BUG_ON((caddr_t) bf->bf_desc >=
-				       ((caddr_t) dd->dd_desc +
-					dd->dd_desc_len));
-
-				ds += (desc_len * ndesc);
-				bf->bf_desc = ds;
-				bf->bf_daddr = DS2PHYS(dd, ds);
+		for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
+			bf->bf_desc = ds;
+			bf->bf_daddr = DS2PHYS(dd, ds);
+
+			if (!(sc->sc_ah->caps.hw_caps &
+				  ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+				/*
+				 * Skip descriptor addresses which can cause 4KB
+				 * boundary crossing (addr + length) with a 32 dword
+				 * descriptor fetch.
+				 */
+				while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
+					BUG_ON((caddr_t) bf->bf_desc >=
+						   ((caddr_t) dd->dd_desc +
+						dd->dd_desc_len));
+
+					ds += (desc_len * ndesc);
+					bf->bf_desc = ds;
+					bf->bf_daddr = DS2PHYS(dd, ds);
+				}
 			}
+			list_add_tail(&bf->list, head);
 		}
-		list_add_tail(&bf->list, head);
 	}
 	return 0;
 }
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ab9e3a8..8b788ef 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -19,7 +19,7 @@
 #include "ath9k.h"
 #include "ar9003_mac.h"
 
-#define SKB_CB_ATHBUF(__skb)	(*((struct ath_buf **)__skb->cb))
+#define SKB_CB_ATHBUF(__skb)	(*((struct ath_rxbuf **)__skb->cb))
 
 static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
 {
@@ -35,7 +35,7 @@ static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
  * buffer (or rx fifo). This can incorrectly acknowledge packets
  * to a sender if last desc is self-linked.
  */
-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
+static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
@@ -68,7 +68,7 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
 	sc->rx.rxlink = &ds->ds_link;
 }
 
-static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_buf *bf)
+static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf)
 {
 	if (sc->rx.buf_hold)
 		ath_rx_buf_link(sc, sc->rx.buf_hold);
@@ -112,13 +112,13 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_rx_edma *rx_edma;
 	struct sk_buff *skb;
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 
 	rx_edma = &sc->rx.rx_edma[qtype];
 	if (skb_queue_len(&rx_edma->rx_fifo) >= rx_edma->rx_fifo_hwsize)
 		return false;
 
-	bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+	bf = list_first_entry(&sc->rx.rxbuf, struct ath_rxbuf, list);
 	list_del_init(&bf->list);
 
 	skb = bf->bf_mpdu;
@@ -138,7 +138,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc,
 				  enum ath9k_rx_qtype qtype)
 {
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	struct ath_buf *bf, *tbf;
+	struct ath_rxbuf *bf, *tbf;
 
 	if (list_empty(&sc->rx.rxbuf)) {
 		ath_dbg(common, QUEUE, "No free rx buf available\n");
@@ -154,7 +154,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc,
 static void ath_rx_remove_buffer(struct ath_softc *sc,
 				 enum ath9k_rx_qtype qtype)
 {
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 	struct ath_rx_edma *rx_edma;
 	struct sk_buff *skb;
 
@@ -171,7 +171,7 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 
 	ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP);
 	ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP);
@@ -199,7 +199,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct ath_hw *ah = sc->sc_ah;
 	struct sk_buff *skb;
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 	int error = 0, i;
 	u32 size;
 
@@ -211,7 +211,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
 	ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_HP],
 			       ah->caps.rx_hp_qdepth);
 
-	size = sizeof(struct ath_buf) * nbufs;
+	size = sizeof(struct ath_rxbuf) * nbufs;
 	bf = devm_kzalloc(sc->dev, size, GFP_KERNEL);
 	if (!bf)
 		return -ENOMEM;
@@ -271,7 +271,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
 {
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	struct sk_buff *skb;
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 	int error = 0;
 
 	spin_lock_init(&sc->sc_pcu_lock);
@@ -332,7 +332,7 @@ void ath_rx_cleanup(struct ath_softc *sc)
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct sk_buff *skb;
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 
 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
 		ath_rx_edma_cleanup(sc);
@@ -427,7 +427,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
 int ath_startrecv(struct ath_softc *sc)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ath_buf *bf, *tbf;
+	struct ath_rxbuf *bf, *tbf;
 
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
 		ath_edma_start_recv(sc);
@@ -447,7 +447,7 @@ int ath_startrecv(struct ath_softc *sc)
 	if (list_empty(&sc->rx.rxbuf))
 		goto start_recv;
 
-	bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+	bf = list_first_entry(&sc->rx.rxbuf, struct ath_rxbuf, list);
 	ath9k_hw_putrxbuf(ah, bf->bf_daddr);
 	ath9k_hw_rxena(ah);
 
@@ -603,13 +603,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon)
 static bool ath_edma_get_buffers(struct ath_softc *sc,
 				 enum ath9k_rx_qtype qtype,
 				 struct ath_rx_status *rs,
-				 struct ath_buf **dest)
+				 struct ath_rxbuf **dest)
 {
 	struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype];
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct sk_buff *skb;
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 	int ret;
 
 	skb = skb_peek(&rx_edma->rx_fifo);
@@ -653,11 +653,11 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
 	return true;
 }
 
-static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
+static struct ath_rxbuf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
 						struct ath_rx_status *rs,
 						enum ath9k_rx_qtype qtype)
 {
-	struct ath_buf *bf = NULL;
+	struct ath_rxbuf *bf = NULL;
 
 	while (ath_edma_get_buffers(sc, qtype, rs, &bf)) {
 		if (!bf)
@@ -668,13 +668,13 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc,
 	return NULL;
 }
 
-static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
+static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc,
 					   struct ath_rx_status *rs)
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_desc *ds;
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 	int ret;
 
 	if (list_empty(&sc->rx.rxbuf)) {
@@ -682,7 +682,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
 		return NULL;
 	}
 
-	bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+	bf = list_first_entry(&sc->rx.rxbuf, struct ath_rxbuf, list);
 	if (bf == sc->rx.buf_hold)
 		return NULL;
 
@@ -702,7 +702,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
 	ret = ath9k_hw_rxprocdesc(ah, ds, rs);
 	if (ret == -EINPROGRESS) {
 		struct ath_rx_status trs;
-		struct ath_buf *tbf;
+		struct ath_rxbuf *tbf;
 		struct ath_desc *tds;
 
 		memset(&trs, 0, sizeof(trs));
@@ -711,7 +711,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
 			return NULL;
 		}
 
-		tbf = list_entry(bf->list.next, struct ath_buf, list);
+		tbf = list_entry(bf->list.next, struct ath_rxbuf, list);
 
 		/*
 		 * On some hardware the descriptor status words could
@@ -1308,7 +1308,7 @@ static void ath9k_apply_ampdu_details(struct ath_softc *sc,
 
 int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
 {
-	struct ath_buf *bf;
+	struct ath_rxbuf *bf;
 	struct sk_buff *skb = NULL, *requeue_skb, *hdr_skb;
 	struct ieee80211_rx_status *rxs;
 	struct ath_hw *ah = sc->sc_ah;
-- 
1.8.0.2


^ permalink raw reply related

* [PATCH v2 03/10] ath9k_hw: remove IS_CHAN_B()
From: Felix Fietkau @ 2013-10-11 21:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville
In-Reply-To: <1381527061-43758-1-git-send-email-nbd@openwrt.org>

Hardware 802.11b-only mode isn't supported by the driver (the device is
configured for 802.11n/g instead). Simplify the code by removing checks
for it.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c   | 6 ++++--
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 7 ++-----
 drivers/net/wireless/ath/ath9k/ar9003_phy.c   | 6 ++++--
 drivers/net/wireless/ath/ath9k/hw.c           | 9 ++-------
 drivers/net/wireless/ath/ath9k/hw.h           | 1 -
 drivers/net/wireless/ath/ath9k/mac.c          | 6 +-----
 6 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 2bfa6fb..b197bf2 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -794,8 +794,10 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
 	if (chan == NULL)
 		return;
 
-	rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
-		? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+	if (IS_CHAN_2GHZ(chan))
+		rfMode |= AR_PHY_MODE_DYNAMIC;
+	else
+		rfMode |= AR_PHY_MODE_OFDM;
 
 	if (!AR_SREV_9280_20_OR_LATER(ah))
 		rfMode |= (IS_CHAN_5GHZ(chan)) ?
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 32376ad..cdc7400 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -33,15 +33,12 @@ static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
 	bool supported = false;
 	switch (ah->supp_cals & cal_type) {
 	case IQ_MISMATCH_CAL:
-		/* Run IQ Mismatch for non-CCK only */
-		if (!IS_CHAN_B(chan))
-			supported = true;
+		supported = true;
 		break;
 	case ADC_GAIN_CAL:
 	case ADC_DC_CAL:
 		/* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
-		if (!IS_CHAN_B(chan) &&
-		    !((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) &&
+		if (!((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) &&
 		      IS_CHAN_HT20(chan)))
 			supported = true;
 		break;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 7249844..312c868 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -808,8 +808,10 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah,
 	if (chan == NULL)
 		return;
 
-	rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
-		? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+	if (IS_CHAN_2GHZ(chan))
+		rfMode |= AR_PHY_MODE_DYNAMIC;
+	else
+		rfMode |= AR_PHY_MODE_OFDM;
 
 	if (IS_CHAN_A_FAST_CLOCK(ah, chan))
 		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 7c4d600..34c8e2e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -190,10 +190,7 @@ EXPORT_SYMBOL(ath9k_hw_wait);
 void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
 			  int hw_delay)
 {
-	if (IS_CHAN_B(chan))
-		hw_delay = (4 * hw_delay) / 22;
-	else
-		hw_delay /= 10;
+	hw_delay /= 10;
 
 	if (IS_CHAN_HALF_RATE(chan))
 		hw_delay *= 2;
@@ -1159,9 +1156,7 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
 {
 	u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
 
-	if (IS_CHAN_B(chan))
-		ctl |= CTL_11B;
-	else if (IS_CHAN_G(chan))
+	if (IS_CHAN_G(chan))
 		ctl |= CTL_11G;
 	else
 		ctl |= CTL_11A;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 102b3b6..eaaf98b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -455,7 +455,6 @@ struct ath9k_channel {
 	 ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK))
 
 /* These macros check chanmode and not channelFlags */
-#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
 #define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) ||	\
 			  ((_c)->chanmode == CHANNEL_G_HT20))
 #define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||	\
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index a3eff09..6a18f9d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -374,7 +374,6 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
 bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath9k_channel *chan = ah->curchan;
 	struct ath9k_tx_queue_info *qi;
 	u32 cwMin, chanCwMin, value;
 
@@ -387,10 +386,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 	ath_dbg(common, QUEUE, "Reset TX queue: %u\n", q);
 
 	if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
-		if (chan && IS_CHAN_B(chan))
-			chanCwMin = INIT_CWMIN_11B;
-		else
-			chanCwMin = INIT_CWMIN;
+		chanCwMin = INIT_CWMIN;
 
 		for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
 	} else
-- 
1.8.0.2


^ permalink raw reply related

* [PATCH v2 08/10] ath9k: remove sc->config.cabqReadyTime
From: Felix Fietkau @ 2013-10-11 21:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville
In-Reply-To: <1381527061-43758-1-git-send-email-nbd@openwrt.org>

It is not exposed as a configuration option anyway

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h | 1 -
 drivers/net/wireless/ath/ath9k/init.c  | 1 -
 drivers/net/wireless/ath/ath9k/mac.h   | 2 --
 drivers/net/wireless/ath/ath9k/xmit.c  | 9 +--------
 4 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 83c0455..d03b85e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -64,7 +64,6 @@ struct ath_node;
 
 struct ath_config {
 	u16 txpowlimit;
-	u8 cabqReadytime;
 };
 
 /*************************/
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 9c145fa..7df728f 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -471,7 +471,6 @@ static int ath9k_init_queues(struct ath_softc *sc)
 	sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
 	sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
 
-	sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
 	ath_cabq_update(sc);
 
 	sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index bfccace..e3eed81 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -603,8 +603,6 @@ enum ath9k_tx_queue_flags {
 #define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
 
 #define ATH9K_DECOMP_MASK_SIZE     128
-#define ATH9K_READY_TIME_LO_BOUND  50
-#define ATH9K_READY_TIME_HI_BOUND  96
 
 enum ath9k_pkt_type {
 	ATH9K_PKT_TYPE_NORMAL = 0,
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 08ba590..47696d2 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1704,16 +1704,9 @@ int ath_cabq_update(struct ath_softc *sc)
 	int qnum = sc->beacon.cabq->axq_qnum;
 
 	ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
-	/*
-	 * Ensure the readytime % is within the bounds.
-	 */
-	if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
-		sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
-	else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
-		sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
 
 	qi.tqi_readyTime = (cur_conf->beacon_interval *
-			    sc->config.cabqReadytime) / 100;
+			    ATH_CABQ_READY_TIME) / 100;
 	ath_txq_update(sc, qnum, &qi);
 
 	return 0;
-- 
1.8.0.2


^ permalink raw reply related


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