The following patch series contains a list of fixes and cleanups for rt2x00.
Also included is a fix for mac80211 that fixes the insufficient headroom
bug reported by David Ellingsworth.
[PATCH 1/6] rt2x00: Only initialize HT on rt2800 devices that support it.
[PATCH 2/6] rt2x00: Remove unused variable frame_control from rt2x00mac_tx.
[PATCH 3/6] rt2x00: Clean up use of rt2x00_intf_is_pci.
[PATCH 4/6] rt2x00: Fix typo (lengt --> length) in rt2x00queue.c
[PATCH 5/6] rt2x00: Properly request tx headroom for alignment operations.
[PATCH 6/6] mac80211: Allow extra TX headroom to be consumed by drivers.
---
Gertjan.
Current rt2x00 drivers may result in a "ieee80211_tx_status: headroom too
small" error message when a frame needs to be properly aligned before
transmitting it.
This is because the space needed to ensure proper alignment isn't
requested from mac80211.
Fix this by adding sufficient amount of alignment space to the amount
of headroom requested for TX frames.
Reported-by: David Ellingsworth <[email protected]>
Signed-off-by: Gertjan van Wingerde <[email protected]>
Tested-by: David Ellingsworth <[email protected]>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 30 +++++++++++++++-------------
drivers/net/wireless/rt2x00/rt2500pci.c | 30 +++++++++++++++-------------
drivers/net/wireless/rt2x00/rt2500usb.c | 29 ++++++++++++++-------------
drivers/net/wireless/rt2x00/rt2800lib.c | 7 +----
drivers/net/wireless/rt2x00/rt2800pci.c | 31 +++++++++++++++--------------
drivers/net/wireless/rt2x00/rt2800usb.c | 25 ++++++++++++-----------
drivers/net/wireless/rt2x00/rt2x00.h | 7 ++++++
drivers/net/wireless/rt2x00/rt2x00queue.c | 6 ++--
drivers/net/wireless/rt2x00/rt61pci.c | 28 ++++++++++++++------------
drivers/net/wireless/rt2x00/rt73usb.c | 27 +++++++++++++------------
10 files changed, 117 insertions(+), 103 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 6e68bc7..f534d70 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1432,7 +1432,8 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
- rt2x00dev->hw->extra_tx_headroom = 0;
+ rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
+ RT2X00_ALIGN_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1623,20 +1624,21 @@ static const struct data_queue_desc rt2400pci_queue_atim = {
};
static const struct rt2x00_ops rt2400pci_ops = {
- .name = KBUILD_MODNAME,
- .max_sta_intf = 1,
- .max_ap_intf = 1,
- .eeprom_size = EEPROM_SIZE,
- .rf_size = RF_SIZE,
- .tx_queues = NUM_TX_QUEUES,
- .rx = &rt2400pci_queue_rx,
- .tx = &rt2400pci_queue_tx,
- .bcn = &rt2400pci_queue_bcn,
- .atim = &rt2400pci_queue_atim,
- .lib = &rt2400pci_rt2x00_ops,
- .hw = &rt2400pci_mac80211_ops,
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 1,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .extra_tx_headroom = 0,
+ .rx = &rt2400pci_queue_rx,
+ .tx = &rt2400pci_queue_tx,
+ .bcn = &rt2400pci_queue_bcn,
+ .atim = &rt2400pci_queue_atim,
+ .lib = &rt2400pci_rt2x00_ops,
+ .hw = &rt2400pci_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
- .debugfs = &rt2400pci_rt2x00debug,
+ .debugfs = &rt2400pci_rt2x00debug,
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 9a31e5e..ae40947 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1733,7 +1733,8 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
- rt2x00dev->hw->extra_tx_headroom = 0;
+ rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
+ RT2X00_ALIGN_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1922,20 +1923,21 @@ static const struct data_queue_desc rt2500pci_queue_atim = {
};
static const struct rt2x00_ops rt2500pci_ops = {
- .name = KBUILD_MODNAME,
- .max_sta_intf = 1,
- .max_ap_intf = 1,
- .eeprom_size = EEPROM_SIZE,
- .rf_size = RF_SIZE,
- .tx_queues = NUM_TX_QUEUES,
- .rx = &rt2500pci_queue_rx,
- .tx = &rt2500pci_queue_tx,
- .bcn = &rt2500pci_queue_bcn,
- .atim = &rt2500pci_queue_atim,
- .lib = &rt2500pci_rt2x00_ops,
- .hw = &rt2500pci_mac80211_ops,
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 1,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .extra_tx_headroom = 0,
+ .rx = &rt2500pci_queue_rx,
+ .tx = &rt2500pci_queue_tx,
+ .bcn = &rt2500pci_queue_bcn,
+ .atim = &rt2500pci_queue_atim,
+ .lib = &rt2500pci_rt2x00_ops,
+ .hw = &rt2500pci_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
- .debugfs = &rt2500pci_rt2x00debug,
+ .debugfs = &rt2500pci_rt2x00debug,
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index b2de43e..02b2e1c 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1656,7 +1656,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
- rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
+ rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -1823,20 +1823,21 @@ static const struct data_queue_desc rt2500usb_queue_atim = {
};
static const struct rt2x00_ops rt2500usb_ops = {
- .name = KBUILD_MODNAME,
- .max_sta_intf = 1,
- .max_ap_intf = 1,
- .eeprom_size = EEPROM_SIZE,
- .rf_size = RF_SIZE,
- .tx_queues = NUM_TX_QUEUES,
- .rx = &rt2500usb_queue_rx,
- .tx = &rt2500usb_queue_tx,
- .bcn = &rt2500usb_queue_bcn,
- .atim = &rt2500usb_queue_atim,
- .lib = &rt2500usb_rt2x00_ops,
- .hw = &rt2500usb_mac80211_ops,
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 1,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .extra_tx_headroom = TXD_DESC_SIZE,
+ .rx = &rt2500usb_queue_rx,
+ .tx = &rt2500usb_queue_tx,
+ .bcn = &rt2500usb_queue_bcn,
+ .atim = &rt2500usb_queue_atim,
+ .lib = &rt2500usb_rt2x00_ops,
+ .hw = &rt2500usb_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
- .debugfs = &rt2500usb_rt2x00debug,
+ .debugfs = &rt2500usb_rt2x00debug,
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b809c49..de358b5 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2030,11 +2030,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
- if (rt2x00_intf_is_usb(rt2x00dev))
- rt2x00dev->hw->extra_tx_headroom =
- TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
- else if (rt2x00_intf_is_pci(rt2x00dev))
- rt2x00dev->hw->extra_tx_headroom = TXWI_DESC_SIZE;
+ rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
+ RT2X00_L2PAD_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 87a5094..dfc886f 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -652,7 +652,7 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txd = skbdesc->desc;
- __le32 *txwi = (__le32 *)(skb->data - rt2x00dev->hw->extra_tx_headroom);
+ __le32 *txwi = (__le32 *)(skb->data - rt2x00dev->ops->extra_tx_headroom);
u32 word;
/*
@@ -725,14 +725,14 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W1_BURST,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W1_SD_LEN0,
- rt2x00dev->hw->extra_tx_headroom);
+ rt2x00dev->ops->extra_tx_headroom);
rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
- skbdesc->skb_dma + rt2x00dev->hw->extra_tx_headroom);
+ skbdesc->skb_dma + rt2x00dev->ops->extra_tx_headroom);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
@@ -1201,19 +1201,20 @@ static const struct data_queue_desc rt2800pci_queue_bcn = {
};
static const struct rt2x00_ops rt2800pci_ops = {
- .name = KBUILD_MODNAME,
- .max_sta_intf = 1,
- .max_ap_intf = 8,
- .eeprom_size = EEPROM_SIZE,
- .rf_size = RF_SIZE,
- .tx_queues = NUM_TX_QUEUES,
- .rx = &rt2800pci_queue_rx,
- .tx = &rt2800pci_queue_tx,
- .bcn = &rt2800pci_queue_bcn,
- .lib = &rt2800pci_rt2x00_ops,
- .hw = &rt2800_mac80211_ops,
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 8,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .extra_tx_headroom = TXWI_DESC_SIZE,
+ .rx = &rt2800pci_queue_rx,
+ .tx = &rt2800pci_queue_tx,
+ .bcn = &rt2800pci_queue_bcn,
+ .lib = &rt2800pci_rt2x00_ops,
+ .hw = &rt2800_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
- .debugfs = &rt2800_rt2x00debug,
+ .debugfs = &rt2800_rt2x00debug,
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 9ab15c4..af85d18 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -790,19 +790,20 @@ static const struct data_queue_desc rt2800usb_queue_bcn = {
};
static const struct rt2x00_ops rt2800usb_ops = {
- .name = KBUILD_MODNAME,
- .max_sta_intf = 1,
- .max_ap_intf = 8,
- .eeprom_size = EEPROM_SIZE,
- .rf_size = RF_SIZE,
- .tx_queues = NUM_TX_QUEUES,
- .rx = &rt2800usb_queue_rx,
- .tx = &rt2800usb_queue_tx,
- .bcn = &rt2800usb_queue_bcn,
- .lib = &rt2800usb_rt2x00_ops,
- .hw = &rt2800_mac80211_ops,
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 8,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
+ .rx = &rt2800usb_queue_rx,
+ .tx = &rt2800usb_queue_tx,
+ .bcn = &rt2800usb_queue_bcn,
+ .lib = &rt2800usb_rt2x00_ops,
+ .hw = &rt2800_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
- .debugfs = &rt2800_rt2x00debug,
+ .debugfs = &rt2800_rt2x00debug,
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 1cbb7ac..83008ab 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -113,6 +113,12 @@
( ((unsigned long)((__skb)->data + (__header))) & 3 )
/*
+ * Constants for extra TX headroom for alignment purposes.
+ */
+#define RT2X00_ALIGN_SIZE 4
+#define RT2X00_L2PAD_SIZE 8
+
+/*
* Standard timing and size defines.
* These values should follow the ieee80211 specifications.
*/
@@ -588,6 +594,7 @@ struct rt2x00_ops {
const unsigned int eeprom_size;
const unsigned int rf_size;
const unsigned int tx_queues;
+ const unsigned int extra_tx_headroom;
const struct data_queue_desc *rx;
const struct data_queue_desc *tx;
const struct data_queue_desc *bcn;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 32d4aea..769a8a2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -104,7 +104,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
* is also mapped to the DMA so it can be used for transfering
* additional descriptor information to the hardware.
*/
- skb_push(skb, rt2x00dev->hw->extra_tx_headroom);
+ skb_push(skb, rt2x00dev->ops->extra_tx_headroom);
skbdesc->skb_dma =
dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
@@ -112,7 +112,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
/*
* Restore data pointer to original location again.
*/
- skb_pull(skb, rt2x00dev->hw->extra_tx_headroom);
+ skb_pull(skb, rt2x00dev->ops->extra_tx_headroom);
skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
}
@@ -134,7 +134,7 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
* by the driver, but it was actually mapped to DMA.
*/
dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
- skb->len + rt2x00dev->hw->extra_tx_headroom,
+ skb->len + rt2x00dev->ops->extra_tx_headroom,
DMA_TO_DEVICE);
skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
}
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index bf04605..956f6be 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2546,7 +2546,8 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
- rt2x00dev->hw->extra_tx_headroom = 0;
+ rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
+ RT2X00_ALIGN_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2788,19 +2789,20 @@ static const struct data_queue_desc rt61pci_queue_bcn = {
};
static const struct rt2x00_ops rt61pci_ops = {
- .name = KBUILD_MODNAME,
- .max_sta_intf = 1,
- .max_ap_intf = 4,
- .eeprom_size = EEPROM_SIZE,
- .rf_size = RF_SIZE,
- .tx_queues = NUM_TX_QUEUES,
- .rx = &rt61pci_queue_rx,
- .tx = &rt61pci_queue_tx,
- .bcn = &rt61pci_queue_bcn,
- .lib = &rt61pci_rt2x00_ops,
- .hw = &rt61pci_mac80211_ops,
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 4,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .extra_tx_headroom = 0,
+ .rx = &rt61pci_queue_rx,
+ .tx = &rt61pci_queue_tx,
+ .bcn = &rt61pci_queue_bcn,
+ .lib = &rt61pci_rt2x00_ops,
+ .hw = &rt61pci_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
- .debugfs = &rt61pci_rt2x00debug,
+ .debugfs = &rt61pci_rt2x00debug,
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 5bbcf66..d4317dd 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2069,7 +2069,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_PS_NULLFUNC_STACK;
- rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
+ rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
@@ -2306,19 +2306,20 @@ static const struct data_queue_desc rt73usb_queue_bcn = {
};
static const struct rt2x00_ops rt73usb_ops = {
- .name = KBUILD_MODNAME,
- .max_sta_intf = 1,
- .max_ap_intf = 4,
- .eeprom_size = EEPROM_SIZE,
- .rf_size = RF_SIZE,
- .tx_queues = NUM_TX_QUEUES,
- .rx = &rt73usb_queue_rx,
- .tx = &rt73usb_queue_tx,
- .bcn = &rt73usb_queue_bcn,
- .lib = &rt73usb_rt2x00_ops,
- .hw = &rt73usb_mac80211_ops,
+ .name = KBUILD_MODNAME,
+ .max_sta_intf = 1,
+ .max_ap_intf = 4,
+ .eeprom_size = EEPROM_SIZE,
+ .rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
+ .extra_tx_headroom = TXD_DESC_SIZE,
+ .rx = &rt73usb_queue_rx,
+ .tx = &rt73usb_queue_tx,
+ .bcn = &rt73usb_queue_bcn,
+ .lib = &rt73usb_rt2x00_ops,
+ .hw = &rt73usb_mac80211_ops,
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
- .debugfs = &rt73usb_rt2x00debug,
+ .debugfs = &rt73usb_rt2x00debug,
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
};
--
1.6.5.3
Allow drivers to consume the extra TX headroom they are requesting instead
of assuming they will give it back. This specifically is the case for
the rt2x00 driver, as a large part of the requested extra TX headroom is
used to properly align the frame for DMA usage, and the frame is never
moved back to the original location.
Fix this by reserving TX headroom accounting for both the driver requested
amount and the special monitor interface header that needs to be added,
instead of just the maximum of the two.
See http://marc.info/?l=linux-kernel&m=125892467801662&w=2 for details.
Reported-by: David Ellingsworth <[email protected]>
Signed-off-by: Gertjan van Wingerde <[email protected]>
Tested-by: David Ellingsworth <[email protected]>
Cc: Johannes Berg <[email protected]>
---
net/mac80211/main.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index dd8ec8d..e666b66 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -515,8 +515,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
* and we need some headroom for passing the frame to monitor
* interfaces, but never both at the same time.
*/
- local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
- sizeof(struct ieee80211_tx_status_rtap_hdr));
+ local->tx_headroom = local->hw.extra_tx_headroom +
+ sizeof(struct ieee80211_tx_status_rtap_hdr);
debugfs_hw_add(local);
--
1.6.5.3
On 11/23/09 10:58, Simon Raffeiner wrote:
> Am Montag, 23. November 2009 08:16:00 schrieb Gertjan van Wingerde:
>> Some RT28xx/RT30xx devices don't support 802.11n, when they are combined with
>> the RF2020 chipset. Ensure that HT is disabled for these devices.
>
> Hi Gertjan,
>
> do you know if this fixes the RT2070L chipset? It's an RT3070 descendant without 802.11n support, I cracked the device open and there's no RF2020 to be seen - just a single RT2070L chip. Somebody posted that the RT2070L has the RF part integrated to make it cheaper, maybe RT2070 = RT3070 + RF2020 in a single chip?
>
> I can't test my own device at the moment.
>
Hi Simon,
I would be surprised if this fixes the RT2070L chipset, but it is a
small step in the right direction.
My guess is that the RT2070L chipset is a RT3070 combined with a RF2020 in
a single chip. At least that is how my RT2070L device identifies itself.
---
Gertjan.
On Monday 23 November 2009, Gertjan van Wingerde wrote:
> Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
> ---
> drivers/net/wireless/rt2x00/rt2x00queue.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
> index eaedee8..32d4aea 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
> @@ -162,10 +162,10 @@ void rt2x00queue_align_frame(struct sk_buff *skb)
> skb_trim(skb, frame_length);
> }
>
> -void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_lengt)
> +void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
> {
> unsigned int frame_length = skb->len;
> - unsigned int align = ALIGN_SIZE(skb, header_lengt);
> + unsigned int align = ALIGN_SIZE(skb, header_length);
>
> if (!align)
> return;
As additional fallout also remove the also unused variable ieee80211hdr.
Reported-by: Johannes Stezenbach <[email protected]>
Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2x00mac.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 9c90ceb..de549c2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -103,10 +103,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
enum data_queue_qid qid = skb_get_queue_mapping(skb);
struct data_queue *queue;
- u16 frame_control;
/*
* Mac80211 might be calling this function while we are trying
@@ -141,7 +139,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* either RTS or CTS-to-self frame and handles everything
* inside the hardware.
*/
- frame_control = le16_to_cpu(ieee80211hdr->frame_control);
if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
IEEE80211_TX_RC_USE_CTS_PROTECT)) &&
!rt2x00dev->ops->hw->set_rts_threshold) {
--
1.6.5.3
On Mon, Nov 23, 2009 at 18:16, Gertjan van Wingerde <[email protected]> wrote:
> Current rt2x00 drivers may result in a "ieee80211_tx_status: headroom too
> small" error message when a frame needs to be properly aligned before
> transmitting it.
> This is because the space needed to ensure proper alignment isn't
> requested from mac80211.
> Fix this by adding sufficient amount of alignment space to the amount
> of headroom requested for TX frames.
>
> Reported-by: David Ellingsworth <[email protected]>
> Signed-off-by: Gertjan van Wingerde <[email protected]>
> Tested-by: David Ellingsworth <[email protected]>
> ---
> ?drivers/net/wireless/rt2x00/rt2400pci.c ? | ? 30 +++++++++++++++-------------
> ?drivers/net/wireless/rt2x00/rt2500pci.c ? | ? 30 +++++++++++++++-------------
> ?drivers/net/wireless/rt2x00/rt2500usb.c ? | ? 29 ++++++++++++++-------------
> ?drivers/net/wireless/rt2x00/rt2800lib.c ? | ? ?7 +----
> ?drivers/net/wireless/rt2x00/rt2800pci.c ? | ? 31 +++++++++++++++--------------
> ?drivers/net/wireless/rt2x00/rt2800usb.c ? | ? 25 ++++++++++++-----------
> ?drivers/net/wireless/rt2x00/rt2x00.h ? ? ?| ? ?7 ++++++
> ?drivers/net/wireless/rt2x00/rt2x00queue.c | ? ?6 ++--
> ?drivers/net/wireless/rt2x00/rt61pci.c ? ? | ? 28 ++++++++++++++------------
> ?drivers/net/wireless/rt2x00/rt73usb.c ? ? | ? 27 +++++++++++++------------
> ?10 files changed, 117 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
> index 6e68bc7..f534d70 100644
> --- a/drivers/net/wireless/rt2x00/rt2400pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2400pci.c
> @@ -1623,20 +1624,21 @@ static const struct data_queue_desc rt2400pci_queue_atim = {
> ?};
>
> ?static const struct rt2x00_ops rt2400pci_ops = {
> - ? ? ? .name ? ? ? ? ? = KBUILD_MODNAME,
> - ? ? ? .max_sta_intf ? = 1,
> - ? ? ? .max_ap_intf ? ?= 1,
> - ? ? ? .eeprom_size ? ?= EEPROM_SIZE,
> - ? ? ? .rf_size ? ? ? ?= RF_SIZE,
> - ? ? ? .tx_queues ? ? ?= NUM_TX_QUEUES,
> - ? ? ? .rx ? ? ? ? ? ? = &rt2400pci_queue_rx,
> - ? ? ? .tx ? ? ? ? ? ? = &rt2400pci_queue_tx,
> - ? ? ? .bcn ? ? ? ? ? ?= &rt2400pci_queue_bcn,
> - ? ? ? .atim ? ? ? ? ? = &rt2400pci_queue_atim,
> - ? ? ? .lib ? ? ? ? ? ?= &rt2400pci_rt2x00_ops,
> - ? ? ? .hw ? ? ? ? ? ? = &rt2400pci_mac80211_ops,
> + ? ? ? .name ? ? ? ? ? ? ? ? ? = KBUILD_MODNAME,
> + ? ? ? .max_sta_intf ? ? ? ? ? = 1,
> + ? ? ? .max_ap_intf ? ? ? ? ? ?= 1,
> + ? ? ? .eeprom_size ? ? ? ? ? ?= EEPROM_SIZE,
> + ? ? ? .rf_size ? ? ? ? ? ? ? ?= RF_SIZE,
> + ? ? ? .tx_queues ? ? ? ? ? ? ?= NUM_TX_QUEUES,
> + ? ? ? .extra_tx_headroom ? ? ?= 0,
> + ? ? ? .rx ? ? ? ? ? ? ? ? ? ? = &rt2400pci_queue_rx,
> + ? ? ? .tx ? ? ? ? ? ? ? ? ? ? = &rt2400pci_queue_tx,
> + ? ? ? .bcn ? ? ? ? ? ? ? ? ? ?= &rt2400pci_queue_bcn,
> + ? ? ? .atim ? ? ? ? ? ? ? ? ? = &rt2400pci_queue_atim,
> + ? ? ? .lib ? ? ? ? ? ? ? ? ? ?= &rt2400pci_rt2x00_ops,
> + ? ? ? .hw ? ? ? ? ? ? ? ? ? ? = &rt2400pci_mac80211_ops,
> ?#ifdef CONFIG_RT2X00_LIB_DEBUGFS
> - ? ? ? .debugfs ? ? ? ?= &rt2400pci_rt2x00debug,
> + ? ? ? .debugfs ? ? ? ? ? ? ? ?= &rt2400pci_rt2x00debug,
> ?#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
> ?};
Shouldn't the re-formatting of the ops structures (and addition of the
.debugfs member) go in a separate patch?
Thanks,
--
Julian Calaby
Email: [email protected]
.Plan: http://sites.google.com/site/juliancalaby/
On Monday 23 November 2009, Gertjan van Wingerde wrote:
> RT chipsets are unique across both PCI and USB busses, and don't overlap.
> Therefore there is no need to test for bus type when only checking for
> chipset type. Remove the redundant checks.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
Am Montag, 23. November 2009 08:16:00 schrieb Gertjan van Wingerde:
> Some RT28xx/RT30xx devices don't support 802.11n, when they are combined with
> the RF2020 chipset. Ensure that HT is disabled for these devices.
Hi Gertjan,
do you know if this fixes the RT2070L chipset? It's an RT3070 descendant without 802.11n support, I cracked the device open and there's no RF2020 to be seen - just a single RT2070L chip. Somebody posted that the RT2070L has the RF part integrated to make it cheaper, maybe RT2070 = RT3070 + RF2020 in a single chip?
I can't test my own device at the moment.
regards
Simon Raffeiner
On 11/23/09 11:41, Johannes Berg wrote:
> On Mon, 2009-11-23 at 08:16 +0100, Gertjan van Wingerde wrote:
>> Allow drivers to consume the extra TX headroom they are requesting instead
>> of assuming they will give it back. This specifically is the case for
>> the rt2x00 driver, as a large part of the requested extra TX headroom is
>> used to properly align the frame for DMA usage, and the frame is never
>> moved back to the original location.
>> Fix this by reserving TX headroom accounting for both the driver requested
>> amount and the special monitor interface header that needs to be added,
>> instead of just the maximum of the two.
>>
>> See http://marc.info/?l=linux-kernel&m=125892467801662&w=2 for details.
>
>> - local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
>> - sizeof(struct ieee80211_tx_status_rtap_hdr));
>> + local->tx_headroom = local->hw.extra_tx_headroom +
>> + sizeof(struct ieee80211_tx_status_rtap_hdr);
>
> Even though the radiotap header currently is only 13 bytes long, I don't
> really like this, you're not consuming all of extra_tx_headroom! I'd
> rather have a definition somewhere
>
> #define MAC80211_TX_STATUS_HEADROOM 13
>
> (with a BUILD_BUG_ON(sizeof(rtap_hdr) == MAC80211_TX_STATUS_HEADROOM))
> so that you can make the driver set
> extra_tx_headroom = max_t(MAC80211_TX_STATUS_HEADROOM, txi) + align;
>
We're just talking about a small amount of bytes (max 8 in the rt2x00 case),
but I'll look into this direction.
Probably will have to combine patches 5 & 6 of the series then, though.
---
Gertjan.
On 11/23/09 19:12, Ivo van Doorn wrote:
> On Monday 23 November 2009, Gertjan van Wingerde wrote:
>> Some RT28xx/RT30xx devices don't support 802.11n, when they are combined with
>> the RF2020 chipset. Ensure that HT is disabled for these devices.
>>
>> Signed-off-by: Gertjan van Wingerde <[email protected]>
>> ---
>> drivers/net/wireless/rt2x00/rt2800lib.c | 59 +++++++++++++++++--------------
>> 1 files changed, 32 insertions(+), 27 deletions(-)
>>
>> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
>> index e94f1e1..ac393c3 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
>> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
>> @@ -2070,34 +2070,39 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>> }
>>
>> /*
>> - * Initialize HT information.
>> + * Initialize HT information, unless when we're on RF2020, which doesn't
>> + * support 802.11n.
>> */
>> - spec->ht.ht_supported = true;
>> - spec->ht.cap =
>> - IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
>> - IEEE80211_HT_CAP_GRN_FLD |
>> - IEEE80211_HT_CAP_SGI_20 |
>> - IEEE80211_HT_CAP_SGI_40 |
>> - IEEE80211_HT_CAP_TX_STBC |
>> - IEEE80211_HT_CAP_RX_STBC |
>> - IEEE80211_HT_CAP_PSMP_SUPPORT;
>> - spec->ht.ampdu_factor = 3;
>> - spec->ht.ampdu_density = 4;
>> - spec->ht.mcs.tx_params =
>> - IEEE80211_HT_MCS_TX_DEFINED |
>> - IEEE80211_HT_MCS_TX_RX_DIFF |
>> - ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
>> - IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
>> -
>> - switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
>> - case 3:
>> - spec->ht.mcs.rx_mask[2] = 0xff;
>> - case 2:
>> - spec->ht.mcs.rx_mask[1] = 0xff;
>> - case 1:
>> - spec->ht.mcs.rx_mask[0] = 0xff;
>> - spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
>> - break;
>> + if (!rt2x00_rf(chip, RF2020)) {
>> + spec->ht.ht_supported = true;
>> + spec->ht.cap =
>> + IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
>> + IEEE80211_HT_CAP_GRN_FLD |
>> + IEEE80211_HT_CAP_SGI_20 |
>> + IEEE80211_HT_CAP_SGI_40 |
>> + IEEE80211_HT_CAP_TX_STBC |
>> + IEEE80211_HT_CAP_RX_STBC |
>> + IEEE80211_HT_CAP_PSMP_SUPPORT;
>> + spec->ht.ampdu_factor = 3;
>> + spec->ht.ampdu_density = 4;
>> + spec->ht.mcs.tx_params =
>> + IEEE80211_HT_MCS_TX_DEFINED |
>> + IEEE80211_HT_MCS_TX_RX_DIFF |
>> + ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
>> + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
>> +
>> + switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
>> + case 3:
>> + spec->ht.mcs.rx_mask[2] = 0xff;
>> + case 2:
>> + spec->ht.mcs.rx_mask[1] = 0xff;
>> + case 1:
>> + spec->ht.mcs.rx_mask[0] = 0xff;
>> + spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
>> + break;
>> + }
>> + } else {
>> + spec->ht.ht_supported = false;
>
> Isn't it sufficient to only set spec->ht.ht_supported to true or false?
> mac80211 should ignore all ht parameters if ht_supported is set to
> false anyway (and it saves quite a lot of indenting).
>
I wasn't sure of that. I presume that that would be the case. Not sure if it
is clean to initialize all the ht parameters when it isn't necessary, but I'm
indifferent to that.
I'll respin with your suggestion.
---
Gertjan.
On 11/23/09 11:38, Johannes Berg wrote:
> On Mon, 2009-11-23 at 08:16 +0100, Gertjan van Wingerde wrote:
>
> This patch would be a LOT easier to read if you didn't do unrelated
> whitespace cleanups.
>
Well their not really unrelated (they ensure that everything is still properly
lined out when the new member extra_tx_headroom is added), but I can see that
it distracts from the real "meat" of the patch.
I'll see if I can do a preparatory "whitespace cleanup" patch.
---
Gertjan.
On Monday 23 November 2009, Gertjan van Wingerde wrote:
> Current rt2x00 drivers may result in a "ieee80211_tx_status: headroom too
> small" error message when a frame needs to be properly aligned before
> transmitting it.
> This is because the space needed to ensure proper alignment isn't
> requested from mac80211.
> Fix this by adding sufficient amount of alignment space to the amount
> of headroom requested for TX frames.
>
> Reported-by: David Ellingsworth <[email protected]>
> Signed-off-by: Gertjan van Wingerde <[email protected]>
> Tested-by: David Ellingsworth <[email protected]>
> ---
> drivers/net/wireless/rt2x00/rt2400pci.c | 30 +++++++++++++++-------------
> drivers/net/wireless/rt2x00/rt2500pci.c | 30 +++++++++++++++-------------
> drivers/net/wireless/rt2x00/rt2500usb.c | 29 ++++++++++++++-------------
> drivers/net/wireless/rt2x00/rt2800lib.c | 7 +----
> drivers/net/wireless/rt2x00/rt2800pci.c | 31 +++++++++++++++--------------
> drivers/net/wireless/rt2x00/rt2800usb.c | 25 ++++++++++++-----------
> drivers/net/wireless/rt2x00/rt2x00.h | 7 ++++++
> drivers/net/wireless/rt2x00/rt2x00queue.c | 6 ++--
> drivers/net/wireless/rt2x00/rt61pci.c | 28 ++++++++++++++------------
> drivers/net/wireless/rt2x00/rt73usb.c | 27 +++++++++++++------------
> 10 files changed, 117 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
> index 6e68bc7..f534d70 100644
> --- a/drivers/net/wireless/rt2x00/rt2400pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2400pci.c
> @@ -1432,7 +1432,8 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> IEEE80211_HW_SIGNAL_DBM |
> IEEE80211_HW_SUPPORTS_PS |
> IEEE80211_HW_PS_NULLFUNC_STACK;
> - rt2x00dev->hw->extra_tx_headroom = 0;
> + rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
> + RT2X00_ALIGN_SIZE;
Can't rt2x00lib initialize rt2x00dev->hw->extra_tx_headroom?
The drivers aren't performing the aligning, so it is logical that rt2x00lib
adds the required bytes rather than the drivers. The driver already sets
the value in ops->extra_tx_headroom, so it can rely on rt2x00lib to do the rest.
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index b809c49..de358b5 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -2030,11 +2030,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> IEEE80211_HW_SUPPORTS_PS |
> IEEE80211_HW_PS_NULLFUNC_STACK;
>
> - if (rt2x00_intf_is_usb(rt2x00dev))
> - rt2x00dev->hw->extra_tx_headroom =
> - TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
> - else if (rt2x00_intf_is_pci(rt2x00dev))
> - rt2x00dev->hw->extra_tx_headroom = TXWI_DESC_SIZE;
> + rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
> + RT2X00_L2PAD_SIZE;
In this case we don't use RT2X00_ALIGN_SIZE, but the driver does set a flag to tell
rt2x00lib that L2padding should be used rather then aligning. So this case would still
hold when it is moved to rt2x00lib.
> /*
> + * Constants for extra TX headroom for alignment purposes.
> + */
> +#define RT2X00_ALIGN_SIZE 4
> +#define RT2X00_L2PAD_SIZE 8
#define RT2X00_L2PAD_SIZE RT2X00_ALIGN_SIZE + 4
Would probably better indicate why you are using 8.
Ivo
On Monday 23 November 2009, Gertjan van Wingerde wrote:
> Some RT28xx/RT30xx devices don't support 802.11n, when they are combined with
> the RF2020 chipset. Ensure that HT is disabled for these devices.
>
> Signed-off-by: Gertjan van Wingerde <[email protected]>
> ---
> drivers/net/wireless/rt2x00/rt2800lib.c | 59 +++++++++++++++++--------------
> 1 files changed, 32 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index e94f1e1..ac393c3 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -2070,34 +2070,39 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
> }
>
> /*
> - * Initialize HT information.
> + * Initialize HT information, unless when we're on RF2020, which doesn't
> + * support 802.11n.
> */
> - spec->ht.ht_supported = true;
> - spec->ht.cap =
> - IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
> - IEEE80211_HT_CAP_GRN_FLD |
> - IEEE80211_HT_CAP_SGI_20 |
> - IEEE80211_HT_CAP_SGI_40 |
> - IEEE80211_HT_CAP_TX_STBC |
> - IEEE80211_HT_CAP_RX_STBC |
> - IEEE80211_HT_CAP_PSMP_SUPPORT;
> - spec->ht.ampdu_factor = 3;
> - spec->ht.ampdu_density = 4;
> - spec->ht.mcs.tx_params =
> - IEEE80211_HT_MCS_TX_DEFINED |
> - IEEE80211_HT_MCS_TX_RX_DIFF |
> - ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
> - IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
> -
> - switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
> - case 3:
> - spec->ht.mcs.rx_mask[2] = 0xff;
> - case 2:
> - spec->ht.mcs.rx_mask[1] = 0xff;
> - case 1:
> - spec->ht.mcs.rx_mask[0] = 0xff;
> - spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
> - break;
> + if (!rt2x00_rf(chip, RF2020)) {
> + spec->ht.ht_supported = true;
> + spec->ht.cap =
> + IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
> + IEEE80211_HT_CAP_GRN_FLD |
> + IEEE80211_HT_CAP_SGI_20 |
> + IEEE80211_HT_CAP_SGI_40 |
> + IEEE80211_HT_CAP_TX_STBC |
> + IEEE80211_HT_CAP_RX_STBC |
> + IEEE80211_HT_CAP_PSMP_SUPPORT;
> + spec->ht.ampdu_factor = 3;
> + spec->ht.ampdu_density = 4;
> + spec->ht.mcs.tx_params =
> + IEEE80211_HT_MCS_TX_DEFINED |
> + IEEE80211_HT_MCS_TX_RX_DIFF |
> + ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
> + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
> +
> + switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
> + case 3:
> + spec->ht.mcs.rx_mask[2] = 0xff;
> + case 2:
> + spec->ht.mcs.rx_mask[1] = 0xff;
> + case 1:
> + spec->ht.mcs.rx_mask[0] = 0xff;
> + spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
> + break;
> + }
> + } else {
> + spec->ht.ht_supported = false;
Isn't it sufficient to only set spec->ht.ht_supported to true or false?
mac80211 should ignore all ht parameters if ht_supported is set to
false anyway (and it saves quite a lot of indenting).
Ivo
Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2x00queue.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index eaedee8..32d4aea 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -162,10 +162,10 @@ void rt2x00queue_align_frame(struct sk_buff *skb)
skb_trim(skb, frame_length);
}
-void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_lengt)
+void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
{
unsigned int frame_length = skb->len;
- unsigned int align = ALIGN_SIZE(skb, header_lengt);
+ unsigned int align = ALIGN_SIZE(skb, header_length);
if (!align)
return;
--
1.6.5.3
On Mon, 2009-11-23 at 08:16 +0100, Gertjan van Wingerde wrote:
This patch would be a LOT easier to read if you didn't do unrelated
whitespace cleanups.
johannes
Some RT28xx/RT30xx devices don't support 802.11n, when they are combined with
the RF2020 chipset. Ensure that HT is disabled for these devices.
Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 59 +++++++++++++++++--------------
1 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index e94f1e1..ac393c3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2070,34 +2070,39 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
}
/*
- * Initialize HT information.
+ * Initialize HT information, unless when we're on RF2020, which doesn't
+ * support 802.11n.
*/
- spec->ht.ht_supported = true;
- spec->ht.cap =
- IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
- IEEE80211_HT_CAP_GRN_FLD |
- IEEE80211_HT_CAP_SGI_20 |
- IEEE80211_HT_CAP_SGI_40 |
- IEEE80211_HT_CAP_TX_STBC |
- IEEE80211_HT_CAP_RX_STBC |
- IEEE80211_HT_CAP_PSMP_SUPPORT;
- spec->ht.ampdu_factor = 3;
- spec->ht.ampdu_density = 4;
- spec->ht.mcs.tx_params =
- IEEE80211_HT_MCS_TX_DEFINED |
- IEEE80211_HT_MCS_TX_RX_DIFF |
- ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
- IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
-
- switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
- case 3:
- spec->ht.mcs.rx_mask[2] = 0xff;
- case 2:
- spec->ht.mcs.rx_mask[1] = 0xff;
- case 1:
- spec->ht.mcs.rx_mask[0] = 0xff;
- spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
- break;
+ if (!rt2x00_rf(chip, RF2020)) {
+ spec->ht.ht_supported = true;
+ spec->ht.cap =
+ IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_TX_STBC |
+ IEEE80211_HT_CAP_RX_STBC |
+ IEEE80211_HT_CAP_PSMP_SUPPORT;
+ spec->ht.ampdu_factor = 3;
+ spec->ht.ampdu_density = 4;
+ spec->ht.mcs.tx_params =
+ IEEE80211_HT_MCS_TX_DEFINED |
+ IEEE80211_HT_MCS_TX_RX_DIFF |
+ ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
+ IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
+
+ switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
+ case 3:
+ spec->ht.mcs.rx_mask[2] = 0xff;
+ case 2:
+ spec->ht.mcs.rx_mask[1] = 0xff;
+ case 1:
+ spec->ht.mcs.rx_mask[0] = 0xff;
+ spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
+ break;
+ }
+ } else {
+ spec->ht.ht_supported = false;
}
/*
--
1.6.5.3
On Monday 23 November 2009, Gertjan van Wingerde wrote:
> As additional fallout also remove the also unused variable ieee80211hdr.
>
> Reported-by: Johannes Stezenbach <[email protected]>
> Signed-off-by: Gertjan van Wingerde <[email protected]>
Acked-by: Ivo van Doorn <[email protected]>
On 11/23/09 08:35, Julian Calaby wrote:
> On Mon, Nov 23, 2009 at 18:16, Gertjan van Wingerde <[email protected]> wrote:
>> Current rt2x00 drivers may result in a "ieee80211_tx_status: headroom too
>> small" error message when a frame needs to be properly aligned before
>> transmitting it.
>> This is because the space needed to ensure proper alignment isn't
>> requested from mac80211.
>> Fix this by adding sufficient amount of alignment space to the amount
>> of headroom requested for TX frames.
>>
>> Reported-by: David Ellingsworth <[email protected]>
>> Signed-off-by: Gertjan van Wingerde <[email protected]>
>> Tested-by: David Ellingsworth <[email protected]>
>> ---
>> drivers/net/wireless/rt2x00/rt2400pci.c | 30 +++++++++++++++-------------
>> drivers/net/wireless/rt2x00/rt2500pci.c | 30 +++++++++++++++-------------
>> drivers/net/wireless/rt2x00/rt2500usb.c | 29 ++++++++++++++-------------
>> drivers/net/wireless/rt2x00/rt2800lib.c | 7 +----
>> drivers/net/wireless/rt2x00/rt2800pci.c | 31 +++++++++++++++--------------
>> drivers/net/wireless/rt2x00/rt2800usb.c | 25 ++++++++++++-----------
>> drivers/net/wireless/rt2x00/rt2x00.h | 7 ++++++
>> drivers/net/wireless/rt2x00/rt2x00queue.c | 6 ++--
>> drivers/net/wireless/rt2x00/rt61pci.c | 28 ++++++++++++++------------
>> drivers/net/wireless/rt2x00/rt73usb.c | 27 +++++++++++++------------
>> 10 files changed, 117 insertions(+), 103 deletions(-)
>>
>> diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
>> index 6e68bc7..f534d70 100644
>> --- a/drivers/net/wireless/rt2x00/rt2400pci.c
>> +++ b/drivers/net/wireless/rt2x00/rt2400pci.c
>> @@ -1623,20 +1624,21 @@ static const struct data_queue_desc rt2400pci_queue_atim = {
>> };
>>
>> static const struct rt2x00_ops rt2400pci_ops = {
>> - .name = KBUILD_MODNAME,
>> - .max_sta_intf = 1,
>> - .max_ap_intf = 1,
>> - .eeprom_size = EEPROM_SIZE,
>> - .rf_size = RF_SIZE,
>> - .tx_queues = NUM_TX_QUEUES,
>> - .rx = &rt2400pci_queue_rx,
>> - .tx = &rt2400pci_queue_tx,
>> - .bcn = &rt2400pci_queue_bcn,
>> - .atim = &rt2400pci_queue_atim,
>> - .lib = &rt2400pci_rt2x00_ops,
>> - .hw = &rt2400pci_mac80211_ops,
>> + .name = KBUILD_MODNAME,
>> + .max_sta_intf = 1,
>> + .max_ap_intf = 1,
>> + .eeprom_size = EEPROM_SIZE,
>> + .rf_size = RF_SIZE,
>> + .tx_queues = NUM_TX_QUEUES,
>> + .extra_tx_headroom = 0,
>> + .rx = &rt2400pci_queue_rx,
>> + .tx = &rt2400pci_queue_tx,
>> + .bcn = &rt2400pci_queue_bcn,
>> + .atim = &rt2400pci_queue_atim,
>> + .lib = &rt2400pci_rt2x00_ops,
>> + .hw = &rt2400pci_mac80211_ops,
>> #ifdef CONFIG_RT2X00_LIB_DEBUGFS
>> - .debugfs = &rt2400pci_rt2x00debug,
>> + .debugfs = &rt2400pci_rt2x00debug,
>> #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
>> };
>
> Shouldn't the re-formatting of the ops structures (and addition of the
> .debugfs member) go in a separate patch?
>
Well, strictly speaking is the reformatting the result of the "meat" of this patch.
The addition of the extra_tx_headroom member. However, I can see how the reformatting
distracts the attention from that addition. I'll see if I can do the reformatting as
part of a preparatory patch.
Note that this patch does not add the .debugfs member.
---
Gertjan.
On 11/23/09 19:33, Ivo van Doorn wrote:
> On Monday 23 November 2009, Gertjan van Wingerde wrote:
>> Current rt2x00 drivers may result in a "ieee80211_tx_status: headroom too
>> small" error message when a frame needs to be properly aligned before
>> transmitting it.
>> This is because the space needed to ensure proper alignment isn't
>> requested from mac80211.
>> Fix this by adding sufficient amount of alignment space to the amount
>> of headroom requested for TX frames.
>>
>> Reported-by: David Ellingsworth <[email protected]>
>> Signed-off-by: Gertjan van Wingerde <[email protected]>
>> Tested-by: David Ellingsworth <[email protected]>
>> ---
>> drivers/net/wireless/rt2x00/rt2400pci.c | 30 +++++++++++++++-------------
>> drivers/net/wireless/rt2x00/rt2500pci.c | 30 +++++++++++++++-------------
>> drivers/net/wireless/rt2x00/rt2500usb.c | 29 ++++++++++++++-------------
>> drivers/net/wireless/rt2x00/rt2800lib.c | 7 +----
>> drivers/net/wireless/rt2x00/rt2800pci.c | 31 +++++++++++++++--------------
>> drivers/net/wireless/rt2x00/rt2800usb.c | 25 ++++++++++++-----------
>> drivers/net/wireless/rt2x00/rt2x00.h | 7 ++++++
>> drivers/net/wireless/rt2x00/rt2x00queue.c | 6 ++--
>> drivers/net/wireless/rt2x00/rt61pci.c | 28 ++++++++++++++------------
>> drivers/net/wireless/rt2x00/rt73usb.c | 27 +++++++++++++------------
>> 10 files changed, 117 insertions(+), 103 deletions(-)
>>
>> diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
>> index 6e68bc7..f534d70 100644
>> --- a/drivers/net/wireless/rt2x00/rt2400pci.c
>> +++ b/drivers/net/wireless/rt2x00/rt2400pci.c
>> @@ -1432,7 +1432,8 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>> IEEE80211_HW_SIGNAL_DBM |
>> IEEE80211_HW_SUPPORTS_PS |
>> IEEE80211_HW_PS_NULLFUNC_STACK;
>> - rt2x00dev->hw->extra_tx_headroom = 0;
>> + rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
>> + RT2X00_ALIGN_SIZE;
>
> Can't rt2x00lib initialize rt2x00dev->hw->extra_tx_headroom?
> The drivers aren't performing the aligning, so it is logical that rt2x00lib
> adds the required bytes rather than the drivers. The driver already sets
> the value in ops->extra_tx_headroom, so it can rely on rt2x00lib to do the rest.
>
I guess that that can be done as an extra cleanup. Will do in a revision.
>> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
>> index b809c49..de358b5 100644
>> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
>> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
>> @@ -2030,11 +2030,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>> IEEE80211_HW_SUPPORTS_PS |
>> IEEE80211_HW_PS_NULLFUNC_STACK;
>>
>> - if (rt2x00_intf_is_usb(rt2x00dev))
>> - rt2x00dev->hw->extra_tx_headroom =
>> - TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
>> - else if (rt2x00_intf_is_pci(rt2x00dev))
>> - rt2x00dev->hw->extra_tx_headroom = TXWI_DESC_SIZE;
>> + rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom +
>> + RT2X00_L2PAD_SIZE;
>
> In this case we don't use RT2X00_ALIGN_SIZE, but the driver does set a flag to tell
> rt2x00lib that L2padding should be used rather then aligning. So this case would still
> hold when it is moved to rt2x00lib.
>
Yep, will do in a revision.
>> /*
>> + * Constants for extra TX headroom for alignment purposes.
>> + */
>> +#define RT2X00_ALIGN_SIZE 4
>> +#define RT2X00_L2PAD_SIZE 8
>
> #define RT2X00_L2PAD_SIZE RT2X00_ALIGN_SIZE + 4
>
> Would probably better indicate why you are using 8.
>
I'll add some comments on what these values represent. Don't think that defining RT2X00_L2PAD_SIZE
in your proposed way would help explaining, but some proper comments will.
---
Gertjan.
On Mon, 2009-11-23 at 08:16 +0100, Gertjan van Wingerde wrote:
> Allow drivers to consume the extra TX headroom they are requesting instead
> of assuming they will give it back. This specifically is the case for
> the rt2x00 driver, as a large part of the requested extra TX headroom is
> used to properly align the frame for DMA usage, and the frame is never
> moved back to the original location.
> Fix this by reserving TX headroom accounting for both the driver requested
> amount and the special monitor interface header that needs to be added,
> instead of just the maximum of the two.
>
> See http://marc.info/?l=linux-kernel&m=125892467801662&w=2 for details.
> - local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
> - sizeof(struct ieee80211_tx_status_rtap_hdr));
> + local->tx_headroom = local->hw.extra_tx_headroom +
> + sizeof(struct ieee80211_tx_status_rtap_hdr);
Even though the radiotap header currently is only 13 bytes long, I don't
really like this, you're not consuming all of extra_tx_headroom! I'd
rather have a definition somewhere
#define MAC80211_TX_STATUS_HEADROOM 13
(with a BUILD_BUG_ON(sizeof(rtap_hdr) == MAC80211_TX_STATUS_HEADROOM))
so that you can make the driver set
extra_tx_headroom = max_t(MAC80211_TX_STATUS_HEADROOM, txi) + align;
johannes
RT chipsets are unique across both PCI and USB busses, and don't overlap.
Therefore there is no need to test for bus type when only checking for
chipset type. Remove the redundant checks.
Signed-off-by: Gertjan van Wingerde <[email protected]>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 17 +++++++----------
1 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index ac393c3..b809c49 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -217,14 +217,12 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (rt2x00_intf_is_pci(rt2x00dev)) {
- /*
- * RT2880 and RT3052 don't support MCU requests.
- */
- if (rt2x00_rt(&rt2x00dev->chip, RT2880) ||
- rt2x00_rt(&rt2x00dev->chip, RT3052))
- return;
- }
+ /*
+ * RT2880 and RT3052 don't support MCU requests.
+ */
+ if (rt2x00_rt(&rt2x00dev->chip, RT2880) ||
+ rt2x00_rt(&rt2x00dev->chip, RT3052))
+ return;
mutex_lock(&rt2x00dev->csr_mutex);
@@ -1482,8 +1480,7 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_write(rt2x00dev, 105, 0x05);
}
- if (rt2x00_intf_is_pci(rt2x00dev) &&
- rt2x00_rt(&rt2x00dev->chip, RT3052)) {
+ if (rt2x00_rt(&rt2x00dev->chip, RT3052)) {
rt2800_bbp_write(rt2x00dev, 31, 0x08);
rt2800_bbp_write(rt2x00dev, 78, 0x0e);
rt2800_bbp_write(rt2x00dev, 80, 0x08);
--
1.6.5.3