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/rt2500usb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index ee34c137e7cd..c1eec17fe186 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -648,6 +648,10 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev, rt2x00_set_field16(®, MAC_CSR18_AUTO_WAKE, 1); rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg); + } else { + rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); + rt2x00_set_field16(®, MAC_CSR18_AUTO_WAKE, 0); + rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg); } rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); -- cgit v1.2.3 From 62c33447fa720d71b05bbc626b01351a4889c2d7 Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Tue, 30 Mar 2010 23:50:24 +0200 Subject: rt2x00: Enable powersaving by default again on rt2500usb. Now that the powersave issues on rt2500usb have been tackled, powersave can be enabled by default again. Signed-off-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 54d2716e389c..c1eec17fe186 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1646,11 +1646,6 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) char *tx_power; unsigned int i; - /* - * Disable powersaving as default. - */ - rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; - /* * Initialize all hw fields. */ -- 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/rt2500usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index c1eec17fe186..c6e6e7b0ea53 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1071,7 +1071,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); - 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, !!txdesc->cipher); rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); rt2x00_desc_write(txd, 0, word); -- cgit v1.2.3 From 78b8f3b0ddb061af1e3907f9c4bca76eae39f79f Mon Sep 17 00:00:00 2001 From: Gertjan van Wingerde Date: Sat, 8 May 2010 23:40:20 +0200 Subject: rt2x00: Don't check whether hardware crypto is enabled when reading RXD. We should simply follow what the hardware told us it has done. Signed-off-by: Gertjan van Wingerde Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2500usb.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index c6e6e7b0ea53..f90b308899aa 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1213,11 +1213,9 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; - if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { - rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER); - if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) - rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY; - } + rxdesc->cipher = rt2x00_get_field32(word0, RXD_W0_CIPHER); + if (rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR)) + rxdesc->cipher_status = RX_CRYPTO_FAIL_KEY; if (rxdesc->cipher != CIPHER_NONE) { _rt2x00_desc_read(rxd, 2, &rxdesc->iv[0]); -- 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/rt2500usb.c | 55 +++++++++++++-------------------- 1 file changed, 22 insertions(+), 33 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index f90b308899aa..5ee9b9fd77b3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1090,7 +1090,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry) struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); int pipe = usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint); int length; - u16 reg; + u16 reg, reg0; /* * Add the descriptor in front of the skb. @@ -1132,6 +1132,26 @@ static void rt2500usb_write_beacon(struct queue_entry *entry) * Send out the guardian byte. */ usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC); + + /* + * Enable beaconing again. + */ + rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); + rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1); + reg0 = reg; + rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); + /* + * Beacon generation will fail initially. + * To prevent this we need to change the TXRX_CSR19 + * register several times (reg0 is the same as reg + * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0 + * and 1 in reg). + */ + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0); + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0); + rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); } static int rt2500usb_get_tx_data_len(struct queue_entry *entry) @@ -1148,37 +1168,6 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) return length; } -static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) -{ - u16 reg, reg0; - - if (queue != QID_BEACON) { - rt2x00usb_kick_tx_queue(rt2x00dev, queue); - return; - } - - 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); - reg0 = reg; - rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 1); - /* - * Beacon generation will fail initially. - * To prevent this we need to change the TXRX_CSR19 - * register several times (reg0 is the same as reg - * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0 - * and 1 in reg). - */ - rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); - rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0); - rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); - rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0); - rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); - } -} - /* * RX control handlers */ @@ -1777,7 +1766,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .write_tx_data = rt2x00usb_write_tx_data, .write_beacon = rt2500usb_write_beacon, .get_tx_data_len = rt2500usb_get_tx_data_len, - .kick_tx_queue = rt2500usb_kick_tx_queue, + .kick_tx_queue = rt2x00usb_kick_tx_queue, .kill_tx_queue = rt2x00usb_kill_tx_queue, .fill_rxdone = rt2500usb_fill_rxdone, .config_shared_key = rt2500usb_config_key, -- 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/rt2500usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 5ee9b9fd77b3..30c0544e8036 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1082,7 +1082,8 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, */ static void rt2500usb_beacondone(struct urb *urb); -static void rt2500usb_write_beacon(struct queue_entry *entry) +static void rt2500usb_write_beacon(struct queue_entry *entry, + struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); -- 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/rt2500usb.c | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 30c0544e8036..9a915be547b3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1039,6 +1039,24 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * Start writing the descriptor words. */ + rt2x00_desc_read(txd, 0, &word); + rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); + rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, + test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); + rt2x00_set_field32(&word, TXD_W0_ACK, + test_bit(ENTRY_TXD_ACK, &txdesc->flags)); + rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, + test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); + rt2x00_set_field32(&word, TXD_W0_OFDM, + (txdesc->rate_mode == RATE_MODE_OFDM)); + rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, + test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); + rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); + rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); + rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); + rt2x00_desc_write(txd, 0, word); + rt2x00_desc_read(txd, 1, &word); rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); @@ -1057,24 +1075,6 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, _rt2x00_desc_write(txd, 3, skbdesc->iv[0]); _rt2x00_desc_write(txd, 4, skbdesc->iv[1]); } - - rt2x00_desc_read(txd, 0, &word); - rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit); - rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, - test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_ACK, - test_bit(ENTRY_TXD_ACK, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, - test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_OFDM, - (txdesc->rate_mode == RATE_MODE_OFDM)); - rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, - test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, txdesc->length); - rt2x00_set_field32(&word, TXD_W0_CIPHER, !!txdesc->cipher); - rt2x00_set_field32(&word, TXD_W0_KEY_ID, txdesc->key_idx); - rt2x00_desc_write(txd, 0, word); } /* -- 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/rt2500usb.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c') diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9a915be547b3..b985d8f8cc6e 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1033,7 +1033,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, struct txentry_desc *txdesc) { struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txd = skbdesc->desc; + __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); u32 word; /* @@ -1075,6 +1075,12 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, _rt2x00_desc_write(txd, 3, skbdesc->iv[0]); _rt2x00_desc_write(txd, 4, skbdesc->iv[1]); } + + /* + * Register descriptor details in skb frame descriptor. + */ + skbdesc->desc = txd; + skbdesc->desc_len = TXD_DESC_SIZE; } /* @@ -1088,18 +1094,10 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); int pipe = usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint); int length; u16 reg, reg0; - /* - * Add the descriptor in front of the skb. - */ - skb_push(entry->skb, entry->queue->desc_size); - memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len); - skbdesc->desc = entry->skb->data; - /* * Disable beaconing while we are reloading the beacon data, * otherwise we might be sending out invalid data. @@ -1108,6 +1106,11 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); + /* + * Take the descriptor in front of the skb into account. + */ + skb_push(entry->skb, TXD_DESC_SIZE); + /* * USB devices cannot blindly pass the skb->len as the * length of the data to usb_fill_bulk_urb. Pass the skb -- cgit v1.2.3