From 5731858d0047cad309d334c4cd6ccb6199bf28fe Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Tue, 30 Mar 2010 23:50:23 +0200 Subject: rt2x00: Disable auto wakeup before waking up device. In all drivers ensure that auto wakeup is disabled before waking up the device. This is needed to prevent connection stability issues and problems in waking up the device. Based upon a patch from Ondrej Zary Signed-off-by: Gertjan van Wingerde Cc: Ondrej Zary Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 52bbcf1bd17c..d084d70e5fe2 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -573,6 +573,10 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); rt2x00pci_register_write(rt2x00dev, CSR20, reg); + } else { + rt2x00pci_register_read(rt2x00dev, CSR20, ®); + rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); + rt2x00pci_register_write(rt2x00dev, CSR20, reg); } rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); -- cgit v1.2.3 From df624ca5413d84b3082246de384823fbe8fed6e4 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Mon, 3 May 2010 22:43:05 +0200 Subject: rt2x00: Register frame length in TX entry descriptor instead of L2PAD. And use it consistently in the chipset drivers. Preparation for further clean ups. Signed-off-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d084d70e5fe2..d9b630455e7d 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1208,7 +1208,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); rt2x00_desc_write(txd, 0, word); } -- cgit v1.2.3 From d61cb26696e19494c049297def6c8f37d9e2f534 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 8 May 2010 23:40:24 +0200 Subject: rt2x00: Clean up all driver's kick_tx_queue callback functions. All of the driver's kick_tx_queue callback functions treat the TX queue for beacons in a special manner. Clean this up by integrating the kicking of the beacon queue into the write_beacon callback function, and let the generic code no longer call the kick_tx_queue callback function when updating the beacon. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d9b630455e7d..84ab56ec5872 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1246,6 +1246,14 @@ static void rt2500pci_write_beacon(struct queue_entry *entry) rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); rt2x00_desc_write(entry_priv->desc, 1, word); + + /* + * Enable beaconing again. + */ + 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); } static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, @@ -1253,17 +1261,6 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, { u32 reg; - if (queue == QID_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); - } - return; - } - rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); -- cgit v1.2.3 From f224f4ef794c4a9146a7fa7303018fecab8c9328 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 8 May 2010 23:40:25 +0200 Subject: rt2x00: provide beacon's txdesc to write_beacon callback function. Preparation to fix rt2800 beaconing. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 84ab56ec5872..d876c6d87591 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1216,7 +1216,8 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * TX data initialization */ -static void rt2500pci_write_beacon(struct queue_entry *entry) +static void rt2500pci_write_beacon(struct queue_entry *entry, + struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_pci *entry_priv = entry->priv_data; -- cgit v1.2.3 From e01f1ec35ff91c8a3f4a3e48a0c8ab476124b973 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Tue, 11 May 2010 23:51:39 +0200 Subject: rt2x00: Re-order tx descriptor writing code in drivers. Where possible, write the tx descriptor words from start to end, to follow a logical ordering of words. Where this is not possible (in rt2400pci, rt2500pci and rt61pci) add a comment as to why word 0 needs to be written last. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d876c6d87591..8d3e95e0dcfe 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1193,6 +1193,11 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); rt2x00_desc_write(txd, 10, word); + /* + * Writing TXD word 0 must the last to prevent a race condition with + * the device, whereby the device may take hold of the TXD before we + * finished updating it. + */ rt2x00_desc_read(txd, 0, &word); rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); rt2x00_set_field32(&word, TXD_W0_VALID, 1); -- cgit v1.2.3 From 85b7a8b3871bde7885516fed2a1c8da699913318 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Tue, 11 May 2010 23:51:40 +0200 Subject: rt2x00: Simplify TXD handling of beacons. The handling of tx descriptors for beacons can be simplified by updating write_tx_desc implementations of each driver to write directly to the queue entry descriptor instead of to a provided memory area. This is also a preparation for further clean ups where descriptors are properly reserved in the skb instead of fiddling with the skb data pointer. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500pci.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2500pci.c') diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 8d3e95e0dcfe..070c23ed4013 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1164,15 +1164,15 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; - __le32 *txd = skbdesc->desc; + __le32 *txd = entry_priv->desc; u32 word; /* * Start writing the descriptor words. */ - rt2x00_desc_read(entry_priv->desc, 1, &word); + rt2x00_desc_read(txd, 1, &word); rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); - rt2x00_desc_write(entry_priv->desc, 1, word); + rt2x00_desc_write(txd, 1, word); rt2x00_desc_read(txd, 2, &word); rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); @@ -1216,6 +1216,12 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); rt2x00_desc_write(txd, 0, word); + + /* + * Register descriptor details in skb frame descriptor. + */ + skbdesc->desc = txd; + skbdesc->desc_len = TXD_DESC_SIZE; } /* @@ -1238,15 +1244,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, CSR14, reg); - /* - * Replace rt2x00lib allocated descriptor with the - * pointer to the _real_ hardware descriptor. - * After that, map the beacon to DMA and update the - * descriptor. - */ - memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len); - skbdesc->desc = entry_priv->desc; - rt2x00queue_map_txskb(rt2x00dev, entry->skb); rt2x00_desc_read(entry_priv->desc, 1, &word); -- cgit v1.2.3