* [PATCH 1/2] ath9k: change beacon allocation to prefer the first beacon slot
From: Felix Fietkau @ 2010-05-13 18:37 UTC (permalink / raw)
To: linux-wireless; +Cc: lrodriguez, linville
This fixes IBSS beacon transmissions without VEOL enabled
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/beacon.c | 12 +++---------
1 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index c8a4558..77face7 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -274,17 +274,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
avp->av_bslot = 0;
for (slot = 0; slot < ATH_BCBUF; slot++)
if (sc->beacon.bslot[slot] == NULL) {
- /*
- * XXX hack, space out slots to better
- * deal with misses
- */
- if (slot+1 < ATH_BCBUF &&
- sc->beacon.bslot[slot+1] == NULL) {
- avp->av_bslot = slot+1;
- break;
- }
avp->av_bslot = slot;
+
/* NB: keep looking for a double slot */
+ if (slot == 0 || !sc->beacon.bslot[slot-1])
+ break;
}
BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
sc->beacon.bslot[avp->av_bslot] = vif;
--
1.6.4.2
^ permalink raw reply related
* [PATCH 2/2] ath9k: remove VEOL support for ad-hoc
From: Felix Fietkau @ 2010-05-13 18:37 UTC (permalink / raw)
To: linux-wireless; +Cc: lrodriguez, linville
In-Reply-To: <1273775845-10056-1-git-send-email-nbd@openwrt.org>
With VEOL, Beacon transmission in ad-hoc does not currently work.
I believe for larger ad-hoc networks, VEOL is too unreliable, as
it can get beacon transmissions stuck during synchronization.
Use SWBA based beacon trasmission similar to AP mode instead.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
drivers/net/wireless/ath/ath9k/beacon.c | 63 +++++--------------------------
1 files changed, 10 insertions(+), 53 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 77face7..f43d85a 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -76,22 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
ds = bf->bf_desc;
flags = ATH9K_TXDESC_NOACK;
- if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
- (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
- (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
- ds->ds_link = bf->bf_daddr; /* self-linked */
- flags |= ATH9K_TXDESC_VEOL;
- /* Let hardware handle antenna switching. */
- antenna = 0;
- } else {
- ds->ds_link = 0;
- /*
- * Switch antenna every beacon.
- * Should only switch every beacon period, not for every SWBA
- * XXX assumes two antennae
- */
- antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
- }
+ ds->ds_link = 0;
+ /*
+ * Switch antenna every beacon.
+ * Should only switch every beacon period, not for every SWBA
+ * XXX assumes two antennae
+ */
+ antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
sband = &sc->sbands[common->hw->conf.channel->band];
rate = sband->bitrates[rateidx].hw_value;
@@ -215,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
return bf;
}
-/*
- * Startup beacon transmission for adhoc mode when they are sent entirely
- * by the hardware using the self-linked descriptor + veol trick.
-*/
-static void ath_beacon_start_adhoc(struct ath_softc *sc,
- struct ieee80211_vif *vif)
-{
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath_buf *bf;
- struct ath_vif *avp;
- struct sk_buff *skb;
-
- avp = (void *)vif->drv_priv;
-
- if (avp->av_bcbuf == NULL)
- return;
-
- bf = avp->av_bcbuf;
- skb = bf->bf_mpdu;
-
- ath_beacon_setup(sc, avp, bf, 0);
-
- /* NB: caller is known to have already stopped tx dma */
- ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
- ath9k_hw_txstart(ah, sc->beacon.beaconq);
- ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
- sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
-}
-
int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
{
struct ath_softc *sc = aphy->sc;
@@ -265,7 +226,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
list_del(&avp->av_bcbuf->list);
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
- !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+ sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC ||
+ sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
int slot;
/*
* Assign the vif to a beacon xmit slot. As
@@ -715,8 +677,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
* self-linked tx descriptor and let the hardware deal with things.
*/
intval |= ATH9K_BEACON_ENA;
- if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
- ah->imask |= ATH9K_INT_SWBA;
+ ah->imask |= ATH9K_INT_SWBA;
ath_beaconq_config(sc);
@@ -726,10 +687,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
ath9k_beacon_init(sc, nexttbtt, intval);
sc->beacon.bmisscnt = 0;
ath9k_hw_set_interrupts(ah, ah->imask);
-
- /* FIXME: Handle properly when vif is NULL */
- if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
- ath_beacon_start_adhoc(sc, vif);
}
void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
--
1.6.4.2
^ permalink raw reply related
* [PATCH 2/4] rt2x00: Fix rt2800usb TX descriptor writing.
From: Gertjan van Wingerde @ 2010-05-13 19:16 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273778166-3833-1-git-send-email-gwingerde@gmail.com>
The recent changes to skb handling introduced a bug in the rt2800usb
TX descriptor writing whereby the length of the USB packet wasn't
calculated correctly.
Found via code inspection, as the devices themselves didn't seem to mind.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800usb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 33d7ac9..eaf0a7e 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -414,7 +414,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
*/
rt2x00_desc_read(txi, 0, &word);
rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
- skb->len + TXWI_DESC_SIZE);
+ skb->len - TXINFO_DESC_SIZE);
rt2x00_set_field32(&word, TXINFO_W0_WIV,
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
--
1.7.1
^ permalink raw reply related
* [PATCH 1/4] rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions.
From: Gertjan van Wingerde @ 2010-05-13 19:16 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273778166-3833-1-git-send-email-gwingerde@gmail.com>
(Based on a patch created by Ondrej Zary)
In some circumstances the Ralink devices do not properly go to sleep
or wake up, with timeouts occurring.
Fix this by retrying telling the device that it has to wake up or
sleep.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 9 +++++----
drivers/net/wireless/rt2x00/rt2500pci.c | 9 +++++----
drivers/net/wireless/rt2x00/rt61pci.c | 7 ++++---
drivers/net/wireless/rt2x00/rt73usb.c | 7 ++++---
4 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 641459b..7b36db2 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -925,7 +925,7 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
- u32 reg;
+ u32 reg, reg2;
unsigned int i;
char put_to_sleep;
char bbp_state;
@@ -946,11 +946,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
* device has entered the correct state.
*/
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®);
- bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE);
- rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE);
+ rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2);
+ bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
+ rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
if (bbp_state == state && rf_state == state)
return 0;
+ rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
msleep(10);
}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c8363bc..4a29ede 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1083,7 +1083,7 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
enum dev_state state)
{
- u32 reg;
+ u32 reg, reg2;
unsigned int i;
char put_to_sleep;
char bbp_state;
@@ -1104,11 +1104,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
* device has entered the correct state.
*/
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®);
- bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE);
- rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE);
+ rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2);
+ bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
+ rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
if (bbp_state == state && rf_state == state)
return 0;
+ rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
msleep(10);
}
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 9ac2f5c..a03b6a2 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1688,7 +1688,7 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
{
- u32 reg;
+ u32 reg, reg2;
unsigned int i;
char put_to_sleep;
@@ -1705,10 +1705,11 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
* device has entered the correct state.
*/
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®);
- state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®2);
+ state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE);
if (state == !put_to_sleep)
return 0;
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg);
msleep(10);
}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index a9738ee..dc4a028 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1365,7 +1365,7 @@ static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
{
- u32 reg;
+ u32 reg, reg2;
unsigned int i;
char put_to_sleep;
@@ -1382,10 +1382,11 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
* device has entered the correct state.
*/
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00usb_register_read(rt2x00dev, MAC_CSR12, ®);
- state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR12, ®2);
+ state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE);
if (state == !put_to_sleep)
return 0;
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR12, reg);
msleep(10);
}
--
1.7.1
^ permalink raw reply related
* [PATCH 0/4] Final set of fixes and cleanups for 2.6.35.
From: Gertjan van Wingerde @ 2010-05-13 19:16 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
These are the final set of fixes and cleanups for 2.6.35 from my side.
The first one is a powersave fixlet that was off my radar for a while but
got dusted off. One is a fix of a bug introduced in a previous patch series
and the final two are clean-ups that make it easier to use rt2x00usb
functionality.
This is on top of the last patch series I sent out.
These patches (and the ones of the previous series) can also be pulled from:
git://git.gwingerde.nl/rt2x00-next-2.6.git
Gertjan van Wingerde (4):
rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions.
rt2x00: Fix rt2800usb TX descriptor writing.
rt2x00: Clean up USB vendor request buffer functions.
rt2x00: Centralize rt2800 beacon writing.
drivers/net/wireless/rt2x00/rt2400pci.c | 9 ++--
drivers/net/wireless/rt2x00/rt2500pci.c | 9 ++--
drivers/net/wireless/rt2x00/rt2500usb.c | 14 +-----
drivers/net/wireless/rt2x00/rt2800lib.c | 61 +++++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2800lib.h | 2 +
drivers/net/wireless/rt2x00/rt2800pci.c | 63 +--------------------------
drivers/net/wireless/rt2x00/rt2800usb.c | 74 ++-----------------------------
drivers/net/wireless/rt2x00/rt2x00usb.c | 22 +---------
drivers/net/wireless/rt2x00/rt2x00usb.h | 19 --------
drivers/net/wireless/rt2x00/rt61pci.c | 7 ++-
drivers/net/wireless/rt2x00/rt73usb.c | 39 +++++------------
11 files changed, 96 insertions(+), 223 deletions(-)
^ permalink raw reply
* [PATCH 4/4] rt2x00: Centralize rt2800 beacon writing.
From: Gertjan van Wingerde @ 2010-05-13 19:16 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273778166-3833-1-git-send-email-gwingerde@gmail.com>
The beacon writing functions of rt2800pci and rt2800usb are now identical.
Move them to rt2800lib to only have one central function.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 61 ++++++++++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2800lib.h | 2 +
drivers/net/wireless/rt2x00/rt2800pci.c | 63 +------------------------------
drivers/net/wireless/rt2x00/rt2800usb.c | 63 +------------------------------
4 files changed, 65 insertions(+), 124 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 53a3257..9ee4ffa 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -378,6 +378,67 @@ void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc)
}
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
+void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ unsigned int beacon_base;
+ u32 reg;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
+ rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+ /*
+ * Add space for the TXWI in front of the skb.
+ */
+ skb_push(entry->skb, TXWI_DESC_SIZE);
+ memset(entry->skb, 0, TXWI_DESC_SIZE);
+
+ /*
+ * Register descriptor details in skb frame descriptor.
+ */
+ skbdesc->flags |= SKBDESC_DESC_IN_SKB;
+ skbdesc->desc = entry->skb->data;
+ skbdesc->desc_len = TXWI_DESC_SIZE;
+
+ /*
+ * Add the TXWI for the beacon to the skb.
+ */
+ rt2800_write_txwi((__le32 *)entry->skb->data, txdesc);
+
+ /*
+ * Dump beacon to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
+
+ /*
+ * Write entire beacon with TXWI to register.
+ */
+ beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+ rt2800_register_multiwrite(rt2x00dev, beacon_base,
+ entry->skb->data, entry->skb->len);
+
+ /*
+ * Enable beaconing again.
+ */
+ rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1);
+ rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1);
+ rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
+ rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+ /*
+ * Clean up beacon skb.
+ */
+ dev_kfree_skb_any(entry->skb);
+ entry->skb = NULL;
+}
+EXPORT_SYMBOL(rt2800_write_beacon);
+
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
const struct rt2x00debug rt2800_rt2x00debug = {
.owner = THIS_MODULE,
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 0f0a13c..b16fd6d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -114,6 +114,8 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc);
void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc);
+void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
+
extern const struct rt2x00debug rt2800_rt2x00debug;
int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index db61a78..f271836 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -676,67 +676,6 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* TX data initialization
*/
-static void rt2800pci_write_beacon(struct queue_entry *entry,
- struct txentry_desc *txdesc)
-{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
- unsigned int beacon_base;
- u32 reg;
-
- /*
- * Disable beaconing while we are reloading the beacon data,
- * otherwise we might be sending out invalid data.
- */
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
- rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-
- /*
- * Add space for the TXWI in front of the skb.
- */
- skb_push(entry->skb, TXWI_DESC_SIZE);
- memset(entry->skb, 0, TXWI_DESC_SIZE);
-
- /*
- * Register descriptor details in skb frame descriptor.
- */
- skbdesc->flags |= SKBDESC_DESC_IN_SKB;
- skbdesc->desc = entry->skb->data;
- skbdesc->desc_len = TXWI_DESC_SIZE;
-
- /*
- * Add the TXWI for the beacon to the skb.
- */
- rt2800_write_txwi((__le32 *)entry->skb->data, txdesc);
-
- /*
- * Dump beacon to userspace through debugfs.
- */
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
-
- /*
- * Write entire beacon with TXWI to register.
- */
- beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
- rt2800_register_multiwrite(rt2x00dev, beacon_base,
- entry->skb->data, entry->skb->len);
-
- /*
- * Enable beaconing again.
- */
- rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1);
- rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1);
- rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-
- /*
- * Clean up beacon skb.
- */
- dev_kfree_skb_any(entry->skb);
- entry->skb = NULL;
-}
-
static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue_idx)
{
@@ -1074,7 +1013,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
.write_tx_desc = rt2800pci_write_tx_desc,
.write_tx_data = rt2x00pci_write_tx_data,
.write_tx_datadesc = rt2800pci_write_tx_datadesc,
- .write_beacon = rt2800pci_write_beacon,
+ .write_beacon = rt2800_write_beacon,
.kick_tx_queue = rt2800pci_kick_tx_queue,
.kill_tx_queue = rt2800pci_kill_tx_queue,
.fill_rxdone = rt2800pci_fill_rxdone,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 0f0a4f5..8a15ffb 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -432,67 +432,6 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* TX data initialization
*/
-static void rt2800usb_write_beacon(struct queue_entry *entry,
- struct txentry_desc *txdesc)
-{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
- unsigned int beacon_base;
- u32 reg;
-
- /*
- * Disable beaconing while we are reloading the beacon data,
- * otherwise we might be sending out invalid data.
- */
- rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®);
- rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-
- /*
- * Add space for the TXWI in front of the skb.
- */
- skb_push(entry->skb, TXWI_DESC_SIZE);
- memset(entry->skb, 0, TXWI_DESC_SIZE);
-
- /*
- * Register descriptor details in skb frame descriptor.
- */
- skbdesc->flags |= SKBDESC_DESC_IN_SKB;
- skbdesc->desc = entry->skb->data;
- skbdesc->desc_len = TXWI_DESC_SIZE;
-
- /*
- * Add the TXWI for the beacon to the skb.
- */
- rt2800_write_txwi((__le32 *) entry->skb->data, txdesc);
-
- /*
- * Dump beacon to userspace through debugfs.
- */
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
-
- /*
- * Write entire beacon with descriptor to register.
- */
- beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
- rt2800_register_multiwrite(rt2x00dev, beacon_base,
- entry->skb->data, entry->skb->len);
-
- /*
- * Enable beaconing again.
- */
- rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1);
- rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1);
- rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1);
- rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-
- /*
- * Clean up the beacon skb.
- */
- dev_kfree_skb(entry->skb);
- entry->skb = NULL;
-}
-
static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
{
int length;
@@ -674,7 +613,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
.link_tuner = rt2800_link_tuner,
.write_tx_desc = rt2800usb_write_tx_desc,
.write_tx_data = rt2x00usb_write_tx_data,
- .write_beacon = rt2800usb_write_beacon,
+ .write_beacon = rt2800_write_beacon,
.get_tx_data_len = rt2800usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,
.kill_tx_queue = rt2x00usb_kill_tx_queue,
--
1.7.1
^ permalink raw reply related
* [PATCH 3/4] rt2x00: Clean up USB vendor request buffer functions.
From: Gertjan van Wingerde @ 2010-05-13 19:16 UTC (permalink / raw)
To: John W. Linville
Cc: Ivo van Doorn, linux-wireless, users, Gertjan van Wingerde
In-Reply-To: <1273778166-3833-1-git-send-email-gwingerde@gmail.com>
There is no need to force the separation between a buffer USB vendor
request that does fit the CSR cache and one that doesn't onto the
callers. This is something that the rt2x00usb_vendor_request_buff
function can figure out by itself.
Combine the rt2x00usb_vendor_request_buff and
rt2x00usb_vendor_request_large_buff functions into a single one, as
both of them were equivalent for small buffers anyway.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
---
drivers/net/wireless/rt2x00/rt2500usb.c | 14 +-----------
drivers/net/wireless/rt2x00/rt2800usb.c | 13 +++--------
drivers/net/wireless/rt2x00/rt2x00usb.c | 22 +--------------------
drivers/net/wireless/rt2x00/rt2x00usb.h | 19 ------------------
drivers/net/wireless/rt2x00/rt73usb.c | 32 ++++++------------------------
5 files changed, 14 insertions(+), 86 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index eb99934..a1af5b8 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -344,7 +344,6 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_crypto *crypto,
struct ieee80211_key_conf *key)
{
- int timeout;
u32 mask;
u16 reg;
@@ -366,18 +365,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
key->hw_key_idx += reg ? ffz(reg) : 0;
- /*
- * The encryption key doesn't fit within the CSR cache,
- * this means we should allocate it seperately and use
- * rt2x00usb_vendor_request() to send the key to the hardware.
- */
reg = KEY_ENTRY(key->hw_key_idx);
- timeout = REGISTER_TIMEOUT32(sizeof(crypto->key));
- rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT, reg,
- crypto->key,
- sizeof(crypto->key),
- timeout);
+ rt2500usb_register_multiwrite(rt2x00dev, reg,
+ crypto->key, sizeof(crypto->key));
/*
* The driver does not support the IV/EIV generation
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index eaf0a7e..0f0a4f5 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -169,11 +169,8 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
/*
* Write firmware to device.
*/
- rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT,
- FIRMWARE_IMAGE_BASE,
- data + offset, length,
- REGISTER_TIMEOUT32(length));
+ rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+ data + offset, length);
rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
@@ -478,10 +475,8 @@ static void rt2800usb_write_beacon(struct queue_entry *entry,
* Write entire beacon with descriptor to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
- rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT, beacon_base,
- entry->skb->data, entry->skb->len,
- REGISTER_TIMEOUT32(entry->skb->len));
+ rt2800_register_multiwrite(rt2x00dev, beacon_base,
+ entry->skb->data, entry->skb->len);
/*
* Enable beaconing again.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 1f72c59..1cae159 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -112,26 +112,6 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
const u16 offset, void *buffer,
const u16 buffer_length, const int timeout)
{
- int status;
-
- mutex_lock(&rt2x00dev->csr_mutex);
-
- status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
- requesttype, offset, buffer,
- buffer_length, timeout);
-
- mutex_unlock(&rt2x00dev->csr_mutex);
-
- return status;
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
-
-int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
- const u8 request, const u8 requesttype,
- const u16 offset, const void *buffer,
- const u16 buffer_length,
- const int timeout)
-{
int status = 0;
unsigned char *tb;
u16 off, len, bsize;
@@ -156,7 +136,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
return status;
}
-EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff);
+EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 621d0f8..255b81e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -167,25 +167,6 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
const u16 buffer_length, const int timeout);
/**
- * rt2x00usb_vendor_request_large_buff - Send register command to device (buffered)
- * @rt2x00dev: Pointer to &struct rt2x00_dev
- * @request: USB vendor command (See &enum rt2x00usb_vendor_request)
- * @requesttype: Request type &USB_VENDOR_REQUEST_*
- * @offset: Register start offset to perform action on
- * @buffer: Buffer where information will be read/written to by device
- * @buffer_length: Size of &buffer
- * @timeout: Operation timeout
- *
- * This function is used to transfer register data in blocks larger
- * then CSR_CACHE_SIZE. Use for firmware upload, keys and beacons.
- */
-int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
- const u8 request, const u8 requesttype,
- const u16 offset, const void *buffer,
- const u16 buffer_length,
- const int timeout);
-
-/**
* rt2x00usb_vendor_request_sw - Send single register command to device
* @rt2x00dev: Pointer to &struct rt2x00_dev
* @request: USB vendor command (See &enum rt2x00usb_vendor_request)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index dc4a028..2f7e0ce 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -269,7 +269,6 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
{
struct hw_key_entry key_entry;
struct rt2x00_field32 field;
- int timeout;
u32 mask;
u32 reg;
@@ -305,12 +304,8 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
sizeof(key_entry.rx_mic));
reg = SHARED_KEY_ENTRY(key->hw_key_idx);
- timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
- rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT, reg,
- &key_entry,
- sizeof(key_entry),
- timeout);
+ rt2x00usb_register_multiwrite(rt2x00dev, reg,
+ &key_entry, sizeof(key_entry));
/*
* The cipher types are stored over 2 registers.
@@ -371,7 +366,6 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
{
struct hw_pairwise_ta_entry addr_entry;
struct hw_key_entry key_entry;
- int timeout;
u32 mask;
u32 reg;
@@ -406,17 +400,11 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
sizeof(key_entry.rx_mic));
reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
- timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
- rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT, reg,
- &key_entry,
- sizeof(key_entry),
- timeout);
+ rt2x00usb_register_multiwrite(rt2x00dev, reg,
+ &key_entry, sizeof(key_entry));
/*
* Send the address and cipher type to the hardware register.
- * This data fits within the CSR cache size, so we can use
- * rt2x00usb_register_multiwrite() directly.
*/
memset(&addr_entry, 0, sizeof(addr_entry));
memcpy(&addr_entry, crypto->address, ETH_ALEN);
@@ -1091,11 +1079,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,
/*
* Write firmware to device.
*/
- rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT,
- FIRMWARE_IMAGE_BASE,
- data, len,
- REGISTER_TIMEOUT32(len));
+ rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, data, len);
/*
* Send firmware request to device to load firmware,
@@ -1547,10 +1531,8 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
* Write entire beacon with descriptor to register.
*/
beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
- rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT, beacon_base,
- entry->skb->data, entry->skb->len,
- REGISTER_TIMEOUT32(entry->skb->len));
+ rt2x00usb_register_multiwrite(rt2x00dev, beacon_base,
+ entry->skb->data, entry->skb->len);
/*
* Enable beaconing again.
--
1.7.1
^ permalink raw reply related
* Re: [PATCH 1/4] rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions.
From: Ivo Van Doorn @ 2010-05-13 19:30 UTC (permalink / raw)
To: Gertjan van Wingerde; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <1273778166-3833-2-git-send-email-gwingerde@gmail.com>
On Thu, May 13, 2010 at 9:16 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> (Based on a patch created by Ondrej Zary)
>
> In some circumstances the Ralink devices do not properly go to sleep
> or wake up, with timeouts occurring.
> Fix this by retrying telling the device that it has to wake up or
> sleep.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Nice catch, I think the legacy drivers also did this, but not too sure
about that.
Does this mean we can reenable the flag to enable powersaving by default?
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
> ---
> drivers/net/wireless/rt2x00/rt2400pci.c | 9 +++++----
> drivers/net/wireless/rt2x00/rt2500pci.c | 9 +++++----
> drivers/net/wireless/rt2x00/rt61pci.c | 7 ++++---
> drivers/net/wireless/rt2x00/rt73usb.c | 7 ++++---
> 4 files changed, 18 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
> index 641459b..7b36db2 100644
> --- a/drivers/net/wireless/rt2x00/rt2400pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2400pci.c
> @@ -925,7 +925,7 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
> static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
> enum dev_state state)
> {
> - u32 reg;
> + u32 reg, reg2;
> unsigned int i;
> char put_to_sleep;
> char bbp_state;
> @@ -946,11 +946,12 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
> * device has entered the correct state.
> */
> for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
> - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®);
> - bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE);
> - rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE);
> + rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2);
> + bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
> + rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
> if (bbp_state == state && rf_state == state)
> return 0;
> + rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
> msleep(10);
> }
>
> diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
> index c8363bc..4a29ede 100644
> --- a/drivers/net/wireless/rt2x00/rt2500pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2500pci.c
> @@ -1083,7 +1083,7 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
> static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
> enum dev_state state)
> {
> - u32 reg;
> + u32 reg, reg2;
> unsigned int i;
> char put_to_sleep;
> char bbp_state;
> @@ -1104,11 +1104,12 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
> * device has entered the correct state.
> */
> for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
> - rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®);
> - bbp_state = rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE);
> - rf_state = rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE);
> + rt2x00pci_register_read(rt2x00dev, PWRCSR1, ®2);
> + bbp_state = rt2x00_get_field32(reg2, PWRCSR1_BBP_CURR_STATE);
> + rf_state = rt2x00_get_field32(reg2, PWRCSR1_RF_CURR_STATE);
> if (bbp_state == state && rf_state == state)
> return 0;
> + rt2x00pci_register_write(rt2x00dev, PWRCSR1, reg);
> msleep(10);
> }
>
> diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
> index 9ac2f5c..a03b6a2 100644
> --- a/drivers/net/wireless/rt2x00/rt61pci.c
> +++ b/drivers/net/wireless/rt2x00/rt61pci.c
> @@ -1688,7 +1688,7 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
>
> static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
> {
> - u32 reg;
> + u32 reg, reg2;
> unsigned int i;
> char put_to_sleep;
>
> @@ -1705,10 +1705,11 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
> * device has entered the correct state.
> */
> for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
> - rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®);
> - state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
> + rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®2);
> + state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE);
> if (state == !put_to_sleep)
> return 0;
> + rt2x00pci_register_write(rt2x00dev, MAC_CSR12, reg);
> msleep(10);
> }
>
> diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
> index a9738ee..dc4a028 100644
> --- a/drivers/net/wireless/rt2x00/rt73usb.c
> +++ b/drivers/net/wireless/rt2x00/rt73usb.c
> @@ -1365,7 +1365,7 @@ static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev)
>
> static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
> {
> - u32 reg;
> + u32 reg, reg2;
> unsigned int i;
> char put_to_sleep;
>
> @@ -1382,10 +1382,11 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
> * device has entered the correct state.
> */
> for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
> - rt2x00usb_register_read(rt2x00dev, MAC_CSR12, ®);
> - state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
> + rt2x00usb_register_read(rt2x00dev, MAC_CSR12, ®2);
> + state = rt2x00_get_field32(reg2, MAC_CSR12_BBP_CURRENT_STATE);
> if (state == !put_to_sleep)
> return 0;
> + rt2x00usb_register_write(rt2x00dev, MAC_CSR12, reg);
> msleep(10);
> }
>
> --
> 1.7.1
>
>
^ permalink raw reply
* Re: [PATCH 2/4] rt2x00: Fix rt2800usb TX descriptor writing.
From: Ivo Van Doorn @ 2010-05-13 19:30 UTC (permalink / raw)
To: Gertjan van Wingerde; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <1273778166-3833-3-git-send-email-gwingerde@gmail.com>
On Thu, May 13, 2010 at 9:16 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> The recent changes to skb handling introduced a bug in the rt2800usb
> TX descriptor writing whereby the length of the USB packet wasn't
> calculated correctly.
> Found via code inspection, as the devices themselves didn't seem to mind.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
^ permalink raw reply
* Re: [PATCH 3/4] rt2x00: Clean up USB vendor request buffer functions.
From: Ivo Van Doorn @ 2010-05-13 19:31 UTC (permalink / raw)
To: Gertjan van Wingerde; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <1273778166-3833-4-git-send-email-gwingerde@gmail.com>
On Thu, May 13, 2010 at 9:16 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> There is no need to force the separation between a buffer USB vendor
> request that does fit the CSR cache and one that doesn't onto the
> callers. This is something that the rt2x00usb_vendor_request_buff
> function can figure out by itself.
> Combine the rt2x00usb_vendor_request_buff and
> rt2x00usb_vendor_request_large_buff functions into a single one, as
> both of them were equivalent for small buffers anyway.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
^ permalink raw reply
* Re: [PATCH 4/4] rt2x00: Centralize rt2800 beacon writing.
From: Ivo Van Doorn @ 2010-05-13 19:32 UTC (permalink / raw)
To: Gertjan van Wingerde; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <1273778166-3833-5-git-send-email-gwingerde@gmail.com>
On Thu, May 13, 2010 at 9:16 PM, Gertjan van Wingerde
<gwingerde@gmail.com> wrote:
> The beacon writing functions of rt2800pci and rt2800usb are now identical.
> Move them to rt2800lib to only have one central function.
>
> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
^ permalink raw reply
* [PATCH 11/20] drivers/net/wireless/orinoco: Use kzalloc
From: Julia Lawall @ 2010-05-13 20:02 UTC (permalink / raw)
To: Pavel Roskin, David Gibson, John W. Linville, linux-wireless,
orinoco-users, orinoco-devel, netdev, linux-kernel,
kernel-janitors
From: Julia Lawall <julia@diku.dk>
Use kzalloc rather than the combination of kmalloc and memset.
The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
expression x,size,flags;
statement S;
@@
-x = kmalloc(size,flags);
+x = kzalloc(size,flags);
if (x == NULL) S
-memset(x, 0, size);
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
---
drivers/net/wireless/orinoco/orinoco_usb.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff -u -p a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -356,12 +356,10 @@ static struct request_context *ezusb_all
{
struct request_context *ctx;
- ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
+ ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
if (!ctx)
return NULL;
- memset(ctx, 0, sizeof(*ctx));
-
ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC);
if (!ctx->buf) {
kfree(ctx);
^ permalink raw reply
* Re: [PATCH 1/4] rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions.
From: Gertjan van Wingerde @ 2010-05-13 20:03 UTC (permalink / raw)
To: Ivo Van Doorn; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <AANLkTilccqteZvPru-_q1tRqcDLpAqE2DjIdMoUC0Ij_@mail.gmail.com>
On 05/13/10 21:30, Ivo Van Doorn wrote:
> On Thu, May 13, 2010 at 9:16 PM, Gertjan van Wingerde
> <gwingerde@gmail.com> wrote:
>> (Based on a patch created by Ondrej Zary)
>>
>> In some circumstances the Ralink devices do not properly go to sleep
>> or wake up, with timeouts occurring.
>> Fix this by retrying telling the device that it has to wake up or
>> sleep.
>>
>> Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
>
> Nice catch, I think the legacy drivers also did this, but not too sure
> about that.
> Does this mean we can reenable the flag to enable powersaving by default?
>
Not sure of that yet. There's one more thing that is on my TODO list on powersaving,
namely to not go to sleep if there are still active entries in the TX queues. This is
also done by the legacy, so we should check for that as well. The only issue is how to
make the device go to sleep once the TX queues are empty, as mac80211 will not inform
us again that we need to sleep.
---
Gertjan.
^ permalink raw reply
* Re: [PATCH 2/2] ath9k: remove VEOL support for ad-hoc
From: Benoit Papillault @ 2010-05-13 21:05 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless, lrodriguez, linville
In-Reply-To: <1273775845-10056-2-git-send-email-nbd@openwrt.org>
Le 13/05/2010 20:37, Felix Fietkau a écrit :
> With VEOL, Beacon transmission in ad-hoc does not currently work.
> I believe for larger ad-hoc networks, VEOL is too unreliable, as
> it can get beacon transmissions stuck during synchronization.
> Use SWBA based beacon trasmission similar to AP mode instead.
>
> Signed-off-by: Felix Fietkau<nbd@openwrt.org>
This is very good step toward IBSS. Thanks Felix!
Acked-by: Benoit Papillault <benoit.papillault@free.fr>
> ---
> drivers/net/wireless/ath/ath9k/beacon.c | 63 +++++--------------------------
> 1 files changed, 10 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
> index 77face7..f43d85a 100644
> --- a/drivers/net/wireless/ath/ath9k/beacon.c
> +++ b/drivers/net/wireless/ath/ath9k/beacon.c
> @@ -76,22 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
> ds = bf->bf_desc;
> flags = ATH9K_TXDESC_NOACK;
>
> - if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
> - (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT))&&
> - (ah->caps.hw_caps& ATH9K_HW_CAP_VEOL)) {
> - ds->ds_link = bf->bf_daddr; /* self-linked */
> - flags |= ATH9K_TXDESC_VEOL;
> - /* Let hardware handle antenna switching. */
> - antenna = 0;
> - } else {
> - ds->ds_link = 0;
> - /*
> - * Switch antenna every beacon.
> - * Should only switch every beacon period, not for every SWBA
> - * XXX assumes two antennae
> - */
> - antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs)& 1 ? 2 : 1);
> - }
> + ds->ds_link = 0;
> + /*
> + * Switch antenna every beacon.
> + * Should only switch every beacon period, not for every SWBA
> + * XXX assumes two antennae
> + */
> + antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs)& 1 ? 2 : 1);
>
> sband =&sc->sbands[common->hw->conf.channel->band];
> rate = sband->bitrates[rateidx].hw_value;
> @@ -215,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
> return bf;
> }
>
> -/*
> - * Startup beacon transmission for adhoc mode when they are sent entirely
> - * by the hardware using the self-linked descriptor + veol trick.
> -*/
> -static void ath_beacon_start_adhoc(struct ath_softc *sc,
> - struct ieee80211_vif *vif)
> -{
> - struct ath_hw *ah = sc->sc_ah;
> - struct ath_common *common = ath9k_hw_common(ah);
> - struct ath_buf *bf;
> - struct ath_vif *avp;
> - struct sk_buff *skb;
> -
> - avp = (void *)vif->drv_priv;
> -
> - if (avp->av_bcbuf == NULL)
> - return;
> -
> - bf = avp->av_bcbuf;
> - skb = bf->bf_mpdu;
> -
> - ath_beacon_setup(sc, avp, bf, 0);
> -
> - /* NB: caller is known to have already stopped tx dma */
> - ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
> - ath9k_hw_txstart(ah, sc->beacon.beaconq);
> - ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
> - sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
> -}
> -
> int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
> {
> struct ath_softc *sc = aphy->sc;
> @@ -265,7 +226,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
> list_del(&avp->av_bcbuf->list);
>
> if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
> - !(sc->sc_ah->caps.hw_caps& ATH9K_HW_CAP_VEOL)) {
> + sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC ||
> + sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
> int slot;
> /*
> * Assign the vif to a beacon xmit slot. As
> @@ -715,8 +677,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
> * self-linked tx descriptor and let the hardware deal with things.
> */
> intval |= ATH9K_BEACON_ENA;
> - if (!(ah->caps.hw_caps& ATH9K_HW_CAP_VEOL))
> - ah->imask |= ATH9K_INT_SWBA;
> + ah->imask |= ATH9K_INT_SWBA;
>
> ath_beaconq_config(sc);
>
> @@ -726,10 +687,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
> ath9k_beacon_init(sc, nexttbtt, intval);
> sc->beacon.bmisscnt = 0;
> ath9k_hw_set_interrupts(ah, ah->imask);
> -
> - /* FIXME: Handle properly when vif is NULL */
> - if (vif&& ah->caps.hw_caps& ATH9K_HW_CAP_VEOL)
> - ath_beacon_start_adhoc(sc, vif);
> }
>
> void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
^ permalink raw reply
* [PATCH 0/2] iwlwifi fixes for 2.6.34
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
We include two late fixes hoping to make it into 2.6.34.
"iwlwifi: fix internal scan race" fixes a kernel crash caused by
accessing a NULL pointer. More can be read in
https://bugzilla.kernel.org/show_bug.cgi?id=15824
"iwlagn: work around rate scaling reset delay" is already in
wireless-next-2.6 but has since been shown to be an issue in 2.6.34 also.
This fixes spurious firmware restarts that has been documented in
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2173 , but it is the
community report tracked in
https://bugzilla.kernel.org/show_bug.cgi?id=15782 that prompted us sending
this fix to wireless-2.6 also.
These patches are also available from wireless-2.6 branch on
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
Reinette Chatre (2):
iwlwifi: fix internal scan race
iwlagn: work around rate scaling reset delay
drivers/net/wireless/iwlwifi/iwl-scan.c | 21 +++++++++++++++--
drivers/net/wireless/iwlwifi/iwl-sta.c | 37 ++++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 4 deletions(-)
^ permalink raw reply
* [PATCH 2/2] iwlagn: work around rate scaling reset delay
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1273787385-9248-1-git-send-email-reinette.chatre@intel.com>
From: Reinette Chatre <reinette.chatre@intel.com>
When station is using an HT channel to communicate to AP and communication
is lost then driver will first be notified that channel is not an HT
channel anymore before AP station is removed. A consequence of that is that
the driver will know that it is not communicating on HT anymore, but the
rate scaling table is still under the impression it is operating in HT. Any
time after driver has been notified channel is not HT anymore there will
thus be a firmware SYSASSERT when the current active LQ command is sent.
A workaround for this issue is to not send a LQ command in the short time between
being notified channel is not HT anymore and rate scaling table being
updated.
This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2173
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-sta.c | 37 +++++++++++++++++++++++++++++++-
1 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 4a6686f..702672d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -948,6 +948,39 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
}
#endif
+/**
+ * is_lq_table_valid() - Test one aspect of LQ cmd for validity
+ *
+ * It sometimes happens when a HT rate has been in use and we
+ * loose connectivity with AP then mac80211 will first tell us that the
+ * current channel is not HT anymore before removing the station. In such a
+ * scenario the RXON flags will be updated to indicate we are not
+ * communicating HT anymore, but the LQ command may still contain HT rates.
+ * Test for this to prevent driver from sending LQ command between the time
+ * RXON flags are updated and when LQ command is updated.
+ */
+static bool is_lq_table_valid(struct iwl_priv *priv,
+ struct iwl_link_quality_cmd *lq)
+{
+ int i;
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+
+ if (ht_conf->is_ht)
+ return true;
+
+ IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
+ priv->active_rxon.channel);
+ for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+ if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
+ IWL_DEBUG_INFO(priv,
+ "index %d of LQ expects HT channel\n",
+ i);
+ return false;
+ }
+ }
+ return true;
+}
+
int iwl_send_lq_cmd(struct iwl_priv *priv,
struct iwl_link_quality_cmd *lq, u8 flags)
{
@@ -967,7 +1000,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
iwl_dump_lq_cmd(priv, lq);
- if (iwl_is_associated(priv) && priv->assoc_station_added)
+ if (iwl_is_associated(priv) &&
+ priv->assoc_station_added &&
+ is_lq_table_valid(priv, lq))
return iwl_send_cmd(priv, &cmd);
return 0;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 1/2] iwlwifi: fix internal scan race
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
In-Reply-To: <1273787385-9248-1-git-send-email-reinette.chatre@intel.com>
From: Reinette Chatre <reinette.chatre@intel.com>
It is possible for internal scan to race against itself if the device is
not returning the scan results from first requests. What happens in this
case is the cleanup done during the abort of the first internal scan also
cleans up part of the new scan, causing it to access memory it shouldn't.
Here are details:
* First internal scan is triggered and scan command sent to device.
* After seven seconds there is no scan results so the watchdog timer
triggers a scan abort.
* The scan abort succeeds and a SCAN_COMPLETE_NOTIFICATION is received for
failed scan.
* During processing of SCAN_COMPLETE_NOTIFICATION we clear STATUS_SCANNING
and queue the "scan_completed" work.
** At this time, since the problem that caused the internal scan in first
place is still present, a new internal scan is triggered.
The behavior at this point is a bit different between 2.6.34 and 2.6.35
since 2.6.35 has a lot of this synchronized. The rest of the race
description will thus be generalized.
** As part of preparing for the scan "is_internal_short_scan" is set to
true.
* At this point the completion work for fist scan is run. As part of this
there is some locking missing around the "is_internal_short_scan"
variable and it is set to "false".
** Now the second scan runs and it considers itself a real (not internal0
scan and thus causes problems with wrong memory being accessed.
The fix is twofold.
* Since "is_internal_short_scan" should be protected by mutex, fix this in
scan completion work so that changes to it can be serialized.
* Do not queue a new internal scan if one is in progress.
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=15824
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-scan.c | 21 ++++++++++++++++++---
1 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 2367286..a2c4855 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -560,6 +560,11 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
mutex_lock(&priv->mutex);
+ if (priv->is_internal_short_scan == true) {
+ IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n");
+ goto unlock;
+ }
+
if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
goto unlock;
@@ -957,17 +962,27 @@ void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
+ bool internal = false;
IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
cancel_delayed_work(&priv->scan_check);
- if (!priv->is_internal_short_scan)
- ieee80211_scan_completed(priv->hw, false);
- else {
+ mutex_lock(&priv->mutex);
+ if (priv->is_internal_short_scan) {
priv->is_internal_short_scan = false;
IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
+ internal = true;
}
+ mutex_unlock(&priv->mutex);
+
+ /*
+ * Do not hold mutex here since this will cause mac80211 to call
+ * into driver again into functions that will attempt to take
+ * mutex.
+ */
+ if (!internal)
+ ieee80211_scan_completed(priv->hw, false);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 01/17] iwlwifi: introduce iwl_sta_id_or_broadcast
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Reinette Chatre
In-Reply-To: <1273787399-9280-1-git-send-email-reinette.chatre@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
There are now five places where we need to
look up the station ID, but the sta pointer
may be NULL due to mac80211 passing that to
indicate a certain special state.
Replace all these by a new inline function,
called iwl_sta_id_or_broadcast(), and add
documentation about when to use it.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 5 +---
drivers/net/wireless/iwlwifi/iwl-agn.c | 14 ++----------
drivers/net/wireless/iwlwifi/iwl-sta.c | 16 +++-----------
drivers/net/wireless/iwlwifi/iwl-sta.h | 29 +++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl3945-base.c | 19 +++--------------
5 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index c402bfc..18b1546 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -567,10 +567,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */
- if (!info->control.sta)
- sta_id = priv->hw_params.bcast_sta_id;
- else
- sta_id = iwl_sta_id(info->control.sta);
+ sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 47563cf..d7a9aea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3081,17 +3081,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
- if (sta) {
- sta_id = iwl_sta_id(sta);
-
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
- sta->addr);
- return -EINVAL;
- }
- } else {
- sta_id = priv->hw_params.bcast_sta_id;
- }
+ sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ if (sta_id == IWL_INVALID_STATION)
+ return -EINVAL;
mutex_lock(&priv->mutex);
iwl_scan_cancel_timeout(priv, 100);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 85ed235..2eafba6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -972,24 +972,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
unsigned long flags;
int i;
- if (sta) {
- sta_id = iwl_sta_id(sta);
-
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n",
- sta->addr);
- return;
- }
- } else
- sta_id = priv->hw_params.bcast_sta_id;
-
-
if (iwl_scan_cancel(priv)) {
/* cancel scan failed, just live w/ bad key and rely
briefly on SW decryption */
return;
}
+ sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ if (sta_id == IWL_INVALID_STATION)
+ return;
+
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index c2a453a..5b1b1e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -107,4 +107,33 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
}
+
+/**
+ * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
+ * @priv: iwl priv
+ * @sta: mac80211 station
+ *
+ * In certain circumstances mac80211 passes a station pointer
+ * that may be %NULL, for example during TX or key setup. In
+ * that case, we need to use the broadcast station, so this
+ * inline wraps that pattern.
+ */
+static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
+ struct ieee80211_sta *sta)
+{
+ int sta_id;
+
+ if (!sta)
+ return priv->hw_params.bcast_sta_id;
+
+ sta_id = iwl_sta_id(sta);
+
+ /*
+ * mac80211 should not be passing a partially
+ * initialised station!
+ */
+ WARN_ON(sta_id == IWL_INVALID_STATION);
+
+ return sta_id;
+}
#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4c78783..68b8a1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -509,10 +509,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find index into station table for destination station */
- if (!info->control.sta)
- sta_id = priv->hw_params.bcast_sta_id;
- else
- sta_id = iwl_sta_id(info->control.sta);
+ sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -3336,17 +3333,9 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
static_key = !iwl_is_associated(priv);
if (!static_key) {
- if (!sta) {
- sta_id = priv->hw_params.bcast_sta_id;
- } else {
- sta_id = iwl_sta_id(sta);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv,
- "leave - %pM not in station map.\n",
- sta->addr);
- return -EINVAL;
- }
- }
+ sta_id = iwl_sta_id_or_broadcast(priv, sta);
+ if (sta_id == IWL_INVALID_STATION)
+ return -EINVAL;
}
mutex_lock(&priv->mutex);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 00/17] iwlwifi updates for 2.6.35
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Reinette Chatre
This series includes a lot of driver cleanup. Driver is made more robust to
be able to deal with firmware that miss some information. Duplicate code
scattered in driver is moved to a function. Structures and code specific to
some devices are moved to be only accessible to these devices. We include
better station debug information and make it possible to compile driver
with debugfs support without needing debug support.
We also include some fixes which include the usage of the correct mac80211
variables and fixing of station locking.
We continue the recognition and enabling of some new iwlwifi devices.
These patches are also available from wireless-next-2.6 branch on
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
Johannes Berg (9):
iwlwifi: introduce iwl_sta_id_or_broadcast
iwlwifi: don't crash on firmware file missing info
iwl3945: remove sequence number assignment
iwlwifi: move iwl_free_tfds_in_queue to iwlagn
iwlwifi: improve station debugfs
iwlwifi: remove IWL_MULTICAST_ID
iwlagn: use firmware event/error log information
iwlwifi: split debug and debugfs options
iwlwifi: use proper short slot/preamble settings
Reinette Chatre (1):
iwlwifi: fix and add missing sta_lock usage
Shanyu Zhao (2):
iwlwifi: enable remaining 6000 Gen2 devices
iwlwifi: add new PCI IDs for 6000g2 devices
Wey-Yi Guy (5):
iwlwifi: move _agn statistics related structure
iwlwifi: separate statistics flag function for agn & 3945
iwlwifi: code cleanup for _agn devices
iwlwifi: modify out-dated comments
iwlwifi: move ucode related function to iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/Kconfig | 6 +-
drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c | 28 ++-
drivers/net/wireless/iwlwifi/iwl-3945.c | 15 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 9 +-
drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-6000.c | 286 +++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 91 +++++---
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 23 ++-
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 46 +++-
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 123 ++++++++++
drivers/net/wireless/iwlwifi/iwl-agn.c | 196 ++++++++++++----
drivers/net/wireless/iwlwifi/iwl-agn.h | 34 +++
drivers/net/wireless/iwlwifi/iwl-commands.h | 1 -
drivers/net/wireless/iwlwifi/iwl-core.c | 131 +----------
drivers/net/wireless/iwlwifi/iwl-core.h | 3 -
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 81 ++-----
drivers/net/wireless/iwlwifi/iwl-dev.h | 58 ++---
drivers/net/wireless/iwlwifi/iwl-helpers.h | 5 +
drivers/net/wireless/iwlwifi/iwl-rx.c | 63 +++---
drivers/net/wireless/iwlwifi/iwl-sta.c | 72 +++---
drivers/net/wireless/iwlwifi/iwl-sta.h | 29 +++
drivers/net/wireless/iwlwifi/iwl-tx.c | 15 --
drivers/net/wireless/iwlwifi/iwl3945-base.c | 53 +----
24 files changed, 916 insertions(+), 458 deletions(-)
^ permalink raw reply
* [PATCH 07/17] iwlwifi: improve station debugfs
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Reinette Chatre
In-Reply-To: <1273787399-9280-1-git-send-email-reinette.chatre@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
The stations debugfs entry doesn't even show
the stations' MAC addresses Also, the TID
information is formatted very oddly, and
misses the important tfds_in_queue variable.
Fix this to make the file more useful.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 60 +++++++++++----------------
1 files changed, 25 insertions(+), 35 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 9793050..5e12c96 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -303,45 +303,35 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
for (i = 0; i < max_sta; i++) {
station = &priv->stations[i];
- if (station->used) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "station %d:\ngeneral data:\n", i+1);
- pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n",
- station->sta.sta.sta_id);
- pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n",
- station->sta.mode);
- pos += scnprintf(buf + pos, bufsz - pos,
- "flags: 0x%x\n",
- station->sta.station_flags_msk);
- pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
- pos += scnprintf(buf + pos, bufsz - pos,
- "seq_num\t\ttxq_id");
- pos += scnprintf(buf + pos, bufsz - pos,
- "\tframe_count\twait_for_ba\t");
- pos += scnprintf(buf + pos, bufsz - pos,
- "start_idx\tbitmap0\t");
- pos += scnprintf(buf + pos, bufsz - pos,
- "bitmap1\trate_n_flags");
- pos += scnprintf(buf + pos, bufsz - pos, "\n");
+ if (!station->used)
+ continue;
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "station %d - addr: %pM, flags: %#x\n",
+ i, station->sta.sta.addr,
+ station->sta.station_flags_msk);
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "TID\tseq_num\ttxq_id\tframes\ttfds\t");
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "start_idx\tbitmap\t\t\trate_n_flags\n");
- for (j = 0; j < MAX_TID_COUNT; j++) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "[%d]:\t\t%u", j,
- station->tid[j].seq_number);
- pos += scnprintf(buf + pos, bufsz - pos,
- "\t%u\t\t%u\t\t%u\t\t",
- station->tid[j].agg.txq_id,
- station->tid[j].agg.frame_count,
- station->tid[j].agg.wait_for_ba);
+ for (j = 0; j < MAX_TID_COUNT; j++) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
+ j, station->tid[j].seq_number,
+ station->tid[j].agg.txq_id,
+ station->tid[j].agg.frame_count,
+ station->tid[j].tfds_in_queue,
+ station->tid[j].agg.start_idx,
+ station->tid[j].agg.bitmap,
+ station->tid[j].agg.rate_n_flags);
+
+ if (station->tid[j].agg.wait_for_ba)
pos += scnprintf(buf + pos, bufsz - pos,
- "%u\t%llu\t%u",
- station->tid[j].agg.start_idx,
- (unsigned long long)station->tid[j].agg.bitmap,
- station->tid[j].agg.rate_n_flags);
- pos += scnprintf(buf + pos, bufsz - pos, "\n");
- }
+ " - waitforba");
pos += scnprintf(buf + pos, bufsz - pos, "\n");
}
+
+ pos += scnprintf(buf + pos, bufsz - pos, "\n");
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 03/17] iwlwifi: separate statistics flag function for agn & 3945
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1273787399-9280-1-git-send-email-reinette.chatre@intel.com>
From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Since agn and 3945 have different statistics_notif data structure, each
should has its own statistics_flag function.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c | 28 ++++++++++++++++++++--
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 27 +++++++++++++++++++--
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 22 ------------------
3 files changed, 49 insertions(+), 28 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
index 6a9c64a..ef0835b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
@@ -28,6 +28,28 @@
#include "iwl-3945-debugfs.h"
+
+static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+{
+ int p = 0;
+
+ p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
+ le32_to_cpu(priv->_3945.statistics.flag));
+ if (le32_to_cpu(priv->_3945.statistics.flag) &
+ UCODE_STATISTICS_CLEAR_MSK)
+ p += scnprintf(buf + p, bufsz - p,
+ "\tStatistics have been cleared\n");
+ p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
+ (le32_to_cpu(priv->_3945.statistics.flag) &
+ UCODE_STATISTICS_FREQUENCY_MSK)
+ ? "2.4 GHz" : "5.2 GHz");
+ p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
+ (le32_to_cpu(priv->_3945.statistics.flag) &
+ UCODE_STATISTICS_NARROW_BAND_MSK)
+ ? "enabled" : "disabled");
+ return p;
+}
+
ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
@@ -70,7 +92,7 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
max_cck = &priv->_3945.max_delta.rx.cck;
max_general = &priv->_3945.max_delta.rx.general;
- pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+ pos += iwl3945_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n",
"Statistics_Rx - OFDM:");
@@ -331,7 +353,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
accum_tx = &priv->_3945.accum_statistics.tx;
delta_tx = &priv->_3945.delta_statistics.tx;
max_tx = &priv->_3945.max_delta.tx;
- pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+ pos += iwl3945_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n",
"Statistics_Tx:");
@@ -438,7 +460,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file,
accum_div = &priv->_3945.accum_statistics.general.div;
delta_div = &priv->_3945.delta_statistics.general.div;
max_div = &priv->_3945.max_delta.general.div;
- pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+ pos += iwl3945_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n",
"Statistics_General:");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index 90be033..75d6bfc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -28,6 +28,27 @@
#include "iwl-agn-debugfs.h"
+static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+{
+ int p = 0;
+
+ p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
+ le32_to_cpu(priv->_agn.statistics.flag));
+ if (le32_to_cpu(priv->_agn.statistics.flag) &
+ UCODE_STATISTICS_CLEAR_MSK)
+ p += scnprintf(buf + p, bufsz - p,
+ "\tStatistics have been cleared\n");
+ p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
+ (le32_to_cpu(priv->_agn.statistics.flag) &
+ UCODE_STATISTICS_FREQUENCY_MSK)
+ ? "2.4 GHz" : "5.2 GHz");
+ p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
+ (le32_to_cpu(priv->_agn.statistics.flag) &
+ UCODE_STATISTICS_NARROW_BAND_MSK)
+ ? "enabled" : "disabled");
+ return p;
+}
+
ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -75,7 +96,7 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
max_general = &priv->_agn.max_delta.rx.general;
max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
- pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+ pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n",
"Statistics_Rx - OFDM:");
@@ -543,7 +564,7 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
accum_tx = &priv->_agn.accum_statistics.tx;
delta_tx = &priv->_agn.delta_statistics.tx;
max_tx = &priv->_agn.max_delta.tx;
- pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+ pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n",
"Statistics_Tx:");
@@ -768,7 +789,7 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
accum_div = &priv->_agn.accum_statistics.general.div;
delta_div = &priv->_agn.delta_statistics.general.div;
max_div = &priv->_agn.max_delta.general.div;
- pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+ pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
"acumulative delta max\n",
"Statistics_General:");
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index c248373..9793050 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -100,28 +100,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.open = iwl_dbgfs_open_file_generic, \
};
-int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
-{
- int p = 0;
-
- p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
- le32_to_cpu(priv->_agn.statistics.flag));
- if (le32_to_cpu(priv->_agn.statistics.flag) &
- UCODE_STATISTICS_CLEAR_MSK)
- p += scnprintf(buf + p, bufsz - p,
- "\tStatistics have been cleared\n");
- p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
- (le32_to_cpu(priv->_agn.statistics.flag) &
- UCODE_STATISTICS_FREQUENCY_MSK)
- ? "2.4 GHz" : "5.2 GHz");
- p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
- (le32_to_cpu(priv->_agn.statistics.flag) &
- UCODE_STATISTICS_NARROW_BAND_MSK)
- ? "enabled" : "disabled");
- return p;
-}
-EXPORT_SYMBOL(iwl_dbgfs_statistics_flag);
-
static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos) {
--
1.6.3.3
^ permalink raw reply related
* [PATCH 04/17] iwlwifi: don't crash on firmware file missing info
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Reinette Chatre
In-Reply-To: <1273787399-9280-1-git-send-email-reinette.chatre@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
If a firmware file misses one of the required
instruction or data pieces, the driver currently
crashes. Let it gracefully refuse that firmware
file instead.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-helpers.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 3ff6b9d..6984639 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -92,6 +92,11 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
struct fw_desc *desc)
{
+ if (!desc->len) {
+ desc->v_addr = NULL;
+ return -EINVAL;
+ }
+
desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
&desc->p_addr, GFP_KERNEL);
return (desc->v_addr != NULL) ? 0 : -ENOMEM;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 06/17] iwlwifi: move iwl_free_tfds_in_queue to iwlagn
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Reinette Chatre
In-Reply-To: <1273787399-9280-1-git-send-email-reinette.chatre@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
This function is only used by the agn drivers,
so doesn't have to be in core and exported.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 13 +++++++++++++
drivers/net/wireless/iwlwifi/iwl-agn.h | 2 ++
drivers/net/wireless/iwlwifi/iwl-core.h | 2 --
drivers/net/wireless/iwlwifi/iwl-tx.c | 15 ---------------
4 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index c7ce632..5f07bc2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1529,3 +1529,16 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid);
}
+
+void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+ int sta_id, int tid, int freed)
+{
+ if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
+ priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+ else {
+ IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
+ priv->stations[sta_id].tid[tid].tfds_in_queue,
+ freed);
+ priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
+ }
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 2d74805..fbbefe1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -93,6 +93,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
u16 ssn_idx, u8 tx_fifo);
void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
+void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+ int sta_id, int tid, int freed);
/* uCode */
int iwlagn_load_ucode(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7e5a5ba..63229dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -472,8 +472,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_hw_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
-void iwl_free_tfds_in_queue(struct iwl_priv *priv,
- int sta_id, int tid, int freed);
void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index c3c6505..db83a0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -76,21 +76,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
}
EXPORT_SYMBOL(iwl_txq_update_write_ptr);
-
-void iwl_free_tfds_in_queue(struct iwl_priv *priv,
- int sta_id, int tid, int freed)
-{
- if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
- priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
- else {
- IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
- priv->stations[sta_id].tid[tid].tfds_in_queue,
- freed);
- priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
- }
-}
-EXPORT_SYMBOL(iwl_free_tfds_in_queue);
-
/**
* iwl_tx_queue_free - Deallocate DMA queue.
* @txq: Transmit queue to deallocate.
--
1.6.3.3
^ permalink raw reply related
* [PATCH 08/17] iwlwifi: remove IWL_MULTICAST_ID
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Johannes Berg, Reinette Chatre
In-Reply-To: <1273787399-9280-1-git-send-email-reinette.chatre@intel.com>
From: Johannes Berg <johannes.berg@intel.com>
This constant is not used, and incorrect, since
the broadcast ID must be used for multicast too.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-commands.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 9aab020..4790571 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -952,7 +952,6 @@ struct iwl_qosparam_cmd {
/* Special, dedicated locations within device's station table */
#define IWL_AP_ID 0
-#define IWL_MULTICAST_ID 1
#define IWL_STA_ID 2
#define IWL3945_BROADCAST_ID 24
#define IWL3945_STATION_COUNT 25
--
1.6.3.3
^ permalink raw reply related
* [PATCH 13/17] iwlwifi: modify out-dated comments
From: Reinette Chatre @ 2010-05-13 21:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ipw3945-devel, Wey-Yi Guy, Reinette Chatre
In-Reply-To: <1273787399-9280-1-git-send-email-reinette.chatre@intel.com>
From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Some comments in iwl-dev.h still refer to 4965 but used by all the _agn
devices.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 8b2d06c..05a7a0d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1096,7 +1096,7 @@ struct iwl_priv {
/* force reset */
struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
- /* we allocate array of iwl4965_channel_info for NIC's valid channels.
+ /* we allocate array of iwl_channel_info for NIC's valid channels.
* Access via channel # using indirect index array */
struct iwl_channel_info *channel_info; /* channel info array */
u8 channel_count; /* # of channels */
@@ -1161,7 +1161,7 @@ struct iwl_priv {
struct iwl_switch_rxon switch_rxon;
/* 1st responses from initialize and runtime uCode images.
- * 4965's initialize alive response contains some calibration data. */
+ * _agn's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init;
struct iwl_alive_resp card_alive;
--
1.6.3.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox