Please pull 'upstream' branch of rt2x00
Hi John,
This is the latest version of rt2x00: 2.1.4
All drivers are now showing excellent progress, rt2400pci, rt2500pci, rt61pci and rt73usb seem to be working as expected now. And only rt2500usb is spoiling things by having only a working RX but no TX.
After this patch series, it is highly likely you can close a lot of rt2x00 related bugs in the Fedora bugzilla. :)
Ivo
---
The following changes since commit 4f739cf30891f277a6353d61275489528fab64e3:
Pavel Roskin (1):
at76_usb: make the driver depend on MAC80211
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git/ upstream
Adam Baker (2):
rt2x00: never disable multicast because it disables broadcast too rt2x00:correct rx packet length for USB devices
Ivo van Doorn (18):
rt2x00: Align RX descriptor to 4 bytes
rt2x00: Don't use uninitialized desc_len
rt2x00: Use skbdesc fields for descriptor initialization
rt2x00: Add new D-Link USB ID
rt2x00: Only disable beaconing just before beacon update
rt2x00: Upgrade queue->lock to use irqsave
rt2x00: Move firmware checksumming to driver
rt2x00: Start bugging when rt2x00lib doesn't filter SW diversity
rt2x00: Check IEEE80211_TXCTL_SEND_AFTER_DTIM flag
rt2x00: Rename config_preamble() to config_erp()
rt2x00: Add suspend/resume handlers to rt2x00rfkill
rt2x00: Make rt2x00leds_register return void
rt2x00: Always enable TSF ticking
rt2x00: Fix basic rate initialization
rt2x00: Fix compile error when rfkill is disabled
rt2x00: Fix RX DMA ring initialization
rt2x00: Fix rt2400pci signal
rt2x00: Release rt2x00 2.1.4
Luis Correia (1):
rt2x00: Fix trivial log message
Mattias Nissler (3):
rt2x00: Initialize TX control field in data entries
rt2x00: Use the correct size when copying the control info in txdone
rt2x00: Don't use unitialized rxdesc->size
drivers/net/wireless/rt2x00/Kconfig | 4 +- drivers/net/wireless/rt2x00/rt2400pci.c | 67 +++++++------ drivers/net/wireless/rt2x00/rt2400pci.h | 6 +- drivers/net/wireless/rt2x00/rt2500pci.c | 71 ++++++++------ drivers/net/wireless/rt2x00/rt2500usb.c | 97 ++++++++++--------- drivers/net/wireless/rt2x00/rt2x00.h | 31 ++++-- drivers/net/wireless/rt2x00/rt2x00config.c | 62 +++++++----- drivers/net/wireless/rt2x00/rt2x00debug.c | 5 +- drivers/net/wireless/rt2x00/rt2x00dev.c | 108 +++++++++------------ drivers/net/wireless/rt2x00/rt2x00firmware.c | 34 +------- drivers/net/wireless/rt2x00/rt2x00leds.c | 7 +- drivers/net/wireless/rt2x00/rt2x00lib.h | 45 ++++----- drivers/net/wireless/rt2x00/rt2x00mac.c | 22 +++-- drivers/net/wireless/rt2x00/rt2x00pci.c | 1 + drivers/net/wireless/rt2x00/rt2x00queue.c | 17 ++- drivers/net/wireless/rt2x00/rt2x00queue.h | 3 + drivers/net/wireless/rt2x00/rt2x00rfkill.c | 116 +++++++++++++++-------- drivers/net/wireless/rt2x00/rt2x00usb.c | 19 ++++- drivers/net/wireless/rt2x00/rt61pci.c | 104 ++++++++++++-------- drivers/net/wireless/rt2x00/rt73usb.c | 131 +++++++++++++++----------- 20 files changed, 524 insertions(+), 426 deletions(-)
PATCH 2/24 rt2x00: Initialize TX control field in data entries
From: Mattias Nissler <[email protected]>
In the TX path, the driver didn't copy the TX control data structure. Thus, it was invalid in the TX done handler, causing serious trouble and misbehaviour.
--- drivers/net/wireless/rt2x00/rt2x00pci.c | 1 + drivers/net/wireless/rt2x00/rt2x00usb.c | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt2x00pci.c +1 -0
@@ -67,6 +67,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, skbdesc->desc_len = queue->desc_size; skbdesc->entry = entry; +memcpy (&priv_tx->control, control,sizeof (priv_tx->control));memcpy (priv_tx->data, skb->data, skb->len);rt2x00lib_write_tx_desc (rt2x00dev, skb, control);
drivers/net/wireless/rt2x00/rt2x00usb.c +1 -0
@@ -206,6 +206,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, skbdesc->desc_len = queue->desc_size; skbdesc->entry = entry; +memcpy (&priv_tx->control, control,sizeof (priv_tx->control));rt2x00lib_write_tx_desc (rt2x00dev, skb, control);/*
Signature · 1 line
1.5.4.3
PATCH 3/24 rt2x00: Use the correct size when copying the control info in txdone
In reply to Ivo van DoornFrom: Mattias Nissler <[email protected]>
The sizeof() operator was incorrectly applied to the pointer, not the struct.
--- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt2x00dev.c +1 -1
@@ -521,7 +521,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, tx_status.ack_signal =0 ; tx_status.excessive_retries = (txdesc->status ==TX_FAIL_RETRY ); tx_status.retry_count = txdesc->retry; -memcpy (&tx_status.control, txdesc->control,sizeof (txdesc->control)); +memcpy (&tx_status.control, txdesc->control,sizeof (*txdesc->control));if (!(tx_status.control.flags &IEEE80211_TXCTL_NO_ACK )) {if (success)
Signature · 1 line
1.5.4.3
PATCH 4/24 rt2x00: Don't use uninitialized desc_len
In reply to Ivo van Doornskbdesc->desc_len is uninitialized at the start of the function. So it is a _bad_ idea to use it...
--- drivers/net/wireless/rt2x00/rt73usb.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt73usb.c +1 -1
@@ -1381,7 +1381,7 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,skb_push (entry->skb, offset);memcpy (entry->skb->data, rxd, entry->queue->desc_size); rxd = (__le32 *)entry->skb->data; -skb_pull (entry->skb, offset + skbdesc->desc_len); +skb_pull (entry->skb, offset + entry->queue->desc_size);skb_trim (entry->skb, rxdesc->size);/*
Signature · 1 line
1.5.4.3
PATCH 5/24 rt2x00: never disable multicast because it disables broadcast too
In reply to Ivo van DoornFrom: Adam Baker <[email protected]>
On rt73 and rt61 disabling reception of multicast packets also disables broadcast traffic which we never want to do. Therefore we should never disable multicast.
--- drivers/net/wireless/rt2x00/rt61pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt73usb.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/rt2x00/rt61pci.c +2 -2
@@ -2298,9 +2298,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw,* Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. +* - Multicast filter seems to kill broadcast traffic so never use it. */ -if (mc_count) - *total_flags |=FIF_ALLMULTI ; + *total_flags |=FIF_ALLMULTI ;if (*total_flags &FIF_OTHER_BSS || *total_flags &FIF_PROMISC_IN_BSS ) *total_flags |=FIF_PROMISC_IN_BSS |FIF_OTHER_BSS ;
drivers/net/wireless/rt2x00/rt73usb.c +2 -2
@@ -1889,9 +1889,9 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw,* Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. +* - Multicast filter seems to kill broadcast traffic so never use it. */ -if (mc_count) - *total_flags |=FIF_ALLMULTI ; + *total_flags |=FIF_ALLMULTI ;if (*total_flags &FIF_OTHER_BSS || *total_flags &FIF_PROMISC_IN_BSS ) *total_flags |=FIF_PROMISC_IN_BSS |FIF_OTHER_BSS ;
Signature · 1 line
1.5.4.3
PATCH 6/24 rt2x00: Don't use unitialized rxdesc->size
In reply to Ivo van DoornFrom: Mattias Nissler <[email protected]>
rxdesc->size is unitialized before the desriptor has been read. Move the truncation of the sk buffer to the moment all variables have been initialized.
--- drivers/net/wireless/rt2x00/rt2500usb.c | 11 +++++++---- drivers/net/wireless/rt2x00/rt73usb.c | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-)
drivers/net/wireless/rt2x00/rt2500usb.c +7 -4
@@ -1123,13 +1123,10 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,/* * Copy descriptor to the available headroom inside the skbuffer. -* Remove the original copy by trimming the skbuffer. */ skb_push (entry->skb, offset);memcpy (entry->skb->data, rxd, entry->queue->desc_size); rxd = (__le32 *)entry->skb->data; -skb_pull (entry->skb, offset); -skb_trim (entry->skb, rxdesc->size);/* * The descriptor is now aligned to 4 bytes and thus it is
@@ -1155,11 +1152,17 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS );/* +* Adjust the skb memory window to the frame boundaries. +*/ +skb_pull (entry->skb, offset); +skb_trim (entry->skb, rxdesc->size); + +/* * Set descriptor and data pointer. */ skbdesc->data = entry->skb->data; skbdesc->data_len = rxdesc->size; - skbdesc->desc = entry->skb->data - offset; + skbdesc->desc = rxd; skbdesc->desc_len = entry->queue->desc_size; }
drivers/net/wireless/rt2x00/rt73usb.c +7 -4
@@ -1376,13 +1376,10 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,/* * Copy descriptor to the available headroom inside the skbuffer. -* Remove the original copy by pulling the skbuffer. */ skb_push (entry->skb, offset);memcpy (entry->skb->data, rxd, entry->queue->desc_size); rxd = (__le32 *)entry->skb->data; -skb_pull (entry->skb, offset + entry->queue->desc_size); -skb_trim (entry->skb, rxdesc->size);/* * The descriptor is now aligned to 4 bytes and thus it is
@@ -1405,11 +1402,17 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS );/* +* Adjust the skb memory window to the frame boundaries. +*/ +skb_pull (entry->skb, offset + entry->queue->desc_size); +skb_trim (entry->skb, rxdesc->size); + +/* * Set descriptor and data pointer. */ skbdesc->data = entry->skb->data; skbdesc->data_len = rxdesc->size; - skbdesc->desc = entry->skb->data - offset; + skbdesc->desc = rxd; skbdesc->desc_len = entry->queue->desc_size; }
Signature · 1 line
1.5.4.3
PATCH 7/24 rt2x00: Use skbdesc fields for descriptor initialization
In reply to Ivo van DoornIn rt2x00lib_write_tx_desc() the skb->data and skb->len fields were incorrectly used. For USB drivers both of those values contain invalid data (skb->data points to the device descriptor, skb->len contains the frame _and_ descriptor length).
Instead of using the skbuffer fields we should use the skbdesc fields which are correctly initialized and contain all the data that we need.
--- drivers/net/wireless/rt2x00/rt2x00dev.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/rt2x00/rt2x00dev.c +2 -2
@@ -630,7 +630,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, {struct txentry_desc txdesc;struct skb_frame_desc *skbdesc =get_skb_frame_desc (skb); -struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data;const struct rt2x00_rate *rate;int tx_rate;int length;
@@ -710,7 +710,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, txdesc.signal = rate->plcp; txdesc.service =0x04 ; - length = skb->len +FCS_LEN ; + length = skbdesc->data_len +FCS_LEN ;if (rate->flags &DEV_RATE_OFDM ) {__set_bit (ENTRY_TXD_OFDM_RATE , &txdesc.flags);
Signature · 1 line
1.5.4.3
PATCH 8/24 rt2x00: Add new D-Link USB ID
In reply to Ivo van Doorn--- drivers/net/wireless/rt2x00/rt73usb.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt73usb.c +1 -0
@@ -2137,6 +2137,7 @@ static struct usb_device_id rt73usb_device_table[] = {/* D-Link */ { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) },/* Gemtek */ { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) },/* Gigabyte */
Signature · 1 line
1.5.4.3
PATCH 1/24 rt2x00: Align RX descriptor to 4 bytes
In reply to Ivo van DoornSome architectures give problems when reading RX frame descriptor words when the descriptor is not aligned on a 4 byte boundrary.
Due to optimalizations for the ieee80211 payload 4 byte alignment, it is no longer guarenteed that the descriptor is placed on the 4 byte boundrary (In fact, for rt73usb it is absolutely never aligned to 4 bytes, for rt2500usb it depends on the length of the payload).
This will copy the descriptor to a 4 byte aligned location before it is read for the first time. This will also move the payload data alignment in rt2x00usb (instead of inside the driver) where it has always belonged.
--- drivers/net/wireless/rt2x00/rt2500usb.c | 37 +++++++++++++---------------- drivers/net/wireless/rt2x00/rt2x00usb.c | 17 ++++++++++++- drivers/net/wireless/rt2x00/rt73usb.c | 39 +++++++++++++----------------- 3 files changed, 49 insertions(+), 44 deletions(-)
drivers/net/wireless/rt2x00/rt2500usb.c +17 -20
@@ -1117,11 +1117,24 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,__le32 *rxd = (__le32 *)(entry->skb->data + (priv_rx->urb->actual_length - entry->queue->desc_size)); -struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; -int header_size =ieee80211_get_hdrlen (le16_to_cpu (hdr->frame_control)); +unsigned int offset = entry->queue->desc_size +2 ;u32 word0;u32 word1; +/* +* Copy descriptor to the available headroom inside the skbuffer. +* Remove the original copy by trimming the skbuffer. +*/ +skb_push (entry->skb, offset); +memcpy (entry->skb->data, rxd, entry->queue->desc_size); + rxd = (__le32 *)entry->skb->data; +skb_pull (entry->skb, offset); +skb_trim (entry->skb, rxdesc->size); + +/* +* The descriptor is now aligned to 4 bytes and thus it is +* now safe to read it on all architectures. +*/ rt2x00_desc_read (rxd,0 , &word0);rt2x00_desc_read (rxd,1 , &word1);
@@ -1142,28 +1155,12 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS );/* -* The data behind the ieee80211 header must be -* aligned on a 4 byte boundary. -*/ -if (header_size %4 ==0 ) { -skb_push (entry->skb,2 ); -memmove (entry->skb->data, entry->skb->data +2 , - entry->skb->len -2 ); - } - -/* -* Set descriptor pointer. +* Set descriptor and data pointer. */ skbdesc->data = entry->skb->data; skbdesc->data_len = rxdesc->size; - skbdesc->desc = entry->skb->data + rxdesc->size; + skbdesc->desc = entry->skb->data - offset; skbdesc->desc_len = entry->queue->desc_size; - -/* -* Remove descriptor from skb buffer and trim the whole thing -* down to only contain data. -*/ -skb_trim (entry->skb, rxdesc->size); }/*
drivers/net/wireless/rt2x00/rt2x00usb.c +15 -2
@@ -247,11 +247,11 @@ static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)* advance. */ frame_size = queue->data_size + queue->desc_size; - skb =dev_alloc_skb (frame_size +2 ); + skb =dev_alloc_skb (queue->desc_size + frame_size +2 );if (!skb)return NULL ; -skb_reserve (skb,2 ); +skb_reserve (skb, queue->desc_size +2 );skb_put (skb, frame_size);return skb;
@@ -264,6 +264,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)struct sk_buff *skb;struct skb_frame_desc *skbdesc;struct rxdone_entry_desc rxdesc; +int header_size;if (!test_bit (DEVICE_ENABLED_RADIO , &rt2x00dev->flags) || !test_and_clear_bit (ENTRY_OWNER_DEVICE_DATA , &entry->flags))
@@ -288,6 +289,18 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) rt2x00dev->ops->lib->fill_rxdone (entry, &rxdesc);/* +* The data behind the ieee80211 header must be +* aligned on a 4 byte boundary. +*/ + header_size =ieee80211_get_hdrlen_from_skb (entry->skb); +if (header_size %4 ==0 ) { +skb_push (entry->skb,2 ); +memmove (entry->skb->data, entry->skb->data +2 , + entry->skb->len -2 ); + skbdesc->data = entry->skb->data; + } + +/* * Allocate a new sk buffer to replace the current one. * If allocation fails, we should drop the current frame * so we can recycle the existing sk buffer for the new frame.
drivers/net/wireless/rt2x00/rt73usb.c +17 -22
@@ -1370,12 +1370,24 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, {struct skb_frame_desc *skbdesc =get_skb_frame_desc (entry->skb);__le32 *rxd = (__le32 *)entry->skb->data; -struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *)entry->skb->data + entry->queue->desc_size; -int header_size =ieee80211_get_hdrlen (le16_to_cpu (hdr->frame_control)); +unsigned int offset = entry->queue->desc_size +2 ;u32 word0;u32 word1; +/* +* Copy descriptor to the available headroom inside the skbuffer. +* Remove the original copy by pulling the skbuffer. +*/ +skb_push (entry->skb, offset); +memcpy (entry->skb->data, rxd, entry->queue->desc_size); + rxd = (__le32 *)entry->skb->data; +skb_pull (entry->skb, offset + skbdesc->desc_len); +skb_trim (entry->skb, rxdesc->size); + +/* +* The descriptor is now aligned to 4 bytes and thus it is +* now safe to read it on all architectures. +*/ rt2x00_desc_read (rxd,0 , &word0);rt2x00_desc_read (rxd,1 , &word1);
@@ -1393,29 +1405,12 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS );/* -* The data behind the ieee80211 header must be -* aligned on a 4 byte boundary. -*/ -if (header_size %4 ==0 ) { -skb_push (entry->skb,2 ); -memmove (entry->skb->data, entry->skb->data +2 , - entry->skb->len -2 ); - } - -/* * Set descriptor and data pointer. */ - skbdesc->data = entry->skb->data + entry->queue->desc_size; + skbdesc->data = entry->skb->data; skbdesc->data_len = rxdesc->size; - skbdesc->desc = entry->skb->data; + skbdesc->desc = entry->skb->data - offset; skbdesc->desc_len = entry->queue->desc_size; - -/* -* Remove descriptor from skb buffer and trim the whole thing -* down to only contain data. -*/ -skb_pull (entry->skb, skbdesc->desc_len); -skb_trim (entry->skb, rxdesc->size); }/*
Signature · 1 line
1.5.4.3
PATCH 9/24 rt2x00: Only disable beaconing just before beacon update
In reply to Ivo van DoornWe should not write 0 to the beacon sync register during config_intf() since that will clear out the beacon interval and forces the beacon to be send out at the lowest interval. (reported by Mattias Nissler).
The side effect of the same bug was that while working with multiple virtual AP interfaces a change for any of those interfaces would disable beaconing untill an beacon update was provided.
This is resolved by only updating the TSF_SYNC value during config_intf(). In update_beacon() we disable beaconing temporarily to prevent fake beacons to be transmitted. Finally kick_tx_queue() will enable beaconing again.
--- drivers/net/wireless/rt2x00/rt2400pci.c | 20 +++++++++++++------- drivers/net/wireless/rt2x00/rt2500pci.c | 19 +++++++++++++------ drivers/net/wireless/rt2x00/rt2500usb.c | 19 +++++++++++++------ drivers/net/wireless/rt2x00/rt61pci.c | 18 +++++++++++++----- drivers/net/wireless/rt2x00/rt73usb.c | 18 +++++++++++++----- 5 files changed, 65 insertions(+), 29 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +13 -7
@@ -279,8 +279,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,u32 reg;if (flags &CONFIG_UPDATE_TYPE ) { -rt2x00pci_register_write (rt2x00dev,CSR14 ,0 ); -/* * Enable beacon config */
@@ -293,10 +291,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,* Enable synchronisation. */ rt2x00pci_register_read (rt2x00dev,CSR14 , ®); -rt2x00_set_field32 (®,CSR14_TSF_COUNT ,1 ); -rt2x00_set_field32 (®,CSR14_TBCN , - (conf->sync ==TSF_SYNC_BEACON )); -rt2x00_set_field32 (®,CSR14_BEACON_GEN ,0 );rt2x00_set_field32 (®,CSR14_TSF_SYNC , conf->sync);rt2x00pci_register_write (rt2x00dev,CSR14 , reg); }
@@ -1040,6 +1034,8 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,if (queue ==RT2X00_BCN_QUEUE_BEACON ) {rt2x00pci_register_read (rt2x00dev,CSR14 , ®);if (!rt2x00_get_field32 (reg,CSR14_BEACON_GEN )) { +rt2x00_set_field32 (®,CSR14_TSF_COUNT ,1 ); +rt2x00_set_field32 (®,CSR14_TBCN ,1 );rt2x00_set_field32 (®,CSR14_BEACON_GEN ,1 );rt2x00pci_register_write (rt2x00dev,CSR14 , reg); }
@@ -1517,10 +1513,10 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,struct rt2x00_intf *intf =vif_to_intf (control->vif);struct queue_entry_priv_pci_tx *priv_tx;struct skb_frame_desc *skbdesc; +u32 reg;if (unlikely (!intf->beacon))return -ENOBUFS ; - priv_tx = intf->beacon->priv_data;/*
@@ -1536,6 +1532,16 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, skbdesc->entry = intf->beacon;/* +* Disable beaconing while we are reloading the beacon data, +* otherwise we might be sending out invalid data. +*/ +rt2x00pci_register_read (rt2x00dev,CSR14 , ®); +rt2x00_set_field32 (®,CSR14_TSF_COUNT ,0 ); +rt2x00_set_field32 (®,CSR14_TBCN ,0 ); +rt2x00_set_field32 (®,CSR14_BEACON_GEN ,0 ); +rt2x00pci_register_write (rt2x00dev,CSR14 , reg); + +/* * mac80211 doesn't provide the control->queue variable * for beacons. Set our own queue identification so * it can be used during descriptor initialization.
drivers/net/wireless/rt2x00/rt2500pci.c +13 -6
@@ -281,8 +281,6 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,u32 reg;if (flags &CONFIG_UPDATE_TYPE ) { -rt2x00pci_register_write (rt2x00dev,CSR14 ,0 ); -/* * Enable beacon config */
@@ -296,10 +294,6 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,* Enable synchronisation. */ rt2x00pci_register_read (rt2x00dev,CSR14 , ®); -rt2x00_set_field32 (®,CSR14_TSF_COUNT ,1 ); -rt2x00_set_field32 (®,CSR14_TBCN , - (conf->sync ==TSF_SYNC_BEACON )); -rt2x00_set_field32 (®,CSR14_BEACON_GEN ,0 );rt2x00_set_field32 (®,CSR14_TSF_SYNC , conf->sync);rt2x00pci_register_write (rt2x00dev,CSR14 , reg); }
@@ -1193,6 +1187,8 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,if (queue ==RT2X00_BCN_QUEUE_BEACON ) {rt2x00pci_register_read (rt2x00dev,CSR14 , ®);if (!rt2x00_get_field32 (reg,CSR14_BEACON_GEN )) { +rt2x00_set_field32 (®,CSR14_TSF_COUNT ,1 ); +rt2x00_set_field32 (®,CSR14_TBCN ,1 );rt2x00_set_field32 (®,CSR14_BEACON_GEN ,1 );rt2x00pci_register_write (rt2x00dev,CSR14 , reg); }
@@ -1828,6 +1824,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,struct rt2x00_intf *intf =vif_to_intf (control->vif);struct queue_entry_priv_pci_tx *priv_tx;struct skb_frame_desc *skbdesc; +u32 reg;if (unlikely (!intf->beacon))return -ENOBUFS ;
@@ -1847,6 +1844,16 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, skbdesc->entry = intf->beacon;/* +* Disable beaconing while we are reloading the beacon data, +* otherwise we might be sending out invalid data. +*/ +rt2x00pci_register_read (rt2x00dev,CSR14 , ®); +rt2x00_set_field32 (®,CSR14_TSF_COUNT ,0 ); +rt2x00_set_field32 (®,CSR14_TBCN ,0 ); +rt2x00_set_field32 (®,CSR14_BEACON_GEN ,0 ); +rt2x00pci_register_write (rt2x00dev,CSR14 , reg); + +/* * mac80211 doesn't provide the control->queue variable * for beacons. Set our own queue identification so * it can be used during descriptor initialization.
drivers/net/wireless/rt2x00/rt2500usb.c +13 -6
@@ -324,8 +324,6 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,u16 reg;if (flags &CONFIG_UPDATE_TYPE ) { -rt2500usb_register_write (rt2x00dev,TXRX_CSR19 ,0 ); -/* * Enable beacon config */
@@ -344,10 +342,6 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,rt2500usb_register_write (rt2x00dev,TXRX_CSR18 , reg);rt2500usb_register_read (rt2x00dev,TXRX_CSR19 , ®); -rt2x00_set_field16 (®,TXRX_CSR19_TSF_COUNT ,1 ); -rt2x00_set_field16 (®,TXRX_CSR19_TBCN , - (conf->sync ==TSF_SYNC_BEACON )); -rt2x00_set_field16 (®,TXRX_CSR19_BEACON_GEN ,0 );rt2x00_set_field16 (®,TXRX_CSR19_TSF_SYNC , conf->sync);rt2500usb_register_write (rt2x00dev,TXRX_CSR19 , reg); }
@@ -1092,6 +1086,8 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,rt2500usb_register_read (rt2x00dev,TXRX_CSR19 , ®);if (!rt2x00_get_field16 (reg,TXRX_CSR19_BEACON_GEN )) { +rt2x00_set_field16 (®,TXRX_CSR19_TSF_COUNT ,1 ); +rt2x00_set_field16 (®,TXRX_CSR19_TBCN ,1 );rt2x00_set_field16 (®,TXRX_CSR19_BEACON_GEN ,1 );/* * Beacon generation will fail initially.
@@ -1740,6 +1736,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,struct skb_frame_desc *skbdesc;int pipe =usb_sndbulkpipe (usb_dev,1 );int length; +u16 reg;if (unlikely (!intf->beacon))return -ENOBUFS ;
@@ -1765,6 +1762,16 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, skbdesc->entry = intf->beacon;/* +* Disable beaconing while we are reloading the beacon data, +* otherwise we might be sending out invalid data. +*/ +rt2500usb_register_read (rt2x00dev,TXRX_CSR19 , ®); +rt2x00_set_field16 (®,TXRX_CSR19_TSF_COUNT ,0 ); +rt2x00_set_field16 (®,TXRX_CSR19_TBCN ,0 ); +rt2x00_set_field16 (®,TXRX_CSR19_BEACON_GEN ,0 ); +rt2500usb_register_write (rt2x00dev,TXRX_CSR19 , reg); + +/* * mac80211 doesn't provide the control->queue variable * for beacons. Set our own queue identification so * it can be used during descriptor initialization.
drivers/net/wireless/rt2x00/rt61pci.c +13 -5
@@ -336,17 +336,12 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,* bits which (when set to 0) will invalidate the entire beacon. */ beacon_base =HW_BEACON_OFFSET (intf->beacon->entry_idx); -rt2x00pci_register_write (rt2x00dev,TXRX_CSR9 ,0 );rt2x00pci_register_write (rt2x00dev, beacon_base,0 );/* * Enable synchronisation. */ rt2x00pci_register_read (rt2x00dev,TXRX_CSR9 , ®); -rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,1 ); -rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE , - (conf->sync ==TSF_SYNC_BEACON )); -rt2x00_set_field32 (®,TXRX_CSR9_BEACON_GEN ,0 );rt2x00_set_field32 (®,TXRX_CSR9_TSF_SYNC , conf->sync);rt2x00pci_register_write (rt2x00dev,TXRX_CSR9 , reg); }
@@ -1562,6 +1557,8 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,rt2x00pci_register_read (rt2x00dev,TXRX_CSR9 , ®);if (!rt2x00_get_field32 (reg,TXRX_CSR9_BEACON_GEN )) { +rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,1 ); +rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE ,1 );rt2x00_set_field32 (®,TXRX_CSR9_BEACON_GEN ,1 );rt2x00pci_register_write (rt2x00dev,TXRX_CSR9 , reg); }
@@ -2373,6 +2370,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,struct rt2x00_intf *intf =vif_to_intf (control->vif);struct skb_frame_desc *skbdesc;unsigned int beacon_base; +u32 reg;if (unlikely (!intf->beacon))return -ENOBUFS ;
@@ -2408,6 +2406,16 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, skbdesc->entry = intf->beacon;/* +* Disable beaconing while we are reloading the beacon data, +* otherwise we might be sending out invalid data. +*/ +rt2x00pci_register_read (rt2x00dev,TXRX_CSR9 , ®); +rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,0 ); +rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE ,0 ); +rt2x00_set_field32 (®,TXRX_CSR9_BEACON_GEN ,0 ); +rt2x00pci_register_write (rt2x00dev,TXRX_CSR9 , reg); + +/* * mac80211 doesn't provide the control->queue variable * for beacons. Set our own queue identification so * it can be used during descriptor initialization.
drivers/net/wireless/rt2x00/rt73usb.c +13 -5
@@ -347,17 +347,12 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,* bits which (when set to 0) will invalidate the entire beacon. */ beacon_base =HW_BEACON_OFFSET (intf->beacon->entry_idx); -rt73usb_register_write (rt2x00dev,TXRX_CSR9 ,0 );rt73usb_register_write (rt2x00dev, beacon_base,0 );/* * Enable synchronisation. */ rt73usb_register_read (rt2x00dev,TXRX_CSR9 , ®); -rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,1 ); -rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE , - (conf->sync ==TSF_SYNC_BEACON )); -rt2x00_set_field32 (®,TXRX_CSR9_BEACON_GEN ,0 );rt2x00_set_field32 (®,TXRX_CSR9_TSF_SYNC , conf->sync);rt73usb_register_write (rt2x00dev,TXRX_CSR9 , reg); }
@@ -1312,6 +1307,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,rt73usb_register_read (rt2x00dev,TXRX_CSR9 , ®);if (!rt2x00_get_field32 (reg,TXRX_CSR9_BEACON_GEN )) { +rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,1 ); +rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE ,1 );rt2x00_set_field32 (®,TXRX_CSR9_BEACON_GEN ,1 );rt73usb_register_write (rt2x00dev,TXRX_CSR9 , reg); }
@@ -1987,6 +1984,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,struct skb_frame_desc *skbdesc;unsigned int beacon_base;unsigned int timeout; +u32 reg;if (unlikely (!intf->beacon))return -ENOBUFS ;
@@ -2010,6 +2008,16 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, skbdesc->entry = intf->beacon;/* +* Disable beaconing while we are reloading the beacon data, +* otherwise we might be sending out invalid data. +*/ +rt73usb_register_read (rt2x00dev,TXRX_CSR9 , ®); +rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,0 ); +rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE ,0 ); +rt2x00_set_field32 (®,TXRX_CSR9_BEACON_GEN ,0 ); +rt73usb_register_write (rt2x00dev,TXRX_CSR9 , reg); + +/* * mac80211 doesn't provide the control->queue variable * for beacons. Set our own queue identification so * it can be used during descriptor initialization.
Signature · 1 line
1.5.4.3
PATCH 10/24 rt2x00:correct rx packet length for USB devices
In reply to Ivo van DoornFrom: Adam Baker <[email protected]>
When fixing up the packet alignment, if we had to add 2 bytes to the front of the skb we need to remember to take them off the end afterwards. This fixes reception of encrypted packets which were otherwise failing with an invalid ICV.
--- drivers/net/wireless/rt2x00/rt2x00usb.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt2x00usb.c +1 -0
@@ -299,6 +299,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)memmove (entry->skb->data, entry->skb->data +2 , entry->skb->len -2 ); skbdesc->data = entry->skb->data; +skb_trim (entry->skb,entry->skb->len -2 ); }/*
Signature · 1 line
1.5.4.3
PATCH 11/24 rt2x00: Fix trivial log message
In reply to Ivo van DoornFrom: Luis Correia <[email protected]>
Fix trivial log message.
--- drivers/net/wireless/rt2x00/rt2500usb.c | 3 ++- drivers/net/wireless/rt2x00/rt73usb.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/net/wireless/rt2x00/rt2500usb.c +2 -1
@@ -294,7 +294,8 @@ static void rt2500usb_led_brightness(struct led_classdev *led_cdev,if (in_atomic ()) {NOTICE (led->rt2x00dev, -"Ignoring LED brightness command for led %d" , led->type); +"Ignoring LED brightness command for led %d\n" , + led->type);return ; }
drivers/net/wireless/rt2x00/rt73usb.c +2 -1
@@ -292,7 +292,8 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev,if (in_atomic ()) {NOTICE (led->rt2x00dev, -"Ignoring LED brightness command for led %d" , led->type); +"Ignoring LED brightness command for led %d\n" , + led->type);return ; }
Signature · 1 line
1.5.4.3
PATCH 12/24 rt2x00: Upgrade queue->lock to use irqsave
In reply to Ivo van DoornThe queue->lock could be grabbed from interrupt context, which could lead to lockdep panic like this:
kernel: ======================================================
kernel: [ INFO: soft-safe -> soft-unsafe lock order detected ]
kernel: 2.6.25-0.95.rc4.fc9 #1
kernel: ------------------------------------------------------
kernel: rt2500pci/1251 [HC0[0]:SC0[1]:HE1:SE0] is trying to acquire:
kernel: (&queue->lock){--..}, at: [<ffffffff88213339>] rt2x00queue_get_entry+0x5a/0x81 [rt2x00lib] kernel:
kernel: and this task is already holding:
kernel: (_xmit_IEEE80211){-...}, at: [<ffffffff8122e9a3>] __qdisc_run+0x84/0x1a9
kernel: which would create a new lock dependency:
kernel: (_xmit_IEEE80211){-...} -> (&queue->lock){--..}
kernel:
kernel: but this new dependency connects a soft-irq-safe lock:
kernel: (_xmit_ETHER){-+..}
kernel: ... which became soft-irq-safe at:
kernel: [<ffffffffffffffff>] 0xffffffffffffffff
kernel:
kernel: to a soft-irq-unsafe lock:
kernel: (&queue->lock){--..}
kernel: ... which became soft-irq-unsafe at:
kernel: ... [<ffffffff810545a2>] __lock_acquire+0x62d/0xd63
kernel: [<ffffffff81054d36>] lock_acquire+0x5e/0x78
kernel: [<ffffffff812a1497>] _spin_lock+0x26/0x53
kernel: [<ffffffff88212f98>] rt2x00queue_reset+0x16/0x40 [rt2x00lib]
kernel: [<ffffffff88212fd4>] rt2x00queue_alloc_entries+0x12/0xab [rt2x00lib]
kernel: [<ffffffff88213091>] rt2x00queue_initialize+0x24/0xf2 [rt2x00lib]
kernel: [<ffffffff88212036>] rt2x00lib_start+0x3b/0xd4 [rt2x00lib]
kernel: [<ffffffff88212609>] rt2x00mac_start+0x18/0x1a [rt2x00lib]
kernel: [<ffffffff881b9a4b>] ieee80211_open+0x1f3/0x46d [mac80211]
kernel: [<ffffffff8121d980>] dev_open+0x4d/0x8b
kernel: [<ffffffff8121d41e>] dev_change_flags+0xaf/0x172
kernel: [<ffffffff81224fc2>] do_setlink+0x276/0x338
kernel: [<ffffffff81225198>] rtnl_setlink+0x114/0x116
kernel: [<ffffffff812262fc>] rtnetlink_rcv_msg+0x1d8/0x1f9
kernel: [<ffffffff8123649a>] netlink_rcv_skb+0x3e/0xac
kernel: [<ffffffff8122611a>] rtnetlink_rcv+0x29/0x33
kernel: [<ffffffff81235eed>] netlink_unicast+0x1fe/0x26b
kernel: [<ffffffff81236224>] netlink_sendmsg+0x2ca/0x2dd
kernel: [<ffffffff812103b3>] sock_sendmsg+0xfd/0x120
kernel: [<ffffffff812105a8>] sys_sendmsg+0x1d2/0x23c
kernel: [<ffffffff8100c1c7>] tracesys+0xdc/0xe1
kernel: [<ffffffffffffffff>] 0xffffffffffffffffThis can be fixed by using the irqsave/irqrestore versions during the queue->lock handling.
--- drivers/net/wireless/rt2x00/rt2x00debug.c | 5 +++-- drivers/net/wireless/rt2x00/rt2x00queue.c | 17 +++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-)
drivers/net/wireless/rt2x00/rt2x00debug.c +3 -2
@@ -278,6 +278,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, {struct rt2x00debug_intf *intf = file->private_data;struct data_queue *queue; +unsigned long irqflags;unsigned int lines =1 + intf->rt2x00dev->data_queues;size_t size;char *data;
@@ -294,7 +295,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,sprintf (data,"qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n" );queue_for_each (intf->rt2x00dev, queue) { -spin_lock (&queue->lock); +spin_lock_irqsave (&queue->lock, irqflags); temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, queue->count, queue->limit, queue->length,
@@ -302,7 +303,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, queue->index[Q_INDEX_DONE ], queue->index[Q_INDEX_CRYPTO]); -spin_unlock (&queue->lock); +spin_unlock_irqrestore (&queue->lock, irqflags); } size =strlen (data);
drivers/net/wireless/rt2x00/rt2x00queue.c +11 -6
@@ -53,6 +53,7 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, enum queue_index index) {struct queue_entry *entry; +unsigned long irqflags;if (unlikely (index >=Q_INDEX_MAX )) { ERROR(queue->rt2x00dev,
@@ -60,11 +61,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,return NULL ; } -spin_lock (&queue->lock); +spin_lock_irqsave (&queue->lock, irqflags); entry = &queue->entries[queue->index[index]]; -spin_unlock (&queue->lock); +spin_unlock_irqrestore (&queue->lock, irqflags);return entry; }
@@ -72,13 +73,15 @@ EXPORT_SYMBOL_GPL(rt2x00queue_get_entry);void rt2x00queue_index_inc (struct data_queue *queue,enum queue_index index) { +unsigned long irqflags; +if (unlikely (index >=Q_INDEX_MAX )) {ERROR (queue->rt2x00dev,"Index change on invalid index type (%d)\n" , index);return ; } -spin_lock (&queue->lock); +spin_lock_irqsave (&queue->lock, irqflags); queue->index[index]++;if (queue->index[index] >= queue->limit)
@@ -91,19 +94,21 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) queue->count ++; } -spin_unlock (&queue->lock); +spin_unlock_irqrestore (&queue->lock, irqflags); }EXPORT_SYMBOL_GPL (rt2x00queue_index_inc);static void rt2x00queue_reset (struct data_queue *queue) { -spin_lock (&queue->lock); +unsigned long irqflags; + +spin_lock_irqsave (&queue->lock, irqflags); queue->count =0 ; queue->length =0 ;memset (queue->index,0 ,sizeof (queue->index)); -spin_unlock (&queue->lock); +spin_unlock_irqrestore (&queue->lock, irqflags); }void rt2x00queue_init_rx (struct rt2x00_dev *rt2x00dev)
Signature · 1 line
1.5.4.3
PATCH 13/24 rt2x00: Move firmware checksumming to driver
In reply to Ivo van Doornrt2x00lib depended on 2 crc algorithms because rt61/rt73 use a different algorithm then rt2800. This means that even when only 1 algorithm was needed, the dependency was still present for both.
By moving the checksum generation to the driver we can clean up 2 annoying flags (which indicated which checksum was required) and move the dependency to where it belongs: the driver.
--- drivers/net/wireless/rt2x00/Kconfig | 4 +- drivers/net/wireless/rt2x00/rt2x00.h | 3 +- drivers/net/wireless/rt2x00/rt2x00firmware.c | 34 +------------------------- drivers/net/wireless/rt2x00/rt61pci.c | 28 +++++++++++++++++---- drivers/net/wireless/rt2x00/rt73usb.c | 28 +++++++++++++++++---- 5 files changed, 50 insertions(+), 47 deletions(-)
drivers/net/wireless/rt2x00/Kconfig +2 -2
@@ -27,8 +27,6 @@ config RT2X00_LIB_USB config RT2X00_LIB_FIRMWARE boolean depends on RT2X00_LIB - select CRC_CCITT - select CRC_ITU_T select FW_LOADER config RT2X00_LIB_RFKILL
@@ -102,6 +100,7 @@ config RT61PCI depends on PCI select RT2X00_LIB_PCI select RT2X00_LIB_FIRMWARE + select CRC_ITU_T select EEPROM_93CX6 ---help--- This is an experimental driver for the Ralink rt61 wireless chip.
@@ -145,6 +144,7 @@ config RT73USB depends on USB select RT2X00_LIB_USB select RT2X00_LIB_FIRMWARE + select CRC_ITU_T ---help--- This is an experimental driver for the Ralink rt73 wireless chip.
drivers/net/wireless/rt2x00/rt2x00.h +1 -2
@@ -495,6 +495,7 @@ struct rt2x00lib_ops {*/ int (*probe_hw) (struct rt2x00_dev *rt2x00dev);char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev); +u16 (*get_firmware_crc) (void *data,const size_t len);int (*load_firmware) (struct rt2x00_dev *rt2x00dev,void *data,const size_t len);
@@ -613,8 +614,6 @@ enum rt2x00_flags {*/ DRIVER_SUPPORT_MIXED_INTERFACES ,DRIVER_REQUIRE_FIRMWARE , -DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T , -DRIVER_REQUIRE_FIRMWARE_CCITT ,DRIVER_REQUIRE_BEACON_GUARD , DRIVER_REQUIRE_ATIM_QUEUE,
drivers/net/wireless/rt2x00/rt2x00firmware.c +1 -33
@@ -23,8 +23,6 @@Abstract: rt2x00 firmware loading routines. */ -#include <linux/crc-ccitt.h> -#include <linux/crc-itu-t.h> #include <linux/kernel.h> #include <linux/module.h>
@@ -63,36 +61,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)return -ENOENT ; } -/* -* Perform crc validation on the firmware. -* The last 2 bytes in the firmware array are the crc checksum itself, -* this means that we should never pass those 2 bytes to the crc -* algorithm. -*/ -if (test_bit (DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T , &rt2x00dev->flags)) { -/* -* Use the crc itu-t algorithm. -* Use 0 for the last 2 bytes to complete the checksum. -*/ - crc =crc_itu_t (0 , fw->data, fw->size -2 ); - crc =crc_itu_t_byte (crc,0 ); - crc =crc_itu_t_byte (crc,0 ); - }else if (test_bit (DRIVER_REQUIRE_FIRMWARE_CCITT , &rt2x00dev->flags)) { -/* -* Use the crc ccitt algorithm. -* This will return the same value as the legacy driver which -* used bit ordering reversion on the both the firmware bytes -* before input input as well as on the final output. -* Obviously using crc ccitt directly is much more efficient. -*/ - crc =crc_ccitt (~0 , fw->data, fw->size -2 ); - }else { -ERROR (rt2x00dev,"No checksum algorithm selected " -"for firmware validation.\n" ); - retval = -ENOENT ; - goto exit; - } - + crc = rt2x00dev->ops->lib->get_firmware_crc (fw->data, fw->size);if (crc != (fw->data[fw->size -2 ] <<8 | fw->data[fw->size -1 ])) {ERROR (rt2x00dev,"Firmware checksum error.\n" ); retval = -ENOENT ;
@@ -139,4 +108,3 @@ void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)release_firmware (rt2x00dev->fw); rt2x00dev->fw =NULL ; } -
drivers/net/wireless/rt2x00/rt61pci.c +23 -5
@@ -24,6 +24,7 @@Supported chipsets: RT2561, RT2561s, RT2661. */ +#include <linux/crc-itu-t.h> #include <linux/delay.h> #include <linux/etherdevice.h> #include <linux/init.h>
@@ -856,7 +857,7 @@ dynamic_cca_tune: }/* -* Firmware name function. +* Firmware functions */ static char *rt61pci_get_firmware_name (struct rt2x00_dev *rt2x00dev) {
@@ -880,9 +881,23 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)return fw_name; } -/* -* Initialization functions. -*/ +static u16 rt61pci_get_firmware_crc (void *data,const size_t len) +{ +u16 crc; + +/* +* Use the crc itu-t algorithm. +* The last 2 bytes in the firmware array are the crc checksum itself, +* this means that we should never pass those 2 bytes to the crc +* algorithm. +*/ + crc =crc_itu_t (0 , data, len -2 ); + crc =crc_itu_t_byte (crc,0 ); + crc =crc_itu_t_byte (crc,0 ); + +return crc; +} +static int rt61pci_load_firmware (struct rt2x00_dev *rt2x00dev,void *data,const size_t len) {
@@ -963,6 +978,9 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,return 0 ; } +/* +* Initialization functions. +*/ static void rt61pci_init_rxentry (struct rt2x00_dev *rt2x00dev,struct queue_entry *entry) {
@@ -2257,7 +2275,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)* This device requires firmware. */ __set_bit (DRIVER_REQUIRE_FIRMWARE , &rt2x00dev->flags); -__set_bit (DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T , &rt2x00dev->flags);/* * Set the rssi offset.
@@ -2457,6 +2474,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .irq_handler = rt61pci_interrupt, .probe_hw = rt61pci_probe_hw, .get_firmware_name = rt61pci_get_firmware_name, + .get_firmware_crc = rt61pci_get_firmware_crc, .load_firmware = rt61pci_load_firmware, .initialize = rt2x00pci_initialize, .uninitialize = rt2x00pci_uninitialize,
drivers/net/wireless/rt2x00/rt73usb.c +23 -5
@@ -24,6 +24,7 @@Supported chipsets: rt2571W & rt2671. */ +#include <linux/crc-itu-t.h> #include <linux/delay.h> #include <linux/etherdevice.h> #include <linux/init.h>
@@ -817,16 +818,30 @@ dynamic_cca_tune: }/* -* Firmware name function. +* Firmware functions */ static char *rt73usb_get_firmware_name (struct rt2x00_dev *rt2x00dev) {return FIRMWARE_RT2571 ; } -/* -* Initialization functions. -*/ +static u16 rt73usb_get_firmware_crc (void *data,const size_t len) +{ +u16 crc; + +/* +* Use the crc itu-t algorithm. +* The last 2 bytes in the firmware array are the crc checksum itself, +* this means that we should never pass those 2 bytes to the crc +* algorithm. +*/ + crc =crc_itu_t (0 , data, len -2 ); + crc =crc_itu_t_byte (crc,0 ); + crc =crc_itu_t_byte (crc,0 ); + +return crc; +} +static int rt73usb_load_firmware (struct rt2x00_dev *rt2x00dev,void *data,const size_t len) {
@@ -896,6 +911,9 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,return 0 ; } +/* +* Initialization functions. +*/ static int rt73usb_init_registers (struct rt2x00_dev *rt2x00dev) {u32 reg;
@@ -1852,7 +1870,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)* This device requires firmware. */ __set_bit (DRIVER_REQUIRE_FIRMWARE , &rt2x00dev->flags); -__set_bit (DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T , &rt2x00dev->flags);/* * Set the rssi offset.
@@ -2061,6 +2078,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .probe_hw = rt73usb_probe_hw, .get_firmware_name = rt73usb_get_firmware_name, + .get_firmware_crc = rt73usb_get_firmware_crc, .load_firmware = rt73usb_load_firmware, .initialize = rt2x00usb_initialize, .uninitialize = rt2x00usb_uninitialize,
Signature · 1 line
1.5.4.3
PATCH 14/24 rt2x00: Start bugging when rt2x00lib doesn't filter SW diversity
In reply to Ivo van Doornrt2x00lib should filter SW diversity out before sending any configuration changes to the driver. When rt2x00lib fails to do this, it is important that such events are reported because it _must_ be fixed.
So upgrading the error level to a BUG_ON() which will make sure this bug gets noticed whenever it happens.
--- drivers/net/wireless/rt2x00/rt2400pci.c | 23 +++++++------------ drivers/net/wireless/rt2x00/rt2500pci.c | 25 +++++++------------- drivers/net/wireless/rt2x00/rt2500usb.c | 23 +++++++------------ drivers/net/wireless/rt2x00/rt61pci.c | 36 +++++++++++------------------- drivers/net/wireless/rt2x00/rt73usb.c | 23 +++++++------------ 5 files changed, 49 insertions(+), 81 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +9 -14
@@ -417,6 +417,13 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,u8 r1;u8 r4; +/* +* We should never come here because rt2x00lib is supposed +* to catch this and send us the correct antenna explicitely. +*/ +BUG_ON (ant->rx ==ANTENNA_SW_DIVERSITY || + ant->tx ==ANTENNA_SW_DIVERSITY ); +rt2400pci_bbp_read (rt2x00dev,4 , &r4);rt2400pci_bbp_read (rt2x00dev,1 , &r1);
@@ -430,14 +437,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,case ANTENNA_A :rt2x00_set_field8 (&r1,BBP_R1_TX_ANTENNA ,0 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r1,BBP_R1_TX_ANTENNA ,2 );break ; }
@@ -452,14 +453,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,case ANTENNA_A :rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA ,0 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA ,2 );break ; }
drivers/net/wireless/rt2x00/rt2500pci.c +9 -16
@@ -444,6 +444,13 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,u8 r14;u8 r2; +/* +* We should never come here because rt2x00lib is supposed +* to catch this and send us the correct antenna explicitely. +*/ +BUG_ON (ant->rx ==ANTENNA_SW_DIVERSITY || + ant->tx ==ANTENNA_SW_DIVERSITY ); +rt2x00pci_register_read (rt2x00dev,BBPCSR1 , ®);rt2500pci_bbp_read (rt2x00dev,14 , &r14);rt2500pci_bbp_read (rt2x00dev,2 , &r2);
@@ -457,15 +464,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,rt2x00_set_field32 (®,BBPCSR1_CCK ,0 );rt2x00_set_field32 (®,BBPCSR1_OFDM ,0 );break ; -case ANTENNA_HW_DIVERSITY : -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r2,BBP_R2_TX_ANTENNA ,2 );rt2x00_set_field32 (®,BBPCSR1_CCK ,2 );rt2x00_set_field32 (®,BBPCSR1_OFDM ,2 );
@@ -479,15 +479,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,case ANTENNA_A :rt2x00_set_field8 (&r14,BBP_R14_RX_ANTENNA ,0 );break ; -case ANTENNA_HW_DIVERSITY : -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r14,BBP_R14_RX_ANTENNA ,2 );break ; }
drivers/net/wireless/rt2x00/rt2500usb.c +9 -14
@@ -437,6 +437,13 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,u16 csr5;u16 csr6; +/* +* We should never come here because rt2x00lib is supposed +* to catch this and send us the correct antenna explicitely. +*/ +BUG_ON (ant->rx ==ANTENNA_SW_DIVERSITY || + ant->tx ==ANTENNA_SW_DIVERSITY ); +rt2500usb_bbp_read (rt2x00dev,2 , &r2);rt2500usb_bbp_read (rt2x00dev,14 , &r14);rt2500usb_register_read (rt2x00dev,PHY_CSR5 , &csr5);
@@ -456,14 +463,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,rt2x00_set_field16 (&csr5,PHY_CSR5_CCK ,0 );rt2x00_set_field16 (&csr6,PHY_CSR6_OFDM ,0 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r2,BBP_R2_TX_ANTENNA ,2 );rt2x00_set_field16 (&csr5,PHY_CSR5_CCK ,2 );rt2x00_set_field16 (&csr6,PHY_CSR6_OFDM ,2 );
@@ -480,14 +481,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,case ANTENNA_A :rt2x00_set_field8 (&r14,BBP_R14_RX_ANTENNA ,0 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r14,BBP_R14_RX_ANTENNA ,2 );break ; }
drivers/net/wireless/rt2x00/rt61pci.c +13 -23
@@ -481,14 +481,8 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,else rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,3 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA_CONTROL ,1 );rt2x00_set_field8 (&r4,BBP_R4_RX_FRAME_END ,0 );if (rt2x00dev->curr_band ==IEEE80211_BAND_5GHZ )
@@ -530,14 +524,8 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA_CONTROL ,1 );rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,3 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA_CONTROL ,1 );rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,0 );break ;
@@ -575,10 +563,6 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,rt61pci_bbp_read (rt2x00dev,4 , &r4);rt61pci_bbp_read (rt2x00dev,77 , &r77); -/* FIXME: Antenna selection for the rf 2529 is very confusing in the -* legacy driver. The code below should be ok for non-diversity setups. -*/ -/* * Configure the RX antenna. */
@@ -588,15 +572,14 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,0 );rt61pci_config_antenna_2529_rx (rt2x00dev,0 ,0 );break ; -case ANTENNA_SW_DIVERSITY :case ANTENNA_HW_DIVERSITY :/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. +* FIXME: Antenna selection for the rf 2529 is very confusing +* in the legacy driver. Just default to antenna B until the +* legacy code can be properly translated into rt2x00 code. */ case ANTENNA_B : +default :rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA_CONTROL ,1 );rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,3 );rt61pci_config_antenna_2529_rx (rt2x00dev,1 ,1 );
@@ -647,6 +630,13 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,unsigned int i;u32 reg; +/* +* We should never come here because rt2x00lib is supposed +* to catch this and send us the correct antenna explicitely. +*/ +BUG_ON (ant->rx ==ANTENNA_SW_DIVERSITY || + ant->tx ==ANTENNA_SW_DIVERSITY ); +if (rt2x00dev->curr_band ==IEEE80211_BAND_5GHZ ) { sel = antenna_sel_a; lna =test_bit (CONFIG_EXTERNAL_LNA_A , &rt2x00dev->flags);
drivers/net/wireless/rt2x00/rt73usb.c +9 -14
@@ -497,14 +497,8 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,else rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,3 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA_CONTROL ,1 );rt2x00_set_field8 (&r4,BBP_R4_RX_FRAME_END ,0 );if (rt2x00dev->curr_band ==IEEE80211_BAND_5GHZ )
@@ -545,14 +539,8 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,3 );rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA_CONTROL ,1 );break ; -case ANTENNA_SW_DIVERSITY : -/* -* NOTE: We should never come here because rt2x00lib is -* supposed to catch this and send us the correct antenna -* explicitely. However we are nog going to bug about this. -* Instead, just default to antenna B. -*/ case ANTENNA_B : +default :rt2x00_set_field8 (&r77,BBP_R77_RX_ANTENNA ,0 );rt2x00_set_field8 (&r4,BBP_R4_RX_ANTENNA_CONTROL ,1 );break ;
@@ -602,6 +590,13 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,unsigned int i;u32 reg; +/* +* We should never come here because rt2x00lib is supposed +* to catch this and send us the correct antenna explicitely. +*/ +BUG_ON (ant->rx ==ANTENNA_SW_DIVERSITY || + ant->tx ==ANTENNA_SW_DIVERSITY ); +if (rt2x00dev->curr_band ==IEEE80211_BAND_5GHZ ) { sel = antenna_sel_a; lna =test_bit (CONFIG_EXTERNAL_LNA_A , &rt2x00dev->flags);
Signature · 1 line
1.5.4.3
PATCH 15/24 rt2x00: Check IEEE80211_TXCTL_SEND_AFTER_DTIM flag
In reply to Ivo van DoornWhen mac sets the IEEE80211_TXCTL_SEND_AFTER_DTIM flag, we should check if the ATIM queue is available in the driver and put the frame in that queue for proper behavior (send frame after beacon interval). Unfortunately not all drivers have this ATIM queue, and will lack this feature for now.
--- drivers/net/wireless/rt2x00/rt2x00mac.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt2x00mac.c +5 -1
@@ -99,7 +99,11 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,/* * Determine which queue to put packet on. */ - queue =rt2x00queue_get_queue (rt2x00dev, control->queue); +if (control->flags &IEEE80211_TXCTL_SEND_AFTER_DTIM && +test_bit (DRIVER_REQUIRE_ATIM_QUEUE , &rt2x00dev->flags)) + queue =rt2x00queue_get_queue (rt2x00dev,RT2X00_BCN_QUEUE_ATIM ); +else + queue =rt2x00queue_get_queue (rt2x00dev, control->queue);if (unlikely (!queue)) {ERROR (rt2x00dev, "Attempt to send packet over invalid queue %d.\n"
Signature · 1 line
1.5.4.3
PATCH 16/24 rt2x00: Rename config_preamble() to config_erp()
In reply to Ivo van DoornRename config_preamble() to config_erp() and cleanup argument list by putting it all into a single structure.
This will make the function more meaningful and easier to expand later. This second option is mostly intended to make the patch "mac80211: proper short-slot handling" from Johannes Berg easier to apply for rt2x00.
--- drivers/net/wireless/rt2x00/rt2400pci.c | 16 +++++----- drivers/net/wireless/rt2x00/rt2500pci.c | 16 +++++----- drivers/net/wireless/rt2x00/rt2500usb.c | 12 +++---- drivers/net/wireless/rt2x00/rt2x00.h | 18 ++++++++--- drivers/net/wireless/rt2x00/rt2x00config.c | 43 +++++++++++++--------------- drivers/net/wireless/rt2x00/rt2x00dev.c | 5 +-- drivers/net/wireless/rt2x00/rt2x00lib.h | 6 ++-- drivers/net/wireless/rt2x00/rt2x00mac.c | 16 ++++------ drivers/net/wireless/rt2x00/rt61pci.c | 12 +++---- drivers/net/wireless/rt2x00/rt73usb.c | 12 +++---- 10 files changed, 76 insertions(+), 80 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +8 -8
@@ -304,10 +304,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, conf->bssid, sizeof(conf->bssid)); } -static int rt2400pci_config_preamble (struct rt2x00_dev *rt2x00dev, -const int short_preamble, -const int ack_timeout, -const int ack_consume_time) +static int rt2400pci_config_erp (struct rt2x00_dev *rt2x00dev, +struct rt2x00lib_erp *erp) {int preamble_mask;u32 reg;
@@ -315,11 +313,13 @@ static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev,/* * When short preamble is enabled, we should set bit 0x08 */ - preamble_mask = short_preamble <<3 ; + preamble_mask = erp->short_preamble <<3 ;rt2x00pci_register_read (rt2x00dev,TXCSR1 , ®); -rt2x00_set_field32 (®,TXCSR1_ACK_TIMEOUT , ack_timeout); -rt2x00_set_field32 (®,TXCSR1_ACK_CONSUME_TIME , ack_consume_time); +rt2x00_set_field32 (®,TXCSR1_ACK_TIMEOUT , + erp->ack_timeout); +rt2x00_set_field32 (®,TXCSR1_ACK_CONSUME_TIME , + erp->ack_consume_time);rt2x00pci_register_write (rt2x00dev,TXCSR1 , reg);rt2x00pci_register_read (rt2x00dev,ARCSR2 , ®);
@@ -1601,7 +1601,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { .kick_tx_queue = rt2400pci_kick_tx_queue, .fill_rxdone = rt2400pci_fill_rxdone, .config_intf = rt2400pci_config_intf, - .config_preamble = rt2400pci_config_preamble, + .config_erp = rt2400pci_config_erp, .config = rt2400pci_config, };
drivers/net/wireless/rt2x00/rt2500pci.c +8 -8
@@ -307,10 +307,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, conf->bssid, sizeof(conf->bssid)); } -static int rt2500pci_config_preamble (struct rt2x00_dev *rt2x00dev, -const int short_preamble, -const int ack_timeout, -const int ack_consume_time) +static int rt2500pci_config_erp (struct rt2x00_dev *rt2x00dev, +struct rt2x00lib_erp *erp) {int preamble_mask;u32 reg;
@@ -318,11 +316,13 @@ static int rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev,/* * When short preamble is enabled, we should set bit 0x08 */ - preamble_mask = short_preamble <<3 ; + preamble_mask = erp->short_preamble <<3 ;rt2x00pci_register_read (rt2x00dev,TXCSR1 , ®); -rt2x00_set_field32 (®,TXCSR1_ACK_TIMEOUT , ack_timeout); -rt2x00_set_field32 (®,TXCSR1_ACK_CONSUME_TIME , ack_consume_time); +rt2x00_set_field32 (®,TXCSR1_ACK_TIMEOUT , + erp->ack_timeout); +rt2x00_set_field32 (®,TXCSR1_ACK_CONSUME_TIME , + erp->ack_consume_time);rt2x00pci_register_write (rt2x00dev,TXCSR1 , reg);rt2x00pci_register_read (rt2x00dev,ARCSR2 , ®);
@@ -1911,7 +1911,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { .kick_tx_queue = rt2500pci_kick_tx_queue, .fill_rxdone = rt2500pci_fill_rxdone, .config_intf = rt2500pci_config_intf, - .config_preamble = rt2500pci_config_preamble, + .config_erp = rt2500pci_config_erp, .config = rt2500pci_config, };
drivers/net/wireless/rt2x00/rt2500usb.c +5 -7
@@ -356,10 +356,8 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, (3 * sizeof(__le16))); } -static int rt2500usb_config_preamble (struct rt2x00_dev *rt2x00dev, -const int short_preamble, -const int ack_timeout, -const int ack_consume_time) +static int rt2500usb_config_erp (struct rt2x00_dev *rt2x00dev, +struct rt2x00lib_erp *erp) {u16 reg;
@@ -371,12 +369,12 @@ static int rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev,return -EAGAIN ;rt2500usb_register_read (rt2x00dev,TXRX_CSR1 , ®); -rt2x00_set_field16 (®,TXRX_CSR1_ACK_TIMEOUT , ack_timeout); +rt2x00_set_field16 (®,TXRX_CSR1_ACK_TIMEOUT , erp->ack_timeout);rt2500usb_register_write (rt2x00dev,TXRX_CSR1 , reg);rt2500usb_register_read (rt2x00dev,TXRX_CSR10 , ®);rt2x00_set_field16 (®,TXRX_CSR10_AUTORESPOND_PREAMBLE , - !!short_preamble); + !!erp->short_preamble);rt2500usb_register_write (rt2x00dev,TXRX_CSR10 , reg);return 0 ;
@@ -1842,7 +1840,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .kick_tx_queue = rt2500usb_kick_tx_queue, .fill_rxdone = rt2500usb_fill_rxdone, .config_intf = rt2500usb_config_intf, - .config_preamble = rt2500usb_config_preamble, + .config_erp = rt2500usb_config_erp, .config = rt2500usb_config, };
drivers/net/wireless/rt2x00/rt2x00.h +13 -5
@@ -384,7 +384,7 @@ struct rt2x00_intf {*/ unsigned int delayed_flags;#define DELAYED_UPDATE_BEACON 0x00000001 -#define DELAYED_CONFIG_PREAMBLE 0x00000002 +#define DELAYED_CONFIG_ERP 0x00000002 };static inline struct rt2x00_intf *vif_to_intf (struct ieee80211_vif *vif)
@@ -451,6 +451,16 @@ struct rt2x00lib_conf { };/* +* Configuration structure for erp settings. +*/ +struct rt2x00lib_erp { +int short_preamble; + +int ack_timeout; +int ack_consume_time; +}; + +/* * Configuration structure wrapper around the * rt2x00 interface configuration handler. */
@@ -558,10 +568,8 @@ struct rt2x00lib_ops {#define CONFIG_UPDATE_MAC ( 1 << 2 )#define CONFIG_UPDATE_BSSID ( 1 << 3 ) -int (*config_preamble) (struct rt2x00_dev *rt2x00dev, -const int short_preamble, -const int ack_timeout, -const int ack_consume_time); +int (*config_erp) (struct rt2x00_dev *rt2x00dev, +struct rt2x00lib_erp *erp);void (*config) (struct rt2x00_dev *rt2x00dev,struct rt2x00lib_conf *libconf,const unsigned int flags);
drivers/net/wireless/rt2x00/rt2x00config.c +20 -23
63 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2x00dev.c +2 -3
@@ -447,9 +447,8 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, } } -if (delayed_flags &DELAYED_CONFIG_PREAMBLE ) -rt2x00lib_config_preamble (rt2x00dev, intf, - intf->conf.use_short_preamble); +if (delayed_flags &DELAYED_CONFIG_ERP ) +rt2x00lib_config_erp (rt2x00dev, intf, &intf->conf); }static void rt2x00lib_intf_scheduled (struct work_struct *work)
drivers/net/wireless/rt2x00/rt2x00lib.h +3 -3
@@ -100,9 +100,9 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,struct rt2x00_intf *intf, enum ieee80211_if_types type, u8 *mac, u8 *bssid); -void rt2x00lib_config_preamble (struct rt2x00_dev *rt2x00dev, -struct rt2x00_intf *intf, -const unsigned int short_preamble); +void rt2x00lib_config_erp (struct rt2x00_dev *rt2x00dev, +struct rt2x00_intf *intf, +struct ieee80211_bss_conf *conf);void rt2x00lib_config_antenna (struct rt2x00_dev *rt2x00dev,enum antenna rx,enum antenna tx); void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
drivers/net/wireless/rt2x00/rt2x00mac.c +7 -9
@@ -436,17 +436,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, }/* -* When the preamble mode has changed, we should perform additional -* configuration steps. For all other changes we are already done. +* When the erp information has changed, we should perform +* additional configuration steps. For all other changes we are done. */ -if (changes &BSS_CHANGED_ERP_PREAMBLE ) { -rt2x00lib_config_preamble (rt2x00dev, intf, - bss_conf->use_short_preamble); +if (changes &BSS_CHANGED_ERP_PREAMBLE ) +rt2x00lib_config_erp (rt2x00dev, intf, bss_conf); -spin_lock (&intf->lock); -memcpy (&intf->conf, bss_conf,sizeof (*bss_conf)); -spin_unlock (&intf->lock); - } +spin_lock (&intf->lock); +memcpy (&intf->conf, bss_conf,sizeof (*bss_conf)); +spin_unlock (&intf->lock); }EXPORT_SYMBOL_GPL (rt2x00mac_bss_info_changed);
drivers/net/wireless/rt2x00/rt61pci.c +5 -7
@@ -366,20 +366,18 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, } } -static int rt61pci_config_preamble (struct rt2x00_dev *rt2x00dev, -const int short_preamble, -const int ack_timeout, -const int ack_consume_time) +static int rt61pci_config_erp (struct rt2x00_dev *rt2x00dev, +struct rt2x00lib_erp *erp) {u32 reg;rt2x00pci_register_read (rt2x00dev,TXRX_CSR0 , ®); -rt2x00_set_field32 (®,TXRX_CSR0_RX_ACK_TIMEOUT , ack_timeout); +rt2x00_set_field32 (®,TXRX_CSR0_RX_ACK_TIMEOUT , erp->ack_timeout);rt2x00pci_register_write (rt2x00dev,TXRX_CSR0 , reg);rt2x00pci_register_read (rt2x00dev,TXRX_CSR4 , ®);rt2x00_set_field32 (®,TXRX_CSR4_AUTORESPOND_PREAMBLE , - !!short_preamble); + !!erp->short_preamble);rt2x00pci_register_write (rt2x00dev,TXRX_CSR4 , reg);return 0 ;
@@ -2481,7 +2479,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .kick_tx_queue = rt61pci_kick_tx_queue, .fill_rxdone = rt61pci_fill_rxdone, .config_intf = rt61pci_config_intf, - .config_preamble = rt61pci_config_preamble, + .config_erp = rt61pci_config_erp, .config = rt61pci_config, };
drivers/net/wireless/rt2x00/rt73usb.c +5 -7
@@ -378,10 +378,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, } } -static int rt73usb_config_preamble (struct rt2x00_dev *rt2x00dev, -const int short_preamble, -const int ack_timeout, -const int ack_consume_time) +static int rt73usb_config_erp (struct rt2x00_dev *rt2x00dev, +struct rt2x00lib_erp *erp) {u32 reg;
@@ -393,12 +391,12 @@ static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev,return -EAGAIN ;rt73usb_register_read (rt2x00dev,TXRX_CSR0 , ®); -rt2x00_set_field32 (®,TXRX_CSR0_RX_ACK_TIMEOUT , ack_timeout); +rt2x00_set_field32 (®,TXRX_CSR0_RX_ACK_TIMEOUT , erp->ack_timeout);rt73usb_register_write (rt2x00dev,TXRX_CSR0 , reg);rt73usb_register_read (rt2x00dev,TXRX_CSR4 , ®);rt2x00_set_field32 (®,TXRX_CSR4_AUTORESPOND_PREAMBLE , - !!short_preamble); + !!erp->short_preamble);rt73usb_register_write (rt2x00dev,TXRX_CSR4 , reg);return 0 ;
@@ -2090,7 +2088,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .kick_tx_queue = rt73usb_kick_tx_queue, .fill_rxdone = rt73usb_fill_rxdone, .config_intf = rt73usb_config_intf, - .config_preamble = rt73usb_config_preamble, + .config_erp = rt73usb_config_erp, .config = rt73usb_config, };
Signature · 1 line
1.5.4.3
PATCH 17/24 rt2x00: Add suspend/resume handlers to rt2x00rfkill
In reply to Ivo van DoornAdd suspend/resume handlers to rt2x00rfkill to have it stop the input-polldev and prevent it from calling rt2x00 during suspend period. This could lead to a NULL pointer fault when rt2x00 suspended, but polldev send a request, because the csr_addr is NULL.
Also don't let the rfkill allocation/registration block the initialization of the entire device. Just print a warning and continue as if nothing happened.
--- drivers/net/wireless/rt2x00/rt2x00.h | 4 + drivers/net/wireless/rt2x00/rt2x00dev.c | 43 ++++------- drivers/net/wireless/rt2x00/rt2x00lib.h | 15 ++-- drivers/net/wireless/rt2x00/rt2x00rfkill.c | 116 ++++++++++++++++++---------- 4 files changed, 102 insertions(+), 76 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +4 -0
@@ -671,6 +671,10 @@ struct rt2x00_dev {* This will only be compiled in when required. */ #ifdef CONFIG_RT2X00_LIB_RFKILL +unsigned long rfkill_state; +#define RFKILL_STATE_ALLOCATED 1 +#define RFKILL_STATE_REGISTERED 2 +struct rfkill *rfkill;struct input_polled_dev *poll_dev;#endif /* CONFIG_RT2X00_LIB_RFKILL */
drivers/net/wireless/rt2x00/rt2x00dev.c +14 -29
91 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2x00lib.h +9 -6
@@ -160,28 +160,31 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,* RFkill handlers. */ #ifdef CONFIG_RT2X00_LIB_RFKILL -int rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev);void rt2x00rfkill_unregister (struct rt2x00_dev *rt2x00dev); -int rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev);void rt2x00rfkill_free (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_suspend (struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_resume (struct rt2x00_dev *rt2x00dev);#else -static inline int rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_register (struct rt2x00_dev *rt2x00dev) { -return 0 ; }static inline void rt2x00rfkill_unregister (struct rt2x00_dev *rt2x00dev) { } -static inline int rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_allocate (struct rt2x00_dev *rt2x00dev) { -return 0 ; }static inline void rt2x00rfkill_free (struct rt2x00_dev *rt2x00dev) { } + +static inline void rt2x00rfkill_suspend (struct rt2x00_dev *rt2x00dev); +static inline void rt2x00rfkill_resume (struct rt2x00_dev *rt2x00dev);#endif /* CONFIG_RT2X00_LIB_RFKILL */ /*
drivers/net/wireless/rt2x00/rt2x00rfkill.c +75 -41
171 lines not on this page · raw message
Signature · 1 line
1.5.4.3
PATCH 18/24 rt2x00: Make rt2x00leds_register return void
In reply to Ivo van Doornrt2x00dev isn't interested in the rt2x00leds_register() value anyway. So lets make it return void to even prevent people from assuming there is anybody interested in the returnvalue.
--- drivers/net/wireless/rt2x00/rt2x00leds.c | 7 +++---- drivers/net/wireless/rt2x00/rt2x00lib.h | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-)
drivers/net/wireless/rt2x00/rt2x00leds.c +3 -4
@@ -109,7 +109,7 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,return 0 ; } -int rt2x00leds_register (struct rt2x00_dev *rt2x00dev) +void rt2x00leds_register (struct rt2x00_dev *rt2x00dev) {char *trigger;char dev_name[16 ];
@@ -117,7 +117,7 @@ int rt2x00leds_register(struct rt2x00_dev *rt2x00dev)int retval;if (!rt2x00dev->ops->lib->led_brightness) -return 0 ; +return ;snprintf (dev_name,sizeof (dev_name),"%s-%s" , rt2x00dev->ops->name,wiphy_name (rt2x00dev->hw->wiphy));
@@ -161,11 +161,10 @@ int rt2x00leds_register(struct rt2x00_dev *rt2x00dev) goto exit_fail; } -return 0 ; +return ; exit_fail:rt2x00leds_unregister (rt2x00dev); -return retval; }static void rt2x00leds_unregister_trigger (struct rt2x00_trigger *trigger)
drivers/net/wireless/rt2x00/rt2x00lib.h +2 -3
@@ -192,7 +192,7 @@ static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev);*/ #ifdef CONFIG_RT2X00_LIB_LEDS void rt2x00leds_led_quality (struct rt2x00_dev *rt2x00dev,int rssi); -int rt2x00leds_register (struct rt2x00_dev *rt2x00dev); +void rt2x00leds_register (struct rt2x00_dev *rt2x00dev);void rt2x00leds_unregister (struct rt2x00_dev *rt2x00dev);void rt2x00leds_suspend (struct rt2x00_dev *rt2x00dev);void rt2x00leds_resume (struct rt2x00_dev *rt2x00dev);
@@ -202,9 +202,8 @@ static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, { } -static inline int rt2x00leds_register (struct rt2x00_dev *rt2x00dev) +static inline void rt2x00leds_register (struct rt2x00_dev *rt2x00dev) { -return 0 ; }static inline void rt2x00leds_unregister (struct rt2x00_dev *rt2x00dev)
Signature · 1 line
1.5.4.3
PATCH 19/24 rt2x00: Always enable TSF ticking
In reply to Ivo van DoornWhatever mode we are in, according to the legacy drivers we should always enable TSF ticking/counting. We should also always enable the TBCN/TBTT field, this field is only disabled during beacon regeneration.
--- drivers/net/wireless/rt2x00/rt2400pci.c | 2 ++ drivers/net/wireless/rt2x00/rt2500pci.c | 2 ++ drivers/net/wireless/rt2x00/rt2500usb.c | 2 ++ drivers/net/wireless/rt2x00/rt61pci.c | 2 ++ drivers/net/wireless/rt2x00/rt73usb.c | 2 ++ 5 files changed, 10 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +2 -0
@@ -291,7 +291,9 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,* Enable synchronisation. */ rt2x00pci_register_read (rt2x00dev,CSR14 , ®); +rt2x00_set_field32 (®,CSR14_TSF_COUNT ,1 );rt2x00_set_field32 (®,CSR14_TSF_SYNC , conf->sync); +rt2x00_set_field32 (®,CSR14_TBCN ,1 );rt2x00pci_register_write (rt2x00dev,CSR14 , reg); }
drivers/net/wireless/rt2x00/rt2500pci.c +2 -0
@@ -294,7 +294,9 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,* Enable synchronisation. */ rt2x00pci_register_read (rt2x00dev,CSR14 , ®); +rt2x00_set_field32 (®,CSR14_TSF_COUNT ,1 );rt2x00_set_field32 (®,CSR14_TSF_SYNC , conf->sync); +rt2x00_set_field32 (®,CSR14_TBCN ,1 );rt2x00pci_register_write (rt2x00dev,CSR14 , reg); }
drivers/net/wireless/rt2x00/rt2500usb.c +2 -0
@@ -343,7 +343,9 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,rt2500usb_register_write (rt2x00dev,TXRX_CSR18 , reg);rt2500usb_register_read (rt2x00dev,TXRX_CSR19 , ®); +rt2x00_set_field16 (®,TXRX_CSR19_TSF_COUNT ,1 );rt2x00_set_field16 (®,TXRX_CSR19_TSF_SYNC , conf->sync); +rt2x00_set_field16 (®,TXRX_CSR19_TBCN ,1 );rt2500usb_register_write (rt2x00dev,TXRX_CSR19 , reg); }
drivers/net/wireless/rt2x00/rt61pci.c +2 -0
@@ -343,7 +343,9 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,* Enable synchronisation. */ rt2x00pci_register_read (rt2x00dev,TXRX_CSR9 , ®); +rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,1 );rt2x00_set_field32 (®,TXRX_CSR9_TSF_SYNC , conf->sync); +rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE ,1 );rt2x00pci_register_write (rt2x00dev,TXRX_CSR9 , reg); }
drivers/net/wireless/rt2x00/rt73usb.c +2 -0
@@ -355,7 +355,9 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,* Enable synchronisation. */ rt73usb_register_read (rt2x00dev,TXRX_CSR9 , ®); +rt2x00_set_field32 (®,TXRX_CSR9_TSF_TICKING ,1 );rt2x00_set_field32 (®,TXRX_CSR9_TSF_SYNC , conf->sync); +rt2x00_set_field32 (®,TXRX_CSR9_TBTT_ENABLE ,1 );rt73usb_register_write (rt2x00dev,TXRX_CSR9 , reg); }
Signature · 1 line
1.5.4.3
PATCH 20/24 rt2x00: Fix basic rate initialization
In reply to Ivo van DoornThe basic rate which is configured in the register should not match all supported rates, but only the _basic_ rates.
Fix this by adding a new flag to the rt2x00_rate structure and whenever the mode is changed, loop over all available rates for that band to get the basic rate mask.
--- drivers/net/wireless/rt2x00/rt2x00.h | 4 +- drivers/net/wireless/rt2x00/rt2x00config.c | 19 +++++++++++-- drivers/net/wireless/rt2x00/rt2x00dev.c | 38 ++++++++++++++-------------- drivers/net/wireless/rt2x00/rt2x00lib.h | 14 +--------- 4 files changed, 38 insertions(+), 37 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +2 -2
@@ -441,8 +441,8 @@ struct rt2x00lib_conf {enum ieee80211_band band; -int basic_rates; -int slot_time; +u32 basic_rates; +u32 slot_time;short sifs;short pifs;
drivers/net/wireless/rt2x00/rt2x00config.c +16 -3
@@ -145,12 +145,26 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,rt2x00lib_toggle_rx (rt2x00dev,STATE_RADIO_RX_ON_LINK ); } +static u32 rt2x00lib_get_basic_rates (struct ieee80211_supported_band *band) +{ +const struct rt2x00_rate *rate; +unsigned int i; +u32 mask =0 ; + +for (i =0 ; i < band->n_bitrates; i++) { + rate =rt2x00_get_rate (band->bitrates[i].hw_value); +if (rate->flags &DEV_RATE_BASIC ) + mask |= rate->ratemask; + } + +return mask; +} +void rt2x00lib_config (struct rt2x00_dev *rt2x00dev,struct ieee80211_conf *conf,const int force_config) {struct rt2x00lib_conf libconf;struct ieee80211_supported_band *band; -struct ieee80211_rate *rate;struct antenna_setup *default_ant = &rt2x00dev->default_ant;struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;int flags =0 ;
@@ -227,10 +241,9 @@ config:if (flags &CONFIG_UPDATE_PHYMODE ) { band = &rt2x00dev->bands[conf->channel->band]; - rate = &band->bitrates[band->n_bitrates -1 ]; libconf.band = conf->channel->band; - libconf.basic_rates =rt2x00_get_rate (rate->hw_value)->ratemask; + libconf.basic_rates =rt2x00lib_get_basic_rates (band); }if (flags &CONFIG_UPDATE_CHANNEL ) {
drivers/net/wireless/rt2x00/rt2x00dev.c +19 -19
@@ -766,75 +766,75 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);*/ const struct rt2x00_rate rt2x00_supported_rates[12 ] = { { - .flags =DEV_RATE_CCK , + .flags =DEV_RATE_CCK |DEV_RATE_BASIC , .bitrate =10 , - .ratemask =DEV_RATEMASK_1MB , + .ratemask =BIT (0 ), .plcp =0x00 , }, { - .flags =DEV_RATE_CCK |DEV_RATE_SHORT_PREAMBLE , + .flags =DEV_RATE_CCK |DEV_RATE_SHORT_PREAMBLE |DEV_RATE_BASIC , .bitrate =20 , - .ratemask =DEV_RATEMASK_2MB , + .ratemask =BIT (1 ), .plcp =0x01 , }, { - .flags =DEV_RATE_CCK |DEV_RATE_SHORT_PREAMBLE , + .flags =DEV_RATE_CCK |DEV_RATE_SHORT_PREAMBLE |DEV_RATE_BASIC , .bitrate =55 , - .ratemask =DEV_RATEMASK_5_5MB , + .ratemask =BIT (2 ), .plcp =0x02 , }, { - .flags =DEV_RATE_CCK |DEV_RATE_SHORT_PREAMBLE , + .flags =DEV_RATE_CCK |DEV_RATE_SHORT_PREAMBLE |DEV_RATE_BASIC , .bitrate =110 , - .ratemask =DEV_RATEMASK_11MB , + .ratemask =BIT (3 ), .plcp =0x03 , }, { - .flags =DEV_RATE_OFDM , + .flags =DEV_RATE_OFDM |DEV_RATE_BASIC , .bitrate =60 , - .ratemask =DEV_RATEMASK_6MB , + .ratemask =BIT (4 ), .plcp =0x0b , }, { .flags =DEV_RATE_OFDM , .bitrate =90 , - .ratemask =DEV_RATEMASK_9MB , + .ratemask =BIT (5 ), .plcp =0x0f , }, { - .flags =DEV_RATE_OFDM , + .flags =DEV_RATE_OFDM |DEV_RATE_BASIC , .bitrate =120 , - .ratemask =DEV_RATEMASK_12MB , + .ratemask =BIT (6 ), .plcp =0x0a , }, { .flags =DEV_RATE_OFDM , .bitrate =180 , - .ratemask =DEV_RATEMASK_18MB , + .ratemask =BIT (7 ), .plcp =0x0e , }, { - .flags =DEV_RATE_OFDM , + .flags =DEV_RATE_OFDM |DEV_RATE_BASIC , .bitrate =240 , - .ratemask =DEV_RATEMASK_24MB , + .ratemask =BIT (8 ), .plcp =0x09 , }, { .flags =DEV_RATE_OFDM , .bitrate =360 , - .ratemask =DEV_RATEMASK_36MB , + .ratemask =BIT (9 ), .plcp =0x0d , }, { .flags =DEV_RATE_OFDM , .bitrate =480 , - .ratemask =DEV_RATEMASK_48MB , + .ratemask =BIT (10 ), .plcp =0x08 , }, { .flags =DEV_RATE_OFDM , .bitrate =540 , - .ratemask =DEV_RATEMASK_54MB , + .ratemask =BIT (11 ), .plcp =0x0c , }, };
drivers/net/wireless/rt2x00/rt2x00lib.h +1 -13
@@ -41,22 +41,10 @@ struct rt2x00_rate {#define DEV_RATE_CCK 0x0001#define DEV_RATE_OFDM 0x0002#define DEV_RATE_SHORT_PREAMBLE 0x0004 +#define DEV_RATE_BASIC 0x0008unsigned short bitrate;/* In 100kbit/s */ -unsigned short ratemask; -#define DEV_RATEMASK_1MB ( (1 << 1) - 1 ) -#define DEV_RATEMASK_2MB ( (1 << 2) - 1 ) -#define DEV_RATEMASK_5_5MB ( (1 << 3) - 1 ) -#define DEV_RATEMASK_11MB ( (1 << 4) - 1 ) -#define DEV_RATEMASK_6MB ( (1 << 5) - 1 ) -#define DEV_RATEMASK_9MB ( (1 << 6) - 1 ) -#define DEV_RATEMASK_12MB ( (1 << 7) - 1 ) -#define DEV_RATEMASK_18MB ( (1 << 8) - 1 ) -#define DEV_RATEMASK_24MB ( (1 << 9) - 1 ) -#define DEV_RATEMASK_36MB ( (1 << 10) - 1 ) -#define DEV_RATEMASK_48MB ( (1 << 11) - 1 ) -#define DEV_RATEMASK_54MB ( (1 << 12) - 1 )unsigned short plcp; };
Signature · 1 line
1.5.4.3
PATCH 21/24 rt2x00: Fix compile error when rfkill is disabled
In reply to Ivo van DoornFix obvious error that prevented compilation while rfkill was disabled.
--- drivers/net/wireless/rt2x00/rt2x00lib.h | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
drivers/net/wireless/rt2x00/rt2x00lib.h +7 -2
@@ -171,8 +171,13 @@ static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) { } -static inline void rt2x00rfkill_suspend (struct rt2x00_dev *rt2x00dev); -static inline void rt2x00rfkill_resume (struct rt2x00_dev *rt2x00dev); +static inline void rt2x00rfkill_suspend (struct rt2x00_dev *rt2x00dev) +{ +} + +static inline void rt2x00rfkill_resume (struct rt2x00_dev *rt2x00dev) +{ +}#endif /* CONFIG_RT2X00_LIB_RFKILL */ /*
Signature · 1 line
1.5.4.3
PATCH 22/24 rt2x00: Fix RX DMA ring initialization
In reply to Ivo van DoornDue to a terrible typo the RX DMA base address was initialized to the beacon base address. Obviously bad things happen with bugs like that....
--- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +1 -1
@@ -669,7 +669,7 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) priv_rx = rt2x00dev->rx->entries[0 ].priv_data;rt2x00pci_register_read (rt2x00dev,RXCSR2 , ®); -rt2x00_set_field32 (®,RXCSR2_RX_RING_REGISTER , priv_tx->desc_dma); +rt2x00_set_field32 (®,RXCSR2_RX_RING_REGISTER , priv_rx->desc_dma);rt2x00pci_register_write (rt2x00dev,RXCSR2 , reg);return 0 ;
drivers/net/wireless/rt2x00/rt2500pci.c +1 -1
@@ -751,7 +751,7 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) priv_rx = rt2x00dev->rx->entries[0 ].priv_data;rt2x00pci_register_read (rt2x00dev,RXCSR2 , ®); -rt2x00_set_field32 (®,RXCSR2_RX_RING_REGISTER , priv_tx->desc_dma); +rt2x00_set_field32 (®,RXCSR2_RX_RING_REGISTER , priv_rx->desc_dma);rt2x00pci_register_write (rt2x00dev,RXCSR2 , reg);return 0 ;
Signature · 1 line
1.5.4.3
PATCH 23/24 rt2x00: Fix rt2400pci signal
In reply to Ivo van DoornAfter sampling hundreds of RX frame descriptors,
the results were conclusive:
- The Ralink documentation regarding the SIGNAL and RSSI are wrong.
It turns out that of the 5 BBR registers, we should not use BBR0 and BBR1 for SIGNAL and RSSI respectively, but actually BBR1 and BBR2. BBR0 does show values, but the exact meaning remains unclear, but they cannot be translated into a SIGNAL or RSSI field. BBR3, BBR4 and BBR5 are always 0, so their meaning is unknown.
As it turns out, the reported SIGNAL is the PLCP value, this in contradiction to what was expected looking at rt2500pci which only reported the PLCP values for OFDM rates and bitrate values for CCK rates.
This means we should let the driver raise the flag about the contents of the SIGNAL field so rt2x00lib can always do the right thing based on what the driver reports.
--- drivers/net/wireless/rt2x00/rt2400pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt2400pci.h | 6 +++--- drivers/net/wireless/rt2x00/rt2500pci.c | 9 ++++++++- drivers/net/wireless/rt2x00/rt2500usb.c | 6 +++++- drivers/net/wireless/rt2x00/rt2x00dev.c | 16 +++++++++------- drivers/net/wireless/rt2x00/rt2x00queue.h | 3 +++ drivers/net/wireless/rt2x00/rt61pci.c | 6 +++++- drivers/net/wireless/rt2x00/rt73usb.c | 6 +++++- 8 files changed, 43 insertions(+), 15 deletions(-)
drivers/net/wireless/rt2x00/rt2400pci.c +5 -1
@@ -1058,9 +1058,11 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;u32 word0;u32 word2; +u32 word3;rt2x00_desc_read (priv_rx->desc,0 , &word0);rt2x00_desc_read (priv_rx->desc,2 , &word2); +rt2x00_desc_read (priv_rx->desc,3 , &word3); rxdesc->flags =0 ;if (rt2x00_get_field32 (word0,RXD_W0_CRC_ERROR ))
@@ -1070,9 +1072,11 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,/* * Obtain the status about this packet. +* The signal is the PLCP value. */ rxdesc->signal =rt2x00_get_field32 (word2,RXD_W2_SIGNAL ); - rxdesc->rssi =rt2x00_get_field32 (word2,RXD_W2_RSSI ) - + rxdesc->signal_plcp =1 ; + rxdesc->rssi =rt2x00_get_field32 (word2,RXD_W3_RSSI ) - entry->queue->rt2x00dev->rssi_offset; rxdesc->ofdm =0 ; rxdesc->size =rt2x00_get_field32 (word0,RXD_W0_DATABYTE_COUNT );
drivers/net/wireless/rt2x00/rt2400pci.h +3 -3
@@ -899,13 +899,13 @@* Word2 */ #define RXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff) -#define RXD_W2_SIGNAL FIELD32(0x00ff0000) -#define RXD_W2_RSSI FIELD32(0xff000000) +#define RXD_W2_BBR0 FIELD32(0x00ff0000) +#define RXD_W2_SIGNAL FIELD32(0xff000000)/* * Word3 */ -#define RXD_W3_BBR2 FIELD32(0x000000ff) +#define RXD_W3_RSSI FIELD32(0x000000ff)#define RXD_W3_BBR3 FIELD32(0x0000ff00)#define RXD_W3_BBR4 FIELD32(0x00ff0000)#define RXD_W3_BBR5 FIELD32(0xff000000)
drivers/net/wireless/rt2x00/rt2500pci.c +8 -1
@@ -1219,10 +1219,17 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry,if (rt2x00_get_field32 (word0,RXD_W0_PHYSICAL_ERROR )) rxdesc->flags |=RX_FLAG_FAILED_PLCP_CRC ; +/* +* Obtain the status about this packet. +* When frame was received with an OFDM bitrate, +* the signal is the PLCP value. If it was received with +* a CCK bitrate the signal is the rate in 100kbit/s. +*/ + rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->signal =rt2x00_get_field32 (word2,RXD_W2_SIGNAL ); + rxdesc->signal_plcp = rxdesc->ofdm; rxdesc->rssi =rt2x00_get_field32 (word2,RXD_W2_RSSI ) - entry->queue->rt2x00dev->rssi_offset; - rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->size =rt2x00_get_field32 (word0,RXD_W0_DATABYTE_COUNT ); rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS ); }
drivers/net/wireless/rt2x00/rt2500usb.c +5 -1
@@ -1135,11 +1135,15 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,/* * Obtain the status about this packet. +* When frame was received with an OFDM bitrate, +* the signal is the PLCP value. If it was received with +* a CCK bitrate the signal is the rate in 100kbit/s. */ + rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->signal =rt2x00_get_field32 (word1,RXD_W1_SIGNAL ); + rxdesc->signal_plcp = rxdesc->ofdm; rxdesc->rssi =rt2x00_get_field32 (word1,RXD_W1_RSSI ) - entry->queue->rt2x00dev->rssi_offset; - rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->size =rt2x00_get_field32 (word0,RXD_W0_DATABYTE_COUNT ); rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS );
drivers/net/wireless/rt2x00/rt2x00dev.c +9 -7
@@ -574,19 +574,21 @@ void rt2x00lib_rxdone(struct queue_entry *entry,u16 fc;/* +* If the signal is the plcp value, +* we need to strip the preamble bit (0x08). +*/ +if (rxdesc->signal_plcp) + rxdesc->signal &= ~0x08 ; + +/* * Update RX statistics. */ sband = &rt2x00dev->bands[rt2x00dev->curr_band];for (i =0 ; i < sband->n_bitrates; i++) { rate =rt2x00_get_rate (sband->bitrates[i].hw_value); -/* -* When frame was received with an OFDM bitrate, -* the signal is the PLCP value. If it was received with -* a CCK bitrate the signal is the rate in 100kbit/s. -*/ -if ((rxdesc->ofdm && rate->plcp == rxdesc->signal) || - (!rxdesc->ofdm && rate->bitrate == rxdesc->signal)) { +if ((rxdesc->signal_plcp && rate->plcp == rxdesc->signal) || + (!rxdesc->signal_plcp && rate->bitrate == rxdesc->signal)) { idx = i;break ; }
drivers/net/wireless/rt2x00/rt2x00queue.h +3 -0
@@ -134,6 +134,8 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)* Summary of information that has been read from the RX frame descriptor. * * @signal: Signal of the received frame. +* @signal_plcp: Does the signal field contain the plcp value, +* or does it contain the bitrate itself. * @rssi: RSSI of the received frame. * @ofdm: Was frame send with an OFDM rate. * @size: Data size of the received frame.
@@ -142,6 +144,7 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)*/ struct rxdone_entry_desc {int signal; +int signal_plcp;int rssi;int ofdm;int size;
drivers/net/wireless/rt2x00/rt61pci.c +5 -1
@@ -1645,10 +1645,14 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,/* * Obtain the status about this packet. +* When frame was received with an OFDM bitrate, +* the signal is the PLCP value. If it was received with +* a CCK bitrate the signal is the rate in 100kbit/s. */ + rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->signal =rt2x00_get_field32 (word1,RXD_W1_SIGNAL ); + rxdesc->signal_plcp = rxdesc->ofdm; rxdesc->rssi =rt61pci_agc_to_rssi (entry->queue->rt2x00dev, word1); - rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->size =rt2x00_get_field32 (word0,RXD_W0_DATABYTE_COUNT ); rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS ); }
drivers/net/wireless/rt2x00/rt73usb.c +5 -1
@@ -1405,10 +1405,14 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,/* * Obtain the status about this packet. +* When frame was received with an OFDM bitrate, +* the signal is the PLCP value. If it was received with +* a CCK bitrate the signal is the rate in 100kbit/s. */ + rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->signal =rt2x00_get_field32 (word1,RXD_W1_SIGNAL ); + rxdesc->signal_plcp = rxdesc->ofdm; rxdesc->rssi =rt73usb_agc_to_rssi (entry->queue->rt2x00dev, word1); - rxdesc->ofdm =rt2x00_get_field32 (word0,RXD_W0_OFDM ); rxdesc->size =rt2x00_get_field32 (word0,RXD_W0_DATABYTE_COUNT ); rxdesc->my_bss = !!rt2x00_get_field32 (word0,RXD_W0_MY_BSS );
Signature · 1 line
1.5.4.3
PATCH 24/24 rt2x00: Release rt2x00 2.1.4
In reply to Ivo van DoornVersion bump to 2.1.4
--- drivers/net/wireless/rt2x00/rt2x00.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/rt2x00/rt2x00.h +1 -1
@@ -44,7 +44,7 @@/* * Module information. */ -#define DRV_VERSION "2.1.3" +#define DRV_VERSION "2.1.4"#define DRV_PROJECT "http://rt2x00.serialmonkey.com"/*
Signature · 1 line
1.5.4.3