Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 6/7] ath: move ath_bcast_mac to common header
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252566619-30390-1-git-send-email-lrodriguez@atheros.com>

This is used by both ath5k and ath9k to set the first bssid mask.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath.h          |    2 ++
 drivers/net/wireless/ath/ath5k/attach.c |    2 +-
 drivers/net/wireless/ath/ath5k/base.c   |    2 +-
 drivers/net/wireless/ath/ath5k/pcu.c    |    2 +-
 drivers/net/wireless/ath/ath9k/ath9k.h  |    2 --
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index a63e90c..59072e3 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -19,6 +19,8 @@
 
 #include <linux/skbuff.h>
 
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
 struct reg_dmn_pair_mapping {
 	u16 regDmnEnum;
 	u16 reg_5ghz_ctl;
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 71a1bd2..9a009a7 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -336,7 +336,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
 	ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
 
 	/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
-	memset(ah->ah_bssid, 0xff, ETH_ALEN);
+	memcpy(ah->ah_bssid, ath_bcast_mac, ETH_ALEN);
 	ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
 	ath5k_hw_set_opmode(ah);
 
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 9c6ab53..a28d795 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -815,7 +815,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 
 	SET_IEEE80211_PERM_ADDR(hw, mac);
 	/* All MAC address bits matter for ACKs */
-	memset(sc->bssidmask, 0xff, ETH_ALEN);
+	memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
 	ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
 
 	regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 2942f13..43aa358 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -365,7 +365,7 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
  * assuming only 4 bits for a mac address and for BSSIDs you can then have:
  *
  *                  \
- * MAC:                0001 |
+ * MAC:        0001 |
  * BSSID-01:   0100 | --> Belongs to us
  * BSSID-02:   1001 |
  *                  /
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index d99c92d..e54fac3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -60,8 +60,6 @@ struct ath_node;
 
 #define	ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
 
-static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
 struct ath_config {
 	u32 ath_aggr_prot;
 	u16 txpowlimit;
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 4/7] ath9k: move ath9k_hw_setpower() to main.c
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252566619-30390-1-git-send-email-lrodriguez@atheros.com>

And we make it static.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c   |   12 ------------
 drivers/net/wireless/ath/ath9k/hw.h   |    1 -
 drivers/net/wireless/ath/ath9k/main.c |   12 ++++++++++++
 3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c85c80d..352f197 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2951,18 +2951,6 @@ bool ath9k_hw_setpower_nolock(struct ath_hw *ah, enum ath9k_power_mode mode)
 	return status;
 }
 
-bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
-{
-	unsigned long flags;
-	bool ret;
-
-	spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags);
-	ret = ath9k_hw_setpower_nolock(ah, mode);
-	spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags);
-
-	return ret;
-}
-
 /*
  * Helper for ASPM support.
  *
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 730ae9e..c81f0a0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -654,7 +654,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 				    const struct ath9k_beacon_state *bs);
 
 bool ath9k_hw_setpower_nolock(struct ath_hw *ah, enum ath9k_power_mode mode);
-bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 
 void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4055246..38c34a2 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -243,6 +243,18 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
 	return channel;
 }
 
+static bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
+{
+	unsigned long flags;
+	bool ret;
+
+	spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags);
+	ret = ath9k_hw_setpower_nolock(ah, mode);
+	spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags);
+
+	return ret;
+}
+
 void ath9k_ps_wakeup(struct ath_softc *sc)
 {
 	unsigned long flags;
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 0/7] ath9k/atheros: ps/bssid mask cleanups
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez

Here's my second series on cleanups to fixate driver core
changes in the right place. In this series I stuff power save
helpers which use the driver for locking.

Next thing I'm looking at is the usage of sc->bssidmask and
sc->curbssid even on hw.c on ath9k -- we should not access the
sc on hw code, anyway, while reviewing that I noticed
ath5k/ar9170 could benefit from a few changes already in place
on ath9k.

It seems the last thing we'll need to address is read/write ops.
I've considered defining read/write ops on the ath common
structure, or at the very least on ath_hw, upon initialization
then the driver core would set this. ath9k would use ath9k_iowrite32()
and ath9k_ioread32() would ath9k_htc would define its own. REG_READ
and REG_WRITE could then also point to the common->ops->read / write
or if we don't want to take that approach the ath_hw->rw->read / write.

Other suggestions are welcomed.

A minor thing I did notice is we use ieee80211_hw on ath9k hw.c
for configuration -- this is fine but I realized virtual wiphys
are not using their own hw conf, but the primary wiphy's.

Luis R. Rodriguez (7):
  ath9k: move ps helpers onto core driver when reseting tsf
  ath9k: move ath9k_ps_wakeup() and ath9k_ps_restore() to main.c
  ath9k: avoid usage of ath9k_hw_setpower() on hw.c
  ath9k: move ath9k_hw_setpower() to main.c
  ath9k: rename driver core and hw power save helpers
  ath: move ath_bcast_mac to common header
  atheros: use get_unaligned_le*() for bssid mask setting

 drivers/net/wireless/ath/ar9170/mac.c   |   10 +++---
 drivers/net/wireless/ath/ath.h          |    3 ++
 drivers/net/wireless/ath/ath5k/ath5k.h  |    7 ----
 drivers/net/wireless/ath/ath5k/attach.c |    2 +-
 drivers/net/wireless/ath/ath5k/base.c   |    2 +-
 drivers/net/wireless/ath/ath5k/pcu.c    |   38 +++++++++++--------
 drivers/net/wireless/ath/ath5k/reset.c  |    6 ++-
 drivers/net/wireless/ath/ath9k/ath9k.h  |    2 -
 drivers/net/wireless/ath/ath9k/beacon.c |   17 ++++++++-
 drivers/net/wireless/ath/ath9k/hw.c     |   50 +-------------------------
 drivers/net/wireless/ath/ath9k/hw.h     |    5 ++-
 drivers/net/wireless/ath/ath9k/main.c   |   59 ++++++++++++++++++++++++++++---
 12 files changed, 109 insertions(+), 92 deletions(-)


^ permalink raw reply

* [PATCH 1/7] ath9k: move ps helpers onto core driver when reseting tsf
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252566619-30390-1-git-send-email-lrodriguez@atheros.com>

When the TSF is reset power save state is disabled and
then restored. The helpers to disable power save and restore
it use a lock provided by the driver core. Move the callers
of the helpers outside of the hw code.

We reset the TSF when mac80211 tells us and on the beacon.c
helper ath9k_hw_beaconinit() when it is made explicitly required.
Add a helper on beacon.c which will deal with ps awake/restore
if we need to reset the TSF upon ath9k_hw_beaconinit().

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/beacon.c |   17 +++++++++++++++--
 drivers/net/wireless/ath/ath9k/hw.c     |    2 --
 drivers/net/wireless/ath/ath9k/main.c   |    4 ++++
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 6e7a519..fb4ff55 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -502,6 +502,19 @@ void ath_beacon_tasklet(unsigned long data)
 	}
 }
 
+static void ath9k_beacon_init(struct ath_softc *sc,
+			      u32 next_beacon,
+			      u32 beacon_period)
+{
+	if (beacon_period & ATH9K_BEACON_RESET_TSF)
+		ath9k_ps_wakeup(sc);
+
+	ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
+
+	if (beacon_period & ATH9K_BEACON_RESET_TSF)
+		ath9k_ps_restore(sc);
+}
+
 /*
  * For multi-bss ap support beacons are either staggered evenly over N slots or
  * burst together.  For the former arrange for the SWBA to be delivered for each
@@ -534,7 +547,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
 	/* Set the computed AP beacon timers */
 
 	ath9k_hw_set_interrupts(sc->sc_ah, 0);
-	ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+	ath9k_beacon_init(sc, nexttbtt, intval);
 	sc->beacon.bmisscnt = 0;
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
@@ -707,7 +720,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
 	/* Set the computed ADHOC beacon timers */
 
 	ath9k_hw_set_interrupts(sc->sc_ah, 0);
-	ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+	ath9k_beacon_init(sc, nexttbtt, intval);
 	sc->beacon.bmisscnt = 0;
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 24157d2..d9a6026 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -4061,14 +4061,12 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
 
 void ath9k_hw_reset_tsf(struct ath_hw *ah)
 {
-	ath9k_ps_wakeup(ah->ah_sc);
 	if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0,
 			   AH_TSF_WRITE_TIMEOUT))
 		DPRINTF(ah, ATH_DBG_RESET,
 			"AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
 
 	REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
-	ath9k_ps_restore(ah->ah_sc);
 }
 
 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5a33d01..df09176 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2899,7 +2899,11 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw)
 	struct ath_softc *sc = aphy->sc;
 
 	mutex_lock(&sc->mutex);
+
+	ath9k_ps_wakeup(sc);
 	ath9k_hw_reset_tsf(sc->sc_ah);
+	ath9k_ps_restore(sc);
+
 	mutex_unlock(&sc->mutex);
 }
 
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 3/7] ath9k: avoid usage of ath9k_hw_setpower() on hw.c
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252566619-30390-1-git-send-email-lrodriguez@atheros.com>

ath9k_hw_setpower() is a core driver helper with locking
protection. Locking protection should be left to the driver
core, not the hw code. Hardware code no longer contends for
locking when it needs to wake up the chip or put it to sleep.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index bba8cc2..c85c80d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -919,7 +919,7 @@ int ath9k_hw_init(struct ath_hw *ah)
 		return -EIO;
 	}
 
-	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE)) {
 		DPRINTF(ah, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
 		return -EIO;
 	}
@@ -1234,7 +1234,7 @@ void ath9k_hw_detach(struct ath_hw *ah)
 		ath9k_hw_ani_disable(ah);
 
 	ath9k_hw_rf_free(ah);
-	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_hw_setpower_nolock(ah, ATH9K_PM_FULL_SLEEP);
 	kfree(ah);
 	ah = NULL;
 }
@@ -1791,7 +1791,7 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
 	} else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
 		return false;
 
-	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE))
 		return false;
 
 	ah->chip_fullsleep = false;
@@ -2345,7 +2345,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	ah->txchainmask = sc->tx_chainmask;
 	ah->rxchainmask = sc->rx_chainmask;
 
-	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE))
 		return -EIO;
 
 	if (curchan)
@@ -3958,7 +3958,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah)
 
 bool ath9k_hw_disable(struct ath_hw *ah)
 {
-	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE))
 		return false;
 
 	return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 5/7] ath9k: rename driver core and hw power save helpers
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252566619-30390-1-git-send-email-lrodriguez@atheros.com>

ath9k_hw_setpower_nolock --> ath9k_hw_setpower()
ath9k_hw_setpower() --> ath9k_setpower()

Also change the param for ath9k_setpower() to pass the ath_softc.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c   |   12 ++++++------
 drivers/net/wireless/ath/ath9k/hw.h   |    2 +-
 drivers/net/wireless/ath/ath9k/main.c |   22 +++++++++++-----------
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 352f197..eeaf77a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -919,7 +919,7 @@ int ath9k_hw_init(struct ath_hw *ah)
 		return -EIO;
 	}
 
-	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE)) {
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
 		DPRINTF(ah, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
 		return -EIO;
 	}
@@ -1234,7 +1234,7 @@ void ath9k_hw_detach(struct ath_hw *ah)
 		ath9k_hw_ani_disable(ah);
 
 	ath9k_hw_rf_free(ah);
-	ath9k_hw_setpower_nolock(ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
 	kfree(ah);
 	ah = NULL;
 }
@@ -1791,7 +1791,7 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
 	} else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
 		return false;
 
-	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE))
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return false;
 
 	ah->chip_fullsleep = false;
@@ -2345,7 +2345,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	ah->txchainmask = sc->tx_chainmask;
 	ah->rxchainmask = sc->rx_chainmask;
 
-	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE))
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return -EIO;
 
 	if (curchan)
@@ -2914,7 +2914,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
 	return true;
 }
 
-bool ath9k_hw_setpower_nolock(struct ath_hw *ah, enum ath9k_power_mode mode)
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 {
 	int status = true, setChip = true;
 	static const char *modes[] = {
@@ -3946,7 +3946,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah)
 
 bool ath9k_hw_disable(struct ath_hw *ah)
 {
-	if (!ath9k_hw_setpower_nolock(ah, ATH9K_PM_AWAKE))
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
 		return false;
 
 	return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c81f0a0..421d2ba 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -653,7 +653,7 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 				    const struct ath9k_beacon_state *bs);
 
-bool ath9k_hw_setpower_nolock(struct ath_hw *ah, enum ath9k_power_mode mode);
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
 
 void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 38c34a2..94ef651 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -243,14 +243,14 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
 	return channel;
 }
 
-static bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
+static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
 {
 	unsigned long flags;
 	bool ret;
 
-	spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags);
-	ret = ath9k_hw_setpower_nolock(ah, mode);
-	spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags);
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	ret = ath9k_hw_setpower(sc->sc_ah, mode);
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 
 	return ret;
 }
@@ -263,7 +263,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
 	if (++sc->ps_usecount != 1)
 		goto unlock;
 
-	ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
+	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 
  unlock:
 	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -282,7 +282,7 @@ void ath9k_ps_restore(struct ath_softc *sc)
 			      SC_OP_WAIT_FOR_CAB |
 			      SC_OP_WAIT_FOR_PSPOLL_DATA |
 			      SC_OP_WAIT_FOR_TX_ACK)))
-		ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+		ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
 
  unlock:
 	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -652,7 +652,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 		if (status & ATH9K_INT_TIM_TIMER) {
 			/* Clear RxAbort bit so that we can
 			 * receive frames */
-			ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+			ath9k_setpower(sc, ATH9K_PM_AWAKE);
 			ath9k_hw_setrxabort(sc->sc_ah, 0);
 			sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
 		}
@@ -1254,7 +1254,7 @@ void ath_radio_disable(struct ath_softc *sc)
 	ath9k_hw_phy_disable(ah);
 	ath9k_hw_configpcipowersave(ah, 1);
 	ath9k_ps_restore(sc);
-	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
 }
 
 /*******************/
@@ -1328,7 +1328,7 @@ void ath_detach(struct ath_softc *sc)
 	tasklet_kill(&sc->bcon_tasklet);
 
 	if (!(sc->sc_flags & SC_OP_INVALID))
-		ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+		ath9k_setpower(sc, ATH9K_PM_AWAKE);
 
 	/* cleanup tx queues */
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
@@ -2415,7 +2415,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	/* disable HAL and put h/w to sleep */
 	ath9k_hw_disable(ah);
 	ath9k_hw_configpcipowersave(ah, 1);
-	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+	ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
 
 	sc->sc_flags |= SC_OP_INVALID;
 
@@ -2587,7 +2587,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 			sc->ps_enabled = true;
 		} else {
 			sc->ps_enabled = false;
-			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+			ath9k_setpower(sc, ATH9K_PM_AWAKE);
 			if (!(ah->caps.hw_caps &
 			      ATH9K_HW_CAP_AUTOSLEEP)) {
 				ath9k_hw_setrxabort(sc->sc_ah, 0);
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 2/7] ath9k: move ath9k_ps_wakeup() and ath9k_ps_restore() to main.c
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252566619-30390-1-git-send-email-lrodriguez@atheros.com>

These are driver core helpers.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c   |   36 +--------------------------------
 drivers/net/wireless/ath/ath9k/hw.h   |    6 +++-
 drivers/net/wireless/ath/ath9k/main.c |   33 ++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d9a6026..bba8cc2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2914,8 +2914,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
 	return true;
 }
 
-static bool ath9k_hw_setpower_nolock(struct ath_hw *ah,
-				     enum ath9k_power_mode mode)
+bool ath9k_hw_setpower_nolock(struct ath_hw *ah, enum ath9k_power_mode mode)
 {
 	int status = true, setChip = true;
 	static const char *modes[] = {
@@ -2964,39 +2963,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 	return ret;
 }
 
-void ath9k_ps_wakeup(struct ath_softc *sc)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sc->sc_pm_lock, flags);
-	if (++sc->ps_usecount != 1)
-		goto unlock;
-
-	ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
-
- unlock:
-	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-}
-
-void ath9k_ps_restore(struct ath_softc *sc)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sc->sc_pm_lock, flags);
-	if (--sc->ps_usecount != 0)
-		goto unlock;
-
-	if (sc->ps_enabled &&
-	    !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
-			      SC_OP_WAIT_FOR_CAB |
-			      SC_OP_WAIT_FOR_PSPOLL_DATA |
-			      SC_OP_WAIT_FOR_TX_ACK)))
-		ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
-
- unlock:
-	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-}
-
 /*
  * Helper for ASPM support.
  *
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 2f3bf1a..730ae9e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -652,8 +652,10 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 				    const struct ath9k_beacon_state *bs);
-bool ath9k_hw_setpower(struct ath_hw *ah,
-		       enum ath9k_power_mode mode);
+
+bool ath9k_hw_setpower_nolock(struct ath_hw *ah, enum ath9k_power_mode mode);
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
+
 void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
 
 /* Interrupt Handling */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index df09176..4055246 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -243,6 +243,39 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
 	return channel;
 }
 
+void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	if (++sc->ps_usecount != 1)
+		goto unlock;
+
+	ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
+
+ unlock:
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+}
+
+void ath9k_ps_restore(struct ath_softc *sc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	if (--sc->ps_usecount != 0)
+		goto unlock;
+
+	if (sc->ps_enabled &&
+	    !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+			      SC_OP_WAIT_FOR_CAB |
+			      SC_OP_WAIT_FOR_PSPOLL_DATA |
+			      SC_OP_WAIT_FOR_TX_ACK)))
+		ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+
+ unlock:
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+}
+
 /*
  * Set/change channels.  If the channel is really being changed, it's done
  * by reseting the chip.  To accomplish this we must first cleanup any pending
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 7/7] atheros: use get_unaligned_le*() for bssid mask setting
From: Luis R. Rodriguez @ 2009-09-10  7:10 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez,
	Bob Copeland, Nick Kossifidis, Christian Lamparter
In-Reply-To: <1252566619-30390-1-git-send-email-lrodriguez@atheros.com>

Historically some macro helpers have been users for this,
AR5K_LOW_ID() and AR5K_HIGH_ID(), use upstream unaligned
helpers instead. This applid to ath5k and ar9170. ath9k
already uses this.

Worth noting is ath5k uses an ah_sta_id but that is already
the MAC address combined with the associaiton ID, ah_sta_id
is really ETH_ALEN in size.

Cc: Bob Copeland <me@bobcopeland.com>
Cc: Nick Kossifidis <mick@madwifi-project.org>
Cc: Christian Lamparter <chunkeey@web.de>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ar9170/mac.c  |   10 ++++----
 drivers/net/wireless/ath/ath.h         |    1 +
 drivers/net/wireless/ath/ath5k/ath5k.h |    7 ------
 drivers/net/wireless/ath/ath5k/pcu.c   |   36 ++++++++++++++++++-------------
 drivers/net/wireless/ath/ath5k/reset.c |    6 +++-
 5 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index 614e321..0c6273a 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -35,6 +35,9 @@
  *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#include <asm/unaligned.h>
+
 #include "ar9170.h"
 #include "cmd.h"
 
@@ -227,11 +230,8 @@ static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
 
 	ar9170_regwrite_begin(ar);
 
-	ar9170_regwrite(reg,
-			(mac[3] << 24) | (mac[2] << 16) |
-			(mac[1] << 8) | mac[0]);
-
-	ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
+	ar9170_regwrite(reg, get_unaligned_le32(mac));
+	ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
 
 	ar9170_regwrite_finish();
 
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 59072e3..44f885a 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -18,6 +18,7 @@
 #define ATH_H
 
 #include <linux/skbuff.h>
+#include <linux/if_ether.h>
 
 static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6cd5efc..93a9c1f 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -165,13 +165,6 @@
 #define AR5K_INI_VAL_XR			0
 #define AR5K_INI_VAL_MAX		5
 
-/* Used for BSSID etc manipulation */
-#define AR5K_LOW_ID(_a)(				\
-(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24	\
-)
-
-#define AR5K_HIGH_ID(_a)	((_a)[4] | (_a)[5] << 8)
-
 /*
  * Some tuneable values (these should be changeable by the user)
  * TODO: Make use of them and add more options OR use debug/configfs
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 43aa358..7bbcfe4 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -24,6 +24,8 @@
 * Protocol Control Unit Functions *
 \*********************************/
 
+#include <asm/unaligned.h>
+
 #include "ath5k.h"
 #include "reg.h"
 #include "debug.h"
@@ -95,8 +97,8 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
 	/*
 	 * Set PCU registers
 	 */
-	low_id = AR5K_LOW_ID(ah->ah_sta_id);
-	high_id = AR5K_HIGH_ID(ah->ah_sta_id);
+	low_id = get_unaligned_le32(ah->ah_sta_id);
+	high_id = get_unaligned_le16(ah->ah_sta_id + 4);
 	ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
 	ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
 
@@ -279,8 +281,8 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
 
 	pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
 
-	low_id = AR5K_LOW_ID(mac);
-	high_id = AR5K_HIGH_ID(mac);
+	low_id = get_unaligned_le32(mac);
+	high_id = get_unaligned_le16(mac + 4);
 
 	ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
 	ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
@@ -306,17 +308,18 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
 	 * Set simple BSSID mask on 5212
 	 */
 	if (ah->ah_version == AR5K_AR5212) {
-		ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask),
+		ath5k_hw_reg_write(ah, get_unaligned_le32(ah->ah_bssid_mask),
 							AR5K_BSS_IDM0);
-		ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
-							AR5K_BSS_IDM1);
+		ath5k_hw_reg_write(ah,
+				   get_unaligned_le16(ah->ah_bssid_mask + 4),
+				   AR5K_BSS_IDM1);
 	}
 
 	/*
 	 * Set BSSID which triggers the "SME Join" operation
 	 */
-	low_id = AR5K_LOW_ID(bssid);
-	high_id = AR5K_HIGH_ID(bssid);
+	low_id = get_unaligned_le32(bssid);
+	high_id = get_unaligned_le16(bssid);
 	ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
 	ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
 				AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
@@ -437,8 +440,8 @@ int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
 	 * on reset */
 	memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
 	if (ah->ah_version == AR5K_AR5212) {
-		low_id = AR5K_LOW_ID(mask);
-		high_id = AR5K_HIGH_ID(mask);
+		low_id = get_unaligned_le32(mask);
+		high_id = get_unaligned_le16(mask + 4);
 
 		ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
 		ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
@@ -1157,14 +1160,17 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
 	 /* Invalid entry (key table overflow) */
 	AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
 
-	/* MAC may be NULL if it's a broadcast key. In this case no need to
-	 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
+	/*
+	 * MAC may be NULL if it's a broadcast key. In this case no need to
+	 * to compute get_unaligned_le32 and get_unaligned_le16 as we
+	 * already know it.
+	 */
 	if (!mac) {
 		low_id = 0xffffffff;
 		high_id = 0xffff | AR5K_KEYTABLE_VALID;
 	} else {
-		low_id = AR5K_LOW_ID(mac);
-		high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
+		low_id = get_unaligned_le32(mac);
+		high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID;
 	}
 
 	ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 34e13c7..3454dac 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -25,6 +25,8 @@
   Reset functions and helpers
 \*****************************/
 
+#include <asm/unaligned.h>
+
 #include <linux/pci.h> 		/* To determine if a card is pci-e */
 #include <linux/log2.h>
 #include "ath5k.h"
@@ -1171,9 +1173,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 	ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
 
 	/* Restore sta_id flags and preserve our mac address*/
-	ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
+	ath5k_hw_reg_write(ah, get_unaligned_le32(ah->ah_sta_id),
 						AR5K_STA_ID0);
-	ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
+	ath5k_hw_reg_write(ah, staid1_flags | get_unaligned_le16(ah->ah_sta_id),
 						AR5K_STA_ID1);
 
 
-- 
1.6.3.3


^ permalink raw reply related

* Re: iwlagn: order 2 page allocation failures
From: Pekka Enberg @ 2009-09-10  8:18 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Frans Pop, Larry Finger, John W. Linville, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl, Assaf Krauss,
	Johannes Berg, Mohamed Abbas
In-Reply-To: <20090909165545.GK24614@csn.ul.ie>

On Wed, 2009-09-09 at 17:55 +0100, Mel Gorman wrote:
> On Wed, Sep 09, 2009 at 05:59:30PM +0200, Frans Pop wrote:
> > On Wednesday 09 September 2009, Mel Gorman wrote:
> > > Franz, in the full dmesg was there any mention of "SLUB: Unable to
> > > allocate memory on node"?
> > 
> > No, nothing at all. I double checked the kernel log, but it was completely 
> > quiet in the hours before and after the messages I already posted.
> > 
> 
> Ok, that in itself is unexpected.
> 
> Pekka, it looks from the stack trace that the failure is from
> __alloc_skb and I am guessing the failure path is around here
> 
>         size = SKB_DATA_ALIGN(size);
>         data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info),
>                         gfp_mask, node);
>         if (!data)
>                 goto nodata;
> 
> Why would the SLUB out-of-memory message not appear? It's hardly
> tripping up on printk_ratelimit() is it?

That's because it's a large allocation that's passed directly to the
page allocator. See kmalloc_large_node(), for example.

			Pekka


^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Mel Gorman @ 2009-09-10  9:02 UTC (permalink / raw)
  To: reinette chatre
  Cc: Frans Pop, Larry Finger, John W. Linville, Pekka Enberg,
	linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
	ipw3945-devel@lists.sourceforge.net, Andrew Morton,
	cl@linux-foundation.org, Krauss, Assaf, Johannes Berg,
	Abbas, Mohamed
In-Reply-To: <1252526738.30150.91.camel@rc-desk>

On Wed, Sep 09, 2009 at 01:05:38PM -0700, reinette chatre wrote:
> Mel and Frans, 
> 
> Thank you very much for digging into this.
> 
> On Wed, 2009-09-09 at 09:55 -0700, Mel Gorman wrote:
> > Conceivably a better candidate for this problem is commit
> > 4752c93c30441f98f7ed723001b1a5e3e5619829 introduced in May 2009. If there
> > are less than RX_QUEUE_SIZE/2 left, it starts replenishing buffers. Mohamed,
> > is it absolutly necessary it use GFP_ATOMIC there? If an allocation fails,
> > does it always mean frames are dropped or could it just replenish what it
> > can and try again later printing a warning only if allocation failures are
> > resulting in packet loss?
> 
> I agree that this patch may be the reason we are seeing this issue. We
> would like to keep using GFP_ATOMIC here, but it is not necessary for an
> allocation failure to be so noisy since the function doing the
> allocation (iwl_rx_allocate) is always followed by a call to
> iwl_rx_queue_restock which will schedule a refill if the buffers are
> running low.

Right, so it's a "refill now if you can and defer further refilling
until later".

> We can thus use ___GFP_NOWARN for the allocations in
> iwl_rx_allocate and leave it to the restocking to find the needed memory
> when it tried its allocations using GFP_KERNEL.
> 

Would it be possible to use __GFP_NOWARN *unless* this allocation is
necessary to receive the packet?

> I do think it is useful to let user know about these allocation
> failures, even if it does not result in packet loss. Wrapping it in
> net_ratelimit() will help though.
> 

If it does not distinguish between failures causing packet loss and just a
temporary issue, I'd be worried the messages would generate bug reports and
we genuinely won't know if it's a real problem or not.

As a total aside, there is still the problem that the driver is depending on
order-2 allocations. On systems without swap, the allocation problem could be
more severe as there are fewer pages the system can use to regain contiguity.

> How about the patch below?
> 
> diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
> index b90adcb..f0ee72e 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-rx.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
> @@ -252,10 +252,11 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
>  
>  		/* Alloc a new receive buffer */
>  		skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
> -						priority);
> +				priority | __GFP_NOWARN);
>  

So, would it be possible here to only remove __GFP_NOWARN if this is GFP_ATOMIC
(implying we have to refill now) and the rxq->free_count is really small
e.g. <= 2?

>  		if (!skb) {
> -			IWL_CRIT(priv, "Can not allocate SKB buffers\n");
> +			if (net_ratelimit())
> +				IWL_CRIT(priv, "Can not allocate SKB buffer.\n");

Similarly, could the message either be supressed when there is enough
buffers in the RX queue or differenciate between enough buffers and
things getting tight possibly causing packet loss?

The IWL_CRIT() part even is a hint - there is no guarantee that the allocation
failure is really a critical problem.

>  			/* We don't reschedule replenish work here -- we will
>  			 * call the restock method and if it still needs
>  			 * more buffers it will schedule replenish */
> diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> index 0909668..5d9fb78 100644
> --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
> +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> @@ -1147,10 +1147,10 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
>  		spin_unlock_irqrestore(&rxq->lock, flags);
>  
>  		/* Alloc a new receive buffer */
> -		skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
> +		skb = alloc_skb(priv->hw_params.rx_buf_size, priority | __GFP_NOWARN);
>  		if (!skb) {
>  			if (net_ratelimit())
> -				IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
> +				IWL_CRIT(priv, "Can not allocate SKB buffer.\n");
>  			/* We don't reschedule replenish work here -- we will
>  			 * call the restock method and if it still needs
>  			 * more buffers it will schedule replenish */
> 
> 

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* [RFC] rtl8180: change PCI DMA mask to DMA_BIT_MASK(32) to solve "No suitable DMA available" problems on sparc64.
From: Tiziano Müller @ 2009-09-10  9:37 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless

Hi there

I had problems to get my rtl8185 PCI card running on Sparc64: I always
got an error about "No suitable DMA available" followed by an error
that no device could be detected. When comparing the rtl8180 driver to
others I noticed that others are mostly using DMA_BIT_MASK so I changed
the custom mask to DMA_BIT_MASK(32) which fixed my issue.

Cheers,
Tiziano

---
 drivers/net/wireless/rtl818x/rtl8180_dev.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 16429c4..515f562 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -850,8 +850,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
 		goto err_free_reg;
 	}
 
-	if ((err = pci_set_dma_mask(pdev, 0xFFFFFF00ULL)) ||
-	    (err = pci_set_consistent_dma_mask(pdev, 0xFFFFFF00ULL))) {
+	if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) ||
+	    (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) {
 		printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n",
 		       pci_name(pdev));
 		goto err_free_reg;
-- 
1.6.4


^ permalink raw reply related

* Re: [RFC] rtl8180: change PCI DMA mask to DMA_BIT_MASK(32) to solve "No suitable DMA available" problems on sparc64.
From: David Miller @ 2009-09-10  9:48 UTC (permalink / raw)
  To: tm; +Cc: linville, linux-wireless
In-Reply-To: <1252575463.30576.59.camel@localhost>

From: Tiziano Müller <tm@dev-zero.ch>
Date: Thu, 10 Sep 2009 11:37:43 +0200

> Hi there
> 
> I had problems to get my rtl8185 PCI card running on Sparc64: I always
> got an error about "No suitable DMA available" followed by an error
> that no device could be detected. When comparing the rtl8180 driver to
> others I noticed that others are mostly using DMA_BIT_MASK so I changed
> the custom mask to DMA_BIT_MASK(32) which fixed my issue.

Looks correct to me.

I wonder what it was trying to achieve by clearing the low 8 bits
:-)

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply

* Re: [PATCH 7/7] atheros: use get_unaligned_le*() for bssid mask setting
From: Bob Copeland @ 2009-09-10 11:04 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: linville, linux-wireless, ath9k-devel, devel, Nick Kossifidis,
	Christian Lamparter
In-Reply-To: <1252566619-30390-8-git-send-email-lrodriguez@atheros.com>

On Thu, Sep 10, 2009 at 3:10 AM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> -       /* MAC may be NULL if it's a broadcast key. In this case no need to
> -        * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
> +       /*
> +        * MAC may be NULL if it's a broadcast key. In this case no need to
> +        * to compute get_unaligned_le32 and get_unaligned_le16 as we
> +        * already know it.
> +        */

Maybe not this one... but otherwise ACK :)

-- 
Bob Copeland %% www.bobcopeland.com

^ permalink raw reply

* First Data (EAPOL) frame goes missing
From: Paresh Sawant @ 2009-09-10 12:03 UTC (permalink / raw)
  To: linux-wireless

Hi,

I am running wpa_supplicant on Linux (Kernel 2.6.30.5) with iwl3945
and mac80211. I am working in WPA2 Enterprise mode.

It came to my notice that after a successful association, first EAPOL
packet sent by the access point is missing and never reached the
mac80211. The wireless sniffer shows the frame shipped from the access
point.

I have put printk to dump the inbound frames in function
"__ieee80211_rx" in net/mac80211/rx.c. I see that though the frame is
shown on wireless sniffer but the dump for the same is missing.

Thanks
- Paresh

^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Mel Gorman @ 2009-09-10 12:34 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Frans Pop, Larry Finger, John W. Linville, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl, Assaf Krauss,
	Johannes Berg, Mohamed Abbas
In-Reply-To: <1252570722.4876.23.camel@penberg-laptop>

On Thu, Sep 10, 2009 at 11:18:42AM +0300, Pekka Enberg wrote:
> On Wed, 2009-09-09 at 17:55 +0100, Mel Gorman wrote:
> > On Wed, Sep 09, 2009 at 05:59:30PM +0200, Frans Pop wrote:
> > > On Wednesday 09 September 2009, Mel Gorman wrote:
> > > > Franz, in the full dmesg was there any mention of "SLUB: Unable to
> > > > allocate memory on node"?
> > > 
> > > No, nothing at all. I double checked the kernel log, but it was completely 
> > > quiet in the hours before and after the messages I already posted.
> > > 
> > 
> > Ok, that in itself is unexpected.
> > 
> > Pekka, it looks from the stack trace that the failure is from
> > __alloc_skb and I am guessing the failure path is around here
> > 
> >         size = SKB_DATA_ALIGN(size);
> >         data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info),
> >                         gfp_mask, node);
> >         if (!data)
> >                 goto nodata;
> > 
> > Why would the SLUB out-of-memory message not appear? It's hardly
> > tripping up on printk_ratelimit() is it?
> 
> That's because it's a large allocation that's passed directly to the
> page allocator. See kmalloc_large_node(), for example.
> 

Pants. Is there any chance that could be fixed so that allocation
failures within SLUB get consistently reported?

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Pekka Enberg @ 2009-09-10 12:39 UTC (permalink / raw)
  To: Mel Gorman
  Cc: Frans Pop, Larry Finger, John W. Linville, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl, Assaf Krauss,
	Johannes Berg, Mohamed Abbas
In-Reply-To: <20090910123445.GC31153@csn.ul.ie>

Hi Mel,

On Thu, 2009-09-10 at 13:34 +0100, Mel Gorman wrote:
> > That's because it's a large allocation that's passed directly to the
> > page allocator. See kmalloc_large_node(), for example. 
> 
> Pants. Is there any chance that could be fixed so that allocation
> failures within SLUB get consistently reported?

Did you have something specific in mind? I am not sure it's worth it,
really.

The kmalloc_large() function is a static inline in
include/linux/slub_def.h that gets inlined nicely to a get_order() +
__get_free_pages() pair in the caller for production configs. I'm not
sure what we should print either. There's no known "object size" or
"buffer size" nor do we any of the variable order things or backing
struct kmem_cache_nodes.

			Pekka


^ permalink raw reply

* Re: iwlagn: order 2 page allocation failures
From: Mel Gorman @ 2009-09-10 12:58 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: Frans Pop, Larry Finger, John W. Linville, linux-kernel,
	linux-wireless, ipw3945-devel, Andrew Morton, cl, Assaf Krauss,
	Johannes Berg, Mohamed Abbas
In-Reply-To: <1252586376.4876.29.camel@penberg-laptop>

On Thu, Sep 10, 2009 at 03:39:36PM +0300, Pekka Enberg wrote:
> Hi Mel,
> 
> On Thu, 2009-09-10 at 13:34 +0100, Mel Gorman wrote:
> > > That's because it's a large allocation that's passed directly to the
> > > page allocator. See kmalloc_large_node(), for example. 
> > 
> > Pants. Is there any chance that could be fixed so that allocation
> > failures within SLUB get consistently reported?
> 
> Did you have something specific in mind? I am not sure it's worth it,
> really.
> 
> The kmalloc_large() function is a static inline in
> include/linux/slub_def.h that gets inlined nicely to a get_order() +
> __get_free_pages() pair in the caller for production configs. I'm not
> sure what we should print either. There's no known "object size" or
> "buffer size" nor do we any of the variable order things or backing
> struct kmem_cache_nodes.
> 

All I had in mind really was to grab the size of the buffer that was
passed into kmalloc such as here;

void *__kmalloc(size_t size, gfp_t flags)
{
        struct kmem_cache *s;
        void *ret;

        if (unlikely(size > SLUB_MAX_SIZE))
                return kmalloc_large(size, flags);

and to have consistent reporting of slub-allocation failures but if you
reckon it's not worth it, I wouldn't push strongly on it.

-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* [PATCH] sdio: recognize io card without powercycle
From: Albert Herranz @ 2009-09-10 12:56 UTC (permalink / raw)
  To: akpm, linux-mmc; +Cc: bcm43xx-dev, linux-wireless, Albert Herranz

SDIO Simplified Specification V2.00 states that it is strongly recommended
that the host executes either a power reset or issues a CMD52 (I/O Reset) to
re-initialize an I/O only card or the I/O portion of a combo card.
Additionally, the CMD52 must be issued first because it cannot be issued
after a CMD0.

With this patch the Nintendo Wii SDIO-based WLAN card is detected after a
system reset, without requiring a complete system powercycle.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
---
v1
- reworded commit message
- CC'd akpm as suggested by mb

 drivers/mmc/core/core.c     |    1 +
 drivers/mmc/core/sdio_ops.c |   36 ++++++++++++++++++++++++++++++------
 drivers/mmc/core/sdio_ops.h |    1 +
 3 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d84c880..c768f70 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -890,6 +890,7 @@ void mmc_rescan(struct work_struct *work)
 	mmc_claim_host(host);
 
 	mmc_power_up(host);
+	sdio_go_idle(host);
 	mmc_go_idle(host);
 
 	mmc_send_if_cond(host, host->ocr_avail);
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index 4eb7825..14d3204 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -67,13 +67,13 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 	return err;
 }
 
-int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
-	unsigned addr, u8 in, u8* out)
+static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn,
+	unsigned addr, u8 in, u8 *out)
 {
 	struct mmc_command cmd;
 	int err;
 
-	BUG_ON(!card);
+	BUG_ON(!host);
 	BUG_ON(fn > 7);
 
 	/* sanity check */
@@ -90,11 +90,11 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
 	cmd.arg |= in;
 	cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
 
-	err = mmc_wait_for_cmd(card->host, &cmd, 0);
+	err = mmc_wait_for_cmd(host, &cmd, 0);
 	if (err)
 		return err;
 
-	if (mmc_host_is_spi(card->host)) {
+	if (mmc_host_is_spi(host)) {
 		/* host driver already reported errors */
 	} else {
 		if (cmd.resp[0] & R5_ERROR)
@@ -106,7 +106,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
 	}
 
 	if (out) {
-		if (mmc_host_is_spi(card->host))
+		if (mmc_host_is_spi(host))
 			*out = (cmd.resp[0] >> 8) & 0xFF;
 		else
 			*out = cmd.resp[0] & 0xFF;
@@ -115,6 +115,13 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
 	return 0;
 }
 
+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
+	unsigned addr, u8 in, u8 *out)
+{
+	BUG_ON(!card);
+	return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out);
+}
+
 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
 {
@@ -182,3 +189,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	return 0;
 }
 
+int sdio_go_idle(struct mmc_host *host)
+{
+	int ret;
+	u8 abort;
+
+	/* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */
+
+	ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort);
+	if (ret)
+		abort = 0x08;
+	else
+		abort |= 0x08;
+
+	ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL);
+	return ret;
+}
+
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h
index e2e74b0..9b546c7 100644
--- a/drivers/mmc/core/sdio_ops.h
+++ b/drivers/mmc/core/sdio_ops.h
@@ -17,6 +17,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, u8 in, u8* out);
 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
+int sdio_go_idle(struct mmc_host *host);
 
 #endif
 
-- 
1.6.0.4


^ permalink raw reply related

* [PATCH] sdio: pass unknown cis tuples to sdio drivers
From: Albert Herranz @ 2009-09-10 12:56 UTC (permalink / raw)
  To: akpm, linux-mmc; +Cc: bcm43xx-dev, linux-wireless, Albert Herranz
In-Reply-To: <1252587402-7382-1-git-send-email-albert_herranz@yahoo.es>

Some manufacturers provide vendor information in non-vendor specific CIS
tuples. For example, Broadcom uses an Extended Function tuple to provide
the MAC address on some of their network cards, as in the case of the
Nintendo Wii WLAN daughter card.

This patch allows passing correct tuples unknown to the SDIO core to
a matching SDIO driver instead of rejecting them and failing.

Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
---
v1
- fixed typo in commit message
- CC'd akpm as suggested by mb
- required by commit 4ea602e183ca20a7577ebe253323d0e5d0f9847 in net-next-2.6

 drivers/mmc/core/sdio_cis.c |   46 +++++++++++++++++++++++-------------------
 1 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 963f293..87934ac 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -123,8 +123,9 @@ static int cistpl_funce_func(struct sdio_func *func,
 	vsn = func->card->cccr.sdio_vsn;
 	min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
 
+	/* let the SDIO driver take care of unknown tuples */
 	if (size < min_size || buf[0] != 1)
-		return -EINVAL;
+		return -EILSEQ;
 
 	/* TPLFE_MAX_BLK_SIZE */
 	func->max_blksize = buf[12] | (buf[13] << 8);
@@ -154,13 +155,7 @@ static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
 	else
 		ret = cistpl_funce_common(card, buf, size);
 
-	if (ret) {
-		printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
-		       "type %u\n", mmc_hostname(card->host), size, buf[0]);
-		return ret;
-	}
-
-	return 0;
+	return ret;
 }
 
 typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
@@ -253,21 +248,12 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
 		for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
 			if (cis_tpl_list[i].code == tpl_code)
 				break;
-		if (i >= ARRAY_SIZE(cis_tpl_list)) {
-			/* this tuple is unknown to the core */
-			this->next = NULL;
-			this->code = tpl_code;
-			this->size = tpl_link;
-			*prev = this;
-			prev = &this->next;
-			printk(KERN_DEBUG
-			       "%s: queuing CIS tuple 0x%02x length %u\n",
-			       mmc_hostname(card->host), tpl_code, tpl_link);
-		} else {
+		if (i < ARRAY_SIZE(cis_tpl_list)) {
 			const struct cis_tpl *tpl = cis_tpl_list + i;
 			if (tpl_link < tpl->min_size) {
 				printk(KERN_ERR
-				       "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n",
+				       "%s: bad CIS tuple 0x%02x"
+				       " (length = %u, expected >= %u)\n",
 				       mmc_hostname(card->host),
 				       tpl_code, tpl_link, tpl->min_size);
 				ret = -EINVAL;
@@ -275,7 +261,25 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
 				ret = tpl->parse(card, func,
 						 this->data, tpl_link);
 			}
-			kfree(this);
+			/* already successfully parsed, not needed anymore */
+			if (!ret)
+				kfree(this);
+		} else {
+			/* unknown tuple */
+			ret = -EILSEQ;
+		}
+
+		if (ret == -EILSEQ) {
+			/* this tuple is unknown to the core */
+			this->next = NULL;
+			this->code = tpl_code;
+			this->size = tpl_link;
+			*prev = this;
+			prev = &this->next;
+			pr_debug("%s: queuing CIS tuple 0x%02x length %u\n",
+				 mmc_hostname(card->host), tpl_code, tpl_link);
+			/* keep on analyzing tuples */
+			ret = 0;
 		}
 
 		ptr += tpl_link;
-- 
1.6.0.4


^ permalink raw reply related

* unibomb pending patches - 2009-09-09
From: Luis R. Rodriguez @ 2009-09-10 15:16 UTC (permalink / raw)
  To: linux-wireless, Sujith; +Cc: devel

Here's an all-in-one patch file for my pending 2 series of patches:

http://bombadil.infradead.org/~mcgrof/patches/ath/2009/09/all-2009-09-09.patch

  Luis

^ permalink raw reply

* anything
From: Jon Nettleton @ 2009-09-10 15:36 UTC (permalink / raw)
  To: linux-wireless

subscribe linux-wireless


^ permalink raw reply

* Re: anything
From: Luis R. Rodriguez @ 2009-09-10 15:54 UTC (permalink / raw)
  To: Jon Nettleton; +Cc: linux-wireless
In-Reply-To: <1252597007.4544.0.camel@localhost.localdomain>

On Thu, Sep 10, 2009 at 8:36 AM, Jon Nettleton <jon.nettleton@gmail.com> wrote:
> subscribe linux-wireless

-EWRONG_REQUREST

^ permalink raw reply

* Re: anything
From: Gabor Juhos @ 2009-09-10 15:58 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Jon Nettleton, linux-wireless
In-Reply-To: <43e72e890909100854i8d16de8g9501630ce5c64787@mail.gmail.com>

Luis R. Rodriguez írta:
> On Thu, Sep 10, 2009 at 8:36 AM, Jon Nettleton <jon.nettleton@gmail.com> wrote:
>> subscribe linux-wireless
> 
> -EWRONG_REQUREST

-ETYPO :)


^ permalink raw reply

* [PATCH 2/2] rfkill: Add support for KEY_RFKILL
From: Matthew Garrett @ 2009-09-10 17:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-wireless, marcel, Matthew Garrett
In-Reply-To: <1252603292-20830-1-git-send-email-mjg@redhat.com>

Add support for handling KEY_RFKILL in the rfkill input module. This
simply toggles the state of all rfkill devices. The comment in rfkill.h
is also updated to reflect that RFKILL_TYPE_ALL may be used inside the
kernel.

Signed-off-by: Matthew Garrett <mjg@redhat.com>
---
 include/linux/rfkill.h |    2 +-
 net/rfkill/input.c     |    8 ++++++++
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 278777f..4c39f7e 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -32,7 +32,7 @@
 /**
  * enum rfkill_type - type of rfkill switch.
  *
- * @RFKILL_TYPE_ALL: toggles all switches (userspace only)
+ * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
  * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
  * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
  * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
diff --git a/net/rfkill/input.c b/net/rfkill/input.c
index a7295ad..3713d7e 100644
--- a/net/rfkill/input.c
+++ b/net/rfkill/input.c
@@ -212,6 +212,9 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
 		case KEY_WIMAX:
 			rfkill_schedule_toggle(RFKILL_TYPE_WIMAX);
 			break;
+		case KEY_RFKILL:
+			rfkill_schedule_toggle(RFKILL_TYPE_ALL);
+			break;
 		}
 	} else if (type == EV_SW && code == SW_RFKILL_ALL)
 		rfkill_schedule_evsw_rfkillall(data);
@@ -295,6 +298,11 @@ static const struct input_device_id rfkill_ids[] = {
 		.keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
 	},
 	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+		.evbit = { BIT_MASK(EV_KEY) },
+		.keybit = { [BIT_WORD(KEY_RFKILL)] = BIT_MASK(KEY_RFKILL) },
+	},
+	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
 		.evbit = { BIT(EV_SW) },
 		.swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
-- 
1.6.2.5


^ permalink raw reply related

* [PATCH 1/2] input: Add KEY_RFKILL
From: Matthew Garrett @ 2009-09-10 17:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-wireless, marcel, Matthew Garrett

Most laptops have keys that are intended to toggle all device state, not
just wifi. These are currently generally mapped to KEY_WLAN. As a result,
rfkill will only kill or enable wifi in response to the key press. This
confuses users and can make it difficult for them to enable bluetooth
and wwan devices.

This patch adds a new keycode, KEY_RFKILL_ALL. It indicates that the
system should toggle the state of all rfkillable devices.

Signed-off-by: Matthew Garrett <mjg@redhat.com>
---
 include/linux/input.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/input.h b/include/linux/input.h
index 8b3bc3e..20a622e 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -595,6 +595,8 @@ struct input_absinfo {
 #define KEY_NUMERIC_STAR	0x20a
 #define KEY_NUMERIC_POUND	0x20b
 
+#define KEY_RFKILL		0x20c /* Key that controls all radios */
+
 /* We avoid low common keys in module aliases so they don't get huge. */
 #define KEY_MIN_INTERESTING	KEY_MUTE
 #define KEY_MAX			0x2ff
-- 
1.6.2.5


^ 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