aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c29
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c36
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c32
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h22
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c56
12 files changed, 149 insertions, 67 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 3558cb210747..3078417b326b 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1121,6 +1121,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1121 int pipe = usb_sndbulkpipe(usb_dev, 1); 1121 int pipe = usb_sndbulkpipe(usb_dev, 1);
1122 int length; 1122 int length;
1123 u16 reg; 1123 u16 reg;
1124 u32 word, len;
1124 1125
1125 /* 1126 /*
1126 * Add the descriptor in front of the skb. 1127 * Add the descriptor in front of the skb.
@@ -1130,6 +1131,17 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
1130 skbdesc->desc = entry->skb->data; 1131 skbdesc->desc = entry->skb->data;
1131 1132
1132 /* 1133 /*
1134 * Adjust the beacon databyte count. The current number is
1135 * calculated before this function gets called, but falsely
1136 * assumes that the descriptor was already present in the SKB.
1137 */
1138 rt2x00_desc_read(skbdesc->desc, 0, &word);
1139 len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT);
1140 len += skbdesc->desc_len;
1141 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len);
1142 rt2x00_desc_write(skbdesc->desc, 0, word);
1143
1144 /*
1133 * Disable beaconing while we are reloading the beacon data, 1145 * Disable beaconing while we are reloading the beacon data,
1134 * otherwise we might be sending out invalid data. 1146 * otherwise we might be sending out invalid data.
1135 */ 1147 */
@@ -1650,7 +1662,6 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1650 * Initialize all hw fields. 1662 * Initialize all hw fields.
1651 */ 1663 */
1652 rt2x00dev->hw->flags = 1664 rt2x00dev->hw->flags =
1653 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
1654 IEEE80211_HW_RX_INCLUDES_FCS | 1665 IEEE80211_HW_RX_INCLUDES_FCS |
1655 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1666 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1656 IEEE80211_HW_SIGNAL_DBM; 1667 IEEE80211_HW_SIGNAL_DBM;
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 07b03b3c7ef1..db2dc976d831 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -108,7 +108,10 @@
108#define SHORT_PIFS ( SIFS + SHORT_SLOT_TIME ) 108#define SHORT_PIFS ( SIFS + SHORT_SLOT_TIME )
109#define DIFS ( PIFS + SLOT_TIME ) 109#define DIFS ( PIFS + SLOT_TIME )
110#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME ) 110#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME )
111#define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) ) 111#define EIFS ( SIFS + DIFS + \
112 (8 * (IEEE80211_HEADER + ACK_SIZE)) )
113#define SHORT_EIFS ( SIFS + SHORT_DIFS + \
114 (8 * (IEEE80211_HEADER + ACK_SIZE)) )
112 115
113/* 116/*
114 * Chipset identification 117 * Chipset identification
@@ -597,6 +600,7 @@ enum rt2x00_flags {
597 DEVICE_STARTED_SUSPEND, 600 DEVICE_STARTED_SUSPEND,
598 DEVICE_ENABLED_RADIO, 601 DEVICE_ENABLED_RADIO,
599 DEVICE_DISABLED_RADIO_HW, 602 DEVICE_DISABLED_RADIO_HW,
603 DEVICE_DIRTY_CONFIG,
600 604
601 /* 605 /*
602 * Driver features 606 * Driver features
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index f20ca712504f..3f89516e8332 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -271,7 +271,7 @@ config:
271 libconf.sifs = SIFS; 271 libconf.sifs = SIFS;
272 libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS; 272 libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS;
273 libconf.difs = short_slot_time ? SHORT_DIFS : DIFS; 273 libconf.difs = short_slot_time ? SHORT_DIFS : DIFS;
274 libconf.eifs = EIFS; 274 libconf.eifs = short_slot_time ? SHORT_EIFS : EIFS;
275 } 275 }
276 276
277 libconf.conf = conf; 277 libconf.conf = conf;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 8c93eb8353b0..f42283ad7b02 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1013,6 +1013,7 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
1013 rt2x00dev->intf_associated = 0; 1013 rt2x00dev->intf_associated = 0;
1014 1014
1015 __set_bit(DEVICE_STARTED, &rt2x00dev->flags); 1015 __set_bit(DEVICE_STARTED, &rt2x00dev->flags);
1016 __set_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags);
1016 1017
1017 return 0; 1018 return 0;
1018} 1019}
@@ -1237,9 +1238,9 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1237 /* 1238 /*
1238 * Reconfigure device. 1239 * Reconfigure device.
1239 */ 1240 */
1240 rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, 1); 1241 retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf);
1241 if (!rt2x00dev->hw->conf.radio_enabled) 1242 if (retval)
1242 rt2x00lib_disable_radio(rt2x00dev); 1243 goto exit;
1243 1244
1244 /* 1245 /*
1245 * Iterator over each active interface to 1246 * Iterator over each active interface to
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index f2c9b0e79b5f..c5fb3a72cf37 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -125,13 +125,6 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
125void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); 125void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
126 126
127/** 127/**
128 * rt2x00queue_free_skb - free a skb
129 * @rt2x00dev: Pointer to &struct rt2x00_dev.
130 * @skb: The skb to free.
131 */
132void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
133
134/**
135 * rt2x00queue_write_tx_frame - Write TX frame to hardware 128 * rt2x00queue_write_tx_frame - Write TX frame to hardware
136 * @queue: Queue over which the frame should be send 129 * @queue: Queue over which the frame should be send
137 * @skb: The skb to send 130 * @skb: The skb to send
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index f1dcbaa80c3c..c3ee4ecba792 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -63,7 +63,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
63 */ 63 */
64 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); 64 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
65 rts_info = IEEE80211_SKB_CB(skb); 65 rts_info = IEEE80211_SKB_CB(skb);
66 rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; 66 rts_info->control.hw_key = NULL;
67 rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; 67 rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
68 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; 68 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
69 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; 69 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
@@ -83,6 +83,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
83 (struct ieee80211_rts *)(skb->data)); 83 (struct ieee80211_rts *)(skb->data));
84 84
85 if (rt2x00queue_write_tx_frame(queue, skb)) { 85 if (rt2x00queue_write_tx_frame(queue, skb)) {
86 dev_kfree_skb_any(skb);
86 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); 87 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
87 return NETDEV_TX_BUSY; 88 return NETDEV_TX_BUSY;
88 } 89 }
@@ -96,7 +97,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
96 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 97 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
97 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; 98 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
98 enum data_queue_qid qid = skb_get_queue_mapping(skb); 99 enum data_queue_qid qid = skb_get_queue_mapping(skb);
99 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
100 struct data_queue *queue; 100 struct data_queue *queue;
101 u16 frame_control; 101 u16 frame_control;
102 102
@@ -152,18 +152,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
152 } 152 }
153 } 153 }
154 154
155 /*
156 * XXX: This is as wrong as the old mac80211 code was,
157 * due to beacons not getting sequence numbers assigned
158 * properly.
159 */
160 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
161 if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
162 intf->seqno += 0x10;
163 ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
164 ieee80211hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
165 }
166
167 if (rt2x00queue_write_tx_frame(queue, skb)) { 155 if (rt2x00queue_write_tx_frame(queue, skb)) {
168 ieee80211_stop_queue(rt2x00dev->hw, qid); 156 ieee80211_stop_queue(rt2x00dev->hw, qid);
169 return NETDEV_TX_BUSY; 157 return NETDEV_TX_BUSY;
@@ -322,6 +310,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
322int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 310int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
323{ 311{
324 struct rt2x00_dev *rt2x00dev = hw->priv; 312 struct rt2x00_dev *rt2x00dev = hw->priv;
313 int force_reconfig;
325 314
326 /* 315 /*
327 * Mac80211 might be calling this function while we are trying 316 * Mac80211 might be calling this function while we are trying
@@ -341,7 +330,17 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
341 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); 330 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
342 } 331 }
343 332
344 rt2x00lib_config(rt2x00dev, conf, 0); 333 /*
334 * When the DEVICE_DIRTY_CONFIG flag is set, the device has recently
335 * been started and the configuration must be forced upon the hardware.
336 * Otherwise registers will not be intialized correctly and could
337 * result in non-working hardware because essential registers aren't
338 * initialized.
339 */
340 force_reconfig =
341 __test_and_clear_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags);
342
343 rt2x00lib_config(rt2x00dev, conf, force_reconfig);
345 344
346 /* 345 /*
347 * Reenable RX only if the radio should be on. 346 * Reenable RX only if the radio should be on.
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 7f442030f5ad..3b27f6aa860c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -120,6 +120,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
120{ 120{
121 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 121 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
122 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); 122 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
123 struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
123 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; 124 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
124 struct ieee80211_rate *rate = 125 struct ieee80211_rate *rate =
125 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); 126 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
@@ -200,6 +201,31 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
200 } 201 }
201 202
202 /* 203 /*
204 * Hardware should insert sequence counter.
205 * FIXME: We insert a software sequence counter first for
206 * hardware that doesn't support hardware sequence counting.
207 *
208 * This is wrong because beacons are not getting sequence
209 * numbers assigned properly.
210 *
211 * A secondary problem exists for drivers that cannot toggle
212 * sequence counting per-frame, since those will override the
213 * sequence counter given by mac80211.
214 */
215 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
216 spin_lock(&intf->lock);
217
218 if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
219 intf->seqno += 0x10;
220 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
221 hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
222
223 spin_unlock(&intf->lock);
224
225 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
226 }
227
228 /*
203 * PLCP setup 229 * PLCP setup
204 * Length calculation depends on OFDM/CCK rate. 230 * Length calculation depends on OFDM/CCK rate.
205 */ 231 */
@@ -466,9 +492,12 @@ void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev)
466 if (!rt2x00dev->ops->lib->init_rxentry) 492 if (!rt2x00dev->ops->lib->init_rxentry)
467 return; 493 return;
468 494
469 for (i = 0; i < queue->limit; i++) 495 for (i = 0; i < queue->limit; i++) {
496 queue->entries[i].flags = 0;
497
470 rt2x00dev->ops->lib->init_rxentry(rt2x00dev, 498 rt2x00dev->ops->lib->init_rxentry(rt2x00dev,
471 &queue->entries[i]); 499 &queue->entries[i]);
500 }
472} 501}
473 502
474void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) 503void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
@@ -482,9 +511,12 @@ void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
482 if (!rt2x00dev->ops->lib->init_txentry) 511 if (!rt2x00dev->ops->lib->init_txentry)
483 continue; 512 continue;
484 513
485 for (i = 0; i < queue->limit; i++) 514 for (i = 0; i < queue->limit; i++) {
515 queue->entries[i].flags = 0;
516
486 rt2x00dev->ops->lib->init_txentry(rt2x00dev, 517 rt2x00dev->ops->lib->init_txentry(rt2x00dev,
487 &queue->entries[i]); 518 &queue->entries[i]);
519 }
488 } 520 }
489} 521}
490 522
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 8945945c892e..a4a8c57004db 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -199,6 +199,7 @@ struct txdone_entry_desc {
199 * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. 199 * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame.
200 * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame. 200 * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame.
201 * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. 201 * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate.
202 * @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter.
202 * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame. 203 * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame.
203 * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. 204 * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment.
204 * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted. 205 * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted.
@@ -210,6 +211,7 @@ enum txentry_desc_flags {
210 ENTRY_TXD_RTS_FRAME, 211 ENTRY_TXD_RTS_FRAME,
211 ENTRY_TXD_CTS_FRAME, 212 ENTRY_TXD_CTS_FRAME,
212 ENTRY_TXD_OFDM_RATE, 213 ENTRY_TXD_OFDM_RATE,
214 ENTRY_TXD_GENERATE_SEQ,
213 ENTRY_TXD_FIRST_FRAGMENT, 215 ENTRY_TXD_FIRST_FRAGMENT,
214 ENTRY_TXD_MORE_FRAG, 216 ENTRY_TXD_MORE_FRAG,
215 ENTRY_TXD_REQ_TIMESTAMP, 217 ENTRY_TXD_REQ_TIMESTAMP,
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 83862e7f7aec..933e6cc9359d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -122,6 +122,38 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
122} 122}
123EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); 123EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
124 124
125int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
126 const u8 request, const u8 requesttype,
127 const u16 offset, void *buffer,
128 const u16 buffer_length,
129 const int timeout)
130{
131 int status = 0;
132 unsigned char *tb;
133 u16 off, len, bsize;
134
135 mutex_lock(&rt2x00dev->usb_cache_mutex);
136
137 tb = buffer;
138 off = offset;
139 len = buffer_length;
140 while (len && !status) {
141 bsize = min_t(u16, CSR_CACHE_SIZE, len);
142 status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
143 requesttype, off, tb,
144 bsize, timeout);
145
146 tb += bsize;
147 len -= bsize;
148 off += bsize;
149 }
150
151 mutex_unlock(&rt2x00dev->usb_cache_mutex);
152
153 return status;
154}
155EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff);
156
125/* 157/*
126 * TX data handlers. 158 * TX data handlers.
127 */ 159 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index aad794adf52c..ee3875f894aa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -70,8 +70,7 @@
70/* 70/*
71 * Cache size 71 * Cache size
72 */ 72 */
73#define CSR_CACHE_SIZE 8 73#define CSR_CACHE_SIZE 64
74#define CSR_CACHE_SIZE_FIRMWARE 64
75 74
76/* 75/*
77 * USB request types. 76 * USB request types.
@@ -172,6 +171,25 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
172 const u16 buffer_length, const int timeout); 171 const u16 buffer_length, const int timeout);
173 172
174/** 173/**
174 * rt2x00usb_vendor_request_large_buff - Send register command to device (buffered)
175 * @rt2x00dev: Pointer to &struct rt2x00_dev
176 * @request: USB vendor command (See &enum rt2x00usb_vendor_request)
177 * @requesttype: Request type &USB_VENDOR_REQUEST_*
178 * @offset: Register start offset to perform action on
179 * @buffer: Buffer where information will be read/written to by device
180 * @buffer_length: Size of &buffer
181 * @timeout: Operation timeout
182 *
183 * This function is used to transfer register data in blocks larger
184 * then CSR_CACHE_SIZE. Use for firmware upload, keys and beacons.
185 */
186int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
187 const u8 request, const u8 requesttype,
188 const u16 offset, void *buffer,
189 const u16 buffer_length,
190 const int timeout);
191
192/**
175 * rt2x00usb_vendor_request_sw - Send single register command to device 193 * rt2x00usb_vendor_request_sw - Send single register command to device
176 * @rt2x00dev: Pointer to &struct rt2x00_dev 194 * @rt2x00dev: Pointer to &struct rt2x00_dev
177 * @request: USB vendor command (See &enum rt2x00usb_vendor_request) 195 * @request: USB vendor command (See &enum rt2x00usb_vendor_request)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index f7c1f92c1448..fbe2a652e014 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1544,7 +1544,8 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1544 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); 1544 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
1545 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); 1545 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
1546 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); 1546 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
1547 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); 1547 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
1548 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
1548 rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); 1549 rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
1549 rt2x00_desc_write(txd, 1, word); 1550 rt2x00_desc_write(txd, 1, word);
1550 1551
@@ -2278,7 +2279,6 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2278 * Initialize all hw fields. 2279 * Initialize all hw fields.
2279 */ 2280 */
2280 rt2x00dev->hw->flags = 2281 rt2x00dev->hw->flags =
2281 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
2282 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 2282 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
2283 IEEE80211_HW_SIGNAL_DBM; 2283 IEEE80211_HW_SIGNAL_DBM;
2284 rt2x00dev->hw->extra_tx_headroom = 0; 2284 rt2x00dev->hw->extra_tx_headroom = 0;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index d383735ab8f2..9761eaaa08be 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -890,9 +890,6 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
890 unsigned int i; 890 unsigned int i;
891 int status; 891 int status;
892 u32 reg; 892 u32 reg;
893 const char *ptr = data;
894 char *cache;
895 int buflen;
896 893
897 /* 894 /*
898 * Wait for stable hardware. 895 * Wait for stable hardware.
@@ -911,31 +908,12 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
911 908
912 /* 909 /*
913 * Write firmware to device. 910 * Write firmware to device.
914 * We setup a seperate cache for this action,
915 * since we are going to write larger chunks of data
916 * then normally used cache size.
917 */ 911 */
918 cache = kmalloc(CSR_CACHE_SIZE_FIRMWARE, GFP_KERNEL); 912 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
919 if (!cache) { 913 USB_VENDOR_REQUEST_OUT,
920 ERROR(rt2x00dev, "Failed to allocate firmware cache.\n"); 914 FIRMWARE_IMAGE_BASE,
921 return -ENOMEM; 915 data, len,
922 } 916 REGISTER_TIMEOUT32(len));
923
924 for (i = 0; i < len; i += CSR_CACHE_SIZE_FIRMWARE) {
925 buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE);
926
927 memcpy(cache, ptr, buflen);
928
929 rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
930 USB_VENDOR_REQUEST_OUT,
931 FIRMWARE_IMAGE_BASE + i, 0,
932 cache, buflen,
933 REGISTER_TIMEOUT32(buflen));
934
935 ptr += buflen;
936 }
937
938 kfree(cache);
939 917
940 /* 918 /*
941 * Send firmware request to device to load firmware, 919 * Send firmware request to device to load firmware,
@@ -1303,7 +1281,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1303 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); 1281 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);
1304 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); 1282 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
1305 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); 1283 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
1306 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); 1284 rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,
1285 test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
1307 rt2x00_desc_write(txd, 1, word); 1286 rt2x00_desc_write(txd, 1, word);
1308 1287
1309 rt2x00_desc_read(txd, 2, &word); 1288 rt2x00_desc_read(txd, 2, &word);
@@ -1352,6 +1331,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1352 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 1331 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1353 unsigned int beacon_base; 1332 unsigned int beacon_base;
1354 u32 reg; 1333 u32 reg;
1334 u32 word, len;
1355 1335
1356 /* 1336 /*
1357 * Add the descriptor in front of the skb. 1337 * Add the descriptor in front of the skb.
@@ -1361,6 +1341,17 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1361 skbdesc->desc = entry->skb->data; 1341 skbdesc->desc = entry->skb->data;
1362 1342
1363 /* 1343 /*
1344 * Adjust the beacon databyte count. The current number is
1345 * calculated before this function gets called, but falsely
1346 * assumes that the descriptor was already present in the SKB.
1347 */
1348 rt2x00_desc_read(skbdesc->desc, 0, &word);
1349 len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT);
1350 len += skbdesc->desc_len;
1351 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len);
1352 rt2x00_desc_write(skbdesc->desc, 0, word);
1353
1354 /*
1364 * Disable beaconing while we are reloading the beacon data, 1355 * Disable beaconing while we are reloading the beacon data,
1365 * otherwise we might be sending out invalid data. 1356 * otherwise we might be sending out invalid data.
1366 */ 1357 */
@@ -1374,10 +1365,10 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
1374 * Write entire beacon with descriptor to register. 1365 * Write entire beacon with descriptor to register.
1375 */ 1366 */
1376 beacon_base = HW_BEACON_OFFSET(entry->entry_idx); 1367 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1377 rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, 1368 rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
1378 USB_VENDOR_REQUEST_OUT, beacon_base, 0, 1369 USB_VENDOR_REQUEST_OUT, beacon_base,
1379 entry->skb->data, entry->skb->len, 1370 entry->skb->data, entry->skb->len,
1380 REGISTER_TIMEOUT32(entry->skb->len)); 1371 REGISTER_TIMEOUT32(entry->skb->len));
1381 1372
1382 /* 1373 /*
1383 * Clean up the beacon skb. 1374 * Clean up the beacon skb.
@@ -1871,7 +1862,6 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1871 * Initialize all hw fields. 1862 * Initialize all hw fields.
1872 */ 1863 */
1873 rt2x00dev->hw->flags = 1864 rt2x00dev->hw->flags =
1874 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
1875 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1865 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1876 IEEE80211_HW_SIGNAL_DBM; 1866 IEEE80211_HW_SIGNAL_DBM;
1877 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; 1867 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;