Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 1/2] ath9k: fix a potential buffer leak in the STA teardown path
From: Felix Fietkau @ 2010-07-07 17:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez

It looks like it might be possible for a TID to be paused, while still
holding some queued buffers, however ath_tx_node_cleanup currently only
iterates over active TIDs.
Fix this by always checking every allocated TID for the STA that is being
cleaned up.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@kernel.org
---
 drivers/net/wireless/ath/ath9k/xmit.c |   52 ++++++++++++++++----------------
 1 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index c3681a1..408d1c5 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2430,37 +2430,37 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
 
 void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
 {
-	int i;
-	struct ath_atx_ac *ac, *ac_tmp;
-	struct ath_atx_tid *tid, *tid_tmp;
+	struct ath_atx_ac *ac;
+	struct ath_atx_tid *tid;
 	struct ath_txq *txq;
+	int i, tidno;
 
-	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-		if (ATH_TXQ_SETUP(sc, i)) {
-			txq = &sc->tx.txq[i];
+	for (tidno = 0, tid = &an->tid[tidno];
+	     tidno < WME_NUM_TID; tidno++, tid++) {
+		i = tid->ac->qnum;
 
-			spin_lock_bh(&txq->axq_lock);
+		if (!ATH_TXQ_SETUP(sc, i))
+			continue;
 
-			list_for_each_entry_safe(ac,
-					ac_tmp, &txq->axq_acq, list) {
-				tid = list_first_entry(&ac->tid_q,
-						struct ath_atx_tid, list);
-				if (tid && tid->an != an)
-					continue;
-				list_del(&ac->list);
-				ac->sched = false;
-
-				list_for_each_entry_safe(tid,
-						tid_tmp, &ac->tid_q, list) {
-					list_del(&tid->list);
-					tid->sched = false;
-					ath_tid_drain(sc, txq, tid);
-					tid->state &= ~AGGR_ADDBA_COMPLETE;
-					tid->state &= ~AGGR_CLEANUP;
-				}
-			}
+		txq = &sc->tx.txq[i];
+		ac = tid->ac;
 
-			spin_unlock_bh(&txq->axq_lock);
+		spin_lock_bh(&txq->axq_lock);
+
+		if (tid->sched) {
+			list_del(&tid->list);
+			tid->sched = false;
+		}
+
+		if (ac->sched) {
+			list_del(&ac->list);
+			tid->ac->sched = false;
 		}
+
+		ath_tid_drain(sc, txq, tid);
+		tid->state &= ~AGGR_ADDBA_COMPLETE;
+		tid->state &= ~AGGR_CLEANUP;
+
+		spin_unlock_bh(&txq->axq_lock);
 	}
 }
-- 
1.6.4.2


^ permalink raw reply related

* [PATCH 2/2] ath9k: fix a buffer leak in A-MPDU completion
From: Felix Fietkau @ 2010-07-07 17:42 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, lrodriguez
In-Reply-To: <1278524529-30246-1-git-send-email-nbd@openwrt.org>

When ath_tx_complete_aggr() is called, it's responsible for returning
all buffers in the linked list. This was not done when the STA lookup
failed, leading to a race condition that could leak a few buffers when
a STA just disconnected.
Fix this by immediately returning all buffers to the free list in this case.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@kernel.org
---
 drivers/net/wireless/ath/ath9k/xmit.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 408d1c5..05ec36a 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -329,6 +329,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
 	bool rc_update = true;
 	struct ieee80211_tx_rate rates[4];
+	unsigned long flags;
 
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -344,6 +345,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	sta = ieee80211_find_sta_by_hw(hw, hdr->addr1);
 	if (!sta) {
 		rcu_read_unlock();
+
+		spin_lock_irqsave(&sc->tx.txbuflock, flags);
+		list_splice_tail_init(bf_q, &sc->tx.txbuf);
+		spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
 		return;
 	}
 
-- 
1.6.4.2


^ permalink raw reply related

* [PATCH v2] mac80211: remove wep dependency
From: John W. Linville @ 2010-07-07 18:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, John W. Linville
In-Reply-To: <1278447551-4981-1-git-send-email-linville@tuxdriver.com>

The current mac80211 code assumes that WEP is always available.  If WEP
fails to initialize, ieee80211_register_hw will always fail.

In some cases (e.g. FIPS certification), the cryptography used by WEP is
unavailable.  However, in such cases there is no good reason why CCMP
encryption (or even no link level encryption) cannot be used.  So, this
patch removes mac80211's assumption that WEP (and TKIP) will always be
available for use.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
v2 -> make it safe to call ieee80211_wep_free even if ieee80211_wep_init
	had failed

 net/mac80211/cfg.c  |    5 +++++
 net/mac80211/main.c |    5 +----
 net/mac80211/tkip.c |    8 ++++----
 net/mac80211/tkip.h |    2 +-
 net/mac80211/wep.c  |   18 ++++++++++++------
 net/mac80211/wep.h  |    2 +-
 net/mac80211/wpa.c  |    5 ++---
 7 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e55970b..5b8b446 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -143,6 +143,11 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 		return -EINVAL;
 	}
 
+	/* reject WEP and TKIP keys if WEP failed to initialize */
+	if ((alg == ALG_WEP || alg == ALG_TKIP) &&
+	    IS_ERR(sdata->local->wep_tx_tfm))
+		return -EINVAL;
+
 	key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
 				  params->seq_len, params->seq);
 	if (!key)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index edf7aff..0e95c75 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -637,11 +637,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		goto fail_sta_info;
 
 	result = ieee80211_wep_init(local);
-	if (result < 0) {
+	if (result < 0)
 		printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",
 		       wiphy_name(local->hw.wiphy), result);
-		goto fail_wep;
-	}
 
 	rtnl_lock();
 
@@ -694,7 +692,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
  fail_rate:
 	rtnl_unlock();
 	ieee80211_wep_free(local);
- fail_wep:
 	sta_info_stop(local);
  fail_sta_info:
 	destroy_workqueue(local->workqueue);
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 7ef491e..e840c9c 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -202,9 +202,9 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
  * @payload_len is the length of payload (_not_ including IV/ICV length).
  * @ta is the transmitter addresses.
  */
-void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
-				 struct ieee80211_key *key,
-				 u8 *pos, size_t payload_len, u8 *ta)
+int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
+				struct ieee80211_key *key,
+				u8 *pos, size_t payload_len, u8 *ta)
 {
 	u8 rc4key[16];
 	struct tkip_ctx *ctx = &key->u.tkip.tx;
@@ -216,7 +216,7 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
 
 	tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
 
-	ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
+	return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
 }
 
 /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h
index d471438..7e83dee 100644
--- a/net/mac80211/tkip.h
+++ b/net/mac80211/tkip.h
@@ -15,7 +15,7 @@
 
 u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
 
-void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
+int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
 				 struct ieee80211_key *key,
 				 u8 *pos, size_t payload_len, u8 *ta);
 enum {
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5f3a411..54263db 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -122,19 +122,24 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
 /* Perform WEP encryption using given key. data buffer must have tailroom
  * for 4-byte ICV. data_len must not include this ICV. Note: this function
  * does _not_ add IV. data = RC4(data | CRC32(data)) */
-void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-				size_t klen, u8 *data, size_t data_len)
+int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+			       size_t klen, u8 *data, size_t data_len)
 {
 	struct blkcipher_desc desc = { .tfm = tfm };
 	struct scatterlist sg;
 	__le32 icv;
 
+	if (IS_ERR(tfm))
+		return -1;
+
 	icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 	put_unaligned(icv, (__le32 *)(data + data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
 	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
+
+	return 0;
 }
 
 
@@ -168,10 +173,8 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
 	/* Add room for ICV */
 	skb_put(skb, WEP_ICV_LEN);
 
-	ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
-				   iv + WEP_IV_LEN, len);
-
-	return 0;
+	return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
+					  iv + WEP_IV_LEN, len);
 }
 
 
@@ -185,6 +188,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	struct scatterlist sg;
 	__le32 crc;
 
+	if (IS_ERR(tfm))
+		return -1;
+
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
 	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index fe29d7e..58654ee 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -18,7 +18,7 @@
 
 int ieee80211_wep_init(struct ieee80211_local *local);
 void ieee80211_wep_free(struct ieee80211_local *local);
-void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 				size_t klen, u8 *data, size_t data_len);
 int ieee80211_wep_encrypt(struct ieee80211_local *local,
 			  struct sk_buff *skb,
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index a14e677..8d59d27 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -183,9 +183,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 	skb_put(skb, TKIP_ICV_LEN);
 
 	hdr = (struct ieee80211_hdr *) skb->data;
-	ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
-				    key, pos, len, hdr->addr2);
-	return 0;
+	return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
+					   key, pos, len, hdr->addr2);
 }
 
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH v3] mac80211: remove wep dependency
From: John W. Linville @ 2010-07-07 19:07 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, John W. Linville
In-Reply-To: <1278528270-9703-1-git-send-email-linville@tuxdriver.com>

The current mac80211 code assumes that WEP is always available.  If WEP
fails to initialize, ieee80211_register_hw will always fail.

In some cases (e.g. FIPS certification), the cryptography used by WEP is
unavailable.  However, in such cases there is no good reason why CCMP
encryption (or even no link level encryption) cannot be used.  So, this
patch removes mac80211's assumption that WEP (and TKIP) will always be
available for use.

Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
v3 -> actually post changed patch...
v2 -> make it safe to call ieee80211_wep_free even if ieee80211_wep_init
	had failed

 net/mac80211/cfg.c  |    5 +++++
 net/mac80211/main.c |    5 +----
 net/mac80211/tkip.c |    8 ++++----
 net/mac80211/tkip.h |    2 +-
 net/mac80211/wep.c  |   24 ++++++++++++++++--------
 net/mac80211/wep.h  |    2 +-
 net/mac80211/wpa.c  |    5 ++---
 7 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e55970b..5b8b446 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -143,6 +143,11 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 		return -EINVAL;
 	}
 
+	/* reject WEP and TKIP keys if WEP failed to initialize */
+	if ((alg == ALG_WEP || alg == ALG_TKIP) &&
+	    IS_ERR(sdata->local->wep_tx_tfm))
+		return -EINVAL;
+
 	key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
 				  params->seq_len, params->seq);
 	if (!key)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index edf7aff..0e95c75 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -637,11 +637,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		goto fail_sta_info;
 
 	result = ieee80211_wep_init(local);
-	if (result < 0) {
+	if (result < 0)
 		printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",
 		       wiphy_name(local->hw.wiphy), result);
-		goto fail_wep;
-	}
 
 	rtnl_lock();
 
@@ -694,7 +692,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
  fail_rate:
 	rtnl_unlock();
 	ieee80211_wep_free(local);
- fail_wep:
 	sta_info_stop(local);
  fail_sta_info:
 	destroy_workqueue(local->workqueue);
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 7ef491e..e840c9c 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -202,9 +202,9 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
  * @payload_len is the length of payload (_not_ including IV/ICV length).
  * @ta is the transmitter addresses.
  */
-void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
-				 struct ieee80211_key *key,
-				 u8 *pos, size_t payload_len, u8 *ta)
+int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
+				struct ieee80211_key *key,
+				u8 *pos, size_t payload_len, u8 *ta)
 {
 	u8 rc4key[16];
 	struct tkip_ctx *ctx = &key->u.tkip.tx;
@@ -216,7 +216,7 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
 
 	tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key);
 
-	ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
+	return ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len);
 }
 
 /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h
index d471438..7e83dee 100644
--- a/net/mac80211/tkip.h
+++ b/net/mac80211/tkip.h
@@ -15,7 +15,7 @@
 
 u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
 
-void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
+int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
 				 struct ieee80211_key *key,
 				 u8 *pos, size_t payload_len, u8 *ta);
 enum {
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5f3a411..6d133b6 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -47,8 +47,10 @@ int ieee80211_wep_init(struct ieee80211_local *local)
 
 void ieee80211_wep_free(struct ieee80211_local *local)
 {
-	crypto_free_blkcipher(local->wep_tx_tfm);
-	crypto_free_blkcipher(local->wep_rx_tfm);
+	if (!IS_ERR(local->wep_tx_tfm))
+		crypto_free_blkcipher(local->wep_tx_tfm);
+	if (!IS_ERR(local->wep_rx_tfm))
+		crypto_free_blkcipher(local->wep_rx_tfm);
 }
 
 static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
@@ -122,19 +124,24 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
 /* Perform WEP encryption using given key. data buffer must have tailroom
  * for 4-byte ICV. data_len must not include this ICV. Note: this function
  * does _not_ add IV. data = RC4(data | CRC32(data)) */
-void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-				size_t klen, u8 *data, size_t data_len)
+int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+			       size_t klen, u8 *data, size_t data_len)
 {
 	struct blkcipher_desc desc = { .tfm = tfm };
 	struct scatterlist sg;
 	__le32 icv;
 
+	if (IS_ERR(tfm))
+		return -1;
+
 	icv = cpu_to_le32(~crc32_le(~0, data, data_len));
 	put_unaligned(icv, (__le32 *)(data + data_len));
 
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
 	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
+
+	return 0;
 }
 
 
@@ -168,10 +175,8 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
 	/* Add room for ICV */
 	skb_put(skb, WEP_ICV_LEN);
 
-	ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
-				   iv + WEP_IV_LEN, len);
-
-	return 0;
+	return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
+					  iv + WEP_IV_LEN, len);
 }
 
 
@@ -185,6 +190,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 	struct scatterlist sg;
 	__le32 crc;
 
+	if (IS_ERR(tfm))
+		return -1;
+
 	crypto_blkcipher_setkey(tfm, rc4key, klen);
 	sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
 	crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index fe29d7e..58654ee 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -18,7 +18,7 @@
 
 int ieee80211_wep_init(struct ieee80211_local *local);
 void ieee80211_wep_free(struct ieee80211_local *local);
-void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
+int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 				size_t klen, u8 *data, size_t data_len);
 int ieee80211_wep_encrypt(struct ieee80211_local *local,
 			  struct sk_buff *skb,
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index a14e677..8d59d27 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -183,9 +183,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 	skb_put(skb, TKIP_ICV_LEN);
 
 	hdr = (struct ieee80211_hdr *) skb->data;
-	ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
-				    key, pos, len, hdr->addr2);
-	return 0;
+	return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
+					   key, pos, len, hdr->addr2);
 }
 
 
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH 11/15] wireless: wl1271: introduce platform device support
From: Adrian Hunter @ 2010-07-07 19:59 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Quadros Roger (Nokia-MS/Helsinki), Ohad Ben-Cohen,
	linux-wireless@vger.kernel.org, linux-mmc@vger.kernel.org,
	linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux@arm.linux.org.uk, Chikkature Rajashekar Madhusudhan,
	Coelho Luciano (Nokia-MS/Helsinki), akpm@linux-foundation.org,
	San Mehat
In-Reply-To: <alpine.LFD.2.00.1007070954010.6020@xanadu.home>

Nicolas Pitre wrote:
> On Wed, 7 Jul 2010, Roger Quadros wrote:
> 
>> On 07/06/2010 10:51 PM, Hunter Adrian (Nokia-MS/Helsinki) wrote:
>>> For eMMC in omap_hsmmc, this is all done via claim_host / release_host
>>> which call ->enable() / ->disable() methods.  omap_hsmmc makes use of
>>> mmc_power_restore_host() which calls host->bus_ops->power_restore()
>>> which is not implemented for SDIO, but for MMC and SD it reinitializes
>>> the card.
> 
> This is IMHO a really bad design.  The power control decision has to 
> come from the top, not from the bottom.  And certainly not with a 
> U-turn dependency the omap_hsmmc is using.

The power control decision does come from the top via mmc_claim_host /
mmc_release_host.

> 
> I regret to say this, but the omap_hsmmc driver is becoming a total 
> mess.  The host controller driver has to be a dumb interface serving 
> requests from the hardware used by the upper layer stack, not the place 
> where decisions such as power handling should be made.  Think of it like 
> an ethernet driver.  No ethernet driver in Linux is telling the IP stack 
> when to shut down.

The omap_hsmmc driver does not tell the core to shut down the upper layers.
Instead the core tells the omap_hsmmc driver that it is "disabled" i.e.
not currently being used so it can start taking steps to save power.
That is sensible because not even the upper layers know when the next
activity will be.

> 
>> Shouldn't the power control intelligence (i.e. when to turn power ON/OFF) lie
>> with the bus drivers?
> 
> Absolutely!  And in the SDIO case that should lie with each function 
> drivers.  Please let's stop this omap_hsmmc madness.

You are dealing with a trivial case - turn off the power when not in use.
We have 3 power saving actions: enable DPS, put the card to sleep,
and finally power it off.  Each increases the latency to start up
again and so must be staggered.  With DPS-enabled the host controller can
be powered off at any time.  In that case the controller registers must be
restored.  There are numerous entry points to the driver.  Checking whether
to restore registers at every entry point is error prone and messy.
Instead we require that the core tells the driver when to enable and
disable.

> 
> 
> Nicolas
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply

* Re: [PATCH] compat-wireless: refresh patch
From: Luis R. Rodriguez @ 2010-07-07 20:55 UTC (permalink / raw)
  To: Hauke Mehrtens; +Cc: linux-wireless, mcgrof
In-Reply-To: <1277843775-2656-1-git-send-email-hauke@hauke-m.de>

On Tue, Jun 29, 2010 at 1:36 PM, Hauke Mehrtens <hauke@hauke-m.de> wrote:
>
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

thanks applied, sorry for the delay, was on vacation, I'm back now.

  Luis

^ permalink raw reply

* Re: [PATCH] compat-wireless: update 07-change-default-rate-alg.patch
From: Luis R. Rodriguez @ 2010-07-07 20:56 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: linux-wireless
In-Reply-To: <20100706202408.10219.7113.stgit@mj.roinet.com>

thanks applied!

  Luis

^ permalink raw reply

* Re: [PATCH] compat: Fix panic caused by NULL pointer derefence in rtnl_fill_ifinfo
From: Luis R. Rodriguez @ 2010-07-07 21:10 UTC (permalink / raw)
  To: Rajkumar Manoharan
  Cc: linux-wireless@vger.kernel.org, linux-bluetooth@vger.kernel.org
In-Reply-To: <44EE5C37ADC36343B0625A05DD408C4850DAB4D6BD@CHEXMB-01.global.atheros.com>

On Tue, Jun 29, 2010 at 9:26 AM, Rajkumar Manoharan
<Rajkumar.Manoharan@atheros.com> wrote:
>>________________________________________
>>From: Luis R. Rodriguez [mcgrof@gmail.com]
>>Sent: Tuesday, June 29, 2010 8:51 PM
>>To: Rajkumar Manoharan
>>Cc: mcgrof@kernel.org; linux-wireless@vger.kernel.org; linux-bluetooth@vger.kernel.org
>>Subject: Re: [PATCH] compat: Fix panic caused by NULL pointer derefence in      rtnl_fill_ifinfo
>
>>On Mon, Jun 28, 2010 at 11:38 PM, Rajkumar Manoharan
> <rmanoharan@atheros.com> wrote:
>> get stats netdev ops is blindy called for older kernels (< 2.6.29) and
>> so assigning a NULL pointer from netdev_attach_ops causes a NULL pointer
>> dereference.
>>
>> By default, netdev alloc provides an internal stats reference. So fill
>> this only if ndo_get_stats is defined.
>>
>> Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com>
>> ---
>>  compat/compat-2.6.29.c |    3 ++-
>>  1 files changed, 2 insertions(+), 1 deletions(-)
>>
>> diff --git a/compat/compat-2.6.29.c b/compat/compat-2.6.29.c
>> index f94aed8..2e7e623 100644
>> --- a/compat/compat-2.6.29.c
>> +++ b/compat/compat-2.6.29.c
>> @@ -35,7 +35,8 @@ void netdev_attach_ops(struct net_device *dev,
>>        dev->change_mtu = ops->ndo_change_mtu;
>>        dev->set_mac_address = ops->ndo_set_mac_address;
>>        dev->tx_timeout = ops->ndo_tx_timeout;
>> -       dev->get_stats = ops->ndo_get_stats;
>> +       if (ops->ndo_get_stats)
>> +               dev->get_stats = ops->ndo_get_stats;
>>
>> If ops->ndo_get_stats is NULL then dev->get_stats will be set to NULL.
>> Do you know for sure this fixes something? If so can you explain how?
>> I used to have a macro that checked for not NULL and if true set the
>> callback but then later realized after Johannes poked me that this is
>> silly given that if the op is NULL you are just setting it to NULL.
>>
>> I don't see the potential crash here.
>>
>>  Luis
>
> During alloc_netdev, get_stats is set to default callback (internal_stats).
> It won't be NULL. Based on this assumption, get_stats is
> invoked blindly in rtnl_fill_ifinfo without NULL check. So either
> get_stats set with default callback or callback assigned by module.
> It shouldn't be NULL.

Fun, thanks! Patch applied, and propagated to the  linux-2.6.35.y
stable branch of compat as well.

  Luis

^ permalink raw reply

* Re: [PATCH] iw: fix ampdu spacing & max amsdu length reporting
From: Luis R. Rodriguez @ 2010-07-07 21:15 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless, Johannes Berg
In-Reply-To: <201006270051.24299.chunkeey@googlemail.com>

I know Johannes is on vacation, so just a reminder :)

On Sat, Jun 26, 2010 at 3:51 PM, Christian Lamparter
<chunkeey@googlemail.com> wrote:
> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
> ---
> diff --git a/scan.c b/scan.c
> index 09b1047..cd58290 100644
> --- a/scan.c
> +++ b/scan.c
> @@ -497,7 +497,7 @@ static void print_ht_capa(const uint8_t type, uint8_t len, const uint8_t *data)
>        printf("\n");
>        print_ht_capability(data[0] | (data[1] << 8));
>        print_ampdu_length(data[2] & 3);
> -       print_ampdu_spacing((data[2] >> 2) & 3);
> +       print_ampdu_spacing((data[2] >> 2) & 7);
>        print_ht_mcs(data + 3);
>  }
>
> diff --git a/util.c b/util.c
> index 0c6d978..80d5402 100644
> --- a/util.c
> +++ b/util.c
> @@ -457,8 +457,8 @@ void print_ht_capability(__u16 cap)
>
>        PRINT_HT_CAP((cap & BIT(10)), "HT Delayed Block Ack");
>
> -       PRINT_HT_CAP((cap & BIT(11)), "Max AMSDU length: 3839 bytes");
> -        PRINT_HT_CAP(!(cap & BIT(11)), "Max AMSDU length: 7935 bytes");
> +       PRINT_HT_CAP(!(cap & BIT(11)), "Max AMSDU length: 3839 bytes");
> +       PRINT_HT_CAP((cap & BIT(11)), "Max AMSDU length: 7935 bytes");
>
>        /*
>         * For beacons and probe response this would mean the BSS
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH 02/18] net/wireless: use generic_file_llseek in debugfs
From: Arnd Bergmann @ 2010-07-07 21:40 UTC (permalink / raw)
  To: linux-kernel
  Cc: John Kacur, Frederic Weisbecker, Arnd Bergmann, Christoph Hellwig,
	John W. Linville, linux-wireless, netdev
In-Reply-To: <1278538820-1392-1-git-send-email-arnd@arndb.de>

The default llseek operation is changing from
default_llseek to no_llseek, so all code relying on
the current behaviour needs to make that explicit.

The wireless driver infrastructure and some of the drivers
make use of generated debugfs files, so they cannot
be converted by our script that automatically determines
the right operation.

All these files use debugfs and they typically rely
on simple_read_from_buffer, so the best llseek operation
here is generic_file_llseek.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
---
 drivers/misc/iwmc3200top/debugfs.c           |    3 +++
 drivers/net/wireless/b43/debugfs.c           |    1 +
 drivers/net/wireless/b43legacy/debugfs.c     |    1 +
 drivers/net/wireless/iwlwifi/iwl-debugfs.c   |    3 +++
 drivers/net/wireless/libertas/debugfs.c      |    1 +
 drivers/net/wireless/rt2x00/rt2x00debug.c    |    1 +
 drivers/net/wireless/wl12xx/wl1251_debugfs.c |    2 ++
 drivers/net/wireless/wl12xx/wl1271_debugfs.c |    2 ++
 net/mac80211/debugfs.c                       |    2 ++
 net/mac80211/debugfs_key.c                   |    2 ++
 net/mac80211/debugfs_netdev.c                |    1 +
 net/mac80211/debugfs_sta.c                   |    2 ++
 net/wireless/debugfs.c                       |    1 +
 13 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/drivers/misc/iwmc3200top/debugfs.c b/drivers/misc/iwmc3200top/debugfs.c
index e9eda47..62fbaec 100644
--- a/drivers/misc/iwmc3200top/debugfs.c
+++ b/drivers/misc/iwmc3200top/debugfs.c
@@ -71,6 +71,7 @@ ssize_t iwmct_dbgfs_##name##_write(struct file *file,			\
 	static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
 		.read = iwmct_dbgfs_##name##_read,			\
 		.open = iwmct_dbgfs_open_file_generic,			\
+		.llseek = generic_file_llseek,				\
 	};
 
 #define DEBUGFS_WRITE_FILE_OPS(name)					\
@@ -78,6 +79,7 @@ ssize_t iwmct_dbgfs_##name##_write(struct file *file,			\
 	static const struct file_operations iwmct_dbgfs_##name##_ops = {  \
 		.write = iwmct_dbgfs_##name##_write,			\
 		.open = iwmct_dbgfs_open_file_generic,			\
+		.llseek = generic_file_llseek,				\
 	};
 
 #define DEBUGFS_READ_WRITE_FILE_OPS(name)				\
@@ -87,6 +89,7 @@ ssize_t iwmct_dbgfs_##name##_write(struct file *file,			\
 		.write = iwmct_dbgfs_##name##_write,			\
 		.read = iwmct_dbgfs_##name##_read,			\
 		.open = iwmct_dbgfs_open_file_generic,			\
+		.llseek = generic_file_llseek,				\
 	};
 
 
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 80b19a4..59f59fa 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -627,6 +627,7 @@ out_unlock:
 			.open	= b43_debugfs_open,		\
 			.read	= b43_debugfs_read,		\
 			.write	= b43_debugfs_write,		\
+			.llseek = generic_file_llseek,		\
 		},						\
 		.file_struct_offset = offsetof(struct b43_dfsentry, \
 					       file_##name),	\
diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c
index 1f85ac5..f232618 100644
--- a/drivers/net/wireless/b43legacy/debugfs.c
+++ b/drivers/net/wireless/b43legacy/debugfs.c
@@ -334,6 +334,7 @@ out_unlock:
 			.open	= b43legacy_debugfs_open,		\
 			.read	= b43legacy_debugfs_read,		\
 			.write	= b43legacy_debugfs_write,		\
+			.llseek = generic_file_llseek,			\
 		},						\
 		.file_struct_offset = offsetof(struct b43legacy_dfsentry, \
 					       file_##name),	\
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 9659c5d..0d03cf2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -87,6 +87,7 @@ static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
 	.read = iwl_dbgfs_##name##_read,                       		\
 	.open = iwl_dbgfs_open_file_generic,                    	\
+	.llseek = generic_file_llseek,					\
 };
 
 #define DEBUGFS_WRITE_FILE_OPS(name)                                    \
@@ -94,6 +95,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = {          \
 static const struct file_operations iwl_dbgfs_##name##_ops = {          \
 	.write = iwl_dbgfs_##name##_write,                              \
 	.open = iwl_dbgfs_open_file_generic,                    	\
+	.llseek = generic_file_llseek,					\
 };
 
 
@@ -104,6 +106,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = {          \
 	.write = iwl_dbgfs_##name##_write,                              \
 	.read = iwl_dbgfs_##name##_read,                                \
 	.open = iwl_dbgfs_open_file_generic,                            \
+	.llseek = generic_file_llseek,					\
 };
 
 int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index de2caac..94f8f99 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -713,6 +713,7 @@ out_unlock:
 	.open = open_file_generic, \
 	.read = (fread), \
 	.write = (fwrite), \
+	.llseek = generic_file_llseek, \
 }
 
 struct lbs_debugfs_files {
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index e9fe93f..fe92500 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -508,6 +508,7 @@ static const struct file_operations rt2x00debug_fop_##__name = {\
 	.write		= rt2x00debug_write_##__name,		\
 	.open		= rt2x00debug_file_open,		\
 	.release	= rt2x00debug_file_release,		\
+	.llseek		= generic_file_llseek,			\
 };
 
 RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
index 5e4465a..a4ae7c4 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -50,6 +50,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf,	\
 static const struct file_operations name## _ops = {			\
 	.read = name## _read,						\
 	.open = wl1251_open_file_generic,				\
+	.llseek	= generic_file_llseek,					\
 };
 
 #define DEBUGFS_ADD(name, parent)					\
@@ -86,6 +87,7 @@ static ssize_t sub## _ ##name## _read(struct file *file,		\
 static const struct file_operations sub## _ ##name## _ops = {		\
 	.read = sub## _ ##name## _read,					\
 	.open = wl1251_open_file_generic,				\
+	.llseek	= generic_file_llseek,					\
 };
 
 #define DEBUGFS_FWSTATS_ADD(sub, name)				\
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index c239ef4..6e25303 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -51,6 +51,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf,	\
 static const struct file_operations name## _ops = {			\
 	.read = name## _read,						\
 	.open = wl1271_open_file_generic,				\
+	.llseek	= generic_file_llseek,					\
 };
 
 #define DEBUGFS_ADD(name, parent)					\
@@ -87,6 +88,7 @@ static ssize_t sub## _ ##name## _read(struct file *file,		\
 static const struct file_operations sub## _ ##name## _ops = {		\
 	.read = sub## _ ##name## _read,					\
 	.open = wl1271_open_file_generic,				\
+	.llseek	= generic_file_llseek,					\
 };
 
 #define DEBUGFS_FWSTATS_ADD(sub, name)				\
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 637929b..31b6b89 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -36,6 +36,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf,	\
 static const struct file_operations name## _ops = {			\
 	.read = name## _read,						\
 	.open = mac80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 };
 
 #define DEBUGFS_ADD(name)						\
@@ -349,6 +350,7 @@ static ssize_t stats_ ##name## _read(struct file *file,			\
 static const struct file_operations stats_ ##name## _ops = {		\
 	.read = stats_ ##name## _read,					\
 	.open = mac80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 };
 
 #define DEBUGFS_STATS_ADD(name)						\
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 97c9e46..1bc39ac 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -32,6 +32,7 @@ static ssize_t key_##name##_read(struct file *file,			\
 static const struct file_operations key_ ##name## _ops = {		\
 	.read = key_##name##_read,					\
 	.open = mac80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 }
 
 #define KEY_FILE(name, format)						\
@@ -46,6 +47,7 @@ static const struct file_operations key_ ##name## _ops = {		\
 static const struct file_operations key_ ##name## _ops = {		\
 	.read = key_conf_##name##_read,					\
 	.open = mac80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 }
 
 #define KEY_CONF_FILE(name, format)					\
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 20b2998..8ad33ee 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -121,6 +121,7 @@ static const struct file_operations name##_ops = {			\
 	.read = ieee80211_if_read_##name,				\
 	.write = (_write),						\
 	.open = mac80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 }
 
 #define __IEEE80211_IF_FILE_W(name)					\
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index e763f15..73f8f36 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -37,6 +37,7 @@ static ssize_t sta_ ##name## _read(struct file *file,			\
 static const struct file_operations sta_ ##name## _ops = {		\
 	.read = sta_##name##_read,					\
 	.open = mac80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 }
 
 #define STA_OPS_RW(name)						\
@@ -44,6 +45,7 @@ static const struct file_operations sta_ ##name## _ops = {		\
 	.read = sta_##name##_read,					\
 	.write = sta_##name##_write,					\
 	.open = mac80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 }
 
 #define STA_FILE(name, field, format)					\
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index a4991a3..3f9a57e 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -34,6 +34,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf,	\
 static const struct file_operations name## _ops = {			\
 	.read = name## _read,						\
 	.open = cfg80211_open_file_generic,				\
+	.llseek = generic_file_llseek,					\
 };
 
 DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
-- 
1.7.1


^ permalink raw reply related

* RE: [PATCH 06/15] omap zoom2: wlan board muxing
From: Ghorai, Sukumar @ 2010-07-08  3:39 UTC (permalink / raw)
  To: Ohad Ben-Cohen, linux-wireless@vger.kernel.org,
	linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org
  Cc: linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk,
	Chikkature Rajashekar, Madhusudhan, Luciano Coelho,
	akpm@linux-foundation.org, San Mehat, Ben-cohen, Ohad
In-Reply-To: <1278376666-3509-7-git-send-email-ohad@wizery.com>



> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Ohad Ben-Cohen
> Sent: Tuesday, July 06, 2010 6:08 AM
> To: linux-wireless@vger.kernel.org; linux-mmc@vger.kernel.org; linux-
> omap@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux@arm.linux.org.uk;
> Chikkature Rajashekar, Madhusudhan; Luciano Coelho; akpm@linux-
> foundation.org; San Mehat; Ben-cohen, Ohad
> Subject: [PATCH 06/15] omap zoom2: wlan board muxing
> 
> From: Ohad Ben-Cohen <ohadb@ti.com>
> 
> Add board muxing to support the wlan wl1271 chip that is
> hardwired to mmc2 (third mmc controller) on the ZOOM2.
> 
> Signed-off-by: Ohad Ben-Cohen <ohadb@ti.com>
> ---
>  arch/arm/mach-omap2/board-zoom2.c |   15 +++++++++++++++
>  1 files changed, 15 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-
> omap2/board-zoom2.c
> index 803ef14..00871be 100644
> --- a/arch/arm/mach-omap2/board-zoom2.c
> +++ b/arch/arm/mach-omap2/board-zoom2.c
> @@ -71,6 +71,21 @@ static struct twl4030_platform_data zoom2_twldata = {
> 
>  #ifdef CONFIG_OMAP_MUX
>  static struct omap_board_mux board_mux[] __initdata = {
> +#ifdef CONFIG_OMAP_ZOOM_WLAN
[Ghorai] This is zoom board specific file, So why need this additional flag?

> +	/* WLAN IRQ - GPIO 162 */
> +	OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
> +	/* WLAN POWER ENABLE - GPIO 101 */
> +	OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
> +	/* WLAN SDIO: MMC3 CMD */
> +	OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
> +	/* WLAN SDIO: MMC3 CLK */
> +	OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
> +	/* WLAN SDIO: MMC3 DAT[0-3] */
> +	OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
> +	OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
> +	OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
> +	OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
> +#endif
>  	{ .reg_offset = OMAP_MUX_TERMINATOR },
>  };
>  #else
> --
> 1.7.0.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH 04/15] mmc: support embedded data field in mmc_host
From: Ghorai, Sukumar @ 2010-07-08  3:39 UTC (permalink / raw)
  To: Ohad Ben-Cohen, linux-wireless@vger.kernel.org,
	linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org
  Cc: linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk,
	Chikkature Rajashekar, Madhusudhan, Luciano Coelho,
	akpm@linux-foundation.org, San Mehat, Ben-cohen, Ohad
In-Reply-To: <1278376666-3509-5-git-send-email-ohad@wizery.com>



> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Ohad Ben-Cohen
> Sent: Tuesday, July 06, 2010 6:08 AM
> To: linux-wireless@vger.kernel.org; linux-mmc@vger.kernel.org; linux-
> omap@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux@arm.linux.org.uk;
> Chikkature Rajashekar, Madhusudhan; Luciano Coelho; akpm@linux-
> foundation.org; San Mehat; Ben-cohen, Ohad
> Subject: [PATCH 04/15] mmc: support embedded data field in mmc_host
> 
> From: Ohad Ben-Cohen <ohadb@ti.com>
> 
> Add support to set/get mmc_host private embedded
> data.
> 
> This is needed to allow software to dynamically
> create (and remove) SDIO functions which represents
> embedded SDIO devices.
> 
> Typically, it will be used to set the context of
> a driver that is creating a new SDIO function
> (and would then expect to be able to get that context
> back upon creation of the new sdio func).
> 
> Signed-off-by: Ohad Ben-Cohen <ohadb@ti.com>
> ---
>  drivers/mmc/core/Kconfig |    8 ++++++++
>  include/linux/mmc/host.h |   16 ++++++++++++++++
>  2 files changed, 24 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index bb22ffd..ab27eb3 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -16,3 +16,11 @@ config MMC_UNSAFE_RESUME
> 
>  	  This option sets a default which can be overridden by the
>  	  module parameter "removable=0" or "removable=1".
> +
> +config MMC_EMBEDDED_SDIO
> +	boolean "MMC embedded SDIO device support"
> +	help
> +	  If you say Y here, support will be added for embedded SDIO
> +	  devices (e.g. hardwired embedded WLAN SDIO devices).
> +	  Such devices require software support for emulating
> +	  card detect events.
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index f65913c..9a48486 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -209,6 +209,10 @@ struct mmc_host {
>  	struct led_trigger	*led;		/* activity led */
>  #endif
> 
> +#ifdef CONFIG_MMC_EMBEDDED_SDIO
> +	void			*embedded_data;
> +#endif
> +
>  	struct dentry		*debugfs_root;
> 
>  	unsigned long		private[0] ____cacheline_aligned;
> @@ -264,5 +268,17 @@ static inline void mmc_set_disable_delay(struct
> mmc_host *host,
>  	host->disable_delay = disable_delay;
>  }
> 
> +#ifdef CONFIG_MMC_EMBEDDED_SDIO
> +static inline void *mmc_get_embedded_data(struct mmc_host *host)
> +{
> +	return host->embedded_data;
> +}
> +
> +static inline void mmc_set_embedded_data(struct mmc_host *host, void
> *data)
> +{
> +	host->embedded_data = data;
> +}
> +#endif
> +
[Ghorai] we can avoid CONFIG_MMC_EMBEDDED_SDIO flag itself. Why we are passing fixed data? We can enquire form card for the functions, features,.. and at runtime itself. And we are adding many compile-time/kconfig options in this patch series.
>  #endif
> 
> --
> 1.7.0.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH 00/15] wlan+omap+mmc: out-of-the-box WLAN support for ZOOM2/3
From: Ghorai, Sukumar @ 2010-07-08  3:39 UTC (permalink / raw)
  To: Ohad Ben-Cohen, linux-wireless@vger.kernel.org,
	linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org
  Cc: linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk,
	Chikkature Rajashekar, Madhusudhan, Luciano Coelho,
	akpm@linux-foundation.org, San Mehat, Ben-cohen, Ohad
In-Reply-To: <1278376666-3509-1-git-send-email-ohad@wizery.com>



> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Ohad Ben-Cohen
> Sent: Tuesday, July 06, 2010 6:08 AM
> To: linux-wireless@vger.kernel.org; linux-mmc@vger.kernel.org; linux-
> omap@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux@arm.linux.org.uk;
> Chikkature Rajashekar, Madhusudhan; Luciano Coelho; akpm@linux-
> foundation.org; San Mehat; Ben-cohen, Ohad
> Subject: [PATCH 00/15] wlan+omap+mmc: out-of-the-box WLAN support for
> ZOOM2/3
> 
> From: Ohad Ben-Cohen <ohadb@ti.com>
> 
> The ZOOM2/3 boards include TI's wl1271 wlan sdio device,
> hardwired to the 3rd mmc controller.
> 
> These patches add support for WLAN on the ZOOM2/3 boards
> using only mainline components (most notably mac80211 and wl1271).
> 
> Patches were tested on both ZOOM2 and ZOOM3.
> 
> In short, these patches add software control for emulating
> card detect events, add board configurations to support the
> wl1271 device, and update the wl1271 driver to make use of
> these new mechanisms.
> 
> Software card detect emulation is based on Android's
> EMBEDDED_SDIO patch by San Mehat <san@google.com> (thanks, San!).
> 
> These patches span over several differnt subsystems, but since
> they are highly dependent on each other, it is preferrable
> to pull them all together into a single tree (once approved).
> 
> Patches are available at:
> 
> git://wizery.com/pub/linux-2.6.git wl1271
> 
> And will also be sent as a follow-on to this message to the
> omap, mmc, arm and wireless mailing lists.
> 
> Patches are based on mainline 2.6.35-rc4, but can easily be applied
> on wireless-testing (with two minor conflicts). If desired, I can
> rebase to wireless-testing and resend.
> 
> Note: last missing part for full mainline community support
> of the wl1271 on ZOOM is the firmware, and for that there is already
> on-going TI work to provide it in linux-firmware. Hopefully
> that would be resolved soon.
> 
> Thanks,
> 
> Ohad Ben-Cohen (15):
>   sdio: add TI + wl1271 ids
>   wireless: wl1271: remove SDIO IDs from driver
>   omap: mmc: prepare for software card detect support
>   mmc: support embedded data field in mmc_host
>   omap: hsmmc: add virtual card detect support
>   omap zoom2: wlan board muxing
>   omap zoom3: wlan board muxing
>   wireless: wl1271: make wl12xx.h common to both spi and sdio
>   wireless: wl12xx: support pdata SDIO handlers
>   wireless: wl1271: support return value for the set power func
>   wireless: wl1271: introduce platform device support
>   wireless: wl1271: take irq info from platform data
>   wireless: wl1271: make ref_clock configurable by board
>   omap: zoom: add WLAN device
>   omap: zoom: enable WLAN device
> 
>  arch/arm/mach-omap2/Kconfig                   |    5 +
>  arch/arm/mach-omap2/Makefile                  |    1 +
>  arch/arm/mach-omap2/board-zoom-peripherals.c  |   15 ++
>  arch/arm/mach-omap2/board-zoom-wlan.c         |  129 ++++++++++++++++
>  arch/arm/mach-omap2/board-zoom2.c             |   15 ++
>  arch/arm/mach-omap2/board-zoom3.c             |   15 ++
>  arch/arm/mach-omap2/hsmmc.c                   |    4 +
>  arch/arm/mach-omap2/hsmmc.h                   |    5 +
>  arch/arm/mach-omap2/include/mach/board-zoom.h |    5 +
>  arch/arm/plat-omap/include/plat/mmc.h         |    5 +
>  drivers/mmc/core/Kconfig                      |    8 +
>  drivers/mmc/host/omap_hsmmc.c                 |   37 +++++-
>  drivers/net/wireless/wl12xx/Kconfig           |    1 +
>  drivers/net/wireless/wl12xx/wl1251_sdio.c     |    2 +-
>  drivers/net/wireless/wl12xx/wl1251_spi.c      |    2 +-
>  drivers/net/wireless/wl12xx/wl1271.h          |    8 +-
>  drivers/net/wireless/wl12xx/wl1271_boot.c     |   13 +-
>  drivers/net/wireless/wl12xx/wl1271_boot.h     |    1 -
>  drivers/net/wireless/wl12xx/wl1271_io.h       |    8 +-
>  drivers/net/wireless/wl12xx/wl1271_main.c     |    4 +-
>  drivers/net/wireless/wl12xx/wl1271_sdio.c     |  204 +++++++++++++++++++-
> -----
>  drivers/net/wireless/wl12xx/wl1271_spi.c      |    8 +-
>  include/linux/mmc/host.h                      |   16 ++
>  include/linux/mmc/sdio_ids.h                  |    3 +
>  include/linux/spi/wl12xx.h                    |   34 ----
>  include/linux/wl12xx.h                        |   37 +++++
>  26 files changed, 486 insertions(+), 99 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/board-zoom-wlan.c
>  delete mode 100644 include/linux/spi/wl12xx.h
>  create mode 100644 include/linux/wl12xx.h
>
[Ghorai] This patch series having the CONFIG_MMC_EMBEDDED_SDIO as kconfig option and I feel we should void this. This could be a generic and can be get from sdio card at runtime. Quite long codes are adding in this patch series under this flag.
 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH 15/15] omap: zoom: enable WLAN device
From: Ghorai, Sukumar @ 2010-07-08  3:39 UTC (permalink / raw)
  To: Ohad Ben-Cohen, linux-wireless@vger.kernel.org,
	linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org
  Cc: linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk,
	Chikkature Rajashekar, Madhusudhan, Luciano Coelho,
	akpm@linux-foundation.org, San Mehat, Ben-cohen, Ohad
In-Reply-To: <1278376666-3509-16-git-send-email-ohad@wizery.com>



> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Ohad Ben-Cohen
> Sent: Tuesday, July 06, 2010 6:08 AM
> To: linux-wireless@vger.kernel.org; linux-mmc@vger.kernel.org; linux-
> omap@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux@arm.linux.org.uk;
> Chikkature Rajashekar, Madhusudhan; Luciano Coelho; akpm@linux-
> foundation.org; San Mehat; Ben-cohen, Ohad
> Subject: [PATCH 15/15] omap: zoom: enable WLAN device
> 
> From: Ohad Ben-Cohen <ohadb@ti.com>
> 
> Make it possible to build and use TI's wl1271
> device on the ZOOM boards.
> 
> The device is an embedded SDIO WLAN chip
> that is hardwired to the 3rd mmc controller
> of the ZOOM2/3 boards.
> 
> Signed-off-by: Ohad Ben-Cohen <ohadb@ti.com>
> ---
>  arch/arm/mach-omap2/Kconfig                  |    5 +++++
>  arch/arm/mach-omap2/Makefile                 |    1 +
>  arch/arm/mach-omap2/board-zoom-peripherals.c |   15 +++++++++++++++
>  3 files changed, 21 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> index b31b6f1..7fee11b 100644
> --- a/arch/arm/mach-omap2/Kconfig
> +++ b/arch/arm/mach-omap2/Kconfig
> @@ -131,6 +131,11 @@ config MACH_OMAP_ZOOM3
>  	depends on ARCH_OMAP3
>  	select OMAP_PACKAGE_CBP
> 
> +config OMAP_ZOOM_WLAN
> +	bool "OMAP Zoom board WLAN support"
> +	depends on MACH_OMAP_ZOOM2 || MACH_OMAP_ZOOM3
> +	select MMC_EMBEDDED_SDIO
> +
>  config MACH_CM_T35
>  	bool "CompuLab CM-T35 module"
>  	depends on ARCH_OMAP3
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index ea52b03..ac1bad9 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -129,6 +129,7 @@ obj-$(CONFIG_MACH_OMAP_ZOOM3)		+= board-
> zoom3.o \
>  					   board-zoom-peripherals.o \
>  					   hsmmc.o \
>  					   board-zoom-debugboard.o
> +obj-y					+= board-zoom-wlan.o
>  obj-$(CONFIG_MACH_OMAP_3630SDP)		+= board-3630sdp.o \
>  					   board-zoom-peripherals.o \
>  					   hsmmc.o
> diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-
> omap2/board-zoom-peripherals.c
> index 6b39849..3128cd4 100644
> --- a/arch/arm/mach-omap2/board-zoom-peripherals.c
> +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
> @@ -16,11 +16,13 @@
>  #include <linux/gpio.h>
>  #include <linux/i2c/twl.h>
>  #include <linux/regulator/machine.h>
> +#include <linux/mmc/host.h>
> 
>  #include <asm/mach-types.h>
>  #include <asm/mach/arch.h>
>  #include <asm/mach/map.h>
> 
> +#include <mach/board-zoom.h>
>  #include <plat/common.h>
>  #include <plat/usb.h>
> 
> @@ -168,6 +170,18 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
>  		.nonremovable	= true,
>  		.power_saving	= true,
>  	},
> +#ifdef CONFIG_OMAP_ZOOM_WLAN
> +	{
> +		.mmc		= 3,
> +		.wires		= 4,
> +		.gpio_cd	= -EINVAL,
> +		.gpio_wp	= -EINVAL,
> +		.register_embedded_control =
> +				omap_zoom_wlan_register_embedded_control,
> +		.virtual_get_cd = omap_zoom_wlan_get_virtual_cd,
> +		.ocr_mask	= MMC_VDD_165_195,
> +	},
> +#endif
>  	{}      /* Terminator */
>  };
> 
> @@ -282,4 +296,5 @@ void __init zoom_peripherals_init(void)
>  	omap_i2c_init();
>  	usb_musb_init(&musb_board_data);
>  	enable_board_wakeup_source();
> +	omap_zoom_wlan_init();
>  }
[Ghorai] In general we can avoid OMAP_ZOOM_WLAN and MMC_EMBEDDED_SDIO as kconfig option. 1st one is board specific and 2nd one could be generic sdio code. As I mentioned in other patch too.
> --
> 1.7.0.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH 14/15] omap: zoom: add WLAN device
From: Ghorai, Sukumar @ 2010-07-08  3:39 UTC (permalink / raw)
  To: Ohad Ben-Cohen, linux-wireless@vger.kernel.org,
	linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org
  Cc: linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk,
	Chikkature Rajashekar, Madhusudhan, Luciano Coelho,
	akpm@linux-foundation.org, San Mehat, Ben-cohen, Ohad
In-Reply-To: <1278376666-3509-15-git-send-email-ohad@wizery.com>



> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Ohad Ben-Cohen
> Sent: Tuesday, July 06, 2010 6:08 AM
> To: linux-wireless@vger.kernel.org; linux-mmc@vger.kernel.org; linux-
> omap@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; linux@arm.linux.org.uk;
> Chikkature Rajashekar, Madhusudhan; Luciano Coelho; akpm@linux-
> foundation.org; San Mehat; Ben-cohen, Ohad
> Subject: [PATCH 14/15] omap: zoom: add WLAN device
> 
> From: Ohad Ben-Cohen <ohadb@ti.com>
> 
> Add WLAN platform device and control
> functions (power and virtual card detect)
> in order to allow software to control the
> embedded SDIO WLAN device which resides on
> the ZOOM board (TI's wl1271 device).
> 
> Based on Android's WLAN control functions by
> San Mehat <san@android.com>.
> 
> Signed-off-by: Ohad Ben-Cohen <ohadb@ti.com>
> ---
>  arch/arm/mach-omap2/board-zoom-wlan.c         |  129
> +++++++++++++++++++++++++
>  arch/arm/mach-omap2/include/mach/board-zoom.h |    5 +
>  2 files changed, 134 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/board-zoom-wlan.c
> 
> diff --git a/arch/arm/mach-omap2/board-zoom-wlan.c b/arch/arm/mach-
> omap2/board-zoom-wlan.c
> new file mode 100644
> index 0000000..7ed5139
> --- /dev/null
> +++ b/arch/arm/mach-omap2/board-zoom-wlan.c
> @@ -0,0 +1,129 @@
> +/* mach-omap2/board-zoom-wlan.c
> + *
> + * Board support for wl1271 embedded SDIO device.
> + *
> + * Copyright (C) 2010 Texas Instruments, Inc.
> + *
> + * This file is licensed under the terms of the GNU General Public
> License
> + * version 2. This program is licensed "as is" without any warranty of
> any
> + * kind, whether express or implied.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/sdio_ids.h>
> +#include <linux/err.h>
> +#include <linux/gpio.h>
> +#include <linux/wl12xx.h>
> +
> +#include "mux.h"
> +
> +#ifdef CONFIG_OMAP_ZOOM_WLAN
[Ghorai] Again the file itself is zoom specific, why we need the additional flag?

> +
> +/* these are zoom-specific board numbers */
> +#define OMAP_ZOOM_WLAN_PMENA_GPIO	(101)
> +#define OMAP_ZOOM_WLAN_IRQ_GPIO		(162)
> +
> +/* wl1271 virtual 'card detect' status */
> +static int omap_zoom_wlan_cd;
> +static void (*wlan_set_virtual_cd)(void *dev_id, int card_present);
> +static void (*wlan_set_data)(void *dev_id, void *priv);
> +static void *wlan_host_devid;
> +
> +int omap_zoom_wlan_register_embedded_control(void *dev_id,
> +			void (*set_virtual_cd)(void *dev_id, int card_present),
> +			void (*set_data)(void *dev_id, void *priv))
> +{
> +	if (wlan_host_devid || wlan_set_virtual_cd || wlan_set_data)
> +		return -EBUSY;
> +
> +	wlan_set_virtual_cd = set_virtual_cd;
> +	wlan_set_data = set_data;
> +	wlan_host_devid = dev_id;
> +
> +	return 0;
> +}
> +
> +int omap_zoom_wlan_get_virtual_cd(void)
> +{
> +	return omap_zoom_wlan_cd;
> +}
> +
> +static void omap_zoom_wlan_set_embedded_data(void *priv)
> +{
> +	if (wlan_set_data)
> +		wlan_set_data(wlan_host_devid, priv);
> +	else
> +		pr_err("%s: host controller not registered yet\n", __func__);
> +}
> +
> +static void omap_zoom_wlan_set_carddetect(bool card_present)
> +{
> +	omap_zoom_wlan_cd = card_present ? 1 : 0;
> +
> +	pr_info("%s: %d\n", __func__, omap_zoom_wlan_cd);
> +
> +	if (wlan_set_virtual_cd)
> +		wlan_set_virtual_cd(wlan_host_devid, omap_zoom_wlan_cd);
> +	else
> +		pr_err("%s: host controller not registered yet\n", __func__);
> +}
> +
> +static void omap_zoom_wlan_power(bool enable)
> +{
> +	int val = enable ? 1 : 0;
> +
> +	pr_info("%s: set power %d\n", __func__, val);
> +
> +	gpio_set_value(OMAP_ZOOM_WLAN_PMENA_GPIO, val);
> +}
> +
> +struct wl12xx_platform_data omap_zoom_wlan_control = {
> +	.set_power = omap_zoom_wlan_power,
> +	.set_carddetect = omap_zoom_wlan_set_carddetect,
> +	.set_embedded_data = omap_zoom_wlan_set_embedded_data,
> +	/* ZOOM ref clock is 26 MHz */
> +	.board_ref_clock = 1,
> +	.irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO),
> +};
> +
> +static struct platform_device omap_zoom_wlan_device = {
> +	.name = "wl1271_sdio",
> +	.id = 1,
> +	.dev = {
> +		.platform_data = &omap_zoom_wlan_control,
> +	},
> +};
> +
> +int __init omap_zoom_wlan_init(void)
> +{
> +	int ret;
> +
> +	ret = gpio_request(OMAP_ZOOM_WLAN_PMENA_GPIO, "wlan_power");
> +	if (ret < 0) {
> +		pr_err("%s: power gpio request failed: %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	gpio_direction_output(OMAP_ZOOM_WLAN_PMENA_GPIO, 0);
> +
> +	ret = gpio_request(OMAP_ZOOM_WLAN_IRQ_GPIO, "wlan_irq");
> +	if (ret < 0) {
> +		pr_err("%s: gpio request failed: %d\n", __func__, ret);
> +		return ret;
> +	}
> +	gpio_direction_input(OMAP_ZOOM_WLAN_IRQ_GPIO);
> +
> +	ret = platform_device_register(&omap_zoom_wlan_device);
> +
> +	return ret;
> +}
> +
> +#else
> +int __init omap_zoom_wlan_init(void)
> +{
> +	return 0;
> +}
> +#endif /* CONFIG_OMAP_ZOOM_WLAN */
> diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h
> b/arch/arm/mach-omap2/include/mach/board-zoom.h
> index c93b29e..61bbd81 100644
> --- a/arch/arm/mach-omap2/include/mach/board-zoom.h
> +++ b/arch/arm/mach-omap2/include/mach/board-zoom.h
> @@ -3,3 +3,8 @@
>   */
>  extern int __init zoom_debugboard_init(void);
>  extern void __init zoom_peripherals_init(void);
> +int __init omap_zoom_wlan_init(void);
> +int omap_zoom_wlan_register_embedded_control(void *dev_id,
> +			void (*set_virtual_cd)(void *dev_id, int card_present),
> +			void (*set_data)(void *dev_id, void *priv));
> +int omap_zoom_wlan_get_virtual_cd(void);
> --
> 1.7.0.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 11/15] wireless: wl1271: introduce platform device support
From: Nicolas Pitre @ 2010-07-08  4:34 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: Quadros Roger (Nokia-MS/Helsinki), Ohad Ben-Cohen,
	linux-wireless@vger.kernel.org, linux-mmc@vger.kernel.org,
	linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux@arm.linux.org.uk, Chikkature Rajashekar Madhusudhan,
	Coelho Luciano (Nokia-MS/Helsinki), akpm@linux-foundation.org,
	San Mehat
In-Reply-To: <4C34DC92.80908@nokia.com>

On Wed, 7 Jul 2010, Adrian Hunter wrote:

> Nicolas Pitre wrote:
> > On Wed, 7 Jul 2010, Roger Quadros wrote:
> > 
> > > On 07/06/2010 10:51 PM, Hunter Adrian (Nokia-MS/Helsinki) wrote:
> > > > For eMMC in omap_hsmmc, this is all done via claim_host / release_host
> > > > which call ->enable() / ->disable() methods.  omap_hsmmc makes use of
> > > > mmc_power_restore_host() which calls host->bus_ops->power_restore()
> > > > which is not implemented for SDIO, but for MMC and SD it reinitializes
> > > > the card.
> > 
> > This is IMHO a really bad design.  The power control decision has to come
> > from the top, not from the bottom.  And certainly not with a U-turn
> > dependency the omap_hsmmc is using.
> 
> The power control decision does come from the top via mmc_claim_host /
> mmc_release_host.

NO!!!  THIS IS NOT ABOUT POWER!

To the risk of repeating myself, mmc_claim_host and mmc_release_host are 
about getting exclusive access to the host controller.  This should not 
have any relationship with power.  If anything, you might infer some 
idleness of the host through that, but only to save power at the host 
controller level, but not at the card level.

> > I regret to say this, but the omap_hsmmc driver is becoming a total mess.
> > The host controller driver has to be a dumb interface serving requests from
> > the hardware used by the upper layer stack, not the place where decisions
> > such as power handling should be made.  Think of it like an ethernet driver.
> > No ethernet driver in Linux is telling the IP stack when to shut down.
> 
> The omap_hsmmc driver does not tell the core to shut down the upper layers.

What is this call to mmc_power_save_host() and mmc_power_restore_host() 
then?

> Instead the core tells the omap_hsmmc driver that it is "disabled" i.e.
> not currently being used so it can start taking steps to save power.

That's not how I see things implemented right now.

> That is sensible because not even the upper layers know when the next
> activity will be.

I don't agree with you.  The upper layer, even if it cannot predict 
exactly when the next activity will occur, still has a hell of a better 
visibility on what is going on.  In the context of an MMC/SD card, 
the upper layer knows about the block subsystem and it can look for 
dirty blocks that might be flushed in a near future.  In the context of 
a SDIO card, it is the SDIO function driver that knows when it is 
important to preserve power to the card and when it is not.

All the host controller driver must do is to simply and dumbly process 
requests from the core MMC code, including power control requests.

> > > Shouldn't the power control intelligence (i.e. when to turn power ON/OFF)
> > > lie
> > > with the bus drivers?
> > 
> > Absolutely!  And in the SDIO case that should lie with each function
> > drivers.  Please let's stop this omap_hsmmc madness.
> 
> You are dealing with a trivial case - turn off the power when not in use.

And apparently this cannot be implemented sanely on OMAP without faking 
a card removal.

> We have 3 power saving actions: enable DPS, put the card to sleep,
> and finally power it off.  Each increases the latency to start up
> again and so must be staggered.  With DPS-enabled the host controller can
> be powered off at any time.  In that case the controller registers must be
> restored.

You could implement the first one based on some idle period.  The core 
code probably doesn't need to know as this should be transparent to the 
upper layer.  But the other two definitely should be handled by the core 
code.

> There are numerous entry points to the driver.  Checking whether
> to restore registers at every entry point is error prone and messy.

Please give me something else than this lame excuse.  There is 
effectively only _one_ main entry point, namely the request method of 
the mmc_host_ops structure.  You might need to poke at the hardware when 
the set_ios or the enable_sdio_irq methods are called, and if the 
controller is latent then you'd only have to update the register cache.  
This is certainly not what I would call numerous.

> Instead we require that the core tells the driver when to enable and
> disable.

No you don't.  You are abusing the mmc_claim_host interface with power 
management issues.  Those power issues are then guessed in the host 
controller driver, and then it eventually calls back into the core to 
tell the upper layer to shut off.

What I'm telling you is that:

1) If you want to save power after some idle period you don't need 
   host->ops->enable and host->ops->disable at all.  Simply keep a timer 
   alive in your host driver and reset it when a new request comes in.  
   The code for mmc_host_enable() looks rather redundant, and fishy to 
   me with its flag to prevent recursion, so this all could be removed.

2) Putting the card to sleep and/or removing power to it must be 
   completely managed by the core code and certainly not from the host 
   controller driver.  The fact that mmc_power_save_host() is currently 
   called from a host driver and not from the core code or function 
   drivers is completely backward.  Contrary to the suspend/resume 
   requests which come from the machine bus where the host controller is 
   attached (yes, this concept applies to you even if you don't have 
   PCI), the possibility for shutting down power to the card when not in 
   use must come from the so called "MMC bus driver" like the MMC 
   block driver, or the SDIO function driver.  Putting a SDIO card to 
   sleep is card dependent anyway, and that knowledge has to live in the 
   SDIO function driver for that card, and certainly not in the host 
   driver nor in the platform code.

3) And yet that does _not_ require any new capability or method to be 
   implemented in the host controller driver as mmc_set_ios() can do 
   power handling already.

And incidentally, implementing 3 and 4 would suddenly work for all hosts 
without any change to the existing host controller drivers and prevent a 
whole lot of functionality duplications.


Nicolas

^ permalink raw reply

* [PATCH] ath9k: fix panic while cleaning up virtaul wifis
From: Rajkumar Manoharan @ 2010-07-08  6:42 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Rajkumar Manoharan

num_sec_wiphy means max secondary wifis that the driver can accomudate.
So cancelling wiphy work should be based on the presence of
secondary wifis.

Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com>
---
 drivers/net/wireless/ath/ath9k/init.c |    2 +-
 drivers/net/wireless/ath/ath9k/main.c |    8 +++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index fe730cb..243c177 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -787,12 +787,12 @@ void ath9k_deinit_device(struct ath_softc *sc)
 		ieee80211_unregister_hw(aphy->hw);
 		ieee80211_free_hw(aphy->hw);
 	}
-	kfree(sc->sec_wiphy);
 
 	ieee80211_unregister_hw(hw);
 	ath_rx_cleanup(sc);
 	ath_tx_cleanup(sc);
 	ath9k_deinit_softc(sc);
+	kfree(sc->sec_wiphy);
 }
 
 void ath_descdma_cleanup(struct ath_softc *sc,
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4c0831f..bca8c5a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1264,6 +1264,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	struct ath_softc *sc = aphy->sc;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
+	int i;
 
 	mutex_lock(&sc->mutex);
 
@@ -1276,7 +1277,12 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	cancel_work_sync(&sc->paprd_work);
 	cancel_work_sync(&sc->hw_check_work);
 
-	if (!sc->num_sec_wiphy) {
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		if (sc->sec_wiphy[i])
+			break;
+	}
+
+	if (i == sc->num_sec_wiphy) {
 		cancel_delayed_work_sync(&sc->wiphy_work);
 		cancel_work_sync(&sc->chan_work);
 	}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] Added support for host sleep feature
From: Amitkumar Karwar @ 2010-07-08  1:13 UTC (permalink / raw)
  To: linux-wireless; +Cc: libertas-dev

From: Amitkumar Karwar <akarwar@marvell.com>

Existing "ethtool -s ethX wol X" command configures hostsleep
parameters, but those are activated only during suspend/resume,
there is no way to configure host sleep without actual suspend.

This patch adds debugfs command to enable/disable host sleep based on
already configured host sleep parameters using wol command.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Kiran Divekar <dkiran@marvell.com>
---
 drivers/net/wireless/libertas/README    |   12 ++++++
 drivers/net/wireless/libertas/cmd.c     |   61 ++++++++++++++++++++++++++++-
 drivers/net/wireless/libertas/cmd.h     |    2 +
 drivers/net/wireless/libertas/debugfs.c |   66 +++++++++++++++++++++++++++++++
 drivers/net/wireless/libertas/main.c    |   34 +---------------
 5 files changed, 142 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index 2726c04..60fd1af 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -226,6 +226,18 @@ setuserscan
     All entries in the scan table (not just the new scan data when keep=1)
     will be displayed upon completion by use of the getscantable ioctl.
 
+hostsleep
+	This command is used to enable/disable host sleep.
+	Note: Host sleep parameters should be configured using
+	"ethtool -s ethX wol X" command before enabling host sleep.
+
+	Path: /sys/kernel/debug/libertas_wireless/ethX/
+
+	Usage:
+		cat hostsleep: reads the current hostsleep state
+		echo "1" > hostsleep : enable host sleep.
+		echo "0" > hostsleep : disable host sleep
+
 ========================
 IWCONFIG COMMANDS
 ========================
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 6c8a9d9..749fbde 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -181,7 +181,7 @@ static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
 			struct cmd_header *resp)
 {
 	lbs_deb_enter(LBS_DEB_CMD);
-	if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
+	if (priv->is_host_sleep_activated) {
 		priv->is_host_sleep_configured = 0;
 		if (priv->psstate == PS_STATE_FULL_POWER) {
 			priv->is_host_sleep_activated = 0;
@@ -361,6 +361,65 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
 	return ret;
 }
 
+static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
+		unsigned long dummy,
+		struct cmd_header *cmd)
+{
+	lbs_deb_enter(LBS_DEB_FW);
+	priv->is_host_sleep_activated = 1;
+	wake_up_interruptible(&priv->host_sleep_q);
+	lbs_deb_leave(LBS_DEB_FW);
+	return 0;
+}
+
+int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
+{
+	struct cmd_header cmd;
+	int ret = 0;
+	uint32_t criteria = EHS_REMOVE_WAKEUP;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	if (host_sleep) {
+		if (priv->is_host_sleep_activated != 1) {
+			memset(&cmd, 0, sizeof(cmd));
+			ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
+					(struct wol_config *)NULL);
+			if (ret) {
+				lbs_pr_info("Host sleep configuration failed: "
+						"%d\n", ret);
+				return ret;
+			}
+			if (priv->psstate == PS_STATE_FULL_POWER) {
+				ret = __lbs_cmd(priv,
+						CMD_802_11_HOST_SLEEP_ACTIVATE,
+						&cmd,
+						sizeof(cmd),
+						lbs_ret_host_sleep_activate, 0);
+				if (ret)
+					lbs_pr_info("HOST_SLEEP_ACTIVATE "
+							"failed: %d\n", ret);
+			}
+
+			if (!wait_event_interruptible_timeout(
+						priv->host_sleep_q,
+						priv->is_host_sleep_activated,
+						(10 * HZ))) {
+				lbs_pr_err("host_sleep_q: timer expired\n");
+				ret = -1;
+			}
+		} else {
+			lbs_pr_err("host sleep: already enabled\n");
+		}
+	} else {
+		if (priv->is_host_sleep_activated)
+			ret = lbs_host_sleep_cfg(priv, criteria,
+					(struct wol_config *)NULL);
+	}
+
+	return ret;
+}
+
 /**
  *  @brief Set an SNMP MIB value
  *
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index cb4138a..386e565 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -127,4 +127,6 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm);
 
 int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep);
 
+int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep);
+
 #endif /* _LBS_CMD_H */
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 1736746..acaf811 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -124,6 +124,70 @@ out_unlock:
 	return ret;
 }
 
+static ssize_t lbs_host_sleep_write(struct file *file,
+				const char __user *user_buf, size_t count,
+				loff_t *ppos)
+{
+	struct lbs_private *priv = file->private_data;
+	ssize_t buf_size, ret;
+	int host_sleep;
+	unsigned long addr = get_zeroed_page(GFP_KERNEL);
+	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
+
+	buf_size = min(count, len - 1);
+	if (copy_from_user(buf, user_buf, buf_size)) {
+		ret = -EFAULT;
+		goto out_unlock;
+	}
+	ret = sscanf(buf, "%d", &host_sleep);
+	if (ret != 1) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (host_sleep == 0)
+		ret = lbs_set_host_sleep(priv, 0);
+	else if (host_sleep == 1) {
+		if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
+			lbs_pr_info("wake parameters not configured");
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+		ret = lbs_set_host_sleep(priv, 1);
+	} else {
+		lbs_pr_err("invalid option\n");
+		ret = -EINVAL;
+	}
+
+	if (!ret)
+		ret = count;
+
+out_unlock:
+	free_page(addr);
+	return ret;
+}
+
+static ssize_t lbs_host_sleep_read(struct file *file, char __user *userbuf,
+				  size_t count, loff_t *ppos)
+{
+	struct lbs_private *priv = file->private_data;
+	ssize_t ret;
+	size_t pos = 0;
+	unsigned long addr = get_zeroed_page(GFP_KERNEL);
+	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
+
+	pos += snprintf(buf, len, "%d\n", priv->is_host_sleep_activated);
+
+	ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+
+	free_page(addr);
+	return ret;
+}
+
 /*
  * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might
  * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the
@@ -675,6 +739,8 @@ static const struct lbs_debugfs_files debugfs_files[] = {
 	{ "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
 	{ "sleepparams", 0644, FOPS(lbs_sleepparams_read,
 				lbs_sleepparams_write), },
+	{ "hostsleep", 0644, FOPS(lbs_host_sleep_read,
+				lbs_host_sleep_write), },
 };
 
 static const struct lbs_debugfs_files debugfs_events_files[] = {
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index b519fc7..2a0b590 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -544,20 +544,8 @@ static int lbs_thread(void *data)
 	return 0;
 }
 
-static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
-		unsigned long dummy,
-		struct cmd_header *cmd)
-{
-	lbs_deb_enter(LBS_DEB_FW);
-	priv->is_host_sleep_activated = 1;
-	wake_up_interruptible(&priv->host_sleep_q);
-	lbs_deb_leave(LBS_DEB_FW);
-	return 0;
-}
-
 int lbs_suspend(struct lbs_private *priv)
 {
-	struct cmd_header cmd;
 	int ret;
 
 	lbs_deb_enter(LBS_DEB_FW);
@@ -571,25 +559,8 @@ int lbs_suspend(struct lbs_private *priv)
 		priv->deep_sleep_required = 1;
 	}
 
-	memset(&cmd, 0, sizeof(cmd));
-	ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
-						(struct wol_config *)NULL);
-	if (ret) {
-		lbs_pr_info("Host sleep configuration failed: %d\n", ret);
-		return ret;
-	}
-	if (priv->psstate == PS_STATE_FULL_POWER) {
-		ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
-				sizeof(cmd), lbs_ret_host_sleep_activate, 0);
-		if (ret)
-			lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
-	}
+	ret = lbs_set_host_sleep(priv, 1);
 
-	if (!wait_event_interruptible_timeout(priv->host_sleep_q,
-				priv->is_host_sleep_activated, (10 * HZ))) {
-		lbs_pr_err("host_sleep_q: timer expired\n");
-		ret = -1;
-	}
 	netif_device_detach(priv->dev);
 	if (priv->mesh_dev)
 		netif_device_detach(priv->mesh_dev);
@@ -602,11 +573,10 @@ EXPORT_SYMBOL_GPL(lbs_suspend);
 int lbs_resume(struct lbs_private *priv)
 {
 	int ret;
-	uint32_t criteria = EHS_REMOVE_WAKEUP;
 
 	lbs_deb_enter(LBS_DEB_FW);
 
-	ret = lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
+	ret = lbs_set_host_sleep(priv, 0);
 
 	netif_device_attach(priv->dev);
 	if (priv->mesh_dev)
-- 
1.5.3.4




^ permalink raw reply related

* RE: wl1271 firmware
From: Luciano Coelho @ 2010-07-08  8:42 UTC (permalink / raw)
  To: ext Levi, Shahar; +Cc: Pazzo Da Legare, linux-wireless@vger.kernel.org
In-Reply-To: <AC090B9732AB2B4DB7FF476E907FE66001067C0669@dnce02.ent.ti.com>

Hi,


On Tue, 2010-07-06 at 14:28 +0200, ext Levi, Shahar wrote:
> > I start from tiwlan.ini file for tiwlan driver to produce an nvs file.
> > Could you please indicate values to use for the following parameters
> > of struct wl1271_nvs_file: general_params.srf1[],
> > general_params.srf2[], general_params.srf3[],
> > dyn_radio_params_2[].params.degraded_low_to_normal_thr,
> > dyn_radio_params_2[].params.normal_to_degraded_high_thr,
> > dyn_radio_params_5[i].params.degraded_low_to_normal_thr,
> > dyn_radio_params_5[i].params.normal_to_degraded_high_thr
> 
> Hi,
> The tiwlan driver ini&NVS files has a different stature then the mac80211 NVS. The parameters you mentioned are RF parameters. 
> I believe it will be the best to get the NVS that mach to the mac80211 (that I am pushing to get).
> Regards,
> Shahar  

You need to get the firmware (wl1271-fw.bin) directly from TI or from
your device manufacturer.  I don't have the permission to redistribute
it.  The latest version that we are using is Rev. 6.1.0.0.310 (you can
check this by running strings on and grepping the binary file).

The NVS file is another story.  It contains device-specific calibration
values and you should probably get those from the device manufacturer.
There is a common part (which is the INI file in tiwlan's terms), which
you need to use to create the binary (check wl1271_ini.h for the binary
file structure).  The more problematic part is the device-specific self
generated calibration.  You need to run a specific sequence of commands
in order to get these values and then apply these values to the correct
place in the binary file.

Shahar, maybe you could contribute a tool to generate the NVS file in
the correct format for wl1271? That would be very cool and would help
lots of people.  Please let me know if you have interest and we can
discuss this in more details.

-- 
Cheers,
Luca.


^ permalink raw reply

* Re: [PATCH 11/15] wireless: wl1271: introduce platform device support
From: Roger Quadros @ 2010-07-08  8:54 UTC (permalink / raw)
  To: ext Nicolas Pitre
  Cc: ext Ohad Ben-Cohen, linux-wireless@vger.kernel.org,
	linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk,
	Chikkature Rajashekar Madhusudhan,
	Coelho Luciano (Nokia-MS/Helsinki), akpm@linux-foundation.org,
	San Mehat
In-Reply-To: <alpine.LFD.2.00.1007070937040.6020@xanadu.home>

On 07/07/2010 04:52 PM, ext Nicolas Pitre wrote:
> On Wed, 7 Jul 2010, Roger Quadros wrote:
>
>> On 07/06/2010 08:42 PM, ext Nicolas Pitre wrote:
>>> On Tue, 6 Jul 2010, Roger Quadros wrote:
>>>
>>>> OK, this is how I see it.
>>>>
>>>> - Treat the non-removable card as non-removable. So no need to do card
>>>> detect
>>>> emulation.
>>>>
>>>> - Treat the GPIO power enable on wl1271 as VMMC supply. Use fixed
>>>> regulator
>>>> framework to define this regulator&   supply. Even though you mention that
>>>> it
>>>> is not actually a supply, it fits well in the fixed supply framework.
>>>>
>>>> - When the host controller is enumerated, the mmc core will power up the
>>>> slot,
>>>> find the sdio card, and probe the function driver (i.e. wl1271_sdio).
>>>>
>>>> - if interface is not in use, the function driver must release the sdio
>>>> host,
>>>> and this should eventually disable the vmmc supply.
>>>>
>>>> - Whenever the wlan interface must be brought up, wl1271_sdio, can claim
>>>> the
>>>> sdio host. this will cause the vmmc supply to be enabled, for as long as
>>>> the
>>>> interface is up.
>>>>
>>>> Does this address all issues?
>>>
>>> This is mostly all good, except that claiming/releasing the SDIO host is
>>> about access to the bus.  It must be claimed right before doing any IO,
>>> and released right after that, even when the card is expected to remain
>>> powered.  This is not the proper place to hook power control.
>>
>> Agreed, but is it so that SDIO power may be removed between a host_release and
>> claim? This appears so from omap_hsmmc host controller.
>
> No, it is not because a host is not claimed that power should be
> dropped.  The host claim/release is meant to provide exclusive access to
> the card that's all.
>
> If the OMAP controller is dropping power to the card upon
> host->disable() then it is wrong.  AFAICS only the OMAP controller is
> playing such games at the moment and I suspect the semantics might not
> be all right.  Shutting down the _controller_ when it is idle might be a
> good thing, but not power to the _card_.  Only the function driver might
> know when it is fine to lose power.
>
>
I completely agree with you Nicolas. omap_hsmmc needs to be fixed so that it 
does not control MMC/SDIO slot supply voltage. It should deal with only the mmc 
controller power savings and not the card/function power savings.

regards,
-roger

^ permalink raw reply

* Re: [PATCH 06/15] omap zoom2: wlan board muxing
From: Tony Lindgren @ 2010-07-08  9:45 UTC (permalink / raw)
  To: Ghorai, Sukumar
  Cc: Ohad Ben-Cohen, linux-wireless@vger.kernel.org,
	linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk,
	Chikkature Rajashekar, Madhusudhan, Luciano Coelho,
	akpm@linux-foundation.org, San Mehat, Ben-cohen, Ohad
In-Reply-To: <2A3DCF3DA181AD40BDE86A3150B27B6B030E10C9B3@dbde02.ent.ti.com>

* Ghorai, Sukumar <s-ghorai@ti.com> [100708 06:34]:
> > @@ -71,6 +71,21 @@ static struct twl4030_platform_data zoom2_twldata = {
> > 
> >  #ifdef CONFIG_OMAP_MUX
> >  static struct omap_board_mux board_mux[] __initdata = {
> > +#ifdef CONFIG_OMAP_ZOOM_WLAN
>
> [Ghorai] This is zoom board specific file, So why need this additional flag?

Good point, the ifdef is unnecessary in for both zoom2 and zoom3.
Will update in my queue to remove the ifdefs.

Tony

^ permalink raw reply

* [PATCH 01/13] wl1271: Remove calibration from join command
From: Luciano Coelho @ 2010-07-08 14:49 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1278600608-22411-1-git-send-email-luciano.coelho@nokia.com>

From: Juuso Oikarinen <juuso.oikarinen@nokia.com>

This patch removes the calibration performed on the first join command. The
reasoning is that this is unnecessary as devices get their calibration data
via the NVS file, and because the commands break BT coexistence.

This is actually safe, because of the implementation the calibration
was executed on the first JOIN anyway, after an ifdown/ifup the devices have
relied on the NVS for calibration anyway (== most of the time.)

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1271_cmd.c |  104 ------------------------------
 1 files changed, 0 insertions(+), 104 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 530678e..8307f21 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -104,100 +104,6 @@ out:
 	return ret;
 }
 
-static int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
-{
-	struct wl1271_cmd_cal_channel_tune *cmd;
-	int ret = 0;
-
-	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-	if (!cmd)
-		return -ENOMEM;
-
-	cmd->test.id = TEST_CMD_CHANNEL_TUNE;
-
-	cmd->band = WL1271_CHANNEL_TUNE_BAND_2_4;
-	/* set up any channel, 7 is in the middle of the range */
-	cmd->channel = 7;
-
-	ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
-	if (ret < 0)
-		wl1271_warning("TEST_CMD_CHANNEL_TUNE failed");
-
-	kfree(cmd);
-	return ret;
-}
-
-static int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
-{
-	struct wl1271_cmd_cal_update_ref_point *cmd;
-	int ret = 0;
-
-	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-	if (!cmd)
-		return -ENOMEM;
-
-	cmd->test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT;
-
-	/* FIXME: still waiting for the correct values */
-	cmd->ref_power    = 0;
-	cmd->ref_detector = 0;
-
-	cmd->sub_band     = WL1271_PD_REFERENCE_POINT_BAND_B_G;
-
-	ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
-	if (ret < 0)
-		wl1271_warning("TEST_CMD_UPDATE_PD_REFERENCE_POINT failed");
-
-	kfree(cmd);
-	return ret;
-}
-
-static int wl1271_cmd_cal_p2g(struct wl1271 *wl)
-{
-	struct wl1271_cmd_cal_p2g *cmd;
-	int ret = 0;
-
-	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
-	if (!cmd)
-		return -ENOMEM;
-
-	cmd->test.id = TEST_CMD_P2G_CAL;
-
-	cmd->sub_band_mask = WL1271_CAL_P2G_BAND_B_G;
-
-	ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
-	if (ret < 0)
-		wl1271_warning("TEST_CMD_P2G_CAL failed");
-
-	kfree(cmd);
-	return ret;
-}
-
-static int wl1271_cmd_cal(struct wl1271 *wl)
-{
-	/*
-	 * FIXME: we must make sure that we're not sleeping when calibration
-	 * is done
-	 */
-	int ret;
-
-	wl1271_notice("performing tx calibration");
-
-	ret = wl1271_cmd_cal_channel_tune(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl1271_cmd_cal_update_ref_point(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl1271_cmd_cal_p2g(wl);
-	if (ret < 0)
-		return ret;
-
-	return ret;
-}
-
 int wl1271_cmd_general_parms(struct wl1271 *wl)
 {
 	struct wl1271_general_parms_cmd *gen_parms;
@@ -295,20 +201,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
 
 int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
 {
-	static bool do_cal = true;
 	struct wl1271_cmd_join *join;
 	int ret, i;
 	u8 *bssid;
 
-	/* FIXME: remove when we get calibration from the factory */
-	if (do_cal) {
-		ret = wl1271_cmd_cal(wl);
-		if (ret < 0)
-			wl1271_warning("couldn't calibrate");
-		else
-			do_cal = false;
-	}
-
 	join = kzalloc(sizeof(*join), GFP_KERNEL);
 	if (!join) {
 		ret = -ENOMEM;
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 00/13] wl1271: sending all patches from our internal tree
From: Luciano Coelho @ 2010-07-08 14:49 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

Hi John,

We have accumulted a few more patches in our internal tree again.  Sorry for
that.

These patches contain several improvements and a lot of bug fixes and
stabilization.

Please apply.

Cheers,
Luca.


Juuso Oikarinen (9):
  wl1271: Remove calibration from join command
  wl1271: Add TSF handling
  wl1271: Use the ARP configuration function from mac80211
  wl1271: Use all basic rates for ps-poll, instead of just the slowest
  wl1271: Work around AP's with broken ps-poll functionality
  wl1271: Update hardware ARP filtering configuration handling
  wl1271: Disable dynamic PS based on BT co-ext sense events
  wl1271: Fix warning when disconnecting and ad-hoc network
  wl1271: Update interface to temporarily disable dynamic PS

Luciano Coelho (4):
  wl1271: read fem manufacturer value from nvs
  wl1271: moved scan operations to a separate file
  wl1271: rewritten scanning code
  wl1271: use per-channel max tx power passed by mac80211 when scanning

 drivers/net/wireless/wl12xx/Makefile       |    2 +-
 drivers/net/wireless/wl12xx/wl1271.h       |   24 ++--
 drivers/net/wireless/wl12xx/wl1271_acx.c   |   41 ++++--
 drivers/net/wireless/wl12xx/wl1271_acx.h   |   15 ++-
 drivers/net/wireless/wl12xx/wl1271_boot.c  |    4 +-
 drivers/net/wireless/wl12xx/wl1271_cmd.c   |  248 +--------------------------
 drivers/net/wireless/wl12xx/wl1271_cmd.h   |   68 --------
 drivers/net/wireless/wl12xx/wl1271_conf.h  |   16 +-
 drivers/net/wireless/wl12xx/wl1271_event.c |   99 ++++++++---
 drivers/net/wireless/wl12xx/wl1271_event.h |    1 +
 drivers/net/wireless/wl12xx/wl1271_main.c  |  174 ++++++++-----------
 drivers/net/wireless/wl12xx/wl1271_rx.c    |    6 -
 drivers/net/wireless/wl12xx/wl1271_scan.c  |  257 ++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1271_scan.h  |  109 ++++++++++++
 14 files changed, 577 insertions(+), 487 deletions(-)
 create mode 100644 drivers/net/wireless/wl12xx/wl1271_scan.c
 create mode 100644 drivers/net/wireless/wl12xx/wl1271_scan.h


^ permalink raw reply

* [PATCH 05/13] wl1271: Work around AP's with broken ps-poll functionality
From: Luciano Coelho @ 2010-07-08 14:50 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1278600608-22411-1-git-send-email-luciano.coelho@nokia.com>

From: Juuso Oikarinen <juuso.oikarinen@nokia.com>

Some AP's (such as Zyxel Prestige 600) have totally broken ps-poll
functionality. When powersave is enabled, these AP's will set the TIM bit for
a STA in beacons, but when the STA responds with a ps-poll, the AP does not
respond with data.

The wl1271 firmware is able to send an indication to the host, when this
problem occurs. This patch adds implementation, which temporarily disables
power-save in response to this indication, allowing the AP to transmit whatever
data it has buffered for the STA / whatever data is inbound at that time.

This patch does not make these AP's work reliably in PSM, but improves the
chances of inbound data getting through.

The side effect of this patch is increased power consumption when using a
faulty AP.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1271.h       |    5 ++
 drivers/net/wireless/wl12xx/wl1271_boot.c  |    3 +-
 drivers/net/wireless/wl12xx/wl1271_conf.h  |    7 +++
 drivers/net/wireless/wl12xx/wl1271_event.c |   60 ++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1271_event.h |    1 +
 drivers/net/wireless/wl12xx/wl1271_main.c  |   14 ++++++-
 6 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 1b52ce6..cfdccdb 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -351,6 +351,7 @@ struct wl1271 {
 #define WL1271_FLAG_IRQ_RUNNING       (10)
 #define WL1271_FLAG_IDLE              (11)
 #define WL1271_FLAG_IDLE_REQUESTED    (12)
+#define WL1271_FLAG_PSPOLL_FAILURE    (13)
 	unsigned long flags;
 
 	struct wl1271_partition_set part;
@@ -445,6 +446,10 @@ struct wl1271 {
 
 	struct completion *elp_compl;
 	struct delayed_work elp_work;
+	struct delayed_work pspoll_work;
+
+	/* counter for ps-poll delivery failures */
+	int ps_poll_failures;
 
 	/* retry counter for PSM entries */
 	u8 psm_entry_retry;
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index 1a36d8a..f44ccaf 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -414,7 +414,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
 		PS_REPORT_EVENT_ID |
 		JOIN_EVENT_COMPLETE_ID |
 		DISCONNECT_EVENT_COMPLETE_ID |
-		RSSI_SNR_TRIGGER_0_EVENT_ID;
+		RSSI_SNR_TRIGGER_0_EVENT_ID |
+		PSPOLL_DELIVERY_FAILURE_EVENT_ID;
 
 	ret = wl1271_event_unmask(wl);
 	if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index d046d04..84b0de7 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -874,6 +874,13 @@ struct conf_conn_settings {
 	u8 ps_poll_threshold;
 
 	/*
+	 * PS Poll failure recovery ACTIVE period length
+	 *
+	 * Range: u32 (ms)
+	 */
+	u32 ps_poll_recovery_period;
+
+	/*
 	 * Configuration of signal average weights.
 	 */
 	struct conf_sig_weights sig_weights;
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index ca52cde..15f6b86 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -28,6 +28,63 @@
 #include "wl1271_ps.h"
 #include "wl12xx_80211.h"
 
+void wl1271_pspoll_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct wl1271 *wl;
+
+	dwork = container_of(work, struct delayed_work, work);
+	wl = container_of(dwork, struct wl1271, pspoll_work);
+
+	wl1271_debug(DEBUG_EVENT, "pspoll work");
+
+	mutex_lock(&wl->mutex);
+
+	if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags))
+		goto out;
+
+	if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
+		goto out;
+
+	/*
+	 * if we end up here, then we were in powersave when the pspoll
+	 * delivery failure occurred, and no-one changed state since, so
+	 * we should go back to powersave.
+	 */
+	wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true);
+
+out:
+	mutex_unlock(&wl->mutex);
+};
+
+static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl)
+{
+	int delay = wl->conf.conn.ps_poll_recovery_period;
+	int ret;
+
+	wl->ps_poll_failures++;
+	if (wl->ps_poll_failures == 1)
+		wl1271_info("AP with dysfunctional ps-poll, "
+			    "trying to work around it.");
+
+	/* force active mode receive data from the AP */
+	if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
+		ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true);
+		if (ret < 0)
+			return;
+		set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags);
+		ieee80211_queue_delayed_work(wl->hw, &wl->pspoll_work,
+					     msecs_to_jiffies(delay));
+	}
+
+	/*
+	 * If already in active mode, lets we should be getting data from
+	 * the AP right away. If we enter PSM too fast after this, and data
+	 * remains on the AP, we will get another event like this, and we'll
+	 * go into active once more.
+	 */
+}
+
 static int wl1271_event_scan_complete(struct wl1271 *wl,
 				      struct event_mailbox *mbox)
 {
@@ -191,6 +248,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
 			return ret;
 	}
 
+	if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID)
+		wl1271_event_pspoll_delivery_fail(wl);
+
 	if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
 		wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
 		if (wl->vif)
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
index 5837100..9fb5a94 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.h
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -121,5 +121,6 @@ struct event_mailbox {
 int wl1271_event_unmask(struct wl1271 *wl);
 void wl1271_event_mbox_config(struct wl1271 *wl);
 int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
+void wl1271_pspoll_work(struct work_struct *work);
 
 #endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index a37244c..8a4b17f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -233,7 +233,8 @@ static struct conf_drv_settings default_conf = {
 		.beacon_rx_timeout           = 10000,
 		.broadcast_timeout           = 20000,
 		.rx_broadcast_in_ps          = 1,
-		.ps_poll_threshold           = 20,
+		.ps_poll_threshold           = 10,
+		.ps_poll_recovery_period     = 700,
 		.bet_enable                  = CONF_BET_MODE_ENABLE,
 		.bet_max_consecutive         = 10,
 		.psm_entry_retries           = 3,
@@ -955,6 +956,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
 
 	cancel_work_sync(&wl->irq_work);
 	cancel_work_sync(&wl->tx_work);
+	cancel_delayed_work_sync(&wl->pspoll_work);
 
 	mutex_lock(&wl->mutex);
 
@@ -1260,6 +1262,13 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
 			wl1271_warning("idle mode change failed %d", ret);
 	}
 
+	/*
+	 * if mac80211 changes the PSM mode, make sure the mode is not
+	 * incorrectly changed after the pspoll failure active window.
+	 */
+	if (changed & IEEE80211_CONF_CHANGE_PS)
+		clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags);
+
 	if (conf->flags & IEEE80211_CONF_PS &&
 	    !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {
 		set_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);
@@ -1766,6 +1775,8 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 			wl->aid = bss_conf->aid;
 			set_assoc = true;
 
+			wl->ps_poll_failures = 0;
+
 			/*
 			 * use basic rates from AP, and determine lowest rate
 			 * to use with control frames.
@@ -2390,6 +2401,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
 	skb_queue_head_init(&wl->tx_queue);
 
 	INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
+	INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
 	wl->channel = WL1271_DEFAULT_CHANNEL;
 	wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
 	wl->default_key = 0;
-- 
1.6.3.3


^ permalink raw reply related

* [PATCH 10/13] wl1271: Update interface to temporarily disable dynamic PS
From: Luciano Coelho @ 2010-07-08 14:50 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Juuso Oikarinen
In-Reply-To: <1278600608-22411-1-git-send-email-luciano.coelho@nokia.com>

From: Juuso Oikarinen <juuso.oikarinen@nokia.com>

The mac80211 interface to temporarily disable dynamic PS changed, make
corresponding changes to the driver.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Saravanan Dhanabal <ext-saravanan.dhanabal@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1271_event.c |    4 ++--
 drivers/net/wireless/wl12xx/wl1271_main.c  |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 525ba1a..2d60d22 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -229,9 +229,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
 	if (vector & SOFT_GEMINI_SENSE_EVENT_ID &&
 	    wl->bss_type == BSS_TYPE_STA_BSS) {
 		if (mbox->soft_gemini_sense_info)
-			ieee80211_disable_dyn_ps(wl->vif, true);
+			ieee80211_disable_dyn_ps(wl->vif);
 		else
-			ieee80211_disable_dyn_ps(wl->vif, false);
+			ieee80211_enable_dyn_ps(wl->vif);
 	}
 
 	/*
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index d50c0a9..70c6b0d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -939,7 +939,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
 
 	/* enable dyn ps just in case (if left on due to fw crash etc) */
 	if (wl->bss_type == BSS_TYPE_STA_BSS)
-		ieee80211_disable_dyn_ps(wl->vif, false);
+		ieee80211_enable_dyn_ps(wl->vif);
 
 	if (test_and_clear_bit(WL1271_FLAG_SCANNING, &wl->flags)) {
 		mutex_unlock(&wl->mutex);
@@ -1779,7 +1779,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 			wl->aid = 0;
 
 			/* re-enable dynamic ps - just in case */
-			ieee80211_disable_dyn_ps(wl->vif, false);
+			ieee80211_enable_dyn_ps(wl->vif);
 
 			/* revert back to minimum rates for the current band */
 			wl1271_set_band_rate(wl);
-- 
1.6.3.3


^ 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