diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 5004 |
1 files changed, 713 insertions, 4291 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 0bd55bb19739..71f5da3fe5c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -46,14 +46,13 @@ | |||
46 | #include <asm/div64.h> | 46 | #include <asm/div64.h> |
47 | 47 | ||
48 | #include "iwl-eeprom.h" | 48 | #include "iwl-eeprom.h" |
49 | #include "iwl-4965.h" | 49 | #include "iwl-dev.h" |
50 | #include "iwl-core.h" | 50 | #include "iwl-core.h" |
51 | #include "iwl-io.h" | 51 | #include "iwl-io.h" |
52 | #include "iwl-helpers.h" | 52 | #include "iwl-helpers.h" |
53 | #include "iwl-sta.h" | 53 | #include "iwl-sta.h" |
54 | #include "iwl-calib.h" | ||
54 | 55 | ||
55 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, | ||
56 | struct iwl4965_tx_queue *txq); | ||
57 | 56 | ||
58 | /****************************************************************************** | 57 | /****************************************************************************** |
59 | * | 58 | * |
@@ -88,292 +87,6 @@ MODULE_VERSION(DRV_VERSION); | |||
88 | MODULE_AUTHOR(DRV_COPYRIGHT); | 87 | MODULE_AUTHOR(DRV_COPYRIGHT); |
89 | MODULE_LICENSE("GPL"); | 88 | MODULE_LICENSE("GPL"); |
90 | 89 | ||
91 | __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | ||
92 | { | ||
93 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
94 | int hdr_len = ieee80211_get_hdrlen(fc); | ||
95 | |||
96 | if ((fc & 0x00cc) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA)) | ||
97 | return (__le16 *) ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN); | ||
98 | return NULL; | ||
99 | } | ||
100 | |||
101 | static const struct ieee80211_supported_band *iwl4965_get_hw_mode( | ||
102 | struct iwl_priv *priv, enum ieee80211_band band) | ||
103 | { | ||
104 | return priv->hw->wiphy->bands[band]; | ||
105 | } | ||
106 | |||
107 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) | ||
108 | { | ||
109 | /* Single white space is for Linksys APs */ | ||
110 | if (essid_len == 1 && essid[0] == ' ') | ||
111 | return 1; | ||
112 | |||
113 | /* Otherwise, if the entire essid is 0, we assume it is hidden */ | ||
114 | while (essid_len) { | ||
115 | essid_len--; | ||
116 | if (essid[essid_len] != '\0') | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | static const char *iwl4965_escape_essid(const char *essid, u8 essid_len) | ||
124 | { | ||
125 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | ||
126 | const char *s = essid; | ||
127 | char *d = escaped; | ||
128 | |||
129 | if (iwl4965_is_empty_essid(essid, essid_len)) { | ||
130 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); | ||
131 | return escaped; | ||
132 | } | ||
133 | |||
134 | essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE); | ||
135 | while (essid_len--) { | ||
136 | if (*s == '\0') { | ||
137 | *d++ = '\\'; | ||
138 | *d++ = '0'; | ||
139 | s++; | ||
140 | } else | ||
141 | *d++ = *s++; | ||
142 | } | ||
143 | *d = '\0'; | ||
144 | return escaped; | ||
145 | } | ||
146 | |||
147 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** | ||
148 | * DMA services | ||
149 | * | ||
150 | * Theory of operation | ||
151 | * | ||
152 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer | ||
153 | * of buffer descriptors, each of which points to one or more data buffers for | ||
154 | * the device to read from or fill. Driver and device exchange status of each | ||
155 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty | ||
156 | * entries in each circular buffer, to protect against confusing empty and full | ||
157 | * queue states. | ||
158 | * | ||
159 | * The device reads or writes the data in the queues via the device's several | ||
160 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. | ||
161 | * | ||
162 | * For Tx queue, there are low mark and high mark limits. If, after queuing | ||
163 | * the packet for Tx, free space become < low mark, Tx queue stopped. When | ||
164 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | ||
165 | * Tx queue resumed. | ||
166 | * | ||
167 | * The 4965 operates with up to 17 queues: One receive queue, one transmit | ||
168 | * queue (#4) for sending commands to the device firmware, and 15 other | ||
169 | * Tx queues that may be mapped to prioritized Tx DMA/FIFO channels. | ||
170 | * | ||
171 | * See more detailed info in iwl-4965-hw.h. | ||
172 | ***************************************************/ | ||
173 | |||
174 | int iwl4965_queue_space(const struct iwl4965_queue *q) | ||
175 | { | ||
176 | int s = q->read_ptr - q->write_ptr; | ||
177 | |||
178 | if (q->read_ptr > q->write_ptr) | ||
179 | s -= q->n_bd; | ||
180 | |||
181 | if (s <= 0) | ||
182 | s += q->n_window; | ||
183 | /* keep some reserve to not confuse empty and full situations */ | ||
184 | s -= 2; | ||
185 | if (s < 0) | ||
186 | s = 0; | ||
187 | return s; | ||
188 | } | ||
189 | |||
190 | |||
191 | static inline int x2_queue_used(const struct iwl4965_queue *q, int i) | ||
192 | { | ||
193 | return q->write_ptr > q->read_ptr ? | ||
194 | (i >= q->read_ptr && i < q->write_ptr) : | ||
195 | !(i < q->read_ptr && i >= q->write_ptr); | ||
196 | } | ||
197 | |||
198 | static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) | ||
199 | { | ||
200 | /* This is for scan command, the big buffer at end of command array */ | ||
201 | if (is_huge) | ||
202 | return q->n_window; /* must be power of 2 */ | ||
203 | |||
204 | /* Otherwise, use normal size buffers */ | ||
205 | return index & (q->n_window - 1); | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes | ||
210 | */ | ||
211 | static int iwl4965_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, | ||
212 | int count, int slots_num, u32 id) | ||
213 | { | ||
214 | q->n_bd = count; | ||
215 | q->n_window = slots_num; | ||
216 | q->id = id; | ||
217 | |||
218 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
219 | * and iwl_queue_dec_wrap are broken. */ | ||
220 | BUG_ON(!is_power_of_2(count)); | ||
221 | |||
222 | /* slots_num must be power-of-two size, otherwise | ||
223 | * get_cmd_index is broken. */ | ||
224 | BUG_ON(!is_power_of_2(slots_num)); | ||
225 | |||
226 | q->low_mark = q->n_window / 4; | ||
227 | if (q->low_mark < 4) | ||
228 | q->low_mark = 4; | ||
229 | |||
230 | q->high_mark = q->n_window / 8; | ||
231 | if (q->high_mark < 2) | ||
232 | q->high_mark = 2; | ||
233 | |||
234 | q->write_ptr = q->read_ptr = 0; | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
241 | */ | ||
242 | static int iwl4965_tx_queue_alloc(struct iwl_priv *priv, | ||
243 | struct iwl4965_tx_queue *txq, u32 id) | ||
244 | { | ||
245 | struct pci_dev *dev = priv->pci_dev; | ||
246 | |||
247 | /* Driver private data, only for Tx (not command) queues, | ||
248 | * not shared with device. */ | ||
249 | if (id != IWL_CMD_QUEUE_NUM) { | ||
250 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | ||
251 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | ||
252 | if (!txq->txb) { | ||
253 | IWL_ERROR("kmalloc for auxiliary BD " | ||
254 | "structures failed\n"); | ||
255 | goto error; | ||
256 | } | ||
257 | } else | ||
258 | txq->txb = NULL; | ||
259 | |||
260 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
261 | * shared with device */ | ||
262 | txq->bd = pci_alloc_consistent(dev, | ||
263 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | ||
264 | &txq->q.dma_addr); | ||
265 | |||
266 | if (!txq->bd) { | ||
267 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | ||
268 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); | ||
269 | goto error; | ||
270 | } | ||
271 | txq->q.id = id; | ||
272 | |||
273 | return 0; | ||
274 | |||
275 | error: | ||
276 | if (txq->txb) { | ||
277 | kfree(txq->txb); | ||
278 | txq->txb = NULL; | ||
279 | } | ||
280 | |||
281 | return -ENOMEM; | ||
282 | } | ||
283 | |||
284 | /** | ||
285 | * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
286 | */ | ||
287 | int iwl4965_tx_queue_init(struct iwl_priv *priv, | ||
288 | struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id) | ||
289 | { | ||
290 | struct pci_dev *dev = priv->pci_dev; | ||
291 | int len; | ||
292 | int rc = 0; | ||
293 | |||
294 | /* | ||
295 | * Alloc buffer array for commands (Tx or other types of commands). | ||
296 | * For the command queue (#4), allocate command space + one big | ||
297 | * command for scan, since scan command is very huge; the system will | ||
298 | * not have two scans at the same time, so only one is needed. | ||
299 | * For normal Tx queues (all other queues), no super-size command | ||
300 | * space is needed. | ||
301 | */ | ||
302 | len = sizeof(struct iwl_cmd) * slots_num; | ||
303 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
304 | len += IWL_MAX_SCAN_SIZE; | ||
305 | txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); | ||
306 | if (!txq->cmd) | ||
307 | return -ENOMEM; | ||
308 | |||
309 | /* Alloc driver data array and TFD circular buffer */ | ||
310 | rc = iwl4965_tx_queue_alloc(priv, txq, txq_id); | ||
311 | if (rc) { | ||
312 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
313 | |||
314 | return -ENOMEM; | ||
315 | } | ||
316 | txq->need_update = 0; | ||
317 | |||
318 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
319 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
320 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
321 | |||
322 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
323 | iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
324 | |||
325 | /* Tell device where to find queue */ | ||
326 | iwl4965_hw_tx_queue_init(priv, txq); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | /** | ||
332 | * iwl4965_tx_queue_free - Deallocate DMA queue. | ||
333 | * @txq: Transmit queue to deallocate. | ||
334 | * | ||
335 | * Empty queue by removing and destroying all BD's. | ||
336 | * Free all buffers. | ||
337 | * 0-fill, but do not free "txq" descriptor structure. | ||
338 | */ | ||
339 | void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
340 | { | ||
341 | struct iwl4965_queue *q = &txq->q; | ||
342 | struct pci_dev *dev = priv->pci_dev; | ||
343 | int len; | ||
344 | |||
345 | if (q->n_bd == 0) | ||
346 | return; | ||
347 | |||
348 | /* first, empty all BD's */ | ||
349 | for (; q->write_ptr != q->read_ptr; | ||
350 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | ||
351 | iwl4965_hw_txq_free_tfd(priv, txq); | ||
352 | |||
353 | len = sizeof(struct iwl_cmd) * q->n_window; | ||
354 | if (q->id == IWL_CMD_QUEUE_NUM) | ||
355 | len += IWL_MAX_SCAN_SIZE; | ||
356 | |||
357 | /* De-alloc array of command/tx buffers */ | ||
358 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
359 | |||
360 | /* De-alloc circular buffer of TFDs */ | ||
361 | if (txq->q.n_bd) | ||
362 | pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * | ||
363 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | ||
364 | |||
365 | /* De-alloc array of per-TFD driver data */ | ||
366 | if (txq->txb) { | ||
367 | kfree(txq->txb); | ||
368 | txq->txb = NULL; | ||
369 | } | ||
370 | |||
371 | /* 0-fill queue descriptor structure */ | ||
372 | memset(txq, 0, sizeof(*txq)); | ||
373 | } | ||
374 | |||
375 | const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
376 | |||
377 | /*************** STATION TABLE MANAGEMENT **** | 90 | /*************** STATION TABLE MANAGEMENT **** |
378 | * mac80211 should be examined to determine if sta_info is duplicating | 91 | * mac80211 should be examined to determine if sta_info is duplicating |
379 | * the functionality provided here | 92 | * the functionality provided here |
@@ -381,213 +94,11 @@ const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF | |||
381 | 94 | ||
382 | /**************************************************************/ | 95 | /**************************************************************/ |
383 | 96 | ||
384 | #if 0 /* temporary disable till we add real remove station */ | ||
385 | /** | ||
386 | * iwl4965_remove_station - Remove driver's knowledge of station. | ||
387 | * | ||
388 | * NOTE: This does not remove station from device's station table. | ||
389 | */ | ||
390 | static u8 iwl4965_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | ||
391 | { | ||
392 | int index = IWL_INVALID_STATION; | ||
393 | int i; | ||
394 | unsigned long flags; | ||
395 | |||
396 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
397 | |||
398 | if (is_ap) | ||
399 | index = IWL_AP_ID; | ||
400 | else if (is_broadcast_ether_addr(addr)) | ||
401 | index = priv->hw_params.bcast_sta_id; | ||
402 | else | ||
403 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) | ||
404 | if (priv->stations[i].used && | ||
405 | !compare_ether_addr(priv->stations[i].sta.sta.addr, | ||
406 | addr)) { | ||
407 | index = i; | ||
408 | break; | ||
409 | } | ||
410 | |||
411 | if (unlikely(index == IWL_INVALID_STATION)) | ||
412 | goto out; | ||
413 | |||
414 | if (priv->stations[index].used) { | ||
415 | priv->stations[index].used = 0; | ||
416 | priv->num_stations--; | ||
417 | } | ||
418 | |||
419 | BUG_ON(priv->num_stations < 0); | ||
420 | |||
421 | out: | ||
422 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
423 | return 0; | ||
424 | } | ||
425 | #endif | ||
426 | |||
427 | /** | ||
428 | * iwl4965_add_station_flags - Add station to tables in driver and device | ||
429 | */ | ||
430 | u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, | ||
431 | int is_ap, u8 flags, void *ht_data) | ||
432 | { | ||
433 | int i; | ||
434 | int index = IWL_INVALID_STATION; | ||
435 | struct iwl4965_station_entry *station; | ||
436 | unsigned long flags_spin; | ||
437 | DECLARE_MAC_BUF(mac); | ||
438 | |||
439 | spin_lock_irqsave(&priv->sta_lock, flags_spin); | ||
440 | if (is_ap) | ||
441 | index = IWL_AP_ID; | ||
442 | else if (is_broadcast_ether_addr(addr)) | ||
443 | index = priv->hw_params.bcast_sta_id; | ||
444 | else | ||
445 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { | ||
446 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, | ||
447 | addr)) { | ||
448 | index = i; | ||
449 | break; | ||
450 | } | ||
451 | |||
452 | if (!priv->stations[i].used && | ||
453 | index == IWL_INVALID_STATION) | ||
454 | index = i; | ||
455 | } | ||
456 | |||
457 | |||
458 | /* These two conditions have the same outcome, but keep them separate | ||
459 | since they have different meanings */ | ||
460 | if (unlikely(index == IWL_INVALID_STATION)) { | ||
461 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
462 | return index; | ||
463 | } | ||
464 | |||
465 | if (priv->stations[index].used && | ||
466 | !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) { | ||
467 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
468 | return index; | ||
469 | } | ||
470 | |||
471 | |||
472 | IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr)); | ||
473 | station = &priv->stations[index]; | ||
474 | station->used = 1; | ||
475 | priv->num_stations++; | ||
476 | |||
477 | /* Set up the REPLY_ADD_STA command to send to device */ | ||
478 | memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd)); | ||
479 | memcpy(station->sta.sta.addr, addr, ETH_ALEN); | ||
480 | station->sta.mode = 0; | ||
481 | station->sta.sta.sta_id = index; | ||
482 | station->sta.station_flags = 0; | ||
483 | |||
484 | #ifdef CONFIG_IWL4965_HT | ||
485 | /* BCAST station and IBSS stations do not work in HT mode */ | ||
486 | if (index != priv->hw_params.bcast_sta_id && | ||
487 | priv->iw_mode != IEEE80211_IF_TYPE_IBSS) | ||
488 | iwl4965_set_ht_add_station(priv, index, | ||
489 | (struct ieee80211_ht_info *) ht_data); | ||
490 | #endif /*CONFIG_IWL4965_HT*/ | ||
491 | |||
492 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
493 | |||
494 | /* Add station to device's station table */ | ||
495 | iwl4965_send_add_station(priv, &station->sta, flags); | ||
496 | return index; | ||
497 | |||
498 | } | ||
499 | |||
500 | |||
501 | |||
502 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ | ||
503 | |||
504 | /** | ||
505 | * iwl4965_enqueue_hcmd - enqueue a uCode command | ||
506 | * @priv: device private data point | ||
507 | * @cmd: a point to the ucode command structure | ||
508 | * | ||
509 | * The function returns < 0 values to indicate the operation is | ||
510 | * failed. On success, it turns the index (> 0) of command in the | ||
511 | * command queue. | ||
512 | */ | ||
513 | int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | ||
514 | { | ||
515 | struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | ||
516 | struct iwl4965_queue *q = &txq->q; | ||
517 | struct iwl4965_tfd_frame *tfd; | ||
518 | u32 *control_flags; | ||
519 | struct iwl_cmd *out_cmd; | ||
520 | u32 idx; | ||
521 | u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); | ||
522 | dma_addr_t phys_addr; | ||
523 | int ret; | ||
524 | unsigned long flags; | ||
525 | |||
526 | /* If any of the command structures end up being larger than | ||
527 | * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then | ||
528 | * we will need to increase the size of the TFD entries */ | ||
529 | BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && | ||
530 | !(cmd->meta.flags & CMD_SIZE_HUGE)); | ||
531 | |||
532 | if (iwl_is_rfkill(priv)) { | ||
533 | IWL_DEBUG_INFO("Not sending command - RF KILL"); | ||
534 | return -EIO; | ||
535 | } | ||
536 | |||
537 | if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { | ||
538 | IWL_ERROR("No space for Tx\n"); | ||
539 | return -ENOSPC; | ||
540 | } | ||
541 | |||
542 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
543 | |||
544 | tfd = &txq->bd[q->write_ptr]; | ||
545 | memset(tfd, 0, sizeof(*tfd)); | ||
546 | |||
547 | control_flags = (u32 *) tfd; | ||
548 | 97 | ||
549 | idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); | ||
550 | out_cmd = &txq->cmd[idx]; | ||
551 | |||
552 | out_cmd->hdr.cmd = cmd->id; | ||
553 | memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta)); | ||
554 | memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); | ||
555 | |||
556 | /* At this point, the out_cmd now has all of the incoming cmd | ||
557 | * information */ | ||
558 | |||
559 | out_cmd->hdr.flags = 0; | ||
560 | out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | | ||
561 | INDEX_TO_SEQ(q->write_ptr)); | ||
562 | if (out_cmd->meta.flags & CMD_SIZE_HUGE) | ||
563 | out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME); | ||
564 | |||
565 | phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx + | ||
566 | offsetof(struct iwl_cmd, hdr); | ||
567 | iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); | ||
568 | |||
569 | IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, " | ||
570 | "%d bytes at %d[%d]:%d\n", | ||
571 | get_cmd_string(out_cmd->hdr.cmd), | ||
572 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), | ||
573 | fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); | ||
574 | |||
575 | txq->need_update = 1; | ||
576 | |||
577 | /* Set up entry in queue's byte count circular buffer */ | ||
578 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); | ||
579 | |||
580 | /* Increment and update queue's write index */ | ||
581 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | ||
582 | ret = iwl4965_tx_queue_update_write_ptr(priv, txq); | ||
583 | |||
584 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||
585 | return ret ? ret : idx; | ||
586 | } | ||
587 | 98 | ||
588 | static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) | 99 | static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) |
589 | { | 100 | { |
590 | struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; | 101 | struct iwl_rxon_cmd *rxon = &priv->staging_rxon; |
591 | 102 | ||
592 | if (hw_decrypt) | 103 | if (hw_decrypt) |
593 | rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; | 104 | rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; |
@@ -597,45 +108,13 @@ static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) | |||
597 | } | 108 | } |
598 | 109 | ||
599 | /** | 110 | /** |
600 | * iwl4965_rxon_add_station - add station into station table. | ||
601 | * | ||
602 | * there is only one AP station with id= IWL_AP_ID | ||
603 | * NOTE: mutex must be held before calling this fnction | ||
604 | */ | ||
605 | static int iwl4965_rxon_add_station(struct iwl_priv *priv, | ||
606 | const u8 *addr, int is_ap) | ||
607 | { | ||
608 | u8 sta_id; | ||
609 | |||
610 | /* Add station to device's station table */ | ||
611 | #ifdef CONFIG_IWL4965_HT | ||
612 | struct ieee80211_conf *conf = &priv->hw->conf; | ||
613 | struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; | ||
614 | |||
615 | if ((is_ap) && | ||
616 | (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && | ||
617 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) | ||
618 | sta_id = iwl4965_add_station_flags(priv, addr, is_ap, | ||
619 | 0, cur_ht_config); | ||
620 | else | ||
621 | #endif /* CONFIG_IWL4965_HT */ | ||
622 | sta_id = iwl4965_add_station_flags(priv, addr, is_ap, | ||
623 | 0, NULL); | ||
624 | |||
625 | /* Set up default rate scaling table in device's station table */ | ||
626 | iwl4965_add_station(priv, addr, is_ap); | ||
627 | |||
628 | return sta_id; | ||
629 | } | ||
630 | |||
631 | /** | ||
632 | * iwl4965_check_rxon_cmd - validate RXON structure is valid | 111 | * iwl4965_check_rxon_cmd - validate RXON structure is valid |
633 | * | 112 | * |
634 | * NOTE: This is really only useful during development and can eventually | 113 | * NOTE: This is really only useful during development and can eventually |
635 | * be #ifdef'd out once the driver is stable and folks aren't actively | 114 | * be #ifdef'd out once the driver is stable and folks aren't actively |
636 | * making changes | 115 | * making changes |
637 | */ | 116 | */ |
638 | static int iwl4965_check_rxon_cmd(struct iwl4965_rxon_cmd *rxon) | 117 | static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon) |
639 | { | 118 | { |
640 | int error = 0; | 119 | int error = 0; |
641 | int counter = 1; | 120 | int counter = 1; |
@@ -713,7 +192,7 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) | |||
713 | { | 192 | { |
714 | 193 | ||
715 | /* These items are only settable from the full RXON command */ | 194 | /* These items are only settable from the full RXON command */ |
716 | if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) || | 195 | if (!(iwl_is_associated(priv)) || |
717 | compare_ether_addr(priv->staging_rxon.bssid_addr, | 196 | compare_ether_addr(priv->staging_rxon.bssid_addr, |
718 | priv->active_rxon.bssid_addr) || | 197 | priv->active_rxon.bssid_addr) || |
719 | compare_ether_addr(priv->staging_rxon.node_addr, | 198 | compare_ether_addr(priv->staging_rxon.node_addr, |
@@ -760,18 +239,23 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) | |||
760 | static int iwl4965_commit_rxon(struct iwl_priv *priv) | 239 | static int iwl4965_commit_rxon(struct iwl_priv *priv) |
761 | { | 240 | { |
762 | /* cast away the const for active_rxon in this function */ | 241 | /* cast away the const for active_rxon in this function */ |
763 | struct iwl4965_rxon_cmd *active_rxon = (void *)&priv->active_rxon; | 242 | struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; |
764 | DECLARE_MAC_BUF(mac); | 243 | DECLARE_MAC_BUF(mac); |
765 | int rc = 0; | 244 | int ret; |
245 | bool new_assoc = | ||
246 | !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); | ||
766 | 247 | ||
767 | if (!iwl_is_alive(priv)) | 248 | if (!iwl_is_alive(priv)) |
768 | return -1; | 249 | return -EBUSY; |
769 | 250 | ||
770 | /* always get timestamp with Rx frame */ | 251 | /* always get timestamp with Rx frame */ |
771 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; | 252 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; |
253 | /* allow CTS-to-self if possible. this is relevant only for | ||
254 | * 5000, but will not damage 4965 */ | ||
255 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; | ||
772 | 256 | ||
773 | rc = iwl4965_check_rxon_cmd(&priv->staging_rxon); | 257 | ret = iwl4965_check_rxon_cmd(&priv->staging_rxon); |
774 | if (rc) { | 258 | if (ret) { |
775 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); | 259 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); |
776 | return -EINVAL; | 260 | return -EINVAL; |
777 | } | 261 | } |
@@ -780,49 +264,37 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
780 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter | 264 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter |
781 | * and other flags for the current radio configuration. */ | 265 | * and other flags for the current radio configuration. */ |
782 | if (!iwl4965_full_rxon_required(priv)) { | 266 | if (!iwl4965_full_rxon_required(priv)) { |
783 | rc = iwl_send_rxon_assoc(priv); | 267 | ret = iwl_send_rxon_assoc(priv); |
784 | if (rc) { | 268 | if (ret) { |
785 | IWL_ERROR("Error setting RXON_ASSOC " | 269 | IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); |
786 | "configuration (%d).\n", rc); | 270 | return ret; |
787 | return rc; | ||
788 | } | 271 | } |
789 | 272 | ||
790 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 273 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
791 | |||
792 | return 0; | 274 | return 0; |
793 | } | 275 | } |
794 | 276 | ||
795 | /* station table will be cleared */ | 277 | /* station table will be cleared */ |
796 | priv->assoc_station_added = 0; | 278 | priv->assoc_station_added = 0; |
797 | 279 | ||
798 | #ifdef CONFIG_IWL4965_SENSITIVITY | ||
799 | priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT; | ||
800 | if (!priv->error_recovering) | ||
801 | priv->start_calib = 0; | ||
802 | |||
803 | iwl4965_init_sensitivity(priv, CMD_ASYNC, 1); | ||
804 | #endif /* CONFIG_IWL4965_SENSITIVITY */ | ||
805 | |||
806 | /* If we are currently associated and the new config requires | 280 | /* If we are currently associated and the new config requires |
807 | * an RXON_ASSOC and the new config wants the associated mask enabled, | 281 | * an RXON_ASSOC and the new config wants the associated mask enabled, |
808 | * we must clear the associated from the active configuration | 282 | * we must clear the associated from the active configuration |
809 | * before we apply the new config */ | 283 | * before we apply the new config */ |
810 | if (iwl_is_associated(priv) && | 284 | if (iwl_is_associated(priv) && new_assoc) { |
811 | (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) { | ||
812 | IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); | 285 | IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); |
813 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 286 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
814 | 287 | ||
815 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, | 288 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, |
816 | sizeof(struct iwl4965_rxon_cmd), | 289 | sizeof(struct iwl_rxon_cmd), |
817 | &priv->active_rxon); | 290 | &priv->active_rxon); |
818 | 291 | ||
819 | /* If the mask clearing failed then we set | 292 | /* If the mask clearing failed then we set |
820 | * active_rxon back to what it was previously */ | 293 | * active_rxon back to what it was previously */ |
821 | if (rc) { | 294 | if (ret) { |
822 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; | 295 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; |
823 | IWL_ERROR("Error clearing ASSOC_MSK on current " | 296 | IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret); |
824 | "configuration (%d).\n", rc); | 297 | return ret; |
825 | return rc; | ||
826 | } | 298 | } |
827 | } | 299 | } |
828 | 300 | ||
@@ -830,65 +302,87 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
830 | "* with%s RXON_FILTER_ASSOC_MSK\n" | 302 | "* with%s RXON_FILTER_ASSOC_MSK\n" |
831 | "* channel = %d\n" | 303 | "* channel = %d\n" |
832 | "* bssid = %s\n", | 304 | "* bssid = %s\n", |
833 | ((priv->staging_rxon.filter_flags & | 305 | (new_assoc ? "" : "out"), |
834 | RXON_FILTER_ASSOC_MSK) ? "" : "out"), | ||
835 | le16_to_cpu(priv->staging_rxon.channel), | 306 | le16_to_cpu(priv->staging_rxon.channel), |
836 | print_mac(mac, priv->staging_rxon.bssid_addr)); | 307 | print_mac(mac, priv->staging_rxon.bssid_addr)); |
837 | 308 | ||
838 | iwl4965_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); | 309 | iwl4965_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto); |
839 | /* Apply the new configuration */ | 310 | |
840 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, | 311 | /* Apply the new configuration |
841 | sizeof(struct iwl4965_rxon_cmd), &priv->staging_rxon); | 312 | * RXON unassoc clears the station table in uCode, send it before |
842 | if (rc) { | 313 | * we add the bcast station. If assoc bit is set, we will send RXON |
843 | IWL_ERROR("Error setting new configuration (%d).\n", rc); | 314 | * after having added the bcast and bssid station. |
844 | return rc; | 315 | */ |
316 | if (!new_assoc) { | ||
317 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, | ||
318 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); | ||
319 | if (ret) { | ||
320 | IWL_ERROR("Error setting new RXON (%d)\n", ret); | ||
321 | return ret; | ||
322 | } | ||
323 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | ||
845 | } | 324 | } |
846 | 325 | ||
847 | iwlcore_clear_stations_table(priv); | 326 | iwl_clear_stations_table(priv); |
848 | 327 | ||
849 | #ifdef CONFIG_IWL4965_SENSITIVITY | ||
850 | if (!priv->error_recovering) | 328 | if (!priv->error_recovering) |
851 | priv->start_calib = 0; | 329 | priv->start_calib = 0; |
852 | 330 | ||
853 | priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT; | ||
854 | iwl4965_init_sensitivity(priv, CMD_ASYNC, 1); | ||
855 | #endif /* CONFIG_IWL4965_SENSITIVITY */ | ||
856 | |||
857 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | ||
858 | |||
859 | /* If we issue a new RXON command which required a tune then we must | ||
860 | * send a new TXPOWER command or we won't be able to Tx any frames */ | ||
861 | rc = iwl4965_hw_reg_send_txpower(priv); | ||
862 | if (rc) { | ||
863 | IWL_ERROR("Error setting Tx power (%d).\n", rc); | ||
864 | return rc; | ||
865 | } | ||
866 | |||
867 | /* Add the broadcast address so we can send broadcast frames */ | 331 | /* Add the broadcast address so we can send broadcast frames */ |
868 | if (iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0) == | 332 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == |
869 | IWL_INVALID_STATION) { | 333 | IWL_INVALID_STATION) { |
870 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); | 334 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); |
871 | return -EIO; | 335 | return -EIO; |
872 | } | 336 | } |
873 | 337 | ||
874 | /* If we have set the ASSOC_MSK and we are in BSS mode then | 338 | /* If we have set the ASSOC_MSK and we are in BSS mode then |
875 | * add the IWL_AP_ID to the station rate table */ | 339 | * add the IWL_AP_ID to the station rate table */ |
876 | if (iwl_is_associated(priv) && | 340 | if (new_assoc) { |
877 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) { | 341 | if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { |
878 | if (iwl4965_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1) | 342 | ret = iwl_rxon_add_station(priv, |
879 | == IWL_INVALID_STATION) { | 343 | priv->active_rxon.bssid_addr, 1); |
880 | IWL_ERROR("Error adding AP address for transmit.\n"); | 344 | if (ret == IWL_INVALID_STATION) { |
881 | return -EIO; | 345 | IWL_ERROR("Error adding AP address for TX.\n"); |
346 | return -EIO; | ||
347 | } | ||
348 | priv->assoc_station_added = 1; | ||
349 | if (priv->default_wep_key && | ||
350 | iwl_send_static_wepkey_cmd(priv, 0)) | ||
351 | IWL_ERROR("Could not send WEP static key.\n"); | ||
882 | } | 352 | } |
883 | priv->assoc_station_added = 1; | 353 | |
884 | if (priv->default_wep_key && | 354 | /* Apply the new configuration |
885 | iwl_send_static_wepkey_cmd(priv, 0)) | 355 | * RXON assoc doesn't clear the station table in uCode, |
886 | IWL_ERROR("Could not send WEP static key.\n"); | 356 | */ |
357 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, | ||
358 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); | ||
359 | if (ret) { | ||
360 | IWL_ERROR("Error setting new RXON (%d)\n", ret); | ||
361 | return ret; | ||
362 | } | ||
363 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | ||
364 | } | ||
365 | |||
366 | iwl_init_sensitivity(priv); | ||
367 | |||
368 | /* If we issue a new RXON command which required a tune then we must | ||
369 | * send a new TXPOWER command or we won't be able to Tx any frames */ | ||
370 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | ||
371 | if (ret) { | ||
372 | IWL_ERROR("Error sending TX power (%d)\n", ret); | ||
373 | return ret; | ||
887 | } | 374 | } |
888 | 375 | ||
889 | return 0; | 376 | return 0; |
890 | } | 377 | } |
891 | 378 | ||
379 | void iwl4965_update_chain_flags(struct iwl_priv *priv) | ||
380 | { | ||
381 | |||
382 | iwl_set_rxon_chain(priv); | ||
383 | iwl4965_commit_rxon(priv); | ||
384 | } | ||
385 | |||
892 | static int iwl4965_send_bt_config(struct iwl_priv *priv) | 386 | static int iwl4965_send_bt_config(struct iwl_priv *priv) |
893 | { | 387 | { |
894 | struct iwl4965_bt_cmd bt_cmd = { | 388 | struct iwl4965_bt_cmd bt_cmd = { |
@@ -903,155 +397,7 @@ static int iwl4965_send_bt_config(struct iwl_priv *priv) | |||
903 | sizeof(struct iwl4965_bt_cmd), &bt_cmd); | 397 | sizeof(struct iwl4965_bt_cmd), &bt_cmd); |
904 | } | 398 | } |
905 | 399 | ||
906 | static int iwl4965_send_scan_abort(struct iwl_priv *priv) | 400 | static void iwl_clear_free_frames(struct iwl_priv *priv) |
907 | { | ||
908 | int rc = 0; | ||
909 | struct iwl4965_rx_packet *res; | ||
910 | struct iwl_host_cmd cmd = { | ||
911 | .id = REPLY_SCAN_ABORT_CMD, | ||
912 | .meta.flags = CMD_WANT_SKB, | ||
913 | }; | ||
914 | |||
915 | /* If there isn't a scan actively going on in the hardware | ||
916 | * then we are in between scan bands and not actually | ||
917 | * actively scanning, so don't send the abort command */ | ||
918 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
919 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
920 | return 0; | ||
921 | } | ||
922 | |||
923 | rc = iwl_send_cmd_sync(priv, &cmd); | ||
924 | if (rc) { | ||
925 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
926 | return rc; | ||
927 | } | ||
928 | |||
929 | res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; | ||
930 | if (res->u.status != CAN_ABORT_STATUS) { | ||
931 | /* The scan abort will return 1 for success or | ||
932 | * 2 for "failure". A failure condition can be | ||
933 | * due to simply not being in an active scan which | ||
934 | * can occur if we send the scan abort before we | ||
935 | * the microcode has notified us that a scan is | ||
936 | * completed. */ | ||
937 | IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status); | ||
938 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
939 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
940 | } | ||
941 | |||
942 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
943 | |||
944 | return rc; | ||
945 | } | ||
946 | |||
947 | static int iwl4965_card_state_sync_callback(struct iwl_priv *priv, | ||
948 | struct iwl_cmd *cmd, | ||
949 | struct sk_buff *skb) | ||
950 | { | ||
951 | return 1; | ||
952 | } | ||
953 | |||
954 | /* | ||
955 | * CARD_STATE_CMD | ||
956 | * | ||
957 | * Use: Sets the device's internal card state to enable, disable, or halt | ||
958 | * | ||
959 | * When in the 'enable' state the card operates as normal. | ||
960 | * When in the 'disable' state, the card enters into a low power mode. | ||
961 | * When in the 'halt' state, the card is shut down and must be fully | ||
962 | * restarted to come back on. | ||
963 | */ | ||
964 | static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | ||
965 | { | ||
966 | struct iwl_host_cmd cmd = { | ||
967 | .id = REPLY_CARD_STATE_CMD, | ||
968 | .len = sizeof(u32), | ||
969 | .data = &flags, | ||
970 | .meta.flags = meta_flag, | ||
971 | }; | ||
972 | |||
973 | if (meta_flag & CMD_ASYNC) | ||
974 | cmd.meta.u.callback = iwl4965_card_state_sync_callback; | ||
975 | |||
976 | return iwl_send_cmd(priv, &cmd); | ||
977 | } | ||
978 | |||
979 | static int iwl4965_add_sta_sync_callback(struct iwl_priv *priv, | ||
980 | struct iwl_cmd *cmd, struct sk_buff *skb) | ||
981 | { | ||
982 | struct iwl4965_rx_packet *res = NULL; | ||
983 | |||
984 | if (!skb) { | ||
985 | IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n"); | ||
986 | return 1; | ||
987 | } | ||
988 | |||
989 | res = (struct iwl4965_rx_packet *)skb->data; | ||
990 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
991 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | ||
992 | res->hdr.flags); | ||
993 | return 1; | ||
994 | } | ||
995 | |||
996 | switch (res->u.add_sta.status) { | ||
997 | case ADD_STA_SUCCESS_MSK: | ||
998 | break; | ||
999 | default: | ||
1000 | break; | ||
1001 | } | ||
1002 | |||
1003 | /* We didn't cache the SKB; let the caller free it */ | ||
1004 | return 1; | ||
1005 | } | ||
1006 | |||
1007 | int iwl4965_send_add_station(struct iwl_priv *priv, | ||
1008 | struct iwl4965_addsta_cmd *sta, u8 flags) | ||
1009 | { | ||
1010 | struct iwl4965_rx_packet *res = NULL; | ||
1011 | int rc = 0; | ||
1012 | struct iwl_host_cmd cmd = { | ||
1013 | .id = REPLY_ADD_STA, | ||
1014 | .len = sizeof(struct iwl4965_addsta_cmd), | ||
1015 | .meta.flags = flags, | ||
1016 | .data = sta, | ||
1017 | }; | ||
1018 | |||
1019 | if (flags & CMD_ASYNC) | ||
1020 | cmd.meta.u.callback = iwl4965_add_sta_sync_callback; | ||
1021 | else | ||
1022 | cmd.meta.flags |= CMD_WANT_SKB; | ||
1023 | |||
1024 | rc = iwl_send_cmd(priv, &cmd); | ||
1025 | |||
1026 | if (rc || (flags & CMD_ASYNC)) | ||
1027 | return rc; | ||
1028 | |||
1029 | res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; | ||
1030 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
1031 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | ||
1032 | res->hdr.flags); | ||
1033 | rc = -EIO; | ||
1034 | } | ||
1035 | |||
1036 | if (rc == 0) { | ||
1037 | switch (res->u.add_sta.status) { | ||
1038 | case ADD_STA_SUCCESS_MSK: | ||
1039 | IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); | ||
1040 | break; | ||
1041 | default: | ||
1042 | rc = -EIO; | ||
1043 | IWL_WARNING("REPLY_ADD_STA failed\n"); | ||
1044 | break; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | priv->alloc_rxb_skb--; | ||
1049 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
1050 | |||
1051 | return rc; | ||
1052 | } | ||
1053 | |||
1054 | static void iwl4965_clear_free_frames(struct iwl_priv *priv) | ||
1055 | { | 401 | { |
1056 | struct list_head *element; | 402 | struct list_head *element; |
1057 | 403 | ||
@@ -1061,7 +407,7 @@ static void iwl4965_clear_free_frames(struct iwl_priv *priv) | |||
1061 | while (!list_empty(&priv->free_frames)) { | 407 | while (!list_empty(&priv->free_frames)) { |
1062 | element = priv->free_frames.next; | 408 | element = priv->free_frames.next; |
1063 | list_del(element); | 409 | list_del(element); |
1064 | kfree(list_entry(element, struct iwl4965_frame, list)); | 410 | kfree(list_entry(element, struct iwl_frame, list)); |
1065 | priv->frames_count--; | 411 | priv->frames_count--; |
1066 | } | 412 | } |
1067 | 413 | ||
@@ -1072,9 +418,9 @@ static void iwl4965_clear_free_frames(struct iwl_priv *priv) | |||
1072 | } | 418 | } |
1073 | } | 419 | } |
1074 | 420 | ||
1075 | static struct iwl4965_frame *iwl4965_get_free_frame(struct iwl_priv *priv) | 421 | static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv) |
1076 | { | 422 | { |
1077 | struct iwl4965_frame *frame; | 423 | struct iwl_frame *frame; |
1078 | struct list_head *element; | 424 | struct list_head *element; |
1079 | if (list_empty(&priv->free_frames)) { | 425 | if (list_empty(&priv->free_frames)) { |
1080 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); | 426 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); |
@@ -1089,10 +435,10 @@ static struct iwl4965_frame *iwl4965_get_free_frame(struct iwl_priv *priv) | |||
1089 | 435 | ||
1090 | element = priv->free_frames.next; | 436 | element = priv->free_frames.next; |
1091 | list_del(element); | 437 | list_del(element); |
1092 | return list_entry(element, struct iwl4965_frame, list); | 438 | return list_entry(element, struct iwl_frame, list); |
1093 | } | 439 | } |
1094 | 440 | ||
1095 | static void iwl4965_free_frame(struct iwl_priv *priv, struct iwl4965_frame *frame) | 441 | static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) |
1096 | { | 442 | { |
1097 | memset(frame, 0, sizeof(*frame)); | 443 | memset(frame, 0, sizeof(*frame)); |
1098 | list_add(&frame->list, &priv->free_frames); | 444 | list_add(&frame->list, &priv->free_frames); |
@@ -1116,27 +462,39 @@ unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, | |||
1116 | return priv->ibss_beacon->len; | 462 | return priv->ibss_beacon->len; |
1117 | } | 463 | } |
1118 | 464 | ||
1119 | static u8 iwl4965_rate_get_lowest_plcp(int rate_mask) | 465 | static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv) |
1120 | { | 466 | { |
1121 | u8 i; | 467 | int i; |
468 | int rate_mask; | ||
469 | |||
470 | /* Set rate mask*/ | ||
471 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) | ||
472 | rate_mask = priv->active_rate_basic & 0xF; | ||
473 | else | ||
474 | rate_mask = priv->active_rate_basic & 0xFF0; | ||
1122 | 475 | ||
476 | /* Find lowest valid rate */ | ||
1123 | for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID; | 477 | for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID; |
1124 | i = iwl4965_rates[i].next_ieee) { | 478 | i = iwl_rates[i].next_ieee) { |
1125 | if (rate_mask & (1 << i)) | 479 | if (rate_mask & (1 << i)) |
1126 | return iwl4965_rates[i].plcp; | 480 | return iwl_rates[i].plcp; |
1127 | } | 481 | } |
1128 | 482 | ||
1129 | return IWL_RATE_INVALID; | 483 | /* No valid rate was found. Assign the lowest one */ |
484 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) | ||
485 | return IWL_RATE_1M_PLCP; | ||
486 | else | ||
487 | return IWL_RATE_6M_PLCP; | ||
1130 | } | 488 | } |
1131 | 489 | ||
1132 | static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | 490 | static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) |
1133 | { | 491 | { |
1134 | struct iwl4965_frame *frame; | 492 | struct iwl_frame *frame; |
1135 | unsigned int frame_size; | 493 | unsigned int frame_size; |
1136 | int rc; | 494 | int rc; |
1137 | u8 rate; | 495 | u8 rate; |
1138 | 496 | ||
1139 | frame = iwl4965_get_free_frame(priv); | 497 | frame = iwl_get_free_frame(priv); |
1140 | 498 | ||
1141 | if (!frame) { | 499 | if (!frame) { |
1142 | IWL_ERROR("Could not obtain free frame buffer for beacon " | 500 | IWL_ERROR("Could not obtain free frame buffer for beacon " |
@@ -1144,23 +502,14 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | |||
1144 | return -ENOMEM; | 502 | return -ENOMEM; |
1145 | } | 503 | } |
1146 | 504 | ||
1147 | if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) { | 505 | rate = iwl4965_rate_get_lowest_plcp(priv); |
1148 | rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic & | ||
1149 | 0xFF0); | ||
1150 | if (rate == IWL_INVALID_RATE) | ||
1151 | rate = IWL_RATE_6M_PLCP; | ||
1152 | } else { | ||
1153 | rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic & 0xF); | ||
1154 | if (rate == IWL_INVALID_RATE) | ||
1155 | rate = IWL_RATE_1M_PLCP; | ||
1156 | } | ||
1157 | 506 | ||
1158 | frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate); | 507 | frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate); |
1159 | 508 | ||
1160 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, | 509 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, |
1161 | &frame->u.cmd[0]); | 510 | &frame->u.cmd[0]); |
1162 | 511 | ||
1163 | iwl4965_free_frame(priv, frame); | 512 | iwl_free_frame(priv, frame); |
1164 | 513 | ||
1165 | return rc; | 514 | return rc; |
1166 | } | 515 | } |
@@ -1171,184 +520,69 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | |||
1171 | * | 520 | * |
1172 | ******************************************************************************/ | 521 | ******************************************************************************/ |
1173 | 522 | ||
1174 | static void iwl4965_unset_hw_params(struct iwl_priv *priv) | 523 | static void iwl4965_ht_conf(struct iwl_priv *priv, |
1175 | { | 524 | struct ieee80211_bss_conf *bss_conf) |
1176 | if (priv->shared_virt) | ||
1177 | pci_free_consistent(priv->pci_dev, | ||
1178 | sizeof(struct iwl4965_shared), | ||
1179 | priv->shared_virt, | ||
1180 | priv->shared_phys); | ||
1181 | } | ||
1182 | |||
1183 | /** | ||
1184 | * iwl4965_supported_rate_to_ie - fill in the supported rate in IE field | ||
1185 | * | ||
1186 | * return : set the bit for each supported rate insert in ie | ||
1187 | */ | ||
1188 | static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate, | ||
1189 | u16 basic_rate, int *left) | ||
1190 | { | ||
1191 | u16 ret_rates = 0, bit; | ||
1192 | int i; | ||
1193 | u8 *cnt = ie; | ||
1194 | u8 *rates = ie + 1; | ||
1195 | |||
1196 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { | ||
1197 | if (bit & supported_rate) { | ||
1198 | ret_rates |= bit; | ||
1199 | rates[*cnt] = iwl4965_rates[i].ieee | | ||
1200 | ((bit & basic_rate) ? 0x80 : 0x00); | ||
1201 | (*cnt)++; | ||
1202 | (*left)--; | ||
1203 | if ((*left <= 0) || | ||
1204 | (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) | ||
1205 | break; | ||
1206 | } | ||
1207 | } | ||
1208 | |||
1209 | return ret_rates; | ||
1210 | } | ||
1211 | |||
1212 | /** | ||
1213 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request | ||
1214 | */ | ||
1215 | static u16 iwl4965_fill_probe_req(struct iwl_priv *priv, | ||
1216 | enum ieee80211_band band, | ||
1217 | struct ieee80211_mgmt *frame, | ||
1218 | int left, int is_direct) | ||
1219 | { | 525 | { |
1220 | int len = 0; | 526 | struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf; |
1221 | u8 *pos = NULL; | 527 | struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; |
1222 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; | 528 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; |
1223 | #ifdef CONFIG_IWL4965_HT | ||
1224 | const struct ieee80211_supported_band *sband = | ||
1225 | iwl4965_get_hw_mode(priv, band); | ||
1226 | #endif /* CONFIG_IWL4965_HT */ | ||
1227 | |||
1228 | /* Make sure there is enough space for the probe request, | ||
1229 | * two mandatory IEs and the data */ | ||
1230 | left -= 24; | ||
1231 | if (left < 0) | ||
1232 | return 0; | ||
1233 | len += 24; | ||
1234 | 529 | ||
1235 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | 530 | IWL_DEBUG_MAC80211("enter: \n"); |
1236 | memcpy(frame->da, iwl4965_broadcast_addr, ETH_ALEN); | ||
1237 | memcpy(frame->sa, priv->mac_addr, ETH_ALEN); | ||
1238 | memcpy(frame->bssid, iwl4965_broadcast_addr, ETH_ALEN); | ||
1239 | frame->seq_ctrl = 0; | ||
1240 | 531 | ||
1241 | /* fill in our indirect SSID IE */ | 532 | iwl_conf->is_ht = bss_conf->assoc_ht; |
1242 | /* ...next IE... */ | ||
1243 | 533 | ||
1244 | left -= 2; | 534 | if (!iwl_conf->is_ht) |
1245 | if (left < 0) | 535 | return; |
1246 | return 0; | ||
1247 | len += 2; | ||
1248 | pos = &(frame->u.probe_req.variable[0]); | ||
1249 | *pos++ = WLAN_EID_SSID; | ||
1250 | *pos++ = 0; | ||
1251 | |||
1252 | /* fill in our direct SSID IE... */ | ||
1253 | if (is_direct) { | ||
1254 | /* ...next IE... */ | ||
1255 | left -= 2 + priv->essid_len; | ||
1256 | if (left < 0) | ||
1257 | return 0; | ||
1258 | /* ... fill it in... */ | ||
1259 | *pos++ = WLAN_EID_SSID; | ||
1260 | *pos++ = priv->essid_len; | ||
1261 | memcpy(pos, priv->essid, priv->essid_len); | ||
1262 | pos += priv->essid_len; | ||
1263 | len += 2 + priv->essid_len; | ||
1264 | } | ||
1265 | |||
1266 | /* fill in supported rate */ | ||
1267 | /* ...next IE... */ | ||
1268 | left -= 2; | ||
1269 | if (left < 0) | ||
1270 | return 0; | ||
1271 | 536 | ||
1272 | /* ... fill it in... */ | 537 | priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); |
1273 | *pos++ = WLAN_EID_SUPP_RATES; | ||
1274 | *pos = 0; | ||
1275 | 538 | ||
1276 | /* exclude 60M rate */ | 539 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) |
1277 | active_rates = priv->rates_mask; | 540 | iwl_conf->sgf |= HT_SHORT_GI_20MHZ; |
1278 | active_rates &= ~IWL_RATE_60M_MASK; | 541 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) |
542 | iwl_conf->sgf |= HT_SHORT_GI_40MHZ; | ||
1279 | 543 | ||
1280 | active_rate_basic = active_rates & IWL_BASIC_RATES_MASK; | 544 | iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); |
545 | iwl_conf->max_amsdu_size = | ||
546 | !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); | ||
1281 | 547 | ||
1282 | cck_rates = IWL_CCK_RATES_MASK & active_rates; | 548 | iwl_conf->supported_chan_width = |
1283 | ret_rates = iwl4965_supported_rate_to_ie(pos, cck_rates, | 549 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); |
1284 | active_rate_basic, &left); | 550 | iwl_conf->extension_chan_offset = |
1285 | active_rates &= ~ret_rates; | 551 | ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; |
552 | /* If no above or below channel supplied disable FAT channel */ | ||
553 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE && | ||
554 | iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) { | ||
555 | iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE; | ||
556 | iwl_conf->supported_chan_width = 0; | ||
557 | } | ||
1286 | 558 | ||
1287 | ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates, | 559 | iwl_conf->tx_mimo_ps_mode = |
1288 | active_rate_basic, &left); | 560 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); |
1289 | active_rates &= ~ret_rates; | 561 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); |
1290 | 562 | ||
1291 | len += 2 + *pos; | 563 | iwl_conf->control_channel = ht_bss_conf->primary_channel; |
1292 | pos += (*pos) + 1; | 564 | iwl_conf->tx_chan_width = |
1293 | if (active_rates == 0) | 565 | !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); |
1294 | goto fill_end; | 566 | iwl_conf->ht_protection = |
567 | ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION; | ||
568 | iwl_conf->non_GF_STA_present = | ||
569 | !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT); | ||
1295 | 570 | ||
1296 | /* fill in supported extended rate */ | 571 | IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); |
1297 | /* ...next IE... */ | 572 | IWL_DEBUG_MAC80211("leave\n"); |
1298 | left -= 2; | ||
1299 | if (left < 0) | ||
1300 | return 0; | ||
1301 | /* ... fill it in... */ | ||
1302 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
1303 | *pos = 0; | ||
1304 | iwl4965_supported_rate_to_ie(pos, active_rates, | ||
1305 | active_rate_basic, &left); | ||
1306 | if (*pos > 0) | ||
1307 | len += 2 + *pos; | ||
1308 | |||
1309 | #ifdef CONFIG_IWL4965_HT | ||
1310 | if (sband && sband->ht_info.ht_supported) { | ||
1311 | struct ieee80211_ht_cap *ht_cap; | ||
1312 | pos += (*pos) + 1; | ||
1313 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
1314 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
1315 | ht_cap = (struct ieee80211_ht_cap *)pos; | ||
1316 | ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); | ||
1317 | memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); | ||
1318 | ht_cap->ampdu_params_info =(sband->ht_info.ampdu_factor & | ||
1319 | IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
1320 | ((sband->ht_info.ampdu_density << 2) & | ||
1321 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
1322 | len += 2 + sizeof(struct ieee80211_ht_cap); | ||
1323 | } | ||
1324 | #endif /*CONFIG_IWL4965_HT */ | ||
1325 | |||
1326 | fill_end: | ||
1327 | return (u16)len; | ||
1328 | } | 573 | } |
1329 | 574 | ||
1330 | /* | 575 | /* |
1331 | * QoS support | 576 | * QoS support |
1332 | */ | 577 | */ |
1333 | static int iwl4965_send_qos_params_command(struct iwl_priv *priv, | 578 | static void iwl_activate_qos(struct iwl_priv *priv, u8 force) |
1334 | struct iwl4965_qosparam_cmd *qos) | ||
1335 | { | ||
1336 | |||
1337 | return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM, | ||
1338 | sizeof(struct iwl4965_qosparam_cmd), qos); | ||
1339 | } | ||
1340 | |||
1341 | static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force) | ||
1342 | { | 579 | { |
1343 | unsigned long flags; | ||
1344 | |||
1345 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 580 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1346 | return; | 581 | return; |
1347 | 582 | ||
1348 | if (!priv->qos_data.qos_enable) | 583 | if (!priv->qos_data.qos_enable) |
1349 | return; | 584 | return; |
1350 | 585 | ||
1351 | spin_lock_irqsave(&priv->lock, flags); | ||
1352 | priv->qos_data.def_qos_parm.qos_flags = 0; | 586 | priv->qos_data.def_qos_parm.qos_flags = 0; |
1353 | 587 | ||
1354 | if (priv->qos_data.qos_cap.q_AP.queue_request && | 588 | if (priv->qos_data.qos_cap.q_AP.queue_request && |
@@ -1359,323 +593,18 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force) | |||
1359 | priv->qos_data.def_qos_parm.qos_flags |= | 593 | priv->qos_data.def_qos_parm.qos_flags |= |
1360 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; | 594 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; |
1361 | 595 | ||
1362 | #ifdef CONFIG_IWL4965_HT | ||
1363 | if (priv->current_ht_config.is_ht) | 596 | if (priv->current_ht_config.is_ht) |
1364 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; | 597 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; |
1365 | #endif /* CONFIG_IWL4965_HT */ | ||
1366 | |||
1367 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1368 | 598 | ||
1369 | if (force || iwl_is_associated(priv)) { | 599 | if (force || iwl_is_associated(priv)) { |
1370 | IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", | 600 | IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", |
1371 | priv->qos_data.qos_active, | 601 | priv->qos_data.qos_active, |
1372 | priv->qos_data.def_qos_parm.qos_flags); | 602 | priv->qos_data.def_qos_parm.qos_flags); |
1373 | 603 | ||
1374 | iwl4965_send_qos_params_command(priv, | 604 | iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, |
1375 | &(priv->qos_data.def_qos_parm)); | 605 | sizeof(struct iwl_qosparam_cmd), |
1376 | } | 606 | &priv->qos_data.def_qos_parm, NULL); |
1377 | } | ||
1378 | |||
1379 | /* | ||
1380 | * Power management (not Tx power!) functions | ||
1381 | */ | ||
1382 | #define MSEC_TO_USEC 1024 | ||
1383 | |||
1384 | #define NOSLP __constant_cpu_to_le16(0), 0, 0 | ||
1385 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 | ||
1386 | #define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC) | ||
1387 | #define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \ | ||
1388 | __constant_cpu_to_le32(X1), \ | ||
1389 | __constant_cpu_to_le32(X2), \ | ||
1390 | __constant_cpu_to_le32(X3), \ | ||
1391 | __constant_cpu_to_le32(X4)} | ||
1392 | |||
1393 | |||
1394 | /* default power management (not Tx power) table values */ | ||
1395 | /* for tim 0-10 */ | ||
1396 | static struct iwl4965_power_vec_entry range_0[IWL_POWER_AC] = { | ||
1397 | {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | ||
1398 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, | ||
1399 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0}, | ||
1400 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0}, | ||
1401 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1}, | ||
1402 | {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1} | ||
1403 | }; | ||
1404 | |||
1405 | /* for tim > 10 */ | ||
1406 | static struct iwl4965_power_vec_entry range_1[IWL_POWER_AC] = { | ||
1407 | {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | ||
1408 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), | ||
1409 | SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, | ||
1410 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), | ||
1411 | SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, | ||
1412 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), | ||
1413 | SLP_VEC(2, 6, 9, 9, 0xFF)}, 0}, | ||
1414 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, | ||
1415 | {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), | ||
1416 | SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} | ||
1417 | }; | ||
1418 | |||
1419 | int iwl4965_power_init_handle(struct iwl_priv *priv) | ||
1420 | { | ||
1421 | int rc = 0, i; | ||
1422 | struct iwl4965_power_mgr *pow_data; | ||
1423 | int size = sizeof(struct iwl4965_power_vec_entry) * IWL_POWER_AC; | ||
1424 | u16 pci_pm; | ||
1425 | |||
1426 | IWL_DEBUG_POWER("Initialize power \n"); | ||
1427 | |||
1428 | pow_data = &(priv->power_data); | ||
1429 | |||
1430 | memset(pow_data, 0, sizeof(*pow_data)); | ||
1431 | |||
1432 | pow_data->active_index = IWL_POWER_RANGE_0; | ||
1433 | pow_data->dtim_val = 0xffff; | ||
1434 | |||
1435 | memcpy(&pow_data->pwr_range_0[0], &range_0[0], size); | ||
1436 | memcpy(&pow_data->pwr_range_1[0], &range_1[0], size); | ||
1437 | |||
1438 | rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm); | ||
1439 | if (rc != 0) | ||
1440 | return 0; | ||
1441 | else { | ||
1442 | struct iwl4965_powertable_cmd *cmd; | ||
1443 | |||
1444 | IWL_DEBUG_POWER("adjust power command flags\n"); | ||
1445 | |||
1446 | for (i = 0; i < IWL_POWER_AC; i++) { | ||
1447 | cmd = &pow_data->pwr_range_0[i].cmd; | ||
1448 | |||
1449 | if (pci_pm & 0x1) | ||
1450 | cmd->flags &= ~IWL_POWER_PCI_PM_MSK; | ||
1451 | else | ||
1452 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | ||
1453 | } | ||
1454 | } | 607 | } |
1455 | return rc; | ||
1456 | } | ||
1457 | |||
1458 | static int iwl4965_update_power_cmd(struct iwl_priv *priv, | ||
1459 | struct iwl4965_powertable_cmd *cmd, u32 mode) | ||
1460 | { | ||
1461 | int rc = 0, i; | ||
1462 | u8 skip; | ||
1463 | u32 max_sleep = 0; | ||
1464 | struct iwl4965_power_vec_entry *range; | ||
1465 | u8 period = 0; | ||
1466 | struct iwl4965_power_mgr *pow_data; | ||
1467 | |||
1468 | if (mode > IWL_POWER_INDEX_5) { | ||
1469 | IWL_DEBUG_POWER("Error invalid power mode \n"); | ||
1470 | return -1; | ||
1471 | } | ||
1472 | pow_data = &(priv->power_data); | ||
1473 | |||
1474 | if (pow_data->active_index == IWL_POWER_RANGE_0) | ||
1475 | range = &pow_data->pwr_range_0[0]; | ||
1476 | else | ||
1477 | range = &pow_data->pwr_range_1[1]; | ||
1478 | |||
1479 | memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd)); | ||
1480 | |||
1481 | #ifdef IWL_MAC80211_DISABLE | ||
1482 | if (priv->assoc_network != NULL) { | ||
1483 | unsigned long flags; | ||
1484 | |||
1485 | period = priv->assoc_network->tim.tim_period; | ||
1486 | } | ||
1487 | #endif /*IWL_MAC80211_DISABLE */ | ||
1488 | skip = range[mode].no_dtim; | ||
1489 | |||
1490 | if (period == 0) { | ||
1491 | period = 1; | ||
1492 | skip = 0; | ||
1493 | } | ||
1494 | |||
1495 | if (skip == 0) { | ||
1496 | max_sleep = period; | ||
1497 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
1498 | } else { | ||
1499 | __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]; | ||
1500 | max_sleep = (le32_to_cpu(slp_itrvl) / period) * period; | ||
1501 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
1502 | } | ||
1503 | |||
1504 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) { | ||
1505 | if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) | ||
1506 | cmd->sleep_interval[i] = cpu_to_le32(max_sleep); | ||
1507 | } | ||
1508 | |||
1509 | IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags); | ||
1510 | IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); | ||
1511 | IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout)); | ||
1512 | IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n", | ||
1513 | le32_to_cpu(cmd->sleep_interval[0]), | ||
1514 | le32_to_cpu(cmd->sleep_interval[1]), | ||
1515 | le32_to_cpu(cmd->sleep_interval[2]), | ||
1516 | le32_to_cpu(cmd->sleep_interval[3]), | ||
1517 | le32_to_cpu(cmd->sleep_interval[4])); | ||
1518 | |||
1519 | return rc; | ||
1520 | } | ||
1521 | |||
1522 | static int iwl4965_send_power_mode(struct iwl_priv *priv, u32 mode) | ||
1523 | { | ||
1524 | u32 uninitialized_var(final_mode); | ||
1525 | int rc; | ||
1526 | struct iwl4965_powertable_cmd cmd; | ||
1527 | |||
1528 | /* If on battery, set to 3, | ||
1529 | * if plugged into AC power, set to CAM ("continuously aware mode"), | ||
1530 | * else user level */ | ||
1531 | switch (mode) { | ||
1532 | case IWL_POWER_BATTERY: | ||
1533 | final_mode = IWL_POWER_INDEX_3; | ||
1534 | break; | ||
1535 | case IWL_POWER_AC: | ||
1536 | final_mode = IWL_POWER_MODE_CAM; | ||
1537 | break; | ||
1538 | default: | ||
1539 | final_mode = mode; | ||
1540 | break; | ||
1541 | } | ||
1542 | |||
1543 | cmd.keep_alive_beacons = 0; | ||
1544 | |||
1545 | iwl4965_update_power_cmd(priv, &cmd, final_mode); | ||
1546 | |||
1547 | rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd); | ||
1548 | |||
1549 | if (final_mode == IWL_POWER_MODE_CAM) | ||
1550 | clear_bit(STATUS_POWER_PMI, &priv->status); | ||
1551 | else | ||
1552 | set_bit(STATUS_POWER_PMI, &priv->status); | ||
1553 | |||
1554 | return rc; | ||
1555 | } | ||
1556 | |||
1557 | int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) | ||
1558 | { | ||
1559 | /* Filter incoming packets to determine if they are targeted toward | ||
1560 | * this network, discarding packets coming from ourselves */ | ||
1561 | switch (priv->iw_mode) { | ||
1562 | case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */ | ||
1563 | /* packets from our adapter are dropped (echo) */ | ||
1564 | if (!compare_ether_addr(header->addr2, priv->mac_addr)) | ||
1565 | return 0; | ||
1566 | /* {broad,multi}cast packets to our IBSS go through */ | ||
1567 | if (is_multicast_ether_addr(header->addr1)) | ||
1568 | return !compare_ether_addr(header->addr3, priv->bssid); | ||
1569 | /* packets to our adapter go through */ | ||
1570 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
1571 | case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */ | ||
1572 | /* packets from our adapter are dropped (echo) */ | ||
1573 | if (!compare_ether_addr(header->addr3, priv->mac_addr)) | ||
1574 | return 0; | ||
1575 | /* {broad,multi}cast packets to our BSS go through */ | ||
1576 | if (is_multicast_ether_addr(header->addr1)) | ||
1577 | return !compare_ether_addr(header->addr2, priv->bssid); | ||
1578 | /* packets to our adapter go through */ | ||
1579 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
1580 | default: | ||
1581 | break; | ||
1582 | } | ||
1583 | |||
1584 | return 1; | ||
1585 | } | ||
1586 | |||
1587 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | ||
1588 | |||
1589 | static const char *iwl4965_get_tx_fail_reason(u32 status) | ||
1590 | { | ||
1591 | switch (status & TX_STATUS_MSK) { | ||
1592 | case TX_STATUS_SUCCESS: | ||
1593 | return "SUCCESS"; | ||
1594 | TX_STATUS_ENTRY(SHORT_LIMIT); | ||
1595 | TX_STATUS_ENTRY(LONG_LIMIT); | ||
1596 | TX_STATUS_ENTRY(FIFO_UNDERRUN); | ||
1597 | TX_STATUS_ENTRY(MGMNT_ABORT); | ||
1598 | TX_STATUS_ENTRY(NEXT_FRAG); | ||
1599 | TX_STATUS_ENTRY(LIFE_EXPIRE); | ||
1600 | TX_STATUS_ENTRY(DEST_PS); | ||
1601 | TX_STATUS_ENTRY(ABORTED); | ||
1602 | TX_STATUS_ENTRY(BT_RETRY); | ||
1603 | TX_STATUS_ENTRY(STA_INVALID); | ||
1604 | TX_STATUS_ENTRY(FRAG_DROPPED); | ||
1605 | TX_STATUS_ENTRY(TID_DISABLE); | ||
1606 | TX_STATUS_ENTRY(FRAME_FLUSHED); | ||
1607 | TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); | ||
1608 | TX_STATUS_ENTRY(TX_LOCKED); | ||
1609 | TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); | ||
1610 | } | ||
1611 | |||
1612 | return "UNKNOWN"; | ||
1613 | } | ||
1614 | |||
1615 | /** | ||
1616 | * iwl4965_scan_cancel - Cancel any currently executing HW scan | ||
1617 | * | ||
1618 | * NOTE: priv->mutex is not required before calling this function | ||
1619 | */ | ||
1620 | static int iwl4965_scan_cancel(struct iwl_priv *priv) | ||
1621 | { | ||
1622 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
1623 | clear_bit(STATUS_SCANNING, &priv->status); | ||
1624 | return 0; | ||
1625 | } | ||
1626 | |||
1627 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
1628 | if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
1629 | IWL_DEBUG_SCAN("Queuing scan abort.\n"); | ||
1630 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
1631 | queue_work(priv->workqueue, &priv->abort_scan); | ||
1632 | |||
1633 | } else | ||
1634 | IWL_DEBUG_SCAN("Scan abort already in progress.\n"); | ||
1635 | |||
1636 | return test_bit(STATUS_SCANNING, &priv->status); | ||
1637 | } | ||
1638 | |||
1639 | return 0; | ||
1640 | } | ||
1641 | |||
1642 | /** | ||
1643 | * iwl4965_scan_cancel_timeout - Cancel any currently executing HW scan | ||
1644 | * @ms: amount of time to wait (in milliseconds) for scan to abort | ||
1645 | * | ||
1646 | * NOTE: priv->mutex must be held before calling this function | ||
1647 | */ | ||
1648 | static int iwl4965_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | ||
1649 | { | ||
1650 | unsigned long now = jiffies; | ||
1651 | int ret; | ||
1652 | |||
1653 | ret = iwl4965_scan_cancel(priv); | ||
1654 | if (ret && ms) { | ||
1655 | mutex_unlock(&priv->mutex); | ||
1656 | while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && | ||
1657 | test_bit(STATUS_SCANNING, &priv->status)) | ||
1658 | msleep(1); | ||
1659 | mutex_lock(&priv->mutex); | ||
1660 | |||
1661 | return test_bit(STATUS_SCANNING, &priv->status); | ||
1662 | } | ||
1663 | |||
1664 | return ret; | ||
1665 | } | ||
1666 | |||
1667 | static void iwl4965_sequence_reset(struct iwl_priv *priv) | ||
1668 | { | ||
1669 | /* Reset ieee stats */ | ||
1670 | |||
1671 | /* We don't reset the net_device_stats (ieee->stats) on | ||
1672 | * re-association */ | ||
1673 | |||
1674 | priv->last_seq_num = -1; | ||
1675 | priv->last_frag_num = -1; | ||
1676 | priv->last_packet_time = 0; | ||
1677 | |||
1678 | iwl4965_scan_cancel(priv); | ||
1679 | } | 608 | } |
1680 | 609 | ||
1681 | #define MAX_UCODE_BEACON_INTERVAL 4096 | 610 | #define MAX_UCODE_BEACON_INTERVAL 4096 |
@@ -1750,46 +679,8 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv) | |||
1750 | le16_to_cpu(priv->rxon_timing.atim_window)); | 679 | le16_to_cpu(priv->rxon_timing.atim_window)); |
1751 | } | 680 | } |
1752 | 681 | ||
1753 | static int iwl4965_scan_initiate(struct iwl_priv *priv) | 682 | static void iwl_set_flags_for_band(struct iwl_priv *priv, |
1754 | { | 683 | enum ieee80211_band band) |
1755 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | ||
1756 | IWL_ERROR("APs don't scan.\n"); | ||
1757 | return 0; | ||
1758 | } | ||
1759 | |||
1760 | if (!iwl_is_ready_rf(priv)) { | ||
1761 | IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); | ||
1762 | return -EIO; | ||
1763 | } | ||
1764 | |||
1765 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
1766 | IWL_DEBUG_SCAN("Scan already in progress.\n"); | ||
1767 | return -EAGAIN; | ||
1768 | } | ||
1769 | |||
1770 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
1771 | IWL_DEBUG_SCAN("Scan request while abort pending. " | ||
1772 | "Queuing.\n"); | ||
1773 | return -EAGAIN; | ||
1774 | } | ||
1775 | |||
1776 | IWL_DEBUG_INFO("Starting scan...\n"); | ||
1777 | if (priv->cfg->sku & IWL_SKU_G) | ||
1778 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
1779 | if (priv->cfg->sku & IWL_SKU_A) | ||
1780 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
1781 | set_bit(STATUS_SCANNING, &priv->status); | ||
1782 | priv->scan_start = jiffies; | ||
1783 | priv->scan_pass_start = priv->scan_start; | ||
1784 | |||
1785 | queue_work(priv->workqueue, &priv->request_scan); | ||
1786 | |||
1787 | return 0; | ||
1788 | } | ||
1789 | |||
1790 | |||
1791 | static void iwl4965_set_flags_for_phymode(struct iwl_priv *priv, | ||
1792 | enum ieee80211_band band) | ||
1793 | { | 684 | { |
1794 | if (band == IEEE80211_BAND_5GHZ) { | 685 | if (band == IEEE80211_BAND_5GHZ) { |
1795 | priv->staging_rxon.flags &= | 686 | priv->staging_rxon.flags &= |
@@ -1858,7 +749,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
1858 | #endif | 749 | #endif |
1859 | 750 | ||
1860 | ch_info = iwl_get_channel_info(priv, priv->band, | 751 | ch_info = iwl_get_channel_info(priv, priv->band, |
1861 | le16_to_cpu(priv->staging_rxon.channel)); | 752 | le16_to_cpu(priv->active_rxon.channel)); |
1862 | 753 | ||
1863 | if (!ch_info) | 754 | if (!ch_info) |
1864 | ch_info = &priv->channel_info[0]; | 755 | ch_info = &priv->channel_info[0]; |
@@ -1874,7 +765,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
1874 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 765 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
1875 | priv->band = ch_info->band; | 766 | priv->band = ch_info->band; |
1876 | 767 | ||
1877 | iwl4965_set_flags_for_phymode(priv, priv->band); | 768 | iwl_set_flags_for_band(priv, priv->band); |
1878 | 769 | ||
1879 | priv->staging_rxon.ofdm_basic_rates = | 770 | priv->staging_rxon.ofdm_basic_rates = |
1880 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 771 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -1887,38 +778,24 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
1887 | memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); | 778 | memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); |
1888 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; | 779 | priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; |
1889 | priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; | 780 | priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; |
1890 | iwl4965_set_rxon_chain(priv); | 781 | iwl_set_rxon_chain(priv); |
1891 | } | 782 | } |
1892 | 783 | ||
1893 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) | 784 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) |
1894 | { | 785 | { |
1895 | if (mode == IEEE80211_IF_TYPE_IBSS) { | ||
1896 | const struct iwl_channel_info *ch_info; | ||
1897 | |||
1898 | ch_info = iwl_get_channel_info(priv, | ||
1899 | priv->band, | ||
1900 | le16_to_cpu(priv->staging_rxon.channel)); | ||
1901 | |||
1902 | if (!ch_info || !is_channel_ibss(ch_info)) { | ||
1903 | IWL_ERROR("channel %d not IBSS channel\n", | ||
1904 | le16_to_cpu(priv->staging_rxon.channel)); | ||
1905 | return -EINVAL; | ||
1906 | } | ||
1907 | } | ||
1908 | |||
1909 | priv->iw_mode = mode; | 786 | priv->iw_mode = mode; |
1910 | 787 | ||
1911 | iwl4965_connection_init_rx_config(priv); | 788 | iwl4965_connection_init_rx_config(priv); |
1912 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 789 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
1913 | 790 | ||
1914 | iwlcore_clear_stations_table(priv); | 791 | iwl_clear_stations_table(priv); |
1915 | 792 | ||
1916 | /* dont commit rxon if rf-kill is on*/ | 793 | /* dont commit rxon if rf-kill is on*/ |
1917 | if (!iwl_is_ready_rf(priv)) | 794 | if (!iwl_is_ready_rf(priv)) |
1918 | return -EAGAIN; | 795 | return -EAGAIN; |
1919 | 796 | ||
1920 | cancel_delayed_work(&priv->scan_check); | 797 | cancel_delayed_work(&priv->scan_check); |
1921 | if (iwl4965_scan_cancel_timeout(priv, 100)) { | 798 | if (iwl_scan_cancel_timeout(priv, 100)) { |
1922 | IWL_WARNING("Aborted scan still in progress after 100ms\n"); | 799 | IWL_WARNING("Aborted scan still in progress after 100ms\n"); |
1923 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 800 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
1924 | return -EAGAIN; | 801 | return -EAGAIN; |
@@ -1929,448 +806,13 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode) | |||
1929 | return 0; | 806 | return 0; |
1930 | } | 807 | } |
1931 | 808 | ||
1932 | static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | ||
1933 | struct ieee80211_tx_control *ctl, | ||
1934 | struct iwl_cmd *cmd, | ||
1935 | struct sk_buff *skb_frag, | ||
1936 | int sta_id) | ||
1937 | { | ||
1938 | struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; | ||
1939 | struct iwl_wep_key *wepkey; | ||
1940 | int keyidx = 0; | ||
1941 | |||
1942 | BUG_ON(ctl->key_idx > 3); | ||
1943 | |||
1944 | switch (keyinfo->alg) { | ||
1945 | case ALG_CCMP: | ||
1946 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM; | ||
1947 | memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen); | ||
1948 | if (ctl->flags & IEEE80211_TXCTL_AMPDU) | ||
1949 | cmd->cmd.tx.tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; | ||
1950 | IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n"); | ||
1951 | break; | ||
1952 | |||
1953 | case ALG_TKIP: | ||
1954 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP; | ||
1955 | ieee80211_get_tkip_key(keyinfo->conf, skb_frag, | ||
1956 | IEEE80211_TKIP_P2_KEY, cmd->cmd.tx.key); | ||
1957 | IWL_DEBUG_TX("tx_cmd with tkip hwcrypto\n"); | ||
1958 | break; | ||
1959 | |||
1960 | case ALG_WEP: | ||
1961 | wepkey = &priv->wep_keys[ctl->key_idx]; | ||
1962 | cmd->cmd.tx.sec_ctl = 0; | ||
1963 | if (priv->default_wep_key) { | ||
1964 | /* the WEP key was sent as static */ | ||
1965 | keyidx = ctl->key_idx; | ||
1966 | memcpy(&cmd->cmd.tx.key[3], wepkey->key, | ||
1967 | wepkey->key_size); | ||
1968 | if (wepkey->key_size == WEP_KEY_LEN_128) | ||
1969 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; | ||
1970 | } else { | ||
1971 | /* the WEP key was sent as dynamic */ | ||
1972 | keyidx = keyinfo->keyidx; | ||
1973 | memcpy(&cmd->cmd.tx.key[3], keyinfo->key, | ||
1974 | keyinfo->keylen); | ||
1975 | if (keyinfo->keylen == WEP_KEY_LEN_128) | ||
1976 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; | ||
1977 | } | ||
1978 | |||
1979 | cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP | | ||
1980 | (keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT); | ||
1981 | |||
1982 | IWL_DEBUG_TX("Configuring packet for WEP encryption " | ||
1983 | "with key %d\n", keyidx); | ||
1984 | break; | ||
1985 | |||
1986 | default: | ||
1987 | printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg); | ||
1988 | break; | ||
1989 | } | ||
1990 | } | ||
1991 | |||
1992 | /* | ||
1993 | * handle build REPLY_TX command notification. | ||
1994 | */ | ||
1995 | static void iwl4965_build_tx_cmd_basic(struct iwl_priv *priv, | ||
1996 | struct iwl_cmd *cmd, | ||
1997 | struct ieee80211_tx_control *ctrl, | ||
1998 | struct ieee80211_hdr *hdr, | ||
1999 | int is_unicast, u8 std_id) | ||
2000 | { | ||
2001 | __le16 *qc; | ||
2002 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
2003 | __le32 tx_flags = cmd->cmd.tx.tx_flags; | ||
2004 | |||
2005 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
2006 | if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) { | ||
2007 | tx_flags |= TX_CMD_FLG_ACK_MSK; | ||
2008 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) | ||
2009 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | ||
2010 | if (ieee80211_is_probe_response(fc) && | ||
2011 | !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) | ||
2012 | tx_flags |= TX_CMD_FLG_TSF_MSK; | ||
2013 | } else { | ||
2014 | tx_flags &= (~TX_CMD_FLG_ACK_MSK); | ||
2015 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | ||
2016 | } | ||
2017 | |||
2018 | if (ieee80211_is_back_request(fc)) | ||
2019 | tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; | ||
2020 | |||
2021 | |||
2022 | cmd->cmd.tx.sta_id = std_id; | ||
2023 | if (ieee80211_get_morefrag(hdr)) | ||
2024 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; | ||
2025 | |||
2026 | qc = ieee80211_get_qos_ctrl(hdr); | ||
2027 | if (qc) { | ||
2028 | cmd->cmd.tx.tid_tspec = (u8) (le16_to_cpu(*qc) & 0xf); | ||
2029 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; | ||
2030 | } else | ||
2031 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | ||
2032 | |||
2033 | if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) { | ||
2034 | tx_flags |= TX_CMD_FLG_RTS_MSK; | ||
2035 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; | ||
2036 | } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { | ||
2037 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | ||
2038 | tx_flags |= TX_CMD_FLG_CTS_MSK; | ||
2039 | } | ||
2040 | |||
2041 | if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK)) | ||
2042 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; | ||
2043 | |||
2044 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); | ||
2045 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | ||
2046 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || | ||
2047 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) | ||
2048 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); | ||
2049 | else | ||
2050 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); | ||
2051 | } else { | ||
2052 | cmd->cmd.tx.timeout.pm_frame_timeout = 0; | ||
2053 | } | ||
2054 | |||
2055 | cmd->cmd.tx.driver_txop = 0; | ||
2056 | cmd->cmd.tx.tx_flags = tx_flags; | ||
2057 | cmd->cmd.tx.next_frame_len = 0; | ||
2058 | } | ||
2059 | static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len) | ||
2060 | { | ||
2061 | /* 0 - mgmt, 1 - cnt, 2 - data */ | ||
2062 | int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2; | ||
2063 | priv->tx_stats[idx].cnt++; | ||
2064 | priv->tx_stats[idx].bytes += len; | ||
2065 | } | ||
2066 | /** | ||
2067 | * iwl4965_get_sta_id - Find station's index within station table | ||
2068 | * | ||
2069 | * If new IBSS station, create new entry in station table | ||
2070 | */ | ||
2071 | static int iwl4965_get_sta_id(struct iwl_priv *priv, | ||
2072 | struct ieee80211_hdr *hdr) | ||
2073 | { | ||
2074 | int sta_id; | ||
2075 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
2076 | DECLARE_MAC_BUF(mac); | ||
2077 | |||
2078 | /* If this frame is broadcast or management, use broadcast station id */ | ||
2079 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | ||
2080 | is_multicast_ether_addr(hdr->addr1)) | ||
2081 | return priv->hw_params.bcast_sta_id; | ||
2082 | |||
2083 | switch (priv->iw_mode) { | ||
2084 | |||
2085 | /* If we are a client station in a BSS network, use the special | ||
2086 | * AP station entry (that's the only station we communicate with) */ | ||
2087 | case IEEE80211_IF_TYPE_STA: | ||
2088 | return IWL_AP_ID; | ||
2089 | |||
2090 | /* If we are an AP, then find the station, or use BCAST */ | ||
2091 | case IEEE80211_IF_TYPE_AP: | ||
2092 | sta_id = iwl4965_hw_find_station(priv, hdr->addr1); | ||
2093 | if (sta_id != IWL_INVALID_STATION) | ||
2094 | return sta_id; | ||
2095 | return priv->hw_params.bcast_sta_id; | ||
2096 | |||
2097 | /* If this frame is going out to an IBSS network, find the station, | ||
2098 | * or create a new station table entry */ | ||
2099 | case IEEE80211_IF_TYPE_IBSS: | ||
2100 | sta_id = iwl4965_hw_find_station(priv, hdr->addr1); | ||
2101 | if (sta_id != IWL_INVALID_STATION) | ||
2102 | return sta_id; | ||
2103 | |||
2104 | /* Create new station table entry */ | ||
2105 | sta_id = iwl4965_add_station_flags(priv, hdr->addr1, | ||
2106 | 0, CMD_ASYNC, NULL); | ||
2107 | |||
2108 | if (sta_id != IWL_INVALID_STATION) | ||
2109 | return sta_id; | ||
2110 | |||
2111 | IWL_DEBUG_DROP("Station %s not in station map. " | ||
2112 | "Defaulting to broadcast...\n", | ||
2113 | print_mac(mac, hdr->addr1)); | ||
2114 | iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | ||
2115 | return priv->hw_params.bcast_sta_id; | ||
2116 | |||
2117 | default: | ||
2118 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); | ||
2119 | return priv->hw_params.bcast_sta_id; | ||
2120 | } | ||
2121 | } | ||
2122 | |||
2123 | /* | ||
2124 | * start REPLY_TX command process | ||
2125 | */ | ||
2126 | static int iwl4965_tx_skb(struct iwl_priv *priv, | ||
2127 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) | ||
2128 | { | ||
2129 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
2130 | struct iwl4965_tfd_frame *tfd; | ||
2131 | u32 *control_flags; | ||
2132 | int txq_id = ctl->queue; | ||
2133 | struct iwl4965_tx_queue *txq = NULL; | ||
2134 | struct iwl4965_queue *q = NULL; | ||
2135 | dma_addr_t phys_addr; | ||
2136 | dma_addr_t txcmd_phys; | ||
2137 | dma_addr_t scratch_phys; | ||
2138 | struct iwl_cmd *out_cmd = NULL; | ||
2139 | u16 len, idx, len_org; | ||
2140 | u8 id, hdr_len, unicast; | ||
2141 | u8 sta_id; | ||
2142 | u16 seq_number = 0; | ||
2143 | u16 fc; | ||
2144 | __le16 *qc; | ||
2145 | u8 wait_write_ptr = 0; | ||
2146 | unsigned long flags; | ||
2147 | int rc; | ||
2148 | |||
2149 | spin_lock_irqsave(&priv->lock, flags); | ||
2150 | if (iwl_is_rfkill(priv)) { | ||
2151 | IWL_DEBUG_DROP("Dropping - RF KILL\n"); | ||
2152 | goto drop_unlock; | ||
2153 | } | ||
2154 | |||
2155 | if (!priv->vif) { | ||
2156 | IWL_DEBUG_DROP("Dropping - !priv->vif\n"); | ||
2157 | goto drop_unlock; | ||
2158 | } | ||
2159 | |||
2160 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { | ||
2161 | IWL_ERROR("ERROR: No TX rate available.\n"); | ||
2162 | goto drop_unlock; | ||
2163 | } | ||
2164 | |||
2165 | unicast = !is_multicast_ether_addr(hdr->addr1); | ||
2166 | id = 0; | ||
2167 | |||
2168 | fc = le16_to_cpu(hdr->frame_control); | ||
2169 | |||
2170 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
2171 | if (ieee80211_is_auth(fc)) | ||
2172 | IWL_DEBUG_TX("Sending AUTH frame\n"); | ||
2173 | else if (ieee80211_is_assoc_request(fc)) | ||
2174 | IWL_DEBUG_TX("Sending ASSOC frame\n"); | ||
2175 | else if (ieee80211_is_reassoc_request(fc)) | ||
2176 | IWL_DEBUG_TX("Sending REASSOC frame\n"); | ||
2177 | #endif | ||
2178 | |||
2179 | /* drop all data frame if we are not associated */ | ||
2180 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | ||
2181 | (!iwl_is_associated(priv) || | ||
2182 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || | ||
2183 | !priv->assoc_station_added)) { | ||
2184 | IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n"); | ||
2185 | goto drop_unlock; | ||
2186 | } | ||
2187 | |||
2188 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2189 | |||
2190 | hdr_len = ieee80211_get_hdrlen(fc); | ||
2191 | |||
2192 | /* Find (or create) index into station table for destination station */ | ||
2193 | sta_id = iwl4965_get_sta_id(priv, hdr); | ||
2194 | if (sta_id == IWL_INVALID_STATION) { | ||
2195 | DECLARE_MAC_BUF(mac); | ||
2196 | |||
2197 | IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n", | ||
2198 | print_mac(mac, hdr->addr1)); | ||
2199 | goto drop; | ||
2200 | } | ||
2201 | |||
2202 | IWL_DEBUG_RATE("station Id %d\n", sta_id); | ||
2203 | |||
2204 | qc = ieee80211_get_qos_ctrl(hdr); | ||
2205 | if (qc) { | ||
2206 | u8 tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
2207 | seq_number = priv->stations[sta_id].tid[tid].seq_number & | ||
2208 | IEEE80211_SCTL_SEQ; | ||
2209 | hdr->seq_ctrl = cpu_to_le16(seq_number) | | ||
2210 | (hdr->seq_ctrl & | ||
2211 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); | ||
2212 | seq_number += 0x10; | ||
2213 | #ifdef CONFIG_IWL4965_HT | ||
2214 | /* aggregation is on for this <sta,tid> */ | ||
2215 | if (ctl->flags & IEEE80211_TXCTL_AMPDU) | ||
2216 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; | ||
2217 | priv->stations[sta_id].tid[tid].tfds_in_queue++; | ||
2218 | #endif /* CONFIG_IWL4965_HT */ | ||
2219 | } | ||
2220 | |||
2221 | /* Descriptor for chosen Tx queue */ | ||
2222 | txq = &priv->txq[txq_id]; | ||
2223 | q = &txq->q; | ||
2224 | |||
2225 | spin_lock_irqsave(&priv->lock, flags); | ||
2226 | |||
2227 | /* Set up first empty TFD within this queue's circular TFD buffer */ | ||
2228 | tfd = &txq->bd[q->write_ptr]; | ||
2229 | memset(tfd, 0, sizeof(*tfd)); | ||
2230 | control_flags = (u32 *) tfd; | ||
2231 | idx = get_cmd_index(q, q->write_ptr, 0); | ||
2232 | |||
2233 | /* Set up driver data for this TFD */ | ||
2234 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl4965_tx_info)); | ||
2235 | txq->txb[q->write_ptr].skb[0] = skb; | ||
2236 | memcpy(&(txq->txb[q->write_ptr].status.control), | ||
2237 | ctl, sizeof(struct ieee80211_tx_control)); | ||
2238 | |||
2239 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ | ||
2240 | out_cmd = &txq->cmd[idx]; | ||
2241 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); | ||
2242 | memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); | ||
2243 | |||
2244 | /* | ||
2245 | * Set up the Tx-command (not MAC!) header. | ||
2246 | * Store the chosen Tx queue and TFD index within the sequence field; | ||
2247 | * after Tx, uCode's Tx response will return this value so driver can | ||
2248 | * locate the frame within the tx queue and do post-tx processing. | ||
2249 | */ | ||
2250 | out_cmd->hdr.cmd = REPLY_TX; | ||
2251 | out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | | ||
2252 | INDEX_TO_SEQ(q->write_ptr))); | ||
2253 | |||
2254 | /* Copy MAC header from skb into command buffer */ | ||
2255 | memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); | ||
2256 | |||
2257 | /* | ||
2258 | * Use the first empty entry in this queue's command buffer array | ||
2259 | * to contain the Tx command and MAC header concatenated together | ||
2260 | * (payload data will be in another buffer). | ||
2261 | * Size of this varies, due to varying MAC header length. | ||
2262 | * If end is not dword aligned, we'll have 2 extra bytes at the end | ||
2263 | * of the MAC header (device reads on dword boundaries). | ||
2264 | * We'll tell device about this padding later. | ||
2265 | */ | ||
2266 | len = priv->hw_params.tx_cmd_len + | ||
2267 | sizeof(struct iwl_cmd_header) + hdr_len; | ||
2268 | |||
2269 | len_org = len; | ||
2270 | len = (len + 3) & ~3; | ||
2271 | |||
2272 | if (len_org != len) | ||
2273 | len_org = 1; | ||
2274 | else | ||
2275 | len_org = 0; | ||
2276 | |||
2277 | /* Physical address of this Tx command's header (not MAC header!), | ||
2278 | * within command buffer array. */ | ||
2279 | txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx + | ||
2280 | offsetof(struct iwl_cmd, hdr); | ||
2281 | |||
2282 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
2283 | * first entry */ | ||
2284 | iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | ||
2285 | |||
2286 | if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | ||
2287 | iwl4965_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, sta_id); | ||
2288 | |||
2289 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | ||
2290 | * if any (802.11 null frames have no payload). */ | ||
2291 | len = skb->len - hdr_len; | ||
2292 | if (len) { | ||
2293 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, | ||
2294 | len, PCI_DMA_TODEVICE); | ||
2295 | iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); | ||
2296 | } | ||
2297 | |||
2298 | /* Tell 4965 about any 2-byte padding after MAC header */ | ||
2299 | if (len_org) | ||
2300 | out_cmd->cmd.tx.tx_flags |= TX_CMD_FLG_MH_PAD_MSK; | ||
2301 | |||
2302 | /* Total # bytes to be transmitted */ | ||
2303 | len = (u16)skb->len; | ||
2304 | out_cmd->cmd.tx.len = cpu_to_le16(len); | ||
2305 | |||
2306 | /* TODO need this for burst mode later on */ | ||
2307 | iwl4965_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id); | ||
2308 | |||
2309 | /* set is_hcca to 0; it probably will never be implemented */ | ||
2310 | iwl4965_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0); | ||
2311 | |||
2312 | iwl_update_tx_stats(priv, fc, len); | ||
2313 | |||
2314 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + | ||
2315 | offsetof(struct iwl4965_tx_cmd, scratch); | ||
2316 | out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys); | ||
2317 | out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); | ||
2318 | |||
2319 | if (!ieee80211_get_morefrag(hdr)) { | ||
2320 | txq->need_update = 1; | ||
2321 | if (qc) { | ||
2322 | u8 tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
2323 | priv->stations[sta_id].tid[tid].seq_number = seq_number; | ||
2324 | } | ||
2325 | } else { | ||
2326 | wait_write_ptr = 1; | ||
2327 | txq->need_update = 0; | ||
2328 | } | ||
2329 | |||
2330 | iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, | ||
2331 | sizeof(out_cmd->cmd.tx)); | ||
2332 | |||
2333 | iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, | ||
2334 | ieee80211_get_hdrlen(fc)); | ||
2335 | |||
2336 | /* Set up entry for this TFD in Tx byte-count array */ | ||
2337 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len); | ||
2338 | |||
2339 | /* Tell device the write index *just past* this latest filled TFD */ | ||
2340 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | ||
2341 | rc = iwl4965_tx_queue_update_write_ptr(priv, txq); | ||
2342 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2343 | |||
2344 | if (rc) | ||
2345 | return rc; | ||
2346 | |||
2347 | if ((iwl4965_queue_space(q) < q->high_mark) | ||
2348 | && priv->mac80211_registered) { | ||
2349 | if (wait_write_ptr) { | ||
2350 | spin_lock_irqsave(&priv->lock, flags); | ||
2351 | txq->need_update = 1; | ||
2352 | iwl4965_tx_queue_update_write_ptr(priv, txq); | ||
2353 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2354 | } | ||
2355 | |||
2356 | ieee80211_stop_queue(priv->hw, ctl->queue); | ||
2357 | } | ||
2358 | |||
2359 | return 0; | ||
2360 | |||
2361 | drop_unlock: | ||
2362 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2363 | drop: | ||
2364 | return -1; | ||
2365 | } | ||
2366 | |||
2367 | static void iwl4965_set_rate(struct iwl_priv *priv) | 809 | static void iwl4965_set_rate(struct iwl_priv *priv) |
2368 | { | 810 | { |
2369 | const struct ieee80211_supported_band *hw = NULL; | 811 | const struct ieee80211_supported_band *hw = NULL; |
2370 | struct ieee80211_rate *rate; | 812 | struct ieee80211_rate *rate; |
2371 | int i; | 813 | int i; |
2372 | 814 | ||
2373 | hw = iwl4965_get_hw_mode(priv, priv->band); | 815 | hw = iwl_get_hw_mode(priv, priv->band); |
2374 | if (!hw) { | 816 | if (!hw) { |
2375 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 817 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
2376 | return; | 818 | return; |
@@ -2411,169 +853,6 @@ static void iwl4965_set_rate(struct iwl_priv *priv) | |||
2411 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 853 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
2412 | } | 854 | } |
2413 | 855 | ||
2414 | void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio) | ||
2415 | { | ||
2416 | unsigned long flags; | ||
2417 | |||
2418 | if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
2419 | return; | ||
2420 | |||
2421 | IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n", | ||
2422 | disable_radio ? "OFF" : "ON"); | ||
2423 | |||
2424 | if (disable_radio) { | ||
2425 | iwl4965_scan_cancel(priv); | ||
2426 | /* FIXME: This is a workaround for AP */ | ||
2427 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { | ||
2428 | spin_lock_irqsave(&priv->lock, flags); | ||
2429 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
2430 | CSR_UCODE_SW_BIT_RFKILL); | ||
2431 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2432 | /* call the host command only if no hw rf-kill set */ | ||
2433 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && | ||
2434 | iwl_is_ready(priv)) | ||
2435 | iwl4965_send_card_state(priv, | ||
2436 | CARD_STATE_CMD_DISABLE, | ||
2437 | 0); | ||
2438 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2439 | |||
2440 | /* make sure mac80211 stop sending Tx frame */ | ||
2441 | if (priv->mac80211_registered) | ||
2442 | ieee80211_stop_queues(priv->hw); | ||
2443 | } | ||
2444 | return; | ||
2445 | } | ||
2446 | |||
2447 | spin_lock_irqsave(&priv->lock, flags); | ||
2448 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2449 | |||
2450 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2451 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2452 | |||
2453 | /* wake up ucode */ | ||
2454 | msleep(10); | ||
2455 | |||
2456 | spin_lock_irqsave(&priv->lock, flags); | ||
2457 | iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
2458 | if (!iwl_grab_nic_access(priv)) | ||
2459 | iwl_release_nic_access(priv); | ||
2460 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2461 | |||
2462 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | ||
2463 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " | ||
2464 | "disabled by HW switch\n"); | ||
2465 | return; | ||
2466 | } | ||
2467 | |||
2468 | queue_work(priv->workqueue, &priv->restart); | ||
2469 | return; | ||
2470 | } | ||
2471 | |||
2472 | void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, | ||
2473 | u32 decrypt_res, struct ieee80211_rx_status *stats) | ||
2474 | { | ||
2475 | u16 fc = | ||
2476 | le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control); | ||
2477 | |||
2478 | if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) | ||
2479 | return; | ||
2480 | |||
2481 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | ||
2482 | return; | ||
2483 | |||
2484 | IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res); | ||
2485 | switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) { | ||
2486 | case RX_RES_STATUS_SEC_TYPE_TKIP: | ||
2487 | /* The uCode has got a bad phase 1 Key, pushes the packet. | ||
2488 | * Decryption will be done in SW. */ | ||
2489 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
2490 | RX_RES_STATUS_BAD_KEY_TTAK) | ||
2491 | break; | ||
2492 | |||
2493 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
2494 | RX_RES_STATUS_BAD_ICV_MIC) | ||
2495 | stats->flag |= RX_FLAG_MMIC_ERROR; | ||
2496 | case RX_RES_STATUS_SEC_TYPE_WEP: | ||
2497 | case RX_RES_STATUS_SEC_TYPE_CCMP: | ||
2498 | if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == | ||
2499 | RX_RES_STATUS_DECRYPT_OK) { | ||
2500 | IWL_DEBUG_RX("hw decrypt successfully!!!\n"); | ||
2501 | stats->flag |= RX_FLAG_DECRYPTED; | ||
2502 | } | ||
2503 | break; | ||
2504 | |||
2505 | default: | ||
2506 | break; | ||
2507 | } | ||
2508 | } | ||
2509 | |||
2510 | |||
2511 | #define IWL_PACKET_RETRY_TIME HZ | ||
2512 | |||
2513 | int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) | ||
2514 | { | ||
2515 | u16 sc = le16_to_cpu(header->seq_ctrl); | ||
2516 | u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; | ||
2517 | u16 frag = sc & IEEE80211_SCTL_FRAG; | ||
2518 | u16 *last_seq, *last_frag; | ||
2519 | unsigned long *last_time; | ||
2520 | |||
2521 | switch (priv->iw_mode) { | ||
2522 | case IEEE80211_IF_TYPE_IBSS:{ | ||
2523 | struct list_head *p; | ||
2524 | struct iwl4965_ibss_seq *entry = NULL; | ||
2525 | u8 *mac = header->addr2; | ||
2526 | int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1); | ||
2527 | |||
2528 | __list_for_each(p, &priv->ibss_mac_hash[index]) { | ||
2529 | entry = list_entry(p, struct iwl4965_ibss_seq, list); | ||
2530 | if (!compare_ether_addr(entry->mac, mac)) | ||
2531 | break; | ||
2532 | } | ||
2533 | if (p == &priv->ibss_mac_hash[index]) { | ||
2534 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | ||
2535 | if (!entry) { | ||
2536 | IWL_ERROR("Cannot malloc new mac entry\n"); | ||
2537 | return 0; | ||
2538 | } | ||
2539 | memcpy(entry->mac, mac, ETH_ALEN); | ||
2540 | entry->seq_num = seq; | ||
2541 | entry->frag_num = frag; | ||
2542 | entry->packet_time = jiffies; | ||
2543 | list_add(&entry->list, &priv->ibss_mac_hash[index]); | ||
2544 | return 0; | ||
2545 | } | ||
2546 | last_seq = &entry->seq_num; | ||
2547 | last_frag = &entry->frag_num; | ||
2548 | last_time = &entry->packet_time; | ||
2549 | break; | ||
2550 | } | ||
2551 | case IEEE80211_IF_TYPE_STA: | ||
2552 | last_seq = &priv->last_seq_num; | ||
2553 | last_frag = &priv->last_frag_num; | ||
2554 | last_time = &priv->last_packet_time; | ||
2555 | break; | ||
2556 | default: | ||
2557 | return 0; | ||
2558 | } | ||
2559 | if ((*last_seq == seq) && | ||
2560 | time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) { | ||
2561 | if (*last_frag == frag) | ||
2562 | goto drop; | ||
2563 | if (*last_frag + 1 != frag) | ||
2564 | /* out-of-order fragment */ | ||
2565 | goto drop; | ||
2566 | } else | ||
2567 | *last_seq = seq; | ||
2568 | |||
2569 | *last_frag = frag; | ||
2570 | *last_time = jiffies; | ||
2571 | return 0; | ||
2572 | |||
2573 | drop: | ||
2574 | return 1; | ||
2575 | } | ||
2576 | |||
2577 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 856 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
2578 | 857 | ||
2579 | #include "iwl-spectrum.h" | 858 | #include "iwl-spectrum.h" |
@@ -2632,7 +911,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, | |||
2632 | u8 type) | 911 | u8 type) |
2633 | { | 912 | { |
2634 | struct iwl4965_spectrum_cmd spectrum; | 913 | struct iwl4965_spectrum_cmd spectrum; |
2635 | struct iwl4965_rx_packet *res; | 914 | struct iwl_rx_packet *res; |
2636 | struct iwl_host_cmd cmd = { | 915 | struct iwl_host_cmd cmd = { |
2637 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, | 916 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, |
2638 | .data = (void *)&spectrum, | 917 | .data = (void *)&spectrum, |
@@ -2677,7 +956,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, | |||
2677 | if (rc) | 956 | if (rc) |
2678 | return rc; | 957 | return rc; |
2679 | 958 | ||
2680 | res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; | 959 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
2681 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 960 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
2682 | IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); | 961 | IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); |
2683 | rc = -EIO; | 962 | rc = -EIO; |
@@ -2707,352 +986,16 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, | |||
2707 | } | 986 | } |
2708 | #endif | 987 | #endif |
2709 | 988 | ||
2710 | static void iwl4965_txstatus_to_ieee(struct iwl_priv *priv, | ||
2711 | struct iwl4965_tx_info *tx_sta) | ||
2712 | { | ||
2713 | |||
2714 | tx_sta->status.ack_signal = 0; | ||
2715 | tx_sta->status.excessive_retries = 0; | ||
2716 | tx_sta->status.queue_length = 0; | ||
2717 | tx_sta->status.queue_number = 0; | ||
2718 | |||
2719 | if (in_interrupt()) | ||
2720 | ieee80211_tx_status_irqsafe(priv->hw, | ||
2721 | tx_sta->skb[0], &(tx_sta->status)); | ||
2722 | else | ||
2723 | ieee80211_tx_status(priv->hw, | ||
2724 | tx_sta->skb[0], &(tx_sta->status)); | ||
2725 | |||
2726 | tx_sta->skb[0] = NULL; | ||
2727 | } | ||
2728 | |||
2729 | /** | ||
2730 | * iwl4965_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd | ||
2731 | * | ||
2732 | * When FW advances 'R' index, all entries between old and new 'R' index | ||
2733 | * need to be reclaimed. As result, some free space forms. If there is | ||
2734 | * enough free space (> low mark), wake the stack that feeds us. | ||
2735 | */ | ||
2736 | int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | ||
2737 | { | ||
2738 | struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; | ||
2739 | struct iwl4965_queue *q = &txq->q; | ||
2740 | int nfreed = 0; | ||
2741 | |||
2742 | if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) { | ||
2743 | IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " | ||
2744 | "is out of range [0-%d] %d %d.\n", txq_id, | ||
2745 | index, q->n_bd, q->write_ptr, q->read_ptr); | ||
2746 | return 0; | ||
2747 | } | ||
2748 | |||
2749 | for (index = iwl_queue_inc_wrap(index, q->n_bd); | ||
2750 | q->read_ptr != index; | ||
2751 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
2752 | if (txq_id != IWL_CMD_QUEUE_NUM) { | ||
2753 | iwl4965_txstatus_to_ieee(priv, | ||
2754 | &(txq->txb[txq->q.read_ptr])); | ||
2755 | iwl4965_hw_txq_free_tfd(priv, txq); | ||
2756 | } else if (nfreed > 1) { | ||
2757 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | ||
2758 | q->write_ptr, q->read_ptr); | ||
2759 | queue_work(priv->workqueue, &priv->restart); | ||
2760 | } | ||
2761 | nfreed++; | ||
2762 | } | ||
2763 | |||
2764 | /* if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && | ||
2765 | (txq_id != IWL_CMD_QUEUE_NUM) && | ||
2766 | priv->mac80211_registered) | ||
2767 | ieee80211_wake_queue(priv->hw, txq_id); */ | ||
2768 | |||
2769 | |||
2770 | return nfreed; | ||
2771 | } | ||
2772 | |||
2773 | static int iwl4965_is_tx_success(u32 status) | ||
2774 | { | ||
2775 | status &= TX_STATUS_MSK; | ||
2776 | return (status == TX_STATUS_SUCCESS) | ||
2777 | || (status == TX_STATUS_DIRECT_DONE); | ||
2778 | } | ||
2779 | |||
2780 | /****************************************************************************** | 989 | /****************************************************************************** |
2781 | * | 990 | * |
2782 | * Generic RX handler implementations | 991 | * Generic RX handler implementations |
2783 | * | 992 | * |
2784 | ******************************************************************************/ | 993 | ******************************************************************************/ |
2785 | #ifdef CONFIG_IWL4965_HT | 994 | static void iwl_rx_reply_alive(struct iwl_priv *priv, |
2786 | 995 | struct iwl_rx_mem_buffer *rxb) | |
2787 | static inline int iwl4965_get_ra_sta_id(struct iwl_priv *priv, | ||
2788 | struct ieee80211_hdr *hdr) | ||
2789 | { | 996 | { |
2790 | if (priv->iw_mode == IEEE80211_IF_TYPE_STA) | 997 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
2791 | return IWL_AP_ID; | 998 | struct iwl_alive_resp *palive; |
2792 | else { | ||
2793 | u8 *da = ieee80211_get_DA(hdr); | ||
2794 | return iwl4965_hw_find_station(priv, da); | ||
2795 | } | ||
2796 | } | ||
2797 | |||
2798 | static struct ieee80211_hdr *iwl4965_tx_queue_get_hdr( | ||
2799 | struct iwl_priv *priv, int txq_id, int idx) | ||
2800 | { | ||
2801 | if (priv->txq[txq_id].txb[idx].skb[0]) | ||
2802 | return (struct ieee80211_hdr *)priv->txq[txq_id]. | ||
2803 | txb[idx].skb[0]->data; | ||
2804 | return NULL; | ||
2805 | } | ||
2806 | |||
2807 | static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) | ||
2808 | { | ||
2809 | __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + | ||
2810 | tx_resp->frame_count); | ||
2811 | return le32_to_cpu(*scd_ssn) & MAX_SN; | ||
2812 | |||
2813 | } | ||
2814 | |||
2815 | /** | ||
2816 | * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue | ||
2817 | */ | ||
2818 | static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | ||
2819 | struct iwl4965_ht_agg *agg, | ||
2820 | struct iwl4965_tx_resp_agg *tx_resp, | ||
2821 | u16 start_idx) | ||
2822 | { | ||
2823 | u16 status; | ||
2824 | struct agg_tx_status *frame_status = &tx_resp->status; | ||
2825 | struct ieee80211_tx_status *tx_status = NULL; | ||
2826 | struct ieee80211_hdr *hdr = NULL; | ||
2827 | int i, sh; | ||
2828 | int txq_id, idx; | ||
2829 | u16 seq; | ||
2830 | |||
2831 | if (agg->wait_for_ba) | ||
2832 | IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n"); | ||
2833 | |||
2834 | agg->frame_count = tx_resp->frame_count; | ||
2835 | agg->start_idx = start_idx; | ||
2836 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | ||
2837 | agg->bitmap = 0; | ||
2838 | |||
2839 | /* # frames attempted by Tx command */ | ||
2840 | if (agg->frame_count == 1) { | ||
2841 | /* Only one frame was attempted; no block-ack will arrive */ | ||
2842 | status = le16_to_cpu(frame_status[0].status); | ||
2843 | seq = le16_to_cpu(frame_status[0].sequence); | ||
2844 | idx = SEQ_TO_INDEX(seq); | ||
2845 | txq_id = SEQ_TO_QUEUE(seq); | ||
2846 | |||
2847 | /* FIXME: code repetition */ | ||
2848 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", | ||
2849 | agg->frame_count, agg->start_idx, idx); | ||
2850 | |||
2851 | tx_status = &(priv->txq[txq_id].txb[idx].status); | ||
2852 | tx_status->retry_count = tx_resp->failure_frame; | ||
2853 | tx_status->queue_number = status & 0xff; | ||
2854 | tx_status->queue_length = tx_resp->failure_rts; | ||
2855 | tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU; | ||
2856 | tx_status->flags = iwl4965_is_tx_success(status)? | ||
2857 | IEEE80211_TX_STATUS_ACK : 0; | ||
2858 | iwl4965_hwrate_to_tx_control(priv, | ||
2859 | le32_to_cpu(tx_resp->rate_n_flags), | ||
2860 | &tx_status->control); | ||
2861 | /* FIXME: code repetition end */ | ||
2862 | |||
2863 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", | ||
2864 | status & 0xff, tx_resp->failure_frame); | ||
2865 | IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", | ||
2866 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags)); | ||
2867 | |||
2868 | agg->wait_for_ba = 0; | ||
2869 | } else { | ||
2870 | /* Two or more frames were attempted; expect block-ack */ | ||
2871 | u64 bitmap = 0; | ||
2872 | int start = agg->start_idx; | ||
2873 | |||
2874 | /* Construct bit-map of pending frames within Tx window */ | ||
2875 | for (i = 0; i < agg->frame_count; i++) { | ||
2876 | u16 sc; | ||
2877 | status = le16_to_cpu(frame_status[i].status); | ||
2878 | seq = le16_to_cpu(frame_status[i].sequence); | ||
2879 | idx = SEQ_TO_INDEX(seq); | ||
2880 | txq_id = SEQ_TO_QUEUE(seq); | ||
2881 | |||
2882 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | | ||
2883 | AGG_TX_STATE_ABORT_MSK)) | ||
2884 | continue; | ||
2885 | |||
2886 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n", | ||
2887 | agg->frame_count, txq_id, idx); | ||
2888 | |||
2889 | hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, idx); | ||
2890 | |||
2891 | sc = le16_to_cpu(hdr->seq_ctrl); | ||
2892 | if (idx != (SEQ_TO_SN(sc) & 0xff)) { | ||
2893 | IWL_ERROR("BUG_ON idx doesn't match seq control" | ||
2894 | " idx=%d, seq_idx=%d, seq=%d\n", | ||
2895 | idx, SEQ_TO_SN(sc), | ||
2896 | hdr->seq_ctrl); | ||
2897 | return -1; | ||
2898 | } | ||
2899 | |||
2900 | IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", | ||
2901 | i, idx, SEQ_TO_SN(sc)); | ||
2902 | |||
2903 | sh = idx - start; | ||
2904 | if (sh > 64) { | ||
2905 | sh = (start - idx) + 0xff; | ||
2906 | bitmap = bitmap << sh; | ||
2907 | sh = 0; | ||
2908 | start = idx; | ||
2909 | } else if (sh < -64) | ||
2910 | sh = 0xff - (start - idx); | ||
2911 | else if (sh < 0) { | ||
2912 | sh = start - idx; | ||
2913 | start = idx; | ||
2914 | bitmap = bitmap << sh; | ||
2915 | sh = 0; | ||
2916 | } | ||
2917 | bitmap |= (1 << sh); | ||
2918 | IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n", | ||
2919 | start, (u32)(bitmap & 0xFFFFFFFF)); | ||
2920 | } | ||
2921 | |||
2922 | agg->bitmap = bitmap; | ||
2923 | agg->start_idx = start; | ||
2924 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | ||
2925 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", | ||
2926 | agg->frame_count, agg->start_idx, | ||
2927 | (unsigned long long)agg->bitmap); | ||
2928 | |||
2929 | if (bitmap) | ||
2930 | agg->wait_for_ba = 1; | ||
2931 | } | ||
2932 | return 0; | ||
2933 | } | ||
2934 | #endif | ||
2935 | |||
2936 | /** | ||
2937 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response | ||
2938 | */ | ||
2939 | static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | ||
2940 | struct iwl4965_rx_mem_buffer *rxb) | ||
2941 | { | ||
2942 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | ||
2943 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | ||
2944 | int txq_id = SEQ_TO_QUEUE(sequence); | ||
2945 | int index = SEQ_TO_INDEX(sequence); | ||
2946 | struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; | ||
2947 | struct ieee80211_tx_status *tx_status; | ||
2948 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | ||
2949 | u32 status = le32_to_cpu(tx_resp->status); | ||
2950 | #ifdef CONFIG_IWL4965_HT | ||
2951 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; | ||
2952 | struct ieee80211_hdr *hdr; | ||
2953 | __le16 *qc; | ||
2954 | #endif | ||
2955 | |||
2956 | if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { | ||
2957 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | ||
2958 | "is out of range [0-%d] %d %d\n", txq_id, | ||
2959 | index, txq->q.n_bd, txq->q.write_ptr, | ||
2960 | txq->q.read_ptr); | ||
2961 | return; | ||
2962 | } | ||
2963 | |||
2964 | #ifdef CONFIG_IWL4965_HT | ||
2965 | hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, index); | ||
2966 | qc = ieee80211_get_qos_ctrl(hdr); | ||
2967 | |||
2968 | if (qc) | ||
2969 | tid = le16_to_cpu(*qc) & 0xf; | ||
2970 | |||
2971 | sta_id = iwl4965_get_ra_sta_id(priv, hdr); | ||
2972 | if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { | ||
2973 | IWL_ERROR("Station not known\n"); | ||
2974 | return; | ||
2975 | } | ||
2976 | |||
2977 | if (txq->sched_retry) { | ||
2978 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); | ||
2979 | struct iwl4965_ht_agg *agg = NULL; | ||
2980 | |||
2981 | if (!qc) | ||
2982 | return; | ||
2983 | |||
2984 | agg = &priv->stations[sta_id].tid[tid].agg; | ||
2985 | |||
2986 | iwl4965_tx_status_reply_tx(priv, agg, | ||
2987 | (struct iwl4965_tx_resp_agg *)tx_resp, index); | ||
2988 | |||
2989 | if ((tx_resp->frame_count == 1) && | ||
2990 | !iwl4965_is_tx_success(status)) { | ||
2991 | /* TODO: send BAR */ | ||
2992 | } | ||
2993 | |||
2994 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { | ||
2995 | int freed; | ||
2996 | index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); | ||
2997 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " | ||
2998 | "%d index %d\n", scd_ssn , index); | ||
2999 | freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
3000 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
3001 | |||
3002 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | ||
3003 | txq_id >= 0 && priv->mac80211_registered && | ||
3004 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | ||
3005 | ieee80211_wake_queue(priv->hw, txq_id); | ||
3006 | |||
3007 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | ||
3008 | } | ||
3009 | } else { | ||
3010 | #endif /* CONFIG_IWL4965_HT */ | ||
3011 | tx_status = &(txq->txb[txq->q.read_ptr].status); | ||
3012 | |||
3013 | tx_status->retry_count = tx_resp->failure_frame; | ||
3014 | tx_status->queue_number = status; | ||
3015 | tx_status->queue_length = tx_resp->bt_kill_count; | ||
3016 | tx_status->queue_length |= tx_resp->failure_rts; | ||
3017 | tx_status->flags = | ||
3018 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | ||
3019 | iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | ||
3020 | &tx_status->control); | ||
3021 | |||
3022 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " | ||
3023 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), | ||
3024 | status, le32_to_cpu(tx_resp->rate_n_flags), | ||
3025 | tx_resp->failure_frame); | ||
3026 | |||
3027 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | ||
3028 | if (index != -1) { | ||
3029 | #ifdef CONFIG_IWL4965_HT | ||
3030 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
3031 | |||
3032 | if (tid != MAX_TID_COUNT) | ||
3033 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
3034 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | ||
3035 | (txq_id >= 0) && | ||
3036 | priv->mac80211_registered) | ||
3037 | ieee80211_wake_queue(priv->hw, txq_id); | ||
3038 | if (tid != MAX_TID_COUNT) | ||
3039 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | ||
3040 | #endif | ||
3041 | } | ||
3042 | #ifdef CONFIG_IWL4965_HT | ||
3043 | } | ||
3044 | #endif /* CONFIG_IWL4965_HT */ | ||
3045 | |||
3046 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | ||
3047 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | ||
3048 | } | ||
3049 | |||
3050 | |||
3051 | static void iwl4965_rx_reply_alive(struct iwl_priv *priv, | ||
3052 | struct iwl4965_rx_mem_buffer *rxb) | ||
3053 | { | ||
3054 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | ||
3055 | struct iwl4965_alive_resp *palive; | ||
3056 | struct delayed_work *pwork; | 999 | struct delayed_work *pwork; |
3057 | 1000 | ||
3058 | palive = &pkt->u.alive_frame; | 1001 | palive = &pkt->u.alive_frame; |
@@ -3066,12 +1009,12 @@ static void iwl4965_rx_reply_alive(struct iwl_priv *priv, | |||
3066 | IWL_DEBUG_INFO("Initialization Alive received.\n"); | 1009 | IWL_DEBUG_INFO("Initialization Alive received.\n"); |
3067 | memcpy(&priv->card_alive_init, | 1010 | memcpy(&priv->card_alive_init, |
3068 | &pkt->u.alive_frame, | 1011 | &pkt->u.alive_frame, |
3069 | sizeof(struct iwl4965_init_alive_resp)); | 1012 | sizeof(struct iwl_init_alive_resp)); |
3070 | pwork = &priv->init_alive_start; | 1013 | pwork = &priv->init_alive_start; |
3071 | } else { | 1014 | } else { |
3072 | IWL_DEBUG_INFO("Runtime Alive received.\n"); | 1015 | IWL_DEBUG_INFO("Runtime Alive received.\n"); |
3073 | memcpy(&priv->card_alive, &pkt->u.alive_frame, | 1016 | memcpy(&priv->card_alive, &pkt->u.alive_frame, |
3074 | sizeof(struct iwl4965_alive_resp)); | 1017 | sizeof(struct iwl_alive_resp)); |
3075 | pwork = &priv->alive_start; | 1018 | pwork = &priv->alive_start; |
3076 | } | 1019 | } |
3077 | 1020 | ||
@@ -3084,19 +1027,10 @@ static void iwl4965_rx_reply_alive(struct iwl_priv *priv, | |||
3084 | IWL_WARNING("uCode did not respond OK.\n"); | 1027 | IWL_WARNING("uCode did not respond OK.\n"); |
3085 | } | 1028 | } |
3086 | 1029 | ||
3087 | static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv, | ||
3088 | struct iwl4965_rx_mem_buffer *rxb) | ||
3089 | { | ||
3090 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | ||
3091 | |||
3092 | IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); | ||
3093 | return; | ||
3094 | } | ||
3095 | |||
3096 | static void iwl4965_rx_reply_error(struct iwl_priv *priv, | 1030 | static void iwl4965_rx_reply_error(struct iwl_priv *priv, |
3097 | struct iwl4965_rx_mem_buffer *rxb) | 1031 | struct iwl_rx_mem_buffer *rxb) |
3098 | { | 1032 | { |
3099 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 1033 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3100 | 1034 | ||
3101 | IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " | 1035 | IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " |
3102 | "seq 0x%04X ser 0x%08X\n", | 1036 | "seq 0x%04X ser 0x%08X\n", |
@@ -3109,10 +1043,10 @@ static void iwl4965_rx_reply_error(struct iwl_priv *priv, | |||
3109 | 1043 | ||
3110 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 1044 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x |
3111 | 1045 | ||
3112 | static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb) | 1046 | static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
3113 | { | 1047 | { |
3114 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 1048 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3115 | struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon; | 1049 | struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; |
3116 | struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif); | 1050 | struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif); |
3117 | IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", | 1051 | IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", |
3118 | le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); | 1052 | le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); |
@@ -3121,15 +1055,15 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer * | |||
3121 | } | 1055 | } |
3122 | 1056 | ||
3123 | static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, | 1057 | static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, |
3124 | struct iwl4965_rx_mem_buffer *rxb) | 1058 | struct iwl_rx_mem_buffer *rxb) |
3125 | { | 1059 | { |
3126 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 1060 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
3127 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 1061 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3128 | struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); | 1062 | struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); |
3129 | 1063 | ||
3130 | if (!report->state) { | 1064 | if (!report->state) { |
3131 | IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO, | 1065 | IWL_DEBUG(IWL_DL_11H, |
3132 | "Spectrum Measure Notification: Start\n"); | 1066 | "Spectrum Measure Notification: Start\n"); |
3133 | return; | 1067 | return; |
3134 | } | 1068 | } |
3135 | 1069 | ||
@@ -3139,10 +1073,10 @@ static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, | |||
3139 | } | 1073 | } |
3140 | 1074 | ||
3141 | static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, | 1075 | static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, |
3142 | struct iwl4965_rx_mem_buffer *rxb) | 1076 | struct iwl_rx_mem_buffer *rxb) |
3143 | { | 1077 | { |
3144 | #ifdef CONFIG_IWLWIFI_DEBUG | 1078 | #ifdef CONFIG_IWLWIFI_DEBUG |
3145 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 1079 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3146 | struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif); | 1080 | struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif); |
3147 | IWL_DEBUG_RX("sleep mode: %d, src: %d\n", | 1081 | IWL_DEBUG_RX("sleep mode: %d, src: %d\n", |
3148 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 1082 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
@@ -3150,13 +1084,13 @@ static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, | |||
3150 | } | 1084 | } |
3151 | 1085 | ||
3152 | static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | 1086 | static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
3153 | struct iwl4965_rx_mem_buffer *rxb) | 1087 | struct iwl_rx_mem_buffer *rxb) |
3154 | { | 1088 | { |
3155 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 1089 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3156 | IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " | 1090 | IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " |
3157 | "notification for %s:\n", | 1091 | "notification for %s:\n", |
3158 | le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); | 1092 | le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); |
3159 | iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); | 1093 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); |
3160 | } | 1094 | } |
3161 | 1095 | ||
3162 | static void iwl4965_bg_beacon_update(struct work_struct *work) | 1096 | static void iwl4965_bg_beacon_update(struct work_struct *work) |
@@ -3166,7 +1100,7 @@ static void iwl4965_bg_beacon_update(struct work_struct *work) | |||
3166 | struct sk_buff *beacon; | 1100 | struct sk_buff *beacon; |
3167 | 1101 | ||
3168 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ | 1102 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ |
3169 | beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL); | 1103 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); |
3170 | 1104 | ||
3171 | if (!beacon) { | 1105 | if (!beacon) { |
3172 | IWL_ERROR("update beacon failed\n"); | 1106 | IWL_ERROR("update beacon failed\n"); |
@@ -3184,17 +1118,37 @@ static void iwl4965_bg_beacon_update(struct work_struct *work) | |||
3184 | iwl4965_send_beacon_cmd(priv); | 1118 | iwl4965_send_beacon_cmd(priv); |
3185 | } | 1119 | } |
3186 | 1120 | ||
1121 | /** | ||
1122 | * iwl4965_bg_statistics_periodic - Timer callback to queue statistics | ||
1123 | * | ||
1124 | * This callback is provided in order to send a statistics request. | ||
1125 | * | ||
1126 | * This timer function is continually reset to execute within | ||
1127 | * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION | ||
1128 | * was received. We need to ensure we receive the statistics in order | ||
1129 | * to update the temperature used for calibrating the TXPOWER. | ||
1130 | */ | ||
1131 | static void iwl4965_bg_statistics_periodic(unsigned long data) | ||
1132 | { | ||
1133 | struct iwl_priv *priv = (struct iwl_priv *)data; | ||
1134 | |||
1135 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
1136 | return; | ||
1137 | |||
1138 | iwl_send_statistics_request(priv, CMD_ASYNC); | ||
1139 | } | ||
1140 | |||
3187 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | 1141 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, |
3188 | struct iwl4965_rx_mem_buffer *rxb) | 1142 | struct iwl_rx_mem_buffer *rxb) |
3189 | { | 1143 | { |
3190 | #ifdef CONFIG_IWLWIFI_DEBUG | 1144 | #ifdef CONFIG_IWLWIFI_DEBUG |
3191 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 1145 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3192 | struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); | 1146 | struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); |
3193 | u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 1147 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
3194 | 1148 | ||
3195 | IWL_DEBUG_RX("beacon status %x retries %d iss %d " | 1149 | IWL_DEBUG_RX("beacon status %x retries %d iss %d " |
3196 | "tsf %d %d rate %d\n", | 1150 | "tsf %d %d rate %d\n", |
3197 | le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, | 1151 | le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, |
3198 | beacon->beacon_notify_hdr.failure_frame, | 1152 | beacon->beacon_notify_hdr.failure_frame, |
3199 | le32_to_cpu(beacon->ibss_mgr_status), | 1153 | le32_to_cpu(beacon->ibss_mgr_status), |
3200 | le32_to_cpu(beacon->high_tsf), | 1154 | le32_to_cpu(beacon->high_tsf), |
@@ -3206,129 +1160,12 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | |||
3206 | queue_work(priv->workqueue, &priv->beacon_update); | 1160 | queue_work(priv->workqueue, &priv->beacon_update); |
3207 | } | 1161 | } |
3208 | 1162 | ||
3209 | /* Service response to REPLY_SCAN_CMD (0x80) */ | ||
3210 | static void iwl4965_rx_reply_scan(struct iwl_priv *priv, | ||
3211 | struct iwl4965_rx_mem_buffer *rxb) | ||
3212 | { | ||
3213 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
3214 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | ||
3215 | struct iwl4965_scanreq_notification *notif = | ||
3216 | (struct iwl4965_scanreq_notification *)pkt->u.raw; | ||
3217 | |||
3218 | IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); | ||
3219 | #endif | ||
3220 | } | ||
3221 | |||
3222 | /* Service SCAN_START_NOTIFICATION (0x82) */ | ||
3223 | static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, | ||
3224 | struct iwl4965_rx_mem_buffer *rxb) | ||
3225 | { | ||
3226 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | ||
3227 | struct iwl4965_scanstart_notification *notif = | ||
3228 | (struct iwl4965_scanstart_notification *)pkt->u.raw; | ||
3229 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | ||
3230 | IWL_DEBUG_SCAN("Scan start: " | ||
3231 | "%d [802.11%s] " | ||
3232 | "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", | ||
3233 | notif->channel, | ||
3234 | notif->band ? "bg" : "a", | ||
3235 | notif->tsf_high, | ||
3236 | notif->tsf_low, notif->status, notif->beacon_timer); | ||
3237 | } | ||
3238 | |||
3239 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | ||
3240 | static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, | ||
3241 | struct iwl4965_rx_mem_buffer *rxb) | ||
3242 | { | ||
3243 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | ||
3244 | struct iwl4965_scanresults_notification *notif = | ||
3245 | (struct iwl4965_scanresults_notification *)pkt->u.raw; | ||
3246 | |||
3247 | IWL_DEBUG_SCAN("Scan ch.res: " | ||
3248 | "%d [802.11%s] " | ||
3249 | "(TSF: 0x%08X:%08X) - %d " | ||
3250 | "elapsed=%lu usec (%dms since last)\n", | ||
3251 | notif->channel, | ||
3252 | notif->band ? "bg" : "a", | ||
3253 | le32_to_cpu(notif->tsf_high), | ||
3254 | le32_to_cpu(notif->tsf_low), | ||
3255 | le32_to_cpu(notif->statistics[0]), | ||
3256 | le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, | ||
3257 | jiffies_to_msecs(elapsed_jiffies | ||
3258 | (priv->last_scan_jiffies, jiffies))); | ||
3259 | |||
3260 | priv->last_scan_jiffies = jiffies; | ||
3261 | priv->next_scan_jiffies = 0; | ||
3262 | } | ||
3263 | |||
3264 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ | ||
3265 | static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, | ||
3266 | struct iwl4965_rx_mem_buffer *rxb) | ||
3267 | { | ||
3268 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | ||
3269 | struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | ||
3270 | |||
3271 | IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | ||
3272 | scan_notif->scanned_channels, | ||
3273 | scan_notif->tsf_low, | ||
3274 | scan_notif->tsf_high, scan_notif->status); | ||
3275 | |||
3276 | /* The HW is no longer scanning */ | ||
3277 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
3278 | |||
3279 | /* The scan completion notification came in, so kill that timer... */ | ||
3280 | cancel_delayed_work(&priv->scan_check); | ||
3281 | |||
3282 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | ||
3283 | (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? | ||
3284 | "2.4" : "5.2", | ||
3285 | jiffies_to_msecs(elapsed_jiffies | ||
3286 | (priv->scan_pass_start, jiffies))); | ||
3287 | |||
3288 | /* Remove this scanned band from the list of pending | ||
3289 | * bands to scan, band G precedes A in order of scanning | ||
3290 | * as seen in iwl_bg_request_scan */ | ||
3291 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) | ||
3292 | priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); | ||
3293 | else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) | ||
3294 | priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); | ||
3295 | |||
3296 | /* If a request to abort was given, or the scan did not succeed | ||
3297 | * then we reset the scan state machine and terminate, | ||
3298 | * re-queuing another scan if one has been requested */ | ||
3299 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
3300 | IWL_DEBUG_INFO("Aborted scan completed.\n"); | ||
3301 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
3302 | } else { | ||
3303 | /* If there are more bands on this scan pass reschedule */ | ||
3304 | if (priv->scan_bands) | ||
3305 | goto reschedule; | ||
3306 | } | ||
3307 | |||
3308 | priv->last_scan_jiffies = jiffies; | ||
3309 | priv->next_scan_jiffies = 0; | ||
3310 | IWL_DEBUG_INFO("Setting scan to off\n"); | ||
3311 | |||
3312 | clear_bit(STATUS_SCANNING, &priv->status); | ||
3313 | |||
3314 | IWL_DEBUG_INFO("Scan took %dms\n", | ||
3315 | jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies))); | ||
3316 | |||
3317 | queue_work(priv->workqueue, &priv->scan_completed); | ||
3318 | |||
3319 | return; | ||
3320 | |||
3321 | reschedule: | ||
3322 | priv->scan_pass_start = jiffies; | ||
3323 | queue_work(priv->workqueue, &priv->request_scan); | ||
3324 | } | ||
3325 | |||
3326 | /* Handle notification from uCode that card's power state is changing | 1163 | /* Handle notification from uCode that card's power state is changing |
3327 | * due to software, hardware, or critical temperature RFKILL */ | 1164 | * due to software, hardware, or critical temperature RFKILL */ |
3328 | static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, | 1165 | static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, |
3329 | struct iwl4965_rx_mem_buffer *rxb) | 1166 | struct iwl_rx_mem_buffer *rxb) |
3330 | { | 1167 | { |
3331 | struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; | 1168 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3332 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 1169 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
3333 | unsigned long status = priv->status; | 1170 | unsigned long status = priv->status; |
3334 | 1171 | ||
@@ -3383,7 +1220,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, | |||
3383 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | 1220 | clear_bit(STATUS_RF_KILL_SW, &priv->status); |
3384 | 1221 | ||
3385 | if (!(flags & RXON_CARD_DISABLED)) | 1222 | if (!(flags & RXON_CARD_DISABLED)) |
3386 | iwl4965_scan_cancel(priv); | 1223 | iwl_scan_cancel(priv); |
3387 | 1224 | ||
3388 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 1225 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
3389 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 1226 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || |
@@ -3403,10 +1240,9 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, | |||
3403 | * This function chains into the hardware specific files for them to setup | 1240 | * This function chains into the hardware specific files for them to setup |
3404 | * any hardware specific handlers as well. | 1241 | * any hardware specific handlers as well. |
3405 | */ | 1242 | */ |
3406 | static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | 1243 | static void iwl_setup_rx_handlers(struct iwl_priv *priv) |
3407 | { | 1244 | { |
3408 | priv->rx_handlers[REPLY_ALIVE] = iwl4965_rx_reply_alive; | 1245 | priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; |
3409 | priv->rx_handlers[REPLY_ADD_STA] = iwl4965_rx_reply_add_sta; | ||
3410 | priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error; | 1246 | priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error; |
3411 | priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl4965_rx_csa; | 1247 | priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl4965_rx_csa; |
3412 | priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = | 1248 | priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = |
@@ -3421,500 +1257,47 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | |||
3421 | * statistics request from the host as well as for the periodic | 1257 | * statistics request from the host as well as for the periodic |
3422 | * statistics notifications (after received beacons) from the uCode. | 1258 | * statistics notifications (after received beacons) from the uCode. |
3423 | */ | 1259 | */ |
3424 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics; | 1260 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics; |
3425 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics; | 1261 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; |
3426 | |||
3427 | priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan; | ||
3428 | priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif; | ||
3429 | priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = | ||
3430 | iwl4965_rx_scan_results_notif; | ||
3431 | priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = | ||
3432 | iwl4965_rx_scan_complete_notif; | ||
3433 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif; | ||
3434 | priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; | ||
3435 | |||
3436 | /* Set up hardware specific Rx handlers */ | ||
3437 | iwl4965_hw_rx_handler_setup(priv); | ||
3438 | } | ||
3439 | |||
3440 | /** | ||
3441 | * iwl4965_tx_cmd_complete - Pull unused buffers off the queue and reclaim them | ||
3442 | * @rxb: Rx buffer to reclaim | ||
3443 | * | ||
3444 | * If an Rx buffer has an async callback associated with it the callback | ||
3445 | * will be executed. The attached skb (if present) will only be freed | ||
3446 | * if the callback returns 1 | ||
3447 | */ | ||
3448 | static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, | ||
3449 | struct iwl4965_rx_mem_buffer *rxb) | ||
3450 | { | ||
3451 | struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; | ||
3452 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | ||
3453 | int txq_id = SEQ_TO_QUEUE(sequence); | ||
3454 | int index = SEQ_TO_INDEX(sequence); | ||
3455 | int huge = sequence & SEQ_HUGE_FRAME; | ||
3456 | int cmd_index; | ||
3457 | struct iwl_cmd *cmd; | ||
3458 | |||
3459 | /* If a Tx command is being handled and it isn't in the actual | ||
3460 | * command queue then there a command routing bug has been introduced | ||
3461 | * in the queue management code. */ | ||
3462 | if (txq_id != IWL_CMD_QUEUE_NUM) | ||
3463 | IWL_ERROR("Error wrong command queue %d command id 0x%X\n", | ||
3464 | txq_id, pkt->hdr.cmd); | ||
3465 | BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); | ||
3466 | |||
3467 | cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); | ||
3468 | cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; | ||
3469 | |||
3470 | /* Input error checking is done when commands are added to queue. */ | ||
3471 | if (cmd->meta.flags & CMD_WANT_SKB) { | ||
3472 | cmd->meta.source->u.skb = rxb->skb; | ||
3473 | rxb->skb = NULL; | ||
3474 | } else if (cmd->meta.u.callback && | ||
3475 | !cmd->meta.u.callback(priv, cmd, rxb->skb)) | ||
3476 | rxb->skb = NULL; | ||
3477 | |||
3478 | iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
3479 | |||
3480 | if (!(cmd->meta.flags & CMD_ASYNC)) { | ||
3481 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
3482 | wake_up_interruptible(&priv->wait_command_queue); | ||
3483 | } | ||
3484 | } | ||
3485 | |||
3486 | /************************** RX-FUNCTIONS ****************************/ | ||
3487 | /* | ||
3488 | * Rx theory of operation | ||
3489 | * | ||
3490 | * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), | ||
3491 | * each of which point to Receive Buffers to be filled by 4965. These get | ||
3492 | * used not only for Rx frames, but for any command response or notification | ||
3493 | * from the 4965. The driver and 4965 manage the Rx buffers by means | ||
3494 | * of indexes into the circular buffer. | ||
3495 | * | ||
3496 | * Rx Queue Indexes | ||
3497 | * The host/firmware share two index registers for managing the Rx buffers. | ||
3498 | * | ||
3499 | * The READ index maps to the first position that the firmware may be writing | ||
3500 | * to -- the driver can read up to (but not including) this position and get | ||
3501 | * good data. | ||
3502 | * The READ index is managed by the firmware once the card is enabled. | ||
3503 | * | ||
3504 | * The WRITE index maps to the last position the driver has read from -- the | ||
3505 | * position preceding WRITE is the last slot the firmware can place a packet. | ||
3506 | * | ||
3507 | * The queue is empty (no good data) if WRITE = READ - 1, and is full if | ||
3508 | * WRITE = READ. | ||
3509 | * | ||
3510 | * During initialization, the host sets up the READ queue position to the first | ||
3511 | * INDEX position, and WRITE to the last (READ - 1 wrapped) | ||
3512 | * | ||
3513 | * When the firmware places a packet in a buffer, it will advance the READ index | ||
3514 | * and fire the RX interrupt. The driver can then query the READ index and | ||
3515 | * process as many packets as possible, moving the WRITE index forward as it | ||
3516 | * resets the Rx queue buffers with new memory. | ||
3517 | * | ||
3518 | * The management in the driver is as follows: | ||
3519 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When | ||
3520 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled | ||
3521 | * to replenish the iwl->rxq->rx_free. | ||
3522 | * + In iwl4965_rx_replenish (scheduled) if 'processed' != 'read' then the | ||
3523 | * iwl->rxq is replenished and the READ INDEX is updated (updating the | ||
3524 | * 'processed' and 'read' driver indexes as well) | ||
3525 | * + A received packet is processed and handed to the kernel network stack, | ||
3526 | * detached from the iwl->rxq. The driver 'processed' index is updated. | ||
3527 | * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free | ||
3528 | * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ | ||
3529 | * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there | ||
3530 | * were enough free buffers and RX_STALLED is set it is cleared. | ||
3531 | * | ||
3532 | * | ||
3533 | * Driver sequence: | ||
3534 | * | ||
3535 | * iwl4965_rx_queue_alloc() Allocates rx_free | ||
3536 | * iwl4965_rx_replenish() Replenishes rx_free list from rx_used, and calls | ||
3537 | * iwl4965_rx_queue_restock | ||
3538 | * iwl4965_rx_queue_restock() Moves available buffers from rx_free into Rx | ||
3539 | * queue, updates firmware pointers, and updates | ||
3540 | * the WRITE index. If insufficient rx_free buffers | ||
3541 | * are available, schedules iwl4965_rx_replenish | ||
3542 | * | ||
3543 | * -- enable interrupts -- | ||
3544 | * ISR - iwl4965_rx() Detach iwl4965_rx_mem_buffers from pool up to the | ||
3545 | * READ INDEX, detaching the SKB from the pool. | ||
3546 | * Moves the packet buffer from queue to rx_used. | ||
3547 | * Calls iwl4965_rx_queue_restock to refill any empty | ||
3548 | * slots. | ||
3549 | * ... | ||
3550 | * | ||
3551 | */ | ||
3552 | |||
3553 | /** | ||
3554 | * iwl4965_rx_queue_space - Return number of free slots available in queue. | ||
3555 | */ | ||
3556 | static int iwl4965_rx_queue_space(const struct iwl4965_rx_queue *q) | ||
3557 | { | ||
3558 | int s = q->read - q->write; | ||
3559 | if (s <= 0) | ||
3560 | s += RX_QUEUE_SIZE; | ||
3561 | /* keep some buffer to not confuse full and empty queue */ | ||
3562 | s -= 2; | ||
3563 | if (s < 0) | ||
3564 | s = 0; | ||
3565 | return s; | ||
3566 | } | ||
3567 | |||
3568 | /** | ||
3569 | * iwl4965_rx_queue_update_write_ptr - Update the write pointer for the RX queue | ||
3570 | */ | ||
3571 | int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl4965_rx_queue *q) | ||
3572 | { | ||
3573 | u32 reg = 0; | ||
3574 | int rc = 0; | ||
3575 | unsigned long flags; | ||
3576 | |||
3577 | spin_lock_irqsave(&q->lock, flags); | ||
3578 | |||
3579 | if (q->need_update == 0) | ||
3580 | goto exit_unlock; | ||
3581 | |||
3582 | /* If power-saving is in use, make sure device is awake */ | ||
3583 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
3584 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
3585 | |||
3586 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
3587 | iwl_set_bit(priv, CSR_GP_CNTRL, | ||
3588 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
3589 | goto exit_unlock; | ||
3590 | } | ||
3591 | |||
3592 | rc = iwl_grab_nic_access(priv); | ||
3593 | if (rc) | ||
3594 | goto exit_unlock; | ||
3595 | |||
3596 | /* Device expects a multiple of 8 */ | ||
3597 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
3598 | q->write & ~0x7); | ||
3599 | iwl_release_nic_access(priv); | ||
3600 | |||
3601 | /* Else device is assumed to be awake */ | ||
3602 | } else | ||
3603 | /* Device expects a multiple of 8 */ | ||
3604 | iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); | ||
3605 | 1262 | ||
1263 | iwl_setup_rx_scan_handlers(priv); | ||
3606 | 1264 | ||
3607 | q->need_update = 0; | 1265 | /* status change handler */ |
3608 | 1266 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif; | |
3609 | exit_unlock: | ||
3610 | spin_unlock_irqrestore(&q->lock, flags); | ||
3611 | return rc; | ||
3612 | } | ||
3613 | |||
3614 | /** | ||
3615 | * iwl4965_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | ||
3616 | */ | ||
3617 | static inline __le32 iwl4965_dma_addr2rbd_ptr(struct iwl_priv *priv, | ||
3618 | dma_addr_t dma_addr) | ||
3619 | { | ||
3620 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
3621 | } | ||
3622 | |||
3623 | |||
3624 | /** | ||
3625 | * iwl4965_rx_queue_restock - refill RX queue from pre-allocated pool | ||
3626 | * | ||
3627 | * If there are slots in the RX queue that need to be restocked, | ||
3628 | * and we have free pre-allocated buffers, fill the ranks as much | ||
3629 | * as we can, pulling from rx_free. | ||
3630 | * | ||
3631 | * This moves the 'write' index forward to catch up with 'processed', and | ||
3632 | * also updates the memory address in the firmware to reference the new | ||
3633 | * target buffer. | ||
3634 | */ | ||
3635 | static int iwl4965_rx_queue_restock(struct iwl_priv *priv) | ||
3636 | { | ||
3637 | struct iwl4965_rx_queue *rxq = &priv->rxq; | ||
3638 | struct list_head *element; | ||
3639 | struct iwl4965_rx_mem_buffer *rxb; | ||
3640 | unsigned long flags; | ||
3641 | int write, rc; | ||
3642 | |||
3643 | spin_lock_irqsave(&rxq->lock, flags); | ||
3644 | write = rxq->write & ~0x7; | ||
3645 | while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | ||
3646 | /* Get next free Rx buffer, remove from free list */ | ||
3647 | element = rxq->rx_free.next; | ||
3648 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); | ||
3649 | list_del(element); | ||
3650 | |||
3651 | /* Point to Rx buffer via next RBD in circular buffer */ | ||
3652 | rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr); | ||
3653 | rxq->queue[rxq->write] = rxb; | ||
3654 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | ||
3655 | rxq->free_count--; | ||
3656 | } | ||
3657 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3658 | /* If the pre-allocated buffer pool is dropping low, schedule to | ||
3659 | * refill it */ | ||
3660 | if (rxq->free_count <= RX_LOW_WATERMARK) | ||
3661 | queue_work(priv->workqueue, &priv->rx_replenish); | ||
3662 | |||
3663 | |||
3664 | /* If we've added more space for the firmware to place data, tell it. | ||
3665 | * Increment device's write pointer in multiples of 8. */ | ||
3666 | if ((write != (rxq->write & ~0x7)) | ||
3667 | || (abs(rxq->write - rxq->read) > 7)) { | ||
3668 | spin_lock_irqsave(&rxq->lock, flags); | ||
3669 | rxq->need_update = 1; | ||
3670 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3671 | rc = iwl4965_rx_queue_update_write_ptr(priv, rxq); | ||
3672 | if (rc) | ||
3673 | return rc; | ||
3674 | } | ||
3675 | |||
3676 | return 0; | ||
3677 | } | ||
3678 | |||
3679 | /** | ||
3680 | * iwl4965_rx_replenish - Move all used packet from rx_used to rx_free | ||
3681 | * | ||
3682 | * When moving to rx_free an SKB is allocated for the slot. | ||
3683 | * | ||
3684 | * Also restock the Rx queue via iwl4965_rx_queue_restock. | ||
3685 | * This is called as a scheduled work item (except for during initialization) | ||
3686 | */ | ||
3687 | static void iwl4965_rx_allocate(struct iwl_priv *priv) | ||
3688 | { | ||
3689 | struct iwl4965_rx_queue *rxq = &priv->rxq; | ||
3690 | struct list_head *element; | ||
3691 | struct iwl4965_rx_mem_buffer *rxb; | ||
3692 | unsigned long flags; | ||
3693 | spin_lock_irqsave(&rxq->lock, flags); | ||
3694 | while (!list_empty(&rxq->rx_used)) { | ||
3695 | element = rxq->rx_used.next; | ||
3696 | rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); | ||
3697 | |||
3698 | /* Alloc a new receive buffer */ | ||
3699 | rxb->skb = | ||
3700 | alloc_skb(priv->hw_params.rx_buf_size, | ||
3701 | __GFP_NOWARN | GFP_ATOMIC); | ||
3702 | if (!rxb->skb) { | ||
3703 | if (net_ratelimit()) | ||
3704 | printk(KERN_CRIT DRV_NAME | ||
3705 | ": Can not allocate SKB buffers\n"); | ||
3706 | /* We don't reschedule replenish work here -- we will | ||
3707 | * call the restock method and if it still needs | ||
3708 | * more buffers it will schedule replenish */ | ||
3709 | break; | ||
3710 | } | ||
3711 | priv->alloc_rxb_skb++; | ||
3712 | list_del(element); | ||
3713 | 1267 | ||
3714 | /* Get physical address of RB/SKB */ | 1268 | priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = |
3715 | rxb->dma_addr = | 1269 | iwl_rx_missed_beacon_notif; |
3716 | pci_map_single(priv->pci_dev, rxb->skb->data, | 1270 | /* Rx handlers */ |
3717 | priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); | 1271 | priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy; |
3718 | list_add_tail(&rxb->list, &rxq->rx_free); | 1272 | priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx; |
3719 | rxq->free_count++; | 1273 | /* block ack */ |
3720 | } | 1274 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba; |
3721 | spin_unlock_irqrestore(&rxq->lock, flags); | 1275 | /* Set up hardware specific Rx handlers */ |
1276 | priv->cfg->ops->lib->rx_handler_setup(priv); | ||
3722 | } | 1277 | } |
3723 | 1278 | ||
3724 | /* | 1279 | /* |
3725 | * this should be called while priv->lock is locked | 1280 | * this should be called while priv->lock is locked |
3726 | */ | 1281 | */ |
3727 | static void __iwl4965_rx_replenish(void *data) | 1282 | static void __iwl_rx_replenish(struct iwl_priv *priv) |
3728 | { | 1283 | { |
3729 | struct iwl_priv *priv = data; | 1284 | iwl_rx_allocate(priv); |
3730 | 1285 | iwl_rx_queue_restock(priv); | |
3731 | iwl4965_rx_allocate(priv); | ||
3732 | iwl4965_rx_queue_restock(priv); | ||
3733 | } | 1286 | } |
3734 | 1287 | ||
3735 | 1288 | ||
3736 | void iwl4965_rx_replenish(void *data) | ||
3737 | { | ||
3738 | struct iwl_priv *priv = data; | ||
3739 | unsigned long flags; | ||
3740 | |||
3741 | iwl4965_rx_allocate(priv); | ||
3742 | |||
3743 | spin_lock_irqsave(&priv->lock, flags); | ||
3744 | iwl4965_rx_queue_restock(priv); | ||
3745 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3746 | } | ||
3747 | |||
3748 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. | ||
3749 | * If an SKB has been detached, the POOL needs to have its SKB set to NULL | ||
3750 | * This free routine walks the list of POOL entries and if SKB is set to | ||
3751 | * non NULL it is unmapped and freed | ||
3752 | */ | ||
3753 | static void iwl4965_rx_queue_free(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | ||
3754 | { | ||
3755 | int i; | ||
3756 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | ||
3757 | if (rxq->pool[i].skb != NULL) { | ||
3758 | pci_unmap_single(priv->pci_dev, | ||
3759 | rxq->pool[i].dma_addr, | ||
3760 | priv->hw_params.rx_buf_size, | ||
3761 | PCI_DMA_FROMDEVICE); | ||
3762 | dev_kfree_skb(rxq->pool[i].skb); | ||
3763 | } | ||
3764 | } | ||
3765 | |||
3766 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | ||
3767 | rxq->dma_addr); | ||
3768 | rxq->bd = NULL; | ||
3769 | } | ||
3770 | |||
3771 | int iwl4965_rx_queue_alloc(struct iwl_priv *priv) | ||
3772 | { | ||
3773 | struct iwl4965_rx_queue *rxq = &priv->rxq; | ||
3774 | struct pci_dev *dev = priv->pci_dev; | ||
3775 | int i; | ||
3776 | |||
3777 | spin_lock_init(&rxq->lock); | ||
3778 | INIT_LIST_HEAD(&rxq->rx_free); | ||
3779 | INIT_LIST_HEAD(&rxq->rx_used); | ||
3780 | |||
3781 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
3782 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | ||
3783 | if (!rxq->bd) | ||
3784 | return -ENOMEM; | ||
3785 | |||
3786 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
3787 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | ||
3788 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
3789 | |||
3790 | /* Set us so that we have processed and used all buffers, but have | ||
3791 | * not restocked the Rx queue with fresh buffers */ | ||
3792 | rxq->read = rxq->write = 0; | ||
3793 | rxq->free_count = 0; | ||
3794 | rxq->need_update = 0; | ||
3795 | return 0; | ||
3796 | } | ||
3797 | |||
3798 | void iwl4965_rx_queue_reset(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) | ||
3799 | { | ||
3800 | unsigned long flags; | ||
3801 | int i; | ||
3802 | spin_lock_irqsave(&rxq->lock, flags); | ||
3803 | INIT_LIST_HEAD(&rxq->rx_free); | ||
3804 | INIT_LIST_HEAD(&rxq->rx_used); | ||
3805 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
3806 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
3807 | /* In the reset function, these buffers may have been allocated | ||
3808 | * to an SKB, so we need to unmap and free potential storage */ | ||
3809 | if (rxq->pool[i].skb != NULL) { | ||
3810 | pci_unmap_single(priv->pci_dev, | ||
3811 | rxq->pool[i].dma_addr, | ||
3812 | priv->hw_params.rx_buf_size, | ||
3813 | PCI_DMA_FROMDEVICE); | ||
3814 | priv->alloc_rxb_skb--; | ||
3815 | dev_kfree_skb(rxq->pool[i].skb); | ||
3816 | rxq->pool[i].skb = NULL; | ||
3817 | } | ||
3818 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
3819 | } | ||
3820 | |||
3821 | /* Set us so that we have processed and used all buffers, but have | ||
3822 | * not restocked the Rx queue with fresh buffers */ | ||
3823 | rxq->read = rxq->write = 0; | ||
3824 | rxq->free_count = 0; | ||
3825 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3826 | } | ||
3827 | |||
3828 | /* Convert linear signal-to-noise ratio into dB */ | ||
3829 | static u8 ratio2dB[100] = { | ||
3830 | /* 0 1 2 3 4 5 6 7 8 9 */ | ||
3831 | 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ | ||
3832 | 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ | ||
3833 | 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ | ||
3834 | 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ | ||
3835 | 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ | ||
3836 | 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ | ||
3837 | 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ | ||
3838 | 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ | ||
3839 | 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ | ||
3840 | 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ | ||
3841 | }; | ||
3842 | |||
3843 | /* Calculates a relative dB value from a ratio of linear | ||
3844 | * (i.e. not dB) signal levels. | ||
3845 | * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ | ||
3846 | int iwl4965_calc_db_from_ratio(int sig_ratio) | ||
3847 | { | ||
3848 | /* 1000:1 or higher just report as 60 dB */ | ||
3849 | if (sig_ratio >= 1000) | ||
3850 | return 60; | ||
3851 | |||
3852 | /* 100:1 or higher, divide by 10 and use table, | ||
3853 | * add 20 dB to make up for divide by 10 */ | ||
3854 | if (sig_ratio >= 100) | ||
3855 | return (20 + (int)ratio2dB[sig_ratio/10]); | ||
3856 | |||
3857 | /* We shouldn't see this */ | ||
3858 | if (sig_ratio < 1) | ||
3859 | return 0; | ||
3860 | |||
3861 | /* Use table for ratios 1:1 - 99:1 */ | ||
3862 | return (int)ratio2dB[sig_ratio]; | ||
3863 | } | ||
3864 | |||
3865 | #define PERFECT_RSSI (-20) /* dBm */ | ||
3866 | #define WORST_RSSI (-95) /* dBm */ | ||
3867 | #define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) | ||
3868 | |||
3869 | /* Calculate an indication of rx signal quality (a percentage, not dBm!). | ||
3870 | * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info | ||
3871 | * about formulas used below. */ | ||
3872 | int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) | ||
3873 | { | ||
3874 | int sig_qual; | ||
3875 | int degradation = PERFECT_RSSI - rssi_dbm; | ||
3876 | |||
3877 | /* If we get a noise measurement, use signal-to-noise ratio (SNR) | ||
3878 | * as indicator; formula is (signal dbm - noise dbm). | ||
3879 | * SNR at or above 40 is a great signal (100%). | ||
3880 | * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. | ||
3881 | * Weakest usable signal is usually 10 - 15 dB SNR. */ | ||
3882 | if (noise_dbm) { | ||
3883 | if (rssi_dbm - noise_dbm >= 40) | ||
3884 | return 100; | ||
3885 | else if (rssi_dbm < noise_dbm) | ||
3886 | return 0; | ||
3887 | sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; | ||
3888 | |||
3889 | /* Else use just the signal level. | ||
3890 | * This formula is a least squares fit of data points collected and | ||
3891 | * compared with a reference system that had a percentage (%) display | ||
3892 | * for signal quality. */ | ||
3893 | } else | ||
3894 | sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * | ||
3895 | (15 * RSSI_RANGE + 62 * degradation)) / | ||
3896 | (RSSI_RANGE * RSSI_RANGE); | ||
3897 | |||
3898 | if (sig_qual > 100) | ||
3899 | sig_qual = 100; | ||
3900 | else if (sig_qual < 1) | ||
3901 | sig_qual = 0; | ||
3902 | |||
3903 | return sig_qual; | ||
3904 | } | ||
3905 | |||
3906 | /** | 1289 | /** |
3907 | * iwl4965_rx_handle - Main entry function for receiving responses from uCode | 1290 | * iwl_rx_handle - Main entry function for receiving responses from uCode |
3908 | * | 1291 | * |
3909 | * Uses the priv->rx_handlers callback function array to invoke | 1292 | * Uses the priv->rx_handlers callback function array to invoke |
3910 | * the appropriate handlers, including command responses, | 1293 | * the appropriate handlers, including command responses, |
3911 | * frame-received notifications, and other notifications. | 1294 | * frame-received notifications, and other notifications. |
3912 | */ | 1295 | */ |
3913 | static void iwl4965_rx_handle(struct iwl_priv *priv) | 1296 | void iwl_rx_handle(struct iwl_priv *priv) |
3914 | { | 1297 | { |
3915 | struct iwl4965_rx_mem_buffer *rxb; | 1298 | struct iwl_rx_mem_buffer *rxb; |
3916 | struct iwl4965_rx_packet *pkt; | 1299 | struct iwl_rx_packet *pkt; |
3917 | struct iwl4965_rx_queue *rxq = &priv->rxq; | 1300 | struct iwl_rx_queue *rxq = &priv->rxq; |
3918 | u32 r, i; | 1301 | u32 r, i; |
3919 | int reclaim; | 1302 | int reclaim; |
3920 | unsigned long flags; | 1303 | unsigned long flags; |
@@ -3923,14 +1306,14 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3923 | 1306 | ||
3924 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 1307 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
3925 | * buffer that the driver may process (last buffer filled by ucode). */ | 1308 | * buffer that the driver may process (last buffer filled by ucode). */ |
3926 | r = iwl4965_hw_get_rx_read(priv); | 1309 | r = priv->cfg->ops->lib->shared_mem_rx_idx(priv); |
3927 | i = rxq->read; | 1310 | i = rxq->read; |
3928 | 1311 | ||
3929 | /* Rx interrupt, but nothing sent from uCode */ | 1312 | /* Rx interrupt, but nothing sent from uCode */ |
3930 | if (i == r) | 1313 | if (i == r) |
3931 | IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); | 1314 | IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d\n", r, i); |
3932 | 1315 | ||
3933 | if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) | 1316 | if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) |
3934 | fill_rx = 1; | 1317 | fill_rx = 1; |
3935 | 1318 | ||
3936 | while (i != r) { | 1319 | while (i != r) { |
@@ -3946,7 +1329,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3946 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, | 1329 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, |
3947 | priv->hw_params.rx_buf_size, | 1330 | priv->hw_params.rx_buf_size, |
3948 | PCI_DMA_FROMDEVICE); | 1331 | PCI_DMA_FROMDEVICE); |
3949 | pkt = (struct iwl4965_rx_packet *)rxb->skb->data; | 1332 | pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3950 | 1333 | ||
3951 | /* Reclaim a command buffer only if this packet is a response | 1334 | /* Reclaim a command buffer only if this packet is a response |
3952 | * to a (driver-originated) command. | 1335 | * to a (driver-originated) command. |
@@ -3965,13 +1348,12 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3965 | * handle those that need handling via function in | 1348 | * handle those that need handling via function in |
3966 | * rx_handlers table. See iwl4965_setup_rx_handlers() */ | 1349 | * rx_handlers table. See iwl4965_setup_rx_handlers() */ |
3967 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 1350 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
3968 | IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, | 1351 | IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r, |
3969 | "r = %d, i = %d, %s, 0x%02x\n", r, i, | 1352 | i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
3970 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | ||
3971 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | 1353 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); |
3972 | } else { | 1354 | } else { |
3973 | /* No handling needed */ | 1355 | /* No handling needed */ |
3974 | IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, | 1356 | IWL_DEBUG(IWL_DL_RX, |
3975 | "r %d i %d No handler needed for %s, 0x%02x\n", | 1357 | "r %d i %d No handler needed for %s, 0x%02x\n", |
3976 | r, i, get_cmd_string(pkt->hdr.cmd), | 1358 | r, i, get_cmd_string(pkt->hdr.cmd), |
3977 | pkt->hdr.cmd); | 1359 | pkt->hdr.cmd); |
@@ -3982,7 +1364,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
3982 | * fire off the (possibly) blocking iwl_send_cmd() | 1364 | * fire off the (possibly) blocking iwl_send_cmd() |
3983 | * as we reclaim the driver command queue */ | 1365 | * as we reclaim the driver command queue */ |
3984 | if (rxb && rxb->skb) | 1366 | if (rxb && rxb->skb) |
3985 | iwl4965_tx_cmd_complete(priv, rxb); | 1367 | iwl_tx_cmd_complete(priv, rxb); |
3986 | else | 1368 | else |
3987 | IWL_WARNING("Claim null rxb?\n"); | 1369 | IWL_WARNING("Claim null rxb?\n"); |
3988 | } | 1370 | } |
@@ -4009,7 +1391,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
4009 | count++; | 1391 | count++; |
4010 | if (count >= 8) { | 1392 | if (count >= 8) { |
4011 | priv->rxq.read = i; | 1393 | priv->rxq.read = i; |
4012 | __iwl4965_rx_replenish(priv); | 1394 | __iwl_rx_replenish(priv); |
4013 | count = 0; | 1395 | count = 0; |
4014 | } | 1396 | } |
4015 | } | 1397 | } |
@@ -4017,62 +1399,17 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) | |||
4017 | 1399 | ||
4018 | /* Backtrack one entry */ | 1400 | /* Backtrack one entry */ |
4019 | priv->rxq.read = i; | 1401 | priv->rxq.read = i; |
4020 | iwl4965_rx_queue_restock(priv); | 1402 | iwl_rx_queue_restock(priv); |
4021 | } | ||
4022 | |||
4023 | /** | ||
4024 | * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware | ||
4025 | */ | ||
4026 | static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, | ||
4027 | struct iwl4965_tx_queue *txq) | ||
4028 | { | ||
4029 | u32 reg = 0; | ||
4030 | int rc = 0; | ||
4031 | int txq_id = txq->q.id; | ||
4032 | |||
4033 | if (txq->need_update == 0) | ||
4034 | return rc; | ||
4035 | |||
4036 | /* if we're trying to save power */ | ||
4037 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
4038 | /* wake up nic if it's powered down ... | ||
4039 | * uCode will wake up, and interrupt us again, so next | ||
4040 | * time we'll skip this part. */ | ||
4041 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
4042 | |||
4043 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
4044 | IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg); | ||
4045 | iwl_set_bit(priv, CSR_GP_CNTRL, | ||
4046 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
4047 | return rc; | ||
4048 | } | ||
4049 | |||
4050 | /* restore this queue's parameters in nic hardware. */ | ||
4051 | rc = iwl_grab_nic_access(priv); | ||
4052 | if (rc) | ||
4053 | return rc; | ||
4054 | iwl_write_direct32(priv, HBUS_TARG_WRPTR, | ||
4055 | txq->q.write_ptr | (txq_id << 8)); | ||
4056 | iwl_release_nic_access(priv); | ||
4057 | |||
4058 | /* else not in power-save mode, uCode will never sleep when we're | ||
4059 | * trying to tx (during RFKILL, we're not trying to tx). */ | ||
4060 | } else | ||
4061 | iwl_write32(priv, HBUS_TARG_WRPTR, | ||
4062 | txq->q.write_ptr | (txq_id << 8)); | ||
4063 | |||
4064 | txq->need_update = 0; | ||
4065 | |||
4066 | return rc; | ||
4067 | } | 1403 | } |
4068 | 1404 | ||
4069 | #ifdef CONFIG_IWLWIFI_DEBUG | 1405 | #ifdef CONFIG_IWLWIFI_DEBUG |
4070 | static void iwl4965_print_rx_config_cmd(struct iwl4965_rxon_cmd *rxon) | 1406 | static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv) |
4071 | { | 1407 | { |
1408 | struct iwl_rxon_cmd *rxon = &priv->staging_rxon; | ||
4072 | DECLARE_MAC_BUF(mac); | 1409 | DECLARE_MAC_BUF(mac); |
4073 | 1410 | ||
4074 | IWL_DEBUG_RADIO("RX CONFIG:\n"); | 1411 | IWL_DEBUG_RADIO("RX CONFIG:\n"); |
4075 | iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); | 1412 | iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); |
4076 | IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); | 1413 | IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); |
4077 | IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); | 1414 | IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); |
4078 | IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", | 1415 | IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", |
@@ -4118,173 +1455,6 @@ static inline void iwl4965_disable_interrupts(struct iwl_priv *priv) | |||
4118 | IWL_DEBUG_ISR("Disabled interrupts\n"); | 1455 | IWL_DEBUG_ISR("Disabled interrupts\n"); |
4119 | } | 1456 | } |
4120 | 1457 | ||
4121 | static const char *desc_lookup(int i) | ||
4122 | { | ||
4123 | switch (i) { | ||
4124 | case 1: | ||
4125 | return "FAIL"; | ||
4126 | case 2: | ||
4127 | return "BAD_PARAM"; | ||
4128 | case 3: | ||
4129 | return "BAD_CHECKSUM"; | ||
4130 | case 4: | ||
4131 | return "NMI_INTERRUPT"; | ||
4132 | case 5: | ||
4133 | return "SYSASSERT"; | ||
4134 | case 6: | ||
4135 | return "FATAL_ERROR"; | ||
4136 | } | ||
4137 | |||
4138 | return "UNKNOWN"; | ||
4139 | } | ||
4140 | |||
4141 | #define ERROR_START_OFFSET (1 * sizeof(u32)) | ||
4142 | #define ERROR_ELEM_SIZE (7 * sizeof(u32)) | ||
4143 | |||
4144 | static void iwl4965_dump_nic_error_log(struct iwl_priv *priv) | ||
4145 | { | ||
4146 | u32 data2, line; | ||
4147 | u32 desc, time, count, base, data1; | ||
4148 | u32 blink1, blink2, ilink1, ilink2; | ||
4149 | int rc; | ||
4150 | |||
4151 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); | ||
4152 | |||
4153 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | ||
4154 | IWL_ERROR("Not valid error log pointer 0x%08X\n", base); | ||
4155 | return; | ||
4156 | } | ||
4157 | |||
4158 | rc = iwl_grab_nic_access(priv); | ||
4159 | if (rc) { | ||
4160 | IWL_WARNING("Can not read from adapter at this time.\n"); | ||
4161 | return; | ||
4162 | } | ||
4163 | |||
4164 | count = iwl_read_targ_mem(priv, base); | ||
4165 | |||
4166 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { | ||
4167 | IWL_ERROR("Start IWL Error Log Dump:\n"); | ||
4168 | IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count); | ||
4169 | } | ||
4170 | |||
4171 | desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); | ||
4172 | blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32)); | ||
4173 | blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32)); | ||
4174 | ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32)); | ||
4175 | ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32)); | ||
4176 | data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32)); | ||
4177 | data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32)); | ||
4178 | line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); | ||
4179 | time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); | ||
4180 | |||
4181 | IWL_ERROR("Desc Time " | ||
4182 | "data1 data2 line\n"); | ||
4183 | IWL_ERROR("%-13s (#%d) %010u 0x%08X 0x%08X %u\n", | ||
4184 | desc_lookup(desc), desc, time, data1, data2, line); | ||
4185 | IWL_ERROR("blink1 blink2 ilink1 ilink2\n"); | ||
4186 | IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2, | ||
4187 | ilink1, ilink2); | ||
4188 | |||
4189 | iwl_release_nic_access(priv); | ||
4190 | } | ||
4191 | |||
4192 | #define EVENT_START_OFFSET (4 * sizeof(u32)) | ||
4193 | |||
4194 | /** | ||
4195 | * iwl4965_print_event_log - Dump error event log to syslog | ||
4196 | * | ||
4197 | * NOTE: Must be called with iwl_grab_nic_access() already obtained! | ||
4198 | */ | ||
4199 | static void iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx, | ||
4200 | u32 num_events, u32 mode) | ||
4201 | { | ||
4202 | u32 i; | ||
4203 | u32 base; /* SRAM byte address of event log header */ | ||
4204 | u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */ | ||
4205 | u32 ptr; /* SRAM byte address of log data */ | ||
4206 | u32 ev, time, data; /* event log data */ | ||
4207 | |||
4208 | if (num_events == 0) | ||
4209 | return; | ||
4210 | |||
4211 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
4212 | |||
4213 | if (mode == 0) | ||
4214 | event_size = 2 * sizeof(u32); | ||
4215 | else | ||
4216 | event_size = 3 * sizeof(u32); | ||
4217 | |||
4218 | ptr = base + EVENT_START_OFFSET + (start_idx * event_size); | ||
4219 | |||
4220 | /* "time" is actually "data" for mode 0 (no timestamp). | ||
4221 | * place event id # at far right for easier visual parsing. */ | ||
4222 | for (i = 0; i < num_events; i++) { | ||
4223 | ev = iwl_read_targ_mem(priv, ptr); | ||
4224 | ptr += sizeof(u32); | ||
4225 | time = iwl_read_targ_mem(priv, ptr); | ||
4226 | ptr += sizeof(u32); | ||
4227 | if (mode == 0) | ||
4228 | IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */ | ||
4229 | else { | ||
4230 | data = iwl_read_targ_mem(priv, ptr); | ||
4231 | ptr += sizeof(u32); | ||
4232 | IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev); | ||
4233 | } | ||
4234 | } | ||
4235 | } | ||
4236 | |||
4237 | static void iwl4965_dump_nic_event_log(struct iwl_priv *priv) | ||
4238 | { | ||
4239 | int rc; | ||
4240 | u32 base; /* SRAM byte address of event log header */ | ||
4241 | u32 capacity; /* event log capacity in # entries */ | ||
4242 | u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ | ||
4243 | u32 num_wraps; /* # times uCode wrapped to top of log */ | ||
4244 | u32 next_entry; /* index of next entry to be written by uCode */ | ||
4245 | u32 size; /* # entries that we'll print */ | ||
4246 | |||
4247 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | ||
4248 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | ||
4249 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); | ||
4250 | return; | ||
4251 | } | ||
4252 | |||
4253 | rc = iwl_grab_nic_access(priv); | ||
4254 | if (rc) { | ||
4255 | IWL_WARNING("Can not read from adapter at this time.\n"); | ||
4256 | return; | ||
4257 | } | ||
4258 | |||
4259 | /* event log header */ | ||
4260 | capacity = iwl_read_targ_mem(priv, base); | ||
4261 | mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); | ||
4262 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); | ||
4263 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); | ||
4264 | |||
4265 | size = num_wraps ? capacity : next_entry; | ||
4266 | |||
4267 | /* bail out if nothing in log */ | ||
4268 | if (size == 0) { | ||
4269 | IWL_ERROR("Start IWL Event Log Dump: nothing in log\n"); | ||
4270 | iwl_release_nic_access(priv); | ||
4271 | return; | ||
4272 | } | ||
4273 | |||
4274 | IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n", | ||
4275 | size, num_wraps); | ||
4276 | |||
4277 | /* if uCode has wrapped back to top of log, start at the oldest entry, | ||
4278 | * i.e the next one that uCode would fill. */ | ||
4279 | if (num_wraps) | ||
4280 | iwl4965_print_event_log(priv, next_entry, | ||
4281 | capacity - next_entry, mode); | ||
4282 | |||
4283 | /* (then/else) start at top of log */ | ||
4284 | iwl4965_print_event_log(priv, 0, next_entry, mode); | ||
4285 | |||
4286 | iwl_release_nic_access(priv); | ||
4287 | } | ||
4288 | 1458 | ||
4289 | /** | 1459 | /** |
4290 | * iwl4965_irq_handle_error - called for HW or SW error interrupt from card | 1460 | * iwl4965_irq_handle_error - called for HW or SW error interrupt from card |
@@ -4298,10 +1468,10 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) | |||
4298 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 1468 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
4299 | 1469 | ||
4300 | #ifdef CONFIG_IWLWIFI_DEBUG | 1470 | #ifdef CONFIG_IWLWIFI_DEBUG |
4301 | if (iwl_debug_level & IWL_DL_FW_ERRORS) { | 1471 | if (priv->debug_level & IWL_DL_FW_ERRORS) { |
4302 | iwl4965_dump_nic_error_log(priv); | 1472 | iwl_dump_nic_error_log(priv); |
4303 | iwl4965_dump_nic_event_log(priv); | 1473 | iwl_dump_nic_event_log(priv); |
4304 | iwl4965_print_rx_config_cmd(&priv->staging_rxon); | 1474 | iwl4965_print_rx_config_cmd(priv); |
4305 | } | 1475 | } |
4306 | #endif | 1476 | #endif |
4307 | 1477 | ||
@@ -4312,7 +1482,7 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) | |||
4312 | clear_bit(STATUS_READY, &priv->status); | 1482 | clear_bit(STATUS_READY, &priv->status); |
4313 | 1483 | ||
4314 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 1484 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
4315 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS, | 1485 | IWL_DEBUG(IWL_DL_FW_ERRORS, |
4316 | "Restarting adapter due to uCode error.\n"); | 1486 | "Restarting adapter due to uCode error.\n"); |
4317 | 1487 | ||
4318 | if (iwl_is_associated(priv)) { | 1488 | if (iwl_is_associated(priv)) { |
@@ -4320,7 +1490,8 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) | |||
4320 | sizeof(priv->recovery_rxon)); | 1490 | sizeof(priv->recovery_rxon)); |
4321 | priv->error_recovering = 1; | 1491 | priv->error_recovering = 1; |
4322 | } | 1492 | } |
4323 | queue_work(priv->workqueue, &priv->restart); | 1493 | if (priv->cfg->mod_params->restart_fw) |
1494 | queue_work(priv->workqueue, &priv->restart); | ||
4324 | } | 1495 | } |
4325 | } | 1496 | } |
4326 | 1497 | ||
@@ -4333,7 +1504,7 @@ static void iwl4965_error_recovery(struct iwl_priv *priv) | |||
4333 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 1504 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
4334 | iwl4965_commit_rxon(priv); | 1505 | iwl4965_commit_rxon(priv); |
4335 | 1506 | ||
4336 | iwl4965_rxon_add_station(priv, priv->bssid, 1); | 1507 | iwl_rxon_add_station(priv, priv->bssid, 1); |
4337 | 1508 | ||
4338 | spin_lock_irqsave(&priv->lock, flags); | 1509 | spin_lock_irqsave(&priv->lock, flags); |
4339 | priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); | 1510 | priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); |
@@ -4365,7 +1536,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4365 | iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); | 1536 | iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); |
4366 | 1537 | ||
4367 | #ifdef CONFIG_IWLWIFI_DEBUG | 1538 | #ifdef CONFIG_IWLWIFI_DEBUG |
4368 | if (iwl_debug_level & IWL_DL_ISR) { | 1539 | if (priv->debug_level & IWL_DL_ISR) { |
4369 | /* just for debug */ | 1540 | /* just for debug */ |
4370 | inta_mask = iwl_read32(priv, CSR_INT_MASK); | 1541 | inta_mask = iwl_read32(priv, CSR_INT_MASK); |
4371 | IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", | 1542 | IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", |
@@ -4399,7 +1570,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4399 | } | 1570 | } |
4400 | 1571 | ||
4401 | #ifdef CONFIG_IWLWIFI_DEBUG | 1572 | #ifdef CONFIG_IWLWIFI_DEBUG |
4402 | if (iwl_debug_level & (IWL_DL_ISR)) { | 1573 | if (priv->debug_level & (IWL_DL_ISR)) { |
4403 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 1574 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
4404 | if (inta & CSR_INT_BIT_SCD) | 1575 | if (inta & CSR_INT_BIT_SCD) |
4405 | IWL_DEBUG_ISR("Scheduler finished to transmit " | 1576 | IWL_DEBUG_ISR("Scheduler finished to transmit " |
@@ -4420,18 +1591,15 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4420 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 1591 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) |
4421 | hw_rf_kill = 1; | 1592 | hw_rf_kill = 1; |
4422 | 1593 | ||
4423 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL | IWL_DL_ISR, | 1594 | IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n", |
4424 | "RF_KILL bit toggled to %s.\n", | ||
4425 | hw_rf_kill ? "disable radio":"enable radio"); | 1595 | hw_rf_kill ? "disable radio":"enable radio"); |
4426 | 1596 | ||
4427 | /* Queue restart only if RF_KILL switch was set to "kill" | 1597 | /* driver only loads ucode once setting the interface up. |
4428 | * when we loaded driver, and is now set to "enable". | 1598 | * the driver as well won't allow loading if RFKILL is set |
4429 | * After we're Alive, RF_KILL gets handled by | 1599 | * therefore no need to restart the driver from this handler |
4430 | * iwl4965_rx_card_state_notif() */ | 1600 | */ |
4431 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 1601 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) |
4432 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1602 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
4433 | queue_work(priv->workqueue, &priv->restart); | ||
4434 | } | ||
4435 | 1603 | ||
4436 | handled |= CSR_INT_BIT_RF_KILL; | 1604 | handled |= CSR_INT_BIT_RF_KILL; |
4437 | } | 1605 | } |
@@ -4453,13 +1621,13 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4453 | /* uCode wakes up after power-down sleep */ | 1621 | /* uCode wakes up after power-down sleep */ |
4454 | if (inta & CSR_INT_BIT_WAKEUP) { | 1622 | if (inta & CSR_INT_BIT_WAKEUP) { |
4455 | IWL_DEBUG_ISR("Wakeup interrupt\n"); | 1623 | IWL_DEBUG_ISR("Wakeup interrupt\n"); |
4456 | iwl4965_rx_queue_update_write_ptr(priv, &priv->rxq); | 1624 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); |
4457 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[0]); | 1625 | iwl_txq_update_write_ptr(priv, &priv->txq[0]); |
4458 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[1]); | 1626 | iwl_txq_update_write_ptr(priv, &priv->txq[1]); |
4459 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[2]); | 1627 | iwl_txq_update_write_ptr(priv, &priv->txq[2]); |
4460 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[3]); | 1628 | iwl_txq_update_write_ptr(priv, &priv->txq[3]); |
4461 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[4]); | 1629 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); |
4462 | iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[5]); | 1630 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); |
4463 | 1631 | ||
4464 | handled |= CSR_INT_BIT_WAKEUP; | 1632 | handled |= CSR_INT_BIT_WAKEUP; |
4465 | } | 1633 | } |
@@ -4468,13 +1636,16 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4468 | * Rx "responses" (frame-received notification), and other | 1636 | * Rx "responses" (frame-received notification), and other |
4469 | * notifications from uCode come through here*/ | 1637 | * notifications from uCode come through here*/ |
4470 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 1638 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
4471 | iwl4965_rx_handle(priv); | 1639 | iwl_rx_handle(priv); |
4472 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 1640 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
4473 | } | 1641 | } |
4474 | 1642 | ||
4475 | if (inta & CSR_INT_BIT_FH_TX) { | 1643 | if (inta & CSR_INT_BIT_FH_TX) { |
4476 | IWL_DEBUG_ISR("Tx interrupt\n"); | 1644 | IWL_DEBUG_ISR("Tx interrupt\n"); |
4477 | handled |= CSR_INT_BIT_FH_TX; | 1645 | handled |= CSR_INT_BIT_FH_TX; |
1646 | /* FH finished to write, send event */ | ||
1647 | priv->ucode_write_complete = 1; | ||
1648 | wake_up_interruptible(&priv->wait_command_queue); | ||
4478 | } | 1649 | } |
4479 | 1650 | ||
4480 | if (inta & ~handled) | 1651 | if (inta & ~handled) |
@@ -4492,7 +1663,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
4492 | iwl4965_enable_interrupts(priv); | 1663 | iwl4965_enable_interrupts(priv); |
4493 | 1664 | ||
4494 | #ifdef CONFIG_IWLWIFI_DEBUG | 1665 | #ifdef CONFIG_IWLWIFI_DEBUG |
4495 | if (iwl_debug_level & (IWL_DL_ISR)) { | 1666 | if (priv->debug_level & (IWL_DL_ISR)) { |
4496 | inta = iwl_read32(priv, CSR_INT); | 1667 | inta = iwl_read32(priv, CSR_INT); |
4497 | inta_mask = iwl_read32(priv, CSR_INT_MASK); | 1668 | inta_mask = iwl_read32(priv, CSR_INT_MASK); |
4498 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); | 1669 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); |
@@ -4561,297 +1732,6 @@ static irqreturn_t iwl4965_isr(int irq, void *data) | |||
4561 | return IRQ_NONE; | 1732 | return IRQ_NONE; |
4562 | } | 1733 | } |
4563 | 1734 | ||
4564 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | ||
4565 | * sending probe req. This should be set long enough to hear probe responses | ||
4566 | * from more than one AP. */ | ||
4567 | #define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ | ||
4568 | #define IWL_ACTIVE_DWELL_TIME_52 (10) | ||
4569 | |||
4570 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
4571 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
4572 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
4573 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
4574 | * no other traffic). | ||
4575 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
4576 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | ||
4577 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ | ||
4578 | |||
4579 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. | ||
4580 | * Must be set longer than active dwell time. | ||
4581 | * For the most reliable scan, set > AP beacon interval (typically 100msec). */ | ||
4582 | #define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ | ||
4583 | #define IWL_PASSIVE_DWELL_TIME_52 (10) | ||
4584 | #define IWL_PASSIVE_DWELL_BASE (100) | ||
4585 | #define IWL_CHANNEL_TUNE_TIME 5 | ||
4586 | |||
4587 | static inline u16 iwl4965_get_active_dwell_time(struct iwl_priv *priv, | ||
4588 | enum ieee80211_band band) | ||
4589 | { | ||
4590 | if (band == IEEE80211_BAND_5GHZ) | ||
4591 | return IWL_ACTIVE_DWELL_TIME_52; | ||
4592 | else | ||
4593 | return IWL_ACTIVE_DWELL_TIME_24; | ||
4594 | } | ||
4595 | |||
4596 | static u16 iwl4965_get_passive_dwell_time(struct iwl_priv *priv, | ||
4597 | enum ieee80211_band band) | ||
4598 | { | ||
4599 | u16 active = iwl4965_get_active_dwell_time(priv, band); | ||
4600 | u16 passive = (band != IEEE80211_BAND_5GHZ) ? | ||
4601 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | ||
4602 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | ||
4603 | |||
4604 | if (iwl_is_associated(priv)) { | ||
4605 | /* If we're associated, we clamp the maximum passive | ||
4606 | * dwell time to be 98% of the beacon interval (minus | ||
4607 | * 2 * channel tune time) */ | ||
4608 | passive = priv->beacon_int; | ||
4609 | if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) | ||
4610 | passive = IWL_PASSIVE_DWELL_BASE; | ||
4611 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | ||
4612 | } | ||
4613 | |||
4614 | if (passive <= active) | ||
4615 | passive = active + 1; | ||
4616 | |||
4617 | return passive; | ||
4618 | } | ||
4619 | |||
4620 | static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, | ||
4621 | enum ieee80211_band band, | ||
4622 | u8 is_active, u8 direct_mask, | ||
4623 | struct iwl4965_scan_channel *scan_ch) | ||
4624 | { | ||
4625 | const struct ieee80211_channel *channels = NULL; | ||
4626 | const struct ieee80211_supported_band *sband; | ||
4627 | const struct iwl_channel_info *ch_info; | ||
4628 | u16 passive_dwell = 0; | ||
4629 | u16 active_dwell = 0; | ||
4630 | int added, i; | ||
4631 | |||
4632 | sband = iwl4965_get_hw_mode(priv, band); | ||
4633 | if (!sband) | ||
4634 | return 0; | ||
4635 | |||
4636 | channels = sband->channels; | ||
4637 | |||
4638 | active_dwell = iwl4965_get_active_dwell_time(priv, band); | ||
4639 | passive_dwell = iwl4965_get_passive_dwell_time(priv, band); | ||
4640 | |||
4641 | for (i = 0, added = 0; i < sband->n_channels; i++) { | ||
4642 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) | ||
4643 | continue; | ||
4644 | |||
4645 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); | ||
4646 | |||
4647 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); | ||
4648 | if (!is_channel_valid(ch_info)) { | ||
4649 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", | ||
4650 | scan_ch->channel); | ||
4651 | continue; | ||
4652 | } | ||
4653 | |||
4654 | if (!is_active || is_channel_passive(ch_info) || | ||
4655 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) | ||
4656 | scan_ch->type = 0; /* passive */ | ||
4657 | else | ||
4658 | scan_ch->type = 1; /* active */ | ||
4659 | |||
4660 | if (scan_ch->type & 1) | ||
4661 | scan_ch->type |= (direct_mask << 1); | ||
4662 | |||
4663 | if (is_channel_narrow(ch_info)) | ||
4664 | scan_ch->type |= (1 << 7); | ||
4665 | |||
4666 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
4667 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
4668 | |||
4669 | /* Set txpower levels to defaults */ | ||
4670 | scan_ch->tpc.dsp_atten = 110; | ||
4671 | /* scan_pwr_info->tpc.dsp_atten; */ | ||
4672 | |||
4673 | /*scan_pwr_info->tpc.tx_gain; */ | ||
4674 | if (band == IEEE80211_BAND_5GHZ) | ||
4675 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
4676 | else { | ||
4677 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | ||
4678 | /* NOTE: if we were doing 6Mb OFDM for scans we'd use | ||
4679 | * power level: | ||
4680 | * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3; | ||
4681 | */ | ||
4682 | } | ||
4683 | |||
4684 | IWL_DEBUG_SCAN("Scanning %d [%s %d]\n", | ||
4685 | scan_ch->channel, | ||
4686 | (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", | ||
4687 | (scan_ch->type & 1) ? | ||
4688 | active_dwell : passive_dwell); | ||
4689 | |||
4690 | scan_ch++; | ||
4691 | added++; | ||
4692 | } | ||
4693 | |||
4694 | IWL_DEBUG_SCAN("total channels to scan %d \n", added); | ||
4695 | return added; | ||
4696 | } | ||
4697 | |||
4698 | static void iwl4965_init_hw_rates(struct iwl_priv *priv, | ||
4699 | struct ieee80211_rate *rates) | ||
4700 | { | ||
4701 | int i; | ||
4702 | |||
4703 | for (i = 0; i < IWL_RATE_COUNT; i++) { | ||
4704 | rates[i].bitrate = iwl4965_rates[i].ieee * 5; | ||
4705 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | ||
4706 | rates[i].hw_value_short = i; | ||
4707 | rates[i].flags = 0; | ||
4708 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { | ||
4709 | /* | ||
4710 | * If CCK != 1M then set short preamble rate flag. | ||
4711 | */ | ||
4712 | rates[i].flags |= | ||
4713 | (iwl4965_rates[i].plcp == IWL_RATE_1M_PLCP) ? | ||
4714 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; | ||
4715 | } | ||
4716 | } | ||
4717 | } | ||
4718 | |||
4719 | /** | ||
4720 | * iwl4965_init_geos - Initialize mac80211's geo/channel info based from eeprom | ||
4721 | */ | ||
4722 | int iwl4965_init_geos(struct iwl_priv *priv) | ||
4723 | { | ||
4724 | struct iwl_channel_info *ch; | ||
4725 | struct ieee80211_supported_band *sband; | ||
4726 | struct ieee80211_channel *channels; | ||
4727 | struct ieee80211_channel *geo_ch; | ||
4728 | struct ieee80211_rate *rates; | ||
4729 | int i = 0; | ||
4730 | |||
4731 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||
4732 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
4733 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | ||
4734 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4735 | return 0; | ||
4736 | } | ||
4737 | |||
4738 | channels = kzalloc(sizeof(struct ieee80211_channel) * | ||
4739 | priv->channel_count, GFP_KERNEL); | ||
4740 | if (!channels) | ||
4741 | return -ENOMEM; | ||
4742 | |||
4743 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)), | ||
4744 | GFP_KERNEL); | ||
4745 | if (!rates) { | ||
4746 | kfree(channels); | ||
4747 | return -ENOMEM; | ||
4748 | } | ||
4749 | |||
4750 | /* 5.2GHz channels start after the 2.4GHz channels */ | ||
4751 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4752 | sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; | ||
4753 | /* just OFDM */ | ||
4754 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | ||
4755 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; | ||
4756 | |||
4757 | iwl4965_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_5GHZ); | ||
4758 | |||
4759 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4760 | sband->channels = channels; | ||
4761 | /* OFDM & CCK */ | ||
4762 | sband->bitrates = rates; | ||
4763 | sband->n_bitrates = IWL_RATE_COUNT; | ||
4764 | |||
4765 | iwl4965_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_2GHZ); | ||
4766 | |||
4767 | priv->ieee_channels = channels; | ||
4768 | priv->ieee_rates = rates; | ||
4769 | |||
4770 | iwl4965_init_hw_rates(priv, rates); | ||
4771 | |||
4772 | for (i = 0; i < priv->channel_count; i++) { | ||
4773 | ch = &priv->channel_info[i]; | ||
4774 | |||
4775 | /* FIXME: might be removed if scan is OK */ | ||
4776 | if (!is_channel_valid(ch)) | ||
4777 | continue; | ||
4778 | |||
4779 | if (is_channel_a_band(ch)) | ||
4780 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4781 | else | ||
4782 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4783 | |||
4784 | geo_ch = &sband->channels[sband->n_channels++]; | ||
4785 | |||
4786 | geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel); | ||
4787 | geo_ch->max_power = ch->max_power_avg; | ||
4788 | geo_ch->max_antenna_gain = 0xff; | ||
4789 | geo_ch->hw_value = ch->channel; | ||
4790 | |||
4791 | if (is_channel_valid(ch)) { | ||
4792 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) | ||
4793 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; | ||
4794 | |||
4795 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
4796 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
4797 | |||
4798 | if (ch->flags & EEPROM_CHANNEL_RADAR) | ||
4799 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | ||
4800 | |||
4801 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | ||
4802 | priv->max_channel_txpower_limit = | ||
4803 | ch->max_power_avg; | ||
4804 | } else { | ||
4805 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
4806 | } | ||
4807 | |||
4808 | /* Save flags for reg domain usage */ | ||
4809 | geo_ch->orig_flags = geo_ch->flags; | ||
4810 | |||
4811 | IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n", | ||
4812 | ch->channel, geo_ch->center_freq, | ||
4813 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
4814 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
4815 | "restricted" : "valid", | ||
4816 | geo_ch->flags); | ||
4817 | } | ||
4818 | |||
4819 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||
4820 | priv->cfg->sku & IWL_SKU_A) { | ||
4821 | printk(KERN_INFO DRV_NAME | ||
4822 | ": Incorrectly detected BG card as ABG. Please send " | ||
4823 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | ||
4824 | priv->pci_dev->device, priv->pci_dev->subsystem_device); | ||
4825 | priv->cfg->sku &= ~IWL_SKU_A; | ||
4826 | } | ||
4827 | |||
4828 | printk(KERN_INFO DRV_NAME | ||
4829 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | ||
4830 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | ||
4831 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
4832 | |||
4833 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
4834 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
4835 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4836 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
4837 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
4838 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4839 | |||
4840 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4841 | |||
4842 | return 0; | ||
4843 | } | ||
4844 | |||
4845 | /* | ||
4846 | * iwl4965_free_geos - undo allocations in iwl4965_init_geos | ||
4847 | */ | ||
4848 | void iwl4965_free_geos(struct iwl_priv *priv) | ||
4849 | { | ||
4850 | kfree(priv->ieee_channels); | ||
4851 | kfree(priv->ieee_rates); | ||
4852 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4853 | } | ||
4854 | |||
4855 | /****************************************************************************** | 1735 | /****************************************************************************** |
4856 | * | 1736 | * |
4857 | * uCode download functions | 1737 | * uCode download functions |
@@ -4868,146 +1748,6 @@ static void iwl4965_dealloc_ucode_pci(struct iwl_priv *priv) | |||
4868 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); | 1748 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot); |
4869 | } | 1749 | } |
4870 | 1750 | ||
4871 | /** | ||
4872 | * iwl4965_verify_inst_full - verify runtime uCode image in card vs. host, | ||
4873 | * looking at all data. | ||
4874 | */ | ||
4875 | static int iwl4965_verify_inst_full(struct iwl_priv *priv, __le32 *image, | ||
4876 | u32 len) | ||
4877 | { | ||
4878 | u32 val; | ||
4879 | u32 save_len = len; | ||
4880 | int rc = 0; | ||
4881 | u32 errcnt; | ||
4882 | |||
4883 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | ||
4884 | |||
4885 | rc = iwl_grab_nic_access(priv); | ||
4886 | if (rc) | ||
4887 | return rc; | ||
4888 | |||
4889 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); | ||
4890 | |||
4891 | errcnt = 0; | ||
4892 | for (; len > 0; len -= sizeof(u32), image++) { | ||
4893 | /* read data comes through single port, auto-incr addr */ | ||
4894 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
4895 | * if IWL_DL_IO is set */ | ||
4896 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
4897 | if (val != le32_to_cpu(*image)) { | ||
4898 | IWL_ERROR("uCode INST section is invalid at " | ||
4899 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | ||
4900 | save_len - len, val, le32_to_cpu(*image)); | ||
4901 | rc = -EIO; | ||
4902 | errcnt++; | ||
4903 | if (errcnt >= 20) | ||
4904 | break; | ||
4905 | } | ||
4906 | } | ||
4907 | |||
4908 | iwl_release_nic_access(priv); | ||
4909 | |||
4910 | if (!errcnt) | ||
4911 | IWL_DEBUG_INFO | ||
4912 | ("ucode image in INSTRUCTION memory is good\n"); | ||
4913 | |||
4914 | return rc; | ||
4915 | } | ||
4916 | |||
4917 | |||
4918 | /** | ||
4919 | * iwl4965_verify_inst_sparse - verify runtime uCode image in card vs. host, | ||
4920 | * using sample data 100 bytes apart. If these sample points are good, | ||
4921 | * it's a pretty good bet that everything between them is good, too. | ||
4922 | */ | ||
4923 | static int iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) | ||
4924 | { | ||
4925 | u32 val; | ||
4926 | int rc = 0; | ||
4927 | u32 errcnt = 0; | ||
4928 | u32 i; | ||
4929 | |||
4930 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | ||
4931 | |||
4932 | rc = iwl_grab_nic_access(priv); | ||
4933 | if (rc) | ||
4934 | return rc; | ||
4935 | |||
4936 | for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { | ||
4937 | /* read data comes through single port, auto-incr addr */ | ||
4938 | /* NOTE: Use the debugless read so we don't flood kernel log | ||
4939 | * if IWL_DL_IO is set */ | ||
4940 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | ||
4941 | i + RTC_INST_LOWER_BOUND); | ||
4942 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
4943 | if (val != le32_to_cpu(*image)) { | ||
4944 | #if 0 /* Enable this if you want to see details */ | ||
4945 | IWL_ERROR("uCode INST section is invalid at " | ||
4946 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | ||
4947 | i, val, *image); | ||
4948 | #endif | ||
4949 | rc = -EIO; | ||
4950 | errcnt++; | ||
4951 | if (errcnt >= 3) | ||
4952 | break; | ||
4953 | } | ||
4954 | } | ||
4955 | |||
4956 | iwl_release_nic_access(priv); | ||
4957 | |||
4958 | return rc; | ||
4959 | } | ||
4960 | |||
4961 | |||
4962 | /** | ||
4963 | * iwl4965_verify_ucode - determine which instruction image is in SRAM, | ||
4964 | * and verify its contents | ||
4965 | */ | ||
4966 | static int iwl4965_verify_ucode(struct iwl_priv *priv) | ||
4967 | { | ||
4968 | __le32 *image; | ||
4969 | u32 len; | ||
4970 | int rc = 0; | ||
4971 | |||
4972 | /* Try bootstrap */ | ||
4973 | image = (__le32 *)priv->ucode_boot.v_addr; | ||
4974 | len = priv->ucode_boot.len; | ||
4975 | rc = iwl4965_verify_inst_sparse(priv, image, len); | ||
4976 | if (rc == 0) { | ||
4977 | IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n"); | ||
4978 | return 0; | ||
4979 | } | ||
4980 | |||
4981 | /* Try initialize */ | ||
4982 | image = (__le32 *)priv->ucode_init.v_addr; | ||
4983 | len = priv->ucode_init.len; | ||
4984 | rc = iwl4965_verify_inst_sparse(priv, image, len); | ||
4985 | if (rc == 0) { | ||
4986 | IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n"); | ||
4987 | return 0; | ||
4988 | } | ||
4989 | |||
4990 | /* Try runtime/protocol */ | ||
4991 | image = (__le32 *)priv->ucode_code.v_addr; | ||
4992 | len = priv->ucode_code.len; | ||
4993 | rc = iwl4965_verify_inst_sparse(priv, image, len); | ||
4994 | if (rc == 0) { | ||
4995 | IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n"); | ||
4996 | return 0; | ||
4997 | } | ||
4998 | |||
4999 | IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); | ||
5000 | |||
5001 | /* Since nothing seems to match, show first several data entries in | ||
5002 | * instruction SRAM, so maybe visual inspection will give a clue. | ||
5003 | * Selection of bootstrap image (vs. other images) is arbitrary. */ | ||
5004 | image = (__le32 *)priv->ucode_boot.v_addr; | ||
5005 | len = priv->ucode_boot.len; | ||
5006 | rc = iwl4965_verify_inst_full(priv, image, len); | ||
5007 | |||
5008 | return rc; | ||
5009 | } | ||
5010 | |||
5011 | static void iwl4965_nic_start(struct iwl_priv *priv) | 1751 | static void iwl4965_nic_start(struct iwl_priv *priv) |
5012 | { | 1752 | { |
5013 | /* Remove all resets to allow NIC to operate */ | 1753 | /* Remove all resets to allow NIC to operate */ |
@@ -5022,7 +1762,7 @@ static void iwl4965_nic_start(struct iwl_priv *priv) | |||
5022 | */ | 1762 | */ |
5023 | static int iwl4965_read_ucode(struct iwl_priv *priv) | 1763 | static int iwl4965_read_ucode(struct iwl_priv *priv) |
5024 | { | 1764 | { |
5025 | struct iwl4965_ucode *ucode; | 1765 | struct iwl_ucode *ucode; |
5026 | int ret; | 1766 | int ret; |
5027 | const struct firmware *ucode_raw; | 1767 | const struct firmware *ucode_raw; |
5028 | const char *name = priv->cfg->fw_name; | 1768 | const char *name = priv->cfg->fw_name; |
@@ -5083,34 +1823,34 @@ static int iwl4965_read_ucode(struct iwl_priv *priv) | |||
5083 | } | 1823 | } |
5084 | 1824 | ||
5085 | /* Verify that uCode images will fit in card's SRAM */ | 1825 | /* Verify that uCode images will fit in card's SRAM */ |
5086 | if (inst_size > IWL_MAX_INST_SIZE) { | 1826 | if (inst_size > priv->hw_params.max_inst_size) { |
5087 | IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n", | 1827 | IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n", |
5088 | inst_size); | 1828 | inst_size); |
5089 | ret = -EINVAL; | 1829 | ret = -EINVAL; |
5090 | goto err_release; | 1830 | goto err_release; |
5091 | } | 1831 | } |
5092 | 1832 | ||
5093 | if (data_size > IWL_MAX_DATA_SIZE) { | 1833 | if (data_size > priv->hw_params.max_data_size) { |
5094 | IWL_DEBUG_INFO("uCode data len %d too large to fit in\n", | 1834 | IWL_DEBUG_INFO("uCode data len %d too large to fit in\n", |
5095 | data_size); | 1835 | data_size); |
5096 | ret = -EINVAL; | 1836 | ret = -EINVAL; |
5097 | goto err_release; | 1837 | goto err_release; |
5098 | } | 1838 | } |
5099 | if (init_size > IWL_MAX_INST_SIZE) { | 1839 | if (init_size > priv->hw_params.max_inst_size) { |
5100 | IWL_DEBUG_INFO | 1840 | IWL_DEBUG_INFO |
5101 | ("uCode init instr len %d too large to fit in\n", | 1841 | ("uCode init instr len %d too large to fit in\n", |
5102 | init_size); | 1842 | init_size); |
5103 | ret = -EINVAL; | 1843 | ret = -EINVAL; |
5104 | goto err_release; | 1844 | goto err_release; |
5105 | } | 1845 | } |
5106 | if (init_data_size > IWL_MAX_DATA_SIZE) { | 1846 | if (init_data_size > priv->hw_params.max_data_size) { |
5107 | IWL_DEBUG_INFO | 1847 | IWL_DEBUG_INFO |
5108 | ("uCode init data len %d too large to fit in\n", | 1848 | ("uCode init data len %d too large to fit in\n", |
5109 | init_data_size); | 1849 | init_data_size); |
5110 | ret = -EINVAL; | 1850 | ret = -EINVAL; |
5111 | goto err_release; | 1851 | goto err_release; |
5112 | } | 1852 | } |
5113 | if (boot_size > IWL_MAX_BSM_SIZE) { | 1853 | if (boot_size > priv->hw_params.max_bsm_size) { |
5114 | IWL_DEBUG_INFO | 1854 | IWL_DEBUG_INFO |
5115 | ("uCode boot instr len %d too large to fit in\n", | 1855 | ("uCode boot instr len %d too large to fit in\n", |
5116 | boot_size); | 1856 | boot_size); |
@@ -5211,111 +1951,12 @@ static int iwl4965_read_ucode(struct iwl_priv *priv) | |||
5211 | return ret; | 1951 | return ret; |
5212 | } | 1952 | } |
5213 | 1953 | ||
5214 | |||
5215 | /** | ||
5216 | * iwl4965_set_ucode_ptrs - Set uCode address location | ||
5217 | * | ||
5218 | * Tell initialization uCode where to find runtime uCode. | ||
5219 | * | ||
5220 | * BSM registers initially contain pointers to initialization uCode. | ||
5221 | * We need to replace them to load runtime uCode inst and data, | ||
5222 | * and to save runtime data when powering down. | ||
5223 | */ | ||
5224 | static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) | ||
5225 | { | ||
5226 | dma_addr_t pinst; | ||
5227 | dma_addr_t pdata; | ||
5228 | int rc = 0; | ||
5229 | unsigned long flags; | ||
5230 | |||
5231 | /* bits 35:4 for 4965 */ | ||
5232 | pinst = priv->ucode_code.p_addr >> 4; | ||
5233 | pdata = priv->ucode_data_backup.p_addr >> 4; | ||
5234 | |||
5235 | spin_lock_irqsave(&priv->lock, flags); | ||
5236 | rc = iwl_grab_nic_access(priv); | ||
5237 | if (rc) { | ||
5238 | spin_unlock_irqrestore(&priv->lock, flags); | ||
5239 | return rc; | ||
5240 | } | ||
5241 | |||
5242 | /* Tell bootstrap uCode where to find image to load */ | ||
5243 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
5244 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
5245 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, | ||
5246 | priv->ucode_data.len); | ||
5247 | |||
5248 | /* Inst bytecount must be last to set up, bit 31 signals uCode | ||
5249 | * that all new ptr/size info is in place */ | ||
5250 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, | ||
5251 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); | ||
5252 | |||
5253 | iwl_release_nic_access(priv); | ||
5254 | |||
5255 | spin_unlock_irqrestore(&priv->lock, flags); | ||
5256 | |||
5257 | IWL_DEBUG_INFO("Runtime uCode pointers are set.\n"); | ||
5258 | |||
5259 | return rc; | ||
5260 | } | ||
5261 | |||
5262 | /** | ||
5263 | * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received | ||
5264 | * | ||
5265 | * Called after REPLY_ALIVE notification received from "initialize" uCode. | ||
5266 | * | ||
5267 | * The 4965 "initialize" ALIVE reply contains calibration data for: | ||
5268 | * Voltage, temperature, and MIMO tx gain correction, now stored in priv | ||
5269 | * (3945 does not contain this data). | ||
5270 | * | ||
5271 | * Tell "initialize" uCode to go ahead and load the runtime uCode. | ||
5272 | */ | ||
5273 | static void iwl4965_init_alive_start(struct iwl_priv *priv) | ||
5274 | { | ||
5275 | /* Check alive response for "valid" sign from uCode */ | ||
5276 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | ||
5277 | /* We had an error bringing up the hardware, so take it | ||
5278 | * all the way back down so we can try again */ | ||
5279 | IWL_DEBUG_INFO("Initialize Alive failed.\n"); | ||
5280 | goto restart; | ||
5281 | } | ||
5282 | |||
5283 | /* Bootstrap uCode has loaded initialize uCode ... verify inst image. | ||
5284 | * This is a paranoid check, because we would not have gotten the | ||
5285 | * "initialize" alive if code weren't properly loaded. */ | ||
5286 | if (iwl4965_verify_ucode(priv)) { | ||
5287 | /* Runtime instruction load was bad; | ||
5288 | * take it all the way back down so we can try again */ | ||
5289 | IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); | ||
5290 | goto restart; | ||
5291 | } | ||
5292 | |||
5293 | /* Calculate temperature */ | ||
5294 | priv->temperature = iwl4965_get_temperature(priv); | ||
5295 | |||
5296 | /* Send pointers to protocol/runtime uCode image ... init code will | ||
5297 | * load and launch runtime uCode, which will send us another "Alive" | ||
5298 | * notification. */ | ||
5299 | IWL_DEBUG_INFO("Initialization Alive received.\n"); | ||
5300 | if (iwl4965_set_ucode_ptrs(priv)) { | ||
5301 | /* Runtime instruction load won't happen; | ||
5302 | * take it all the way back down so we can try again */ | ||
5303 | IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); | ||
5304 | goto restart; | ||
5305 | } | ||
5306 | return; | ||
5307 | |||
5308 | restart: | ||
5309 | queue_work(priv->workqueue, &priv->restart); | ||
5310 | } | ||
5311 | |||
5312 | |||
5313 | /** | 1954 | /** |
5314 | * iwl4965_alive_start - called after REPLY_ALIVE notification received | 1955 | * iwl_alive_start - called after REPLY_ALIVE notification received |
5315 | * from protocol/runtime uCode (initialization uCode's | 1956 | * from protocol/runtime uCode (initialization uCode's |
5316 | * Alive gets handled by iwl4965_init_alive_start()). | 1957 | * Alive gets handled by iwl_init_alive_start()). |
5317 | */ | 1958 | */ |
5318 | static void iwl4965_alive_start(struct iwl_priv *priv) | 1959 | static void iwl_alive_start(struct iwl_priv *priv) |
5319 | { | 1960 | { |
5320 | int ret = 0; | 1961 | int ret = 0; |
5321 | 1962 | ||
@@ -5331,15 +1972,14 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
5331 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. | 1972 | /* Initialize uCode has loaded Runtime uCode ... verify inst image. |
5332 | * This is a paranoid check, because we would not have gotten the | 1973 | * This is a paranoid check, because we would not have gotten the |
5333 | * "runtime" alive if code weren't properly loaded. */ | 1974 | * "runtime" alive if code weren't properly loaded. */ |
5334 | if (iwl4965_verify_ucode(priv)) { | 1975 | if (iwl_verify_ucode(priv)) { |
5335 | /* Runtime instruction load was bad; | 1976 | /* Runtime instruction load was bad; |
5336 | * take it all the way back down so we can try again */ | 1977 | * take it all the way back down so we can try again */ |
5337 | IWL_DEBUG_INFO("Bad runtime uCode load.\n"); | 1978 | IWL_DEBUG_INFO("Bad runtime uCode load.\n"); |
5338 | goto restart; | 1979 | goto restart; |
5339 | } | 1980 | } |
5340 | 1981 | ||
5341 | iwlcore_clear_stations_table(priv); | 1982 | iwl_clear_stations_table(priv); |
5342 | |||
5343 | ret = priv->cfg->ops->lib->alive_notify(priv); | 1983 | ret = priv->cfg->ops->lib->alive_notify(priv); |
5344 | if (ret) { | 1984 | if (ret) { |
5345 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", | 1985 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", |
@@ -5350,22 +1990,17 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
5350 | /* After the ALIVE response, we can send host commands to 4965 uCode */ | 1990 | /* After the ALIVE response, we can send host commands to 4965 uCode */ |
5351 | set_bit(STATUS_ALIVE, &priv->status); | 1991 | set_bit(STATUS_ALIVE, &priv->status); |
5352 | 1992 | ||
5353 | /* Clear out the uCode error bit if it is set */ | ||
5354 | clear_bit(STATUS_FW_ERROR, &priv->status); | ||
5355 | |||
5356 | if (iwl_is_rfkill(priv)) | 1993 | if (iwl_is_rfkill(priv)) |
5357 | return; | 1994 | return; |
5358 | 1995 | ||
5359 | ieee80211_start_queues(priv->hw); | 1996 | ieee80211_wake_queues(priv->hw); |
5360 | 1997 | ||
5361 | priv->active_rate = priv->rates_mask; | 1998 | priv->active_rate = priv->rates_mask; |
5362 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | 1999 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; |
5363 | 2000 | ||
5364 | iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode)); | ||
5365 | |||
5366 | if (iwl_is_associated(priv)) { | 2001 | if (iwl_is_associated(priv)) { |
5367 | struct iwl4965_rxon_cmd *active_rxon = | 2002 | struct iwl_rxon_cmd *active_rxon = |
5368 | (struct iwl4965_rxon_cmd *)(&priv->active_rxon); | 2003 | (struct iwl_rxon_cmd *)&priv->active_rxon; |
5369 | 2004 | ||
5370 | memcpy(&priv->staging_rxon, &priv->active_rxon, | 2005 | memcpy(&priv->staging_rxon, &priv->active_rxon, |
5371 | sizeof(priv->staging_rxon)); | 2006 | sizeof(priv->staging_rxon)); |
@@ -5379,13 +2014,13 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
5379 | /* Configure Bluetooth device coexistence support */ | 2014 | /* Configure Bluetooth device coexistence support */ |
5380 | iwl4965_send_bt_config(priv); | 2015 | iwl4965_send_bt_config(priv); |
5381 | 2016 | ||
2017 | iwl_reset_run_time_calib(priv); | ||
2018 | |||
5382 | /* Configure the adapter for unassociated operation */ | 2019 | /* Configure the adapter for unassociated operation */ |
5383 | iwl4965_commit_rxon(priv); | 2020 | iwl4965_commit_rxon(priv); |
5384 | 2021 | ||
5385 | /* At this point, the NIC is initialized and operational */ | 2022 | /* At this point, the NIC is initialized and operational */ |
5386 | priv->notif_missed_beacons = 0; | 2023 | iwl_rf_kill_ct_config(priv); |
5387 | |||
5388 | iwl4965_rf_kill_ct_config(priv); | ||
5389 | 2024 | ||
5390 | iwl_leds_register(priv); | 2025 | iwl_leds_register(priv); |
5391 | 2026 | ||
@@ -5396,34 +2031,33 @@ static void iwl4965_alive_start(struct iwl_priv *priv) | |||
5396 | if (priv->error_recovering) | 2031 | if (priv->error_recovering) |
5397 | iwl4965_error_recovery(priv); | 2032 | iwl4965_error_recovery(priv); |
5398 | 2033 | ||
5399 | iwlcore_low_level_notify(priv, IWLCORE_START_EVT); | 2034 | iwl_power_update_mode(priv, 1); |
5400 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | 2035 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); |
2036 | |||
2037 | if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) | ||
2038 | iwl4965_set_mode(priv, priv->iw_mode); | ||
2039 | |||
5401 | return; | 2040 | return; |
5402 | 2041 | ||
5403 | restart: | 2042 | restart: |
5404 | queue_work(priv->workqueue, &priv->restart); | 2043 | queue_work(priv->workqueue, &priv->restart); |
5405 | } | 2044 | } |
5406 | 2045 | ||
5407 | static void iwl4965_cancel_deferred_work(struct iwl_priv *priv); | 2046 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); |
5408 | 2047 | ||
5409 | static void __iwl4965_down(struct iwl_priv *priv) | 2048 | static void __iwl4965_down(struct iwl_priv *priv) |
5410 | { | 2049 | { |
5411 | unsigned long flags; | 2050 | unsigned long flags; |
5412 | int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); | 2051 | int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); |
5413 | struct ieee80211_conf *conf = NULL; | ||
5414 | 2052 | ||
5415 | IWL_DEBUG_INFO(DRV_NAME " is going down\n"); | 2053 | IWL_DEBUG_INFO(DRV_NAME " is going down\n"); |
5416 | 2054 | ||
5417 | conf = ieee80211_get_hw_conf(priv->hw); | ||
5418 | |||
5419 | if (!exit_pending) | 2055 | if (!exit_pending) |
5420 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2056 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
5421 | 2057 | ||
5422 | iwl_leds_unregister(priv); | 2058 | iwl_leds_unregister(priv); |
5423 | 2059 | ||
5424 | iwlcore_low_level_notify(priv, IWLCORE_STOP_EVT); | 2060 | iwl_clear_stations_table(priv); |
5425 | |||
5426 | iwlcore_clear_stations_table(priv); | ||
5427 | 2061 | ||
5428 | /* Unblock any waiting calls */ | 2062 | /* Unblock any waiting calls */ |
5429 | wake_up_interruptible_all(&priv->wait_command_queue); | 2063 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -5455,7 +2089,9 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
5455 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2089 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
5456 | STATUS_GEO_CONFIGURED | | 2090 | STATUS_GEO_CONFIGURED | |
5457 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 2091 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5458 | STATUS_IN_SUSPEND; | 2092 | STATUS_IN_SUSPEND | |
2093 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
2094 | STATUS_EXIT_PENDING; | ||
5459 | goto exit; | 2095 | goto exit; |
5460 | } | 2096 | } |
5461 | 2097 | ||
@@ -5470,15 +2106,17 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
5470 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 2106 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5471 | STATUS_IN_SUSPEND | | 2107 | STATUS_IN_SUSPEND | |
5472 | test_bit(STATUS_FW_ERROR, &priv->status) << | 2108 | test_bit(STATUS_FW_ERROR, &priv->status) << |
5473 | STATUS_FW_ERROR; | 2109 | STATUS_FW_ERROR | |
2110 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
2111 | STATUS_EXIT_PENDING; | ||
5474 | 2112 | ||
5475 | spin_lock_irqsave(&priv->lock, flags); | 2113 | spin_lock_irqsave(&priv->lock, flags); |
5476 | iwl_clear_bit(priv, CSR_GP_CNTRL, | 2114 | iwl_clear_bit(priv, CSR_GP_CNTRL, |
5477 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 2115 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
5478 | spin_unlock_irqrestore(&priv->lock, flags); | 2116 | spin_unlock_irqrestore(&priv->lock, flags); |
5479 | 2117 | ||
5480 | iwl4965_hw_txq_ctx_stop(priv); | 2118 | iwl_txq_ctx_stop(priv); |
5481 | iwl4965_hw_rxq_stop(priv); | 2119 | iwl_rxq_stop(priv); |
5482 | 2120 | ||
5483 | spin_lock_irqsave(&priv->lock, flags); | 2121 | spin_lock_irqsave(&priv->lock, flags); |
5484 | if (!iwl_grab_nic_access(priv)) { | 2122 | if (!iwl_grab_nic_access(priv)) { |
@@ -5490,19 +2128,19 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
5490 | 2128 | ||
5491 | udelay(5); | 2129 | udelay(5); |
5492 | 2130 | ||
5493 | iwl4965_hw_nic_stop_master(priv); | 2131 | /* FIXME: apm_ops.suspend(priv) */ |
5494 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | 2132 | priv->cfg->ops->lib->apm_ops.reset(priv); |
5495 | iwl4965_hw_nic_reset(priv); | 2133 | priv->cfg->ops->lib->free_shared_mem(priv); |
5496 | 2134 | ||
5497 | exit: | 2135 | exit: |
5498 | memset(&priv->card_alive, 0, sizeof(struct iwl4965_alive_resp)); | 2136 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); |
5499 | 2137 | ||
5500 | if (priv->ibss_beacon) | 2138 | if (priv->ibss_beacon) |
5501 | dev_kfree_skb(priv->ibss_beacon); | 2139 | dev_kfree_skb(priv->ibss_beacon); |
5502 | priv->ibss_beacon = NULL; | 2140 | priv->ibss_beacon = NULL; |
5503 | 2141 | ||
5504 | /* clear out any free frames */ | 2142 | /* clear out any free frames */ |
5505 | iwl4965_clear_free_frames(priv); | 2143 | iwl_clear_free_frames(priv); |
5506 | } | 2144 | } |
5507 | 2145 | ||
5508 | static void iwl4965_down(struct iwl_priv *priv) | 2146 | static void iwl4965_down(struct iwl_priv *priv) |
@@ -5511,7 +2149,7 @@ static void iwl4965_down(struct iwl_priv *priv) | |||
5511 | __iwl4965_down(priv); | 2149 | __iwl4965_down(priv); |
5512 | mutex_unlock(&priv->mutex); | 2150 | mutex_unlock(&priv->mutex); |
5513 | 2151 | ||
5514 | iwl4965_cancel_deferred_work(priv); | 2152 | iwl_cancel_deferred_work(priv); |
5515 | } | 2153 | } |
5516 | 2154 | ||
5517 | #define MAX_HW_RESTARTS 5 | 2155 | #define MAX_HW_RESTARTS 5 |
@@ -5526,13 +2164,6 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5526 | return -EIO; | 2164 | return -EIO; |
5527 | } | 2165 | } |
5528 | 2166 | ||
5529 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | ||
5530 | IWL_WARNING("Radio disabled by SW RF kill (module " | ||
5531 | "parameter)\n"); | ||
5532 | iwl_rfkill_set_hw_state(priv); | ||
5533 | return -ENODEV; | ||
5534 | } | ||
5535 | |||
5536 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { | 2167 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { |
5537 | IWL_ERROR("ucode not available for device bringup\n"); | 2168 | IWL_ERROR("ucode not available for device bringup\n"); |
5538 | return -EIO; | 2169 | return -EIO; |
@@ -5542,19 +2173,25 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5542 | if (iwl_read32(priv, CSR_GP_CNTRL) & | 2173 | if (iwl_read32(priv, CSR_GP_CNTRL) & |
5543 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 2174 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
5544 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2175 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
5545 | else { | 2176 | else |
5546 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2177 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
5547 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { | 2178 | |
5548 | iwl_rfkill_set_hw_state(priv); | 2179 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status) && |
5549 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); | 2180 | iwl_is_rfkill(priv)) { |
5550 | return -ENODEV; | 2181 | IWL_WARNING("Radio disabled by %s RF Kill switch\n", |
5551 | } | 2182 | test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); |
2183 | return -ENODEV; | ||
5552 | } | 2184 | } |
5553 | 2185 | ||
5554 | iwl_rfkill_set_hw_state(priv); | ||
5555 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 2186 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
5556 | 2187 | ||
5557 | ret = priv->cfg->ops->lib->hw_nic_init(priv); | 2188 | ret = priv->cfg->ops->lib->alloc_shared_mem(priv); |
2189 | if (ret) { | ||
2190 | IWL_ERROR("Unable to allocate shared memory\n"); | ||
2191 | return ret; | ||
2192 | } | ||
2193 | |||
2194 | ret = iwl_hw_nic_init(priv); | ||
5558 | if (ret) { | 2195 | if (ret) { |
5559 | IWL_ERROR("Unable to init nic\n"); | 2196 | IWL_ERROR("Unable to init nic\n"); |
5560 | return ret; | 2197 | return ret; |
@@ -5580,12 +2217,13 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5580 | priv->ucode_data.len); | 2217 | priv->ucode_data.len); |
5581 | 2218 | ||
5582 | /* We return success when we resume from suspend and rf_kill is on. */ | 2219 | /* We return success when we resume from suspend and rf_kill is on. */ |
5583 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) | 2220 | if (test_bit(STATUS_RF_KILL_HW, &priv->status) || |
2221 | test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
5584 | return 0; | 2222 | return 0; |
5585 | 2223 | ||
5586 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 2224 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
5587 | 2225 | ||
5588 | iwlcore_clear_stations_table(priv); | 2226 | iwl_clear_stations_table(priv); |
5589 | 2227 | ||
5590 | /* load bootstrap state machine, | 2228 | /* load bootstrap state machine, |
5591 | * load bootstrap program into processor's memory, | 2229 | * load bootstrap program into processor's memory, |
@@ -5597,6 +2235,9 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5597 | continue; | 2235 | continue; |
5598 | } | 2236 | } |
5599 | 2237 | ||
2238 | /* Clear out the uCode error bit if it is set */ | ||
2239 | clear_bit(STATUS_FW_ERROR, &priv->status); | ||
2240 | |||
5600 | /* start card; "initialize" will load runtime ucode */ | 2241 | /* start card; "initialize" will load runtime ucode */ |
5601 | iwl4965_nic_start(priv); | 2242 | iwl4965_nic_start(priv); |
5602 | 2243 | ||
@@ -5607,6 +2248,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5607 | 2248 | ||
5608 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2249 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
5609 | __iwl4965_down(priv); | 2250 | __iwl4965_down(priv); |
2251 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | ||
5610 | 2252 | ||
5611 | /* tried to restart and config the device for as long as our | 2253 | /* tried to restart and config the device for as long as our |
5612 | * patience could withstand */ | 2254 | * patience could withstand */ |
@@ -5621,7 +2263,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
5621 | * | 2263 | * |
5622 | *****************************************************************************/ | 2264 | *****************************************************************************/ |
5623 | 2265 | ||
5624 | static void iwl4965_bg_init_alive_start(struct work_struct *data) | 2266 | static void iwl_bg_init_alive_start(struct work_struct *data) |
5625 | { | 2267 | { |
5626 | struct iwl_priv *priv = | 2268 | struct iwl_priv *priv = |
5627 | container_of(data, struct iwl_priv, init_alive_start.work); | 2269 | container_of(data, struct iwl_priv, init_alive_start.work); |
@@ -5630,11 +2272,11 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data) | |||
5630 | return; | 2272 | return; |
5631 | 2273 | ||
5632 | mutex_lock(&priv->mutex); | 2274 | mutex_lock(&priv->mutex); |
5633 | iwl4965_init_alive_start(priv); | 2275 | priv->cfg->ops->lib->init_alive_start(priv); |
5634 | mutex_unlock(&priv->mutex); | 2276 | mutex_unlock(&priv->mutex); |
5635 | } | 2277 | } |
5636 | 2278 | ||
5637 | static void iwl4965_bg_alive_start(struct work_struct *data) | 2279 | static void iwl_bg_alive_start(struct work_struct *data) |
5638 | { | 2280 | { |
5639 | struct iwl_priv *priv = | 2281 | struct iwl_priv *priv = |
5640 | container_of(data, struct iwl_priv, alive_start.work); | 2282 | container_of(data, struct iwl_priv, alive_start.work); |
@@ -5643,7 +2285,7 @@ static void iwl4965_bg_alive_start(struct work_struct *data) | |||
5643 | return; | 2285 | return; |
5644 | 2286 | ||
5645 | mutex_lock(&priv->mutex); | 2287 | mutex_lock(&priv->mutex); |
5646 | iwl4965_alive_start(priv); | 2288 | iwl_alive_start(priv); |
5647 | mutex_unlock(&priv->mutex); | 2289 | mutex_unlock(&priv->mutex); |
5648 | } | 2290 | } |
5649 | 2291 | ||
@@ -5659,7 +2301,7 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) | |||
5659 | mutex_lock(&priv->mutex); | 2301 | mutex_lock(&priv->mutex); |
5660 | 2302 | ||
5661 | if (!iwl_is_rfkill(priv)) { | 2303 | if (!iwl_is_rfkill(priv)) { |
5662 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, | 2304 | IWL_DEBUG(IWL_DL_RF_KILL, |
5663 | "HW and/or SW RF Kill no longer active, restarting " | 2305 | "HW and/or SW RF Kill no longer active, restarting " |
5664 | "device\n"); | 2306 | "device\n"); |
5665 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2307 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) |
@@ -5677,239 +2319,53 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) | |||
5677 | "Kill switch must be turned off for " | 2319 | "Kill switch must be turned off for " |
5678 | "wireless networking to work.\n"); | 2320 | "wireless networking to work.\n"); |
5679 | } | 2321 | } |
5680 | iwl_rfkill_set_hw_state(priv); | ||
5681 | |||
5682 | mutex_unlock(&priv->mutex); | 2322 | mutex_unlock(&priv->mutex); |
2323 | iwl_rfkill_set_hw_state(priv); | ||
5683 | } | 2324 | } |
5684 | 2325 | ||
5685 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 2326 | static void iwl4965_bg_set_monitor(struct work_struct *work) |
5686 | |||
5687 | static void iwl4965_bg_scan_check(struct work_struct *data) | ||
5688 | { | 2327 | { |
5689 | struct iwl_priv *priv = | 2328 | struct iwl_priv *priv = container_of(work, |
5690 | container_of(data, struct iwl_priv, scan_check.work); | 2329 | struct iwl_priv, set_monitor); |
2330 | int ret; | ||
5691 | 2331 | ||
5692 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2332 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); |
5693 | return; | ||
5694 | 2333 | ||
5695 | mutex_lock(&priv->mutex); | 2334 | mutex_lock(&priv->mutex); |
5696 | if (test_bit(STATUS_SCANNING, &priv->status) || | ||
5697 | test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
5698 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, | ||
5699 | "Scan completion watchdog resetting adapter (%dms)\n", | ||
5700 | jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); | ||
5701 | 2335 | ||
5702 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2336 | ret = iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR); |
5703 | iwl4965_send_scan_abort(priv); | 2337 | |
2338 | if (ret) { | ||
2339 | if (ret == -EAGAIN) | ||
2340 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | ||
2341 | else | ||
2342 | IWL_ERROR("iwl4965_set_mode() failed ret = %d\n", ret); | ||
5704 | } | 2343 | } |
2344 | |||
5705 | mutex_unlock(&priv->mutex); | 2345 | mutex_unlock(&priv->mutex); |
5706 | } | 2346 | } |
5707 | 2347 | ||
5708 | static void iwl4965_bg_request_scan(struct work_struct *data) | 2348 | static void iwl_bg_run_time_calib_work(struct work_struct *work) |
5709 | { | 2349 | { |
5710 | struct iwl_priv *priv = | 2350 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
5711 | container_of(data, struct iwl_priv, request_scan); | 2351 | run_time_calib_work); |
5712 | struct iwl_host_cmd cmd = { | ||
5713 | .id = REPLY_SCAN_CMD, | ||
5714 | .len = sizeof(struct iwl4965_scan_cmd), | ||
5715 | .meta.flags = CMD_SIZE_HUGE, | ||
5716 | }; | ||
5717 | struct iwl4965_scan_cmd *scan; | ||
5718 | struct ieee80211_conf *conf = NULL; | ||
5719 | u16 cmd_len; | ||
5720 | enum ieee80211_band band; | ||
5721 | u8 direct_mask; | ||
5722 | int ret = 0; | ||
5723 | |||
5724 | conf = ieee80211_get_hw_conf(priv->hw); | ||
5725 | 2352 | ||
5726 | mutex_lock(&priv->mutex); | 2353 | mutex_lock(&priv->mutex); |
5727 | 2354 | ||
5728 | if (!iwl_is_ready(priv)) { | 2355 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
5729 | IWL_WARNING("request scan called when driver not ready.\n"); | 2356 | test_bit(STATUS_SCANNING, &priv->status)) { |
5730 | goto done; | 2357 | mutex_unlock(&priv->mutex); |
5731 | } | 2358 | return; |
5732 | |||
5733 | /* Make sure the scan wasn't cancelled before this queued work | ||
5734 | * was given the chance to run... */ | ||
5735 | if (!test_bit(STATUS_SCANNING, &priv->status)) | ||
5736 | goto done; | ||
5737 | |||
5738 | /* This should never be called or scheduled if there is currently | ||
5739 | * a scan active in the hardware. */ | ||
5740 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
5741 | IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. " | ||
5742 | "Ignoring second request.\n"); | ||
5743 | ret = -EIO; | ||
5744 | goto done; | ||
5745 | } | ||
5746 | |||
5747 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
5748 | IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n"); | ||
5749 | goto done; | ||
5750 | } | ||
5751 | |||
5752 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
5753 | IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n"); | ||
5754 | goto done; | ||
5755 | } | ||
5756 | |||
5757 | if (iwl_is_rfkill(priv)) { | ||
5758 | IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); | ||
5759 | goto done; | ||
5760 | } | ||
5761 | |||
5762 | if (!test_bit(STATUS_READY, &priv->status)) { | ||
5763 | IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n"); | ||
5764 | goto done; | ||
5765 | } | ||
5766 | |||
5767 | if (!priv->scan_bands) { | ||
5768 | IWL_DEBUG_HC("Aborting scan due to no requested bands\n"); | ||
5769 | goto done; | ||
5770 | } | ||
5771 | |||
5772 | if (!priv->scan) { | ||
5773 | priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) + | ||
5774 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); | ||
5775 | if (!priv->scan) { | ||
5776 | ret = -ENOMEM; | ||
5777 | goto done; | ||
5778 | } | ||
5779 | } | 2359 | } |
5780 | scan = priv->scan; | ||
5781 | memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE); | ||
5782 | 2360 | ||
5783 | scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; | 2361 | if (priv->start_calib) { |
5784 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; | 2362 | iwl_chain_noise_calibration(priv, &priv->statistics); |
5785 | 2363 | ||
5786 | if (iwl_is_associated(priv)) { | 2364 | iwl_sensitivity_calibration(priv, &priv->statistics); |
5787 | u16 interval = 0; | ||
5788 | u32 extra; | ||
5789 | u32 suspend_time = 100; | ||
5790 | u32 scan_suspend_time = 100; | ||
5791 | unsigned long flags; | ||
5792 | |||
5793 | IWL_DEBUG_INFO("Scanning while associated...\n"); | ||
5794 | |||
5795 | spin_lock_irqsave(&priv->lock, flags); | ||
5796 | interval = priv->beacon_int; | ||
5797 | spin_unlock_irqrestore(&priv->lock, flags); | ||
5798 | |||
5799 | scan->suspend_time = 0; | ||
5800 | scan->max_out_time = cpu_to_le32(200 * 1024); | ||
5801 | if (!interval) | ||
5802 | interval = suspend_time; | ||
5803 | |||
5804 | extra = (suspend_time / interval) << 22; | ||
5805 | scan_suspend_time = (extra | | ||
5806 | ((suspend_time % interval) * 1024)); | ||
5807 | scan->suspend_time = cpu_to_le32(scan_suspend_time); | ||
5808 | IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n", | ||
5809 | scan_suspend_time, interval); | ||
5810 | } | ||
5811 | |||
5812 | /* We should add the ability for user to lock to PASSIVE ONLY */ | ||
5813 | if (priv->one_direct_scan) { | ||
5814 | IWL_DEBUG_SCAN | ||
5815 | ("Kicking off one direct scan for '%s'\n", | ||
5816 | iwl4965_escape_essid(priv->direct_ssid, | ||
5817 | priv->direct_ssid_len)); | ||
5818 | scan->direct_scan[0].id = WLAN_EID_SSID; | ||
5819 | scan->direct_scan[0].len = priv->direct_ssid_len; | ||
5820 | memcpy(scan->direct_scan[0].ssid, | ||
5821 | priv->direct_ssid, priv->direct_ssid_len); | ||
5822 | direct_mask = 1; | ||
5823 | } else if (!iwl_is_associated(priv) && priv->essid_len) { | ||
5824 | IWL_DEBUG_SCAN | ||
5825 | ("Kicking off one direct scan for '%s' when not associated\n", | ||
5826 | iwl4965_escape_essid(priv->essid, priv->essid_len)); | ||
5827 | scan->direct_scan[0].id = WLAN_EID_SSID; | ||
5828 | scan->direct_scan[0].len = priv->essid_len; | ||
5829 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); | ||
5830 | direct_mask = 1; | ||
5831 | } else { | ||
5832 | IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); | ||
5833 | direct_mask = 0; | ||
5834 | } | 2365 | } |
5835 | 2366 | ||
5836 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | ||
5837 | scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; | ||
5838 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
5839 | |||
5840 | |||
5841 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { | ||
5842 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | ||
5843 | scan->tx_cmd.rate_n_flags = | ||
5844 | iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, | ||
5845 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); | ||
5846 | |||
5847 | scan->good_CRC_th = 0; | ||
5848 | band = IEEE80211_BAND_2GHZ; | ||
5849 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { | ||
5850 | scan->tx_cmd.rate_n_flags = | ||
5851 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | ||
5852 | RATE_MCS_ANT_B_MSK); | ||
5853 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | ||
5854 | band = IEEE80211_BAND_5GHZ; | ||
5855 | } else { | ||
5856 | IWL_WARNING("Invalid scan band count\n"); | ||
5857 | goto done; | ||
5858 | } | ||
5859 | |||
5860 | /* We don't build a direct scan probe request; the uCode will do | ||
5861 | * that based on the direct_mask added to each channel entry */ | ||
5862 | cmd_len = iwl4965_fill_probe_req(priv, band, | ||
5863 | (struct ieee80211_mgmt *)scan->data, | ||
5864 | IWL_MAX_SCAN_SIZE - sizeof(*scan), 0); | ||
5865 | |||
5866 | scan->tx_cmd.len = cpu_to_le16(cmd_len); | ||
5867 | /* select Rx chains */ | ||
5868 | |||
5869 | /* Force use of chains B and C (0x6) for scan Rx. | ||
5870 | * Avoid A (0x1) because of its off-channel reception on A-band. | ||
5871 | * MIMO is not used here, but value is required to make uCode happy. */ | ||
5872 | scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | | ||
5873 | cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | | ||
5874 | (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) | | ||
5875 | (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); | ||
5876 | |||
5877 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) | ||
5878 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | ||
5879 | |||
5880 | if (direct_mask) | ||
5881 | scan->channel_count = | ||
5882 | iwl4965_get_channels_for_scan( | ||
5883 | priv, band, 1, /* active */ | ||
5884 | direct_mask, | ||
5885 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
5886 | else | ||
5887 | scan->channel_count = | ||
5888 | iwl4965_get_channels_for_scan( | ||
5889 | priv, band, 0, /* passive */ | ||
5890 | direct_mask, | ||
5891 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
5892 | |||
5893 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | ||
5894 | scan->channel_count * sizeof(struct iwl4965_scan_channel); | ||
5895 | cmd.data = scan; | ||
5896 | scan->len = cpu_to_le16(cmd.len); | ||
5897 | |||
5898 | set_bit(STATUS_SCAN_HW, &priv->status); | ||
5899 | ret = iwl_send_cmd_sync(priv, &cmd); | ||
5900 | if (ret) | ||
5901 | goto done; | ||
5902 | |||
5903 | queue_delayed_work(priv->workqueue, &priv->scan_check, | ||
5904 | IWL_SCAN_CHECK_WATCHDOG); | ||
5905 | |||
5906 | mutex_unlock(&priv->mutex); | 2367 | mutex_unlock(&priv->mutex); |
5907 | return; | 2368 | return; |
5908 | |||
5909 | done: | ||
5910 | /* inform mac80211 scan aborted */ | ||
5911 | queue_work(priv->workqueue, &priv->scan_completed); | ||
5912 | mutex_unlock(&priv->mutex); | ||
5913 | } | 2369 | } |
5914 | 2370 | ||
5915 | static void iwl4965_bg_up(struct work_struct *data) | 2371 | static void iwl4965_bg_up(struct work_struct *data) |
@@ -5922,6 +2378,7 @@ static void iwl4965_bg_up(struct work_struct *data) | |||
5922 | mutex_lock(&priv->mutex); | 2378 | mutex_lock(&priv->mutex); |
5923 | __iwl4965_up(priv); | 2379 | __iwl4965_up(priv); |
5924 | mutex_unlock(&priv->mutex); | 2380 | mutex_unlock(&priv->mutex); |
2381 | iwl_rfkill_set_hw_state(priv); | ||
5925 | } | 2382 | } |
5926 | 2383 | ||
5927 | static void iwl4965_bg_restart(struct work_struct *data) | 2384 | static void iwl4965_bg_restart(struct work_struct *data) |
@@ -5944,7 +2401,7 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data) | |||
5944 | return; | 2401 | return; |
5945 | 2402 | ||
5946 | mutex_lock(&priv->mutex); | 2403 | mutex_lock(&priv->mutex); |
5947 | iwl4965_rx_replenish(priv); | 2404 | iwl_rx_replenish(priv); |
5948 | mutex_unlock(&priv->mutex); | 2405 | mutex_unlock(&priv->mutex); |
5949 | } | 2406 | } |
5950 | 2407 | ||
@@ -5955,6 +2412,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
5955 | struct ieee80211_conf *conf = NULL; | 2412 | struct ieee80211_conf *conf = NULL; |
5956 | int ret = 0; | 2413 | int ret = 0; |
5957 | DECLARE_MAC_BUF(mac); | 2414 | DECLARE_MAC_BUF(mac); |
2415 | unsigned long flags; | ||
5958 | 2416 | ||
5959 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 2417 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { |
5960 | IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); | 2418 | IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); |
@@ -5973,7 +2431,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
5973 | if (!priv->vif || !priv->is_open) | 2431 | if (!priv->vif || !priv->is_open) |
5974 | return; | 2432 | return; |
5975 | 2433 | ||
5976 | iwl4965_scan_cancel_timeout(priv, 200); | 2434 | iwl_scan_cancel_timeout(priv, 200); |
5977 | 2435 | ||
5978 | conf = ieee80211_get_hw_conf(priv->hw); | 2436 | conf = ieee80211_get_hw_conf(priv->hw); |
5979 | 2437 | ||
@@ -5990,11 +2448,10 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
5990 | 2448 | ||
5991 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2449 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
5992 | 2450 | ||
5993 | #ifdef CONFIG_IWL4965_HT | ||
5994 | if (priv->current_ht_config.is_ht) | 2451 | if (priv->current_ht_config.is_ht) |
5995 | iwl4965_set_rxon_ht(priv, &priv->current_ht_config); | 2452 | iwl_set_rxon_ht(priv, &priv->current_ht_config); |
5996 | #endif /* CONFIG_IWL4965_HT*/ | 2453 | |
5997 | iwl4965_set_rxon_chain(priv); | 2454 | iwl_set_rxon_chain(priv); |
5998 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 2455 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
5999 | 2456 | ||
6000 | IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n", | 2457 | IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n", |
@@ -6020,17 +2477,14 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
6020 | 2477 | ||
6021 | switch (priv->iw_mode) { | 2478 | switch (priv->iw_mode) { |
6022 | case IEEE80211_IF_TYPE_STA: | 2479 | case IEEE80211_IF_TYPE_STA: |
6023 | iwl4965_rate_scale_init(priv->hw, IWL_AP_ID); | ||
6024 | break; | 2480 | break; |
6025 | 2481 | ||
6026 | case IEEE80211_IF_TYPE_IBSS: | 2482 | case IEEE80211_IF_TYPE_IBSS: |
6027 | 2483 | ||
6028 | /* clear out the station table */ | 2484 | /* assume default assoc id */ |
6029 | iwlcore_clear_stations_table(priv); | 2485 | priv->assoc_id = 1; |
6030 | 2486 | ||
6031 | iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); | 2487 | iwl_rxon_add_station(priv, priv->bssid, 0); |
6032 | iwl4965_rxon_add_station(priv, priv->bssid, 0); | ||
6033 | iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); | ||
6034 | iwl4965_send_beacon_cmd(priv); | 2488 | iwl4965_send_beacon_cmd(priv); |
6035 | 2489 | ||
6036 | break; | 2490 | break; |
@@ -6041,58 +2495,30 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
6041 | break; | 2495 | break; |
6042 | } | 2496 | } |
6043 | 2497 | ||
6044 | iwl4965_sequence_reset(priv); | ||
6045 | |||
6046 | #ifdef CONFIG_IWL4965_SENSITIVITY | ||
6047 | /* Enable Rx differential gain and sensitivity calibrations */ | 2498 | /* Enable Rx differential gain and sensitivity calibrations */ |
6048 | iwl4965_chain_noise_reset(priv); | 2499 | iwl_chain_noise_reset(priv); |
6049 | priv->start_calib = 1; | 2500 | priv->start_calib = 1; |
6050 | #endif /* CONFIG_IWL4965_SENSITIVITY */ | ||
6051 | 2501 | ||
6052 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | 2502 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) |
6053 | priv->assoc_station_added = 1; | 2503 | priv->assoc_station_added = 1; |
6054 | 2504 | ||
6055 | iwl4965_activate_qos(priv, 0); | 2505 | spin_lock_irqsave(&priv->lock, flags); |
2506 | iwl_activate_qos(priv, 0); | ||
2507 | spin_unlock_irqrestore(&priv->lock, flags); | ||
6056 | 2508 | ||
2509 | iwl_power_update_mode(priv, 0); | ||
6057 | /* we have just associated, don't start scan too early */ | 2510 | /* we have just associated, don't start scan too early */ |
6058 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 2511 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
6059 | } | 2512 | } |
6060 | 2513 | ||
6061 | |||
6062 | static void iwl4965_bg_post_associate(struct work_struct *data) | ||
6063 | { | ||
6064 | struct iwl_priv *priv = container_of(data, struct iwl_priv, | ||
6065 | post_associate.work); | ||
6066 | |||
6067 | mutex_lock(&priv->mutex); | ||
6068 | iwl4965_post_associate(priv); | ||
6069 | mutex_unlock(&priv->mutex); | ||
6070 | |||
6071 | } | ||
6072 | |||
6073 | static void iwl4965_bg_abort_scan(struct work_struct *work) | ||
6074 | { | ||
6075 | struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); | ||
6076 | |||
6077 | if (!iwl_is_ready(priv)) | ||
6078 | return; | ||
6079 | |||
6080 | mutex_lock(&priv->mutex); | ||
6081 | |||
6082 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
6083 | iwl4965_send_scan_abort(priv); | ||
6084 | |||
6085 | mutex_unlock(&priv->mutex); | ||
6086 | } | ||
6087 | |||
6088 | static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | 2514 | static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); |
6089 | 2515 | ||
6090 | static void iwl4965_bg_scan_completed(struct work_struct *work) | 2516 | static void iwl_bg_scan_completed(struct work_struct *work) |
6091 | { | 2517 | { |
6092 | struct iwl_priv *priv = | 2518 | struct iwl_priv *priv = |
6093 | container_of(work, struct iwl_priv, scan_completed); | 2519 | container_of(work, struct iwl_priv, scan_completed); |
6094 | 2520 | ||
6095 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n"); | 2521 | IWL_DEBUG_SCAN("SCAN complete scan\n"); |
6096 | 2522 | ||
6097 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2523 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6098 | return; | 2524 | return; |
@@ -6105,7 +2531,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work) | |||
6105 | /* Since setting the TXPOWER may have been deferred while | 2531 | /* Since setting the TXPOWER may have been deferred while |
6106 | * performing the scan, fire one off */ | 2532 | * performing the scan, fire one off */ |
6107 | mutex_lock(&priv->mutex); | 2533 | mutex_lock(&priv->mutex); |
6108 | iwl4965_hw_reg_send_txpower(priv); | 2534 | iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); |
6109 | mutex_unlock(&priv->mutex); | 2535 | mutex_unlock(&priv->mutex); |
6110 | } | 2536 | } |
6111 | 2537 | ||
@@ -6115,7 +2541,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work) | |||
6115 | * | 2541 | * |
6116 | *****************************************************************************/ | 2542 | *****************************************************************************/ |
6117 | 2543 | ||
6118 | #define UCODE_READY_TIMEOUT (2 * HZ) | 2544 | #define UCODE_READY_TIMEOUT (4 * HZ) |
6119 | 2545 | ||
6120 | static int iwl4965_mac_start(struct ieee80211_hw *hw) | 2546 | static int iwl4965_mac_start(struct ieee80211_hw *hw) |
6121 | { | 2547 | { |
@@ -6141,7 +2567,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
6141 | /* we should be verifying the device is ready to be opened */ | 2567 | /* we should be verifying the device is ready to be opened */ |
6142 | mutex_lock(&priv->mutex); | 2568 | mutex_lock(&priv->mutex); |
6143 | 2569 | ||
6144 | memset(&priv->staging_rxon, 0, sizeof(struct iwl4965_rxon_cmd)); | 2570 | memset(&priv->staging_rxon, 0, sizeof(struct iwl_rxon_cmd)); |
6145 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | 2571 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... |
6146 | * ucode filename and max sizes are card-specific. */ | 2572 | * ucode filename and max sizes are card-specific. */ |
6147 | 2573 | ||
@@ -6158,6 +2584,8 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
6158 | 2584 | ||
6159 | mutex_unlock(&priv->mutex); | 2585 | mutex_unlock(&priv->mutex); |
6160 | 2586 | ||
2587 | iwl_rfkill_set_hw_state(priv); | ||
2588 | |||
6161 | if (ret) | 2589 | if (ret) |
6162 | goto out_release_irq; | 2590 | goto out_release_irq; |
6163 | 2591 | ||
@@ -6166,15 +2594,15 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
6166 | if (test_bit(STATUS_IN_SUSPEND, &priv->status)) | 2594 | if (test_bit(STATUS_IN_SUSPEND, &priv->status)) |
6167 | return 0; | 2595 | return 0; |
6168 | 2596 | ||
6169 | /* Wait for START_ALIVE from ucode. Otherwise callbacks from | 2597 | /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from |
6170 | * mac80211 will not be run successfully. */ | 2598 | * mac80211 will not be run successfully. */ |
6171 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 2599 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
6172 | test_bit(STATUS_READY, &priv->status), | 2600 | test_bit(STATUS_READY, &priv->status), |
6173 | UCODE_READY_TIMEOUT); | 2601 | UCODE_READY_TIMEOUT); |
6174 | if (!ret) { | 2602 | if (!ret) { |
6175 | if (!test_bit(STATUS_READY, &priv->status)) { | 2603 | if (!test_bit(STATUS_READY, &priv->status)) { |
6176 | IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n", | 2604 | IWL_ERROR("START_ALIVE timeout after %dms.\n", |
6177 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | 2605 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); |
6178 | ret = -ETIMEDOUT; | 2606 | ret = -ETIMEDOUT; |
6179 | goto out_release_irq; | 2607 | goto out_release_irq; |
6180 | } | 2608 | } |
@@ -6212,8 +2640,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
6212 | * RXON_FILTER_ASSOC_MSK BIT | 2640 | * RXON_FILTER_ASSOC_MSK BIT |
6213 | */ | 2641 | */ |
6214 | mutex_lock(&priv->mutex); | 2642 | mutex_lock(&priv->mutex); |
6215 | iwl4965_scan_cancel_timeout(priv, 100); | 2643 | iwl_scan_cancel_timeout(priv, 100); |
6216 | cancel_delayed_work(&priv->post_associate); | ||
6217 | mutex_unlock(&priv->mutex); | 2644 | mutex_unlock(&priv->mutex); |
6218 | } | 2645 | } |
6219 | 2646 | ||
@@ -6228,8 +2655,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
6228 | IWL_DEBUG_MAC80211("leave\n"); | 2655 | IWL_DEBUG_MAC80211("leave\n"); |
6229 | } | 2656 | } |
6230 | 2657 | ||
6231 | static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | 2658 | static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
6232 | struct ieee80211_tx_control *ctl) | ||
6233 | { | 2659 | { |
6234 | struct iwl_priv *priv = hw->priv; | 2660 | struct iwl_priv *priv = hw->priv; |
6235 | 2661 | ||
@@ -6242,9 +2668,9 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
6242 | } | 2668 | } |
6243 | 2669 | ||
6244 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 2670 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
6245 | ctl->tx_rate->bitrate); | 2671 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); |
6246 | 2672 | ||
6247 | if (iwl4965_tx_skb(priv, skb, ctl)) | 2673 | if (iwl_tx_skb(priv, skb)) |
6248 | dev_kfree_skb_any(skb); | 2674 | dev_kfree_skb_any(skb); |
6249 | 2675 | ||
6250 | IWL_DEBUG_MAC80211("leave\n"); | 2676 | IWL_DEBUG_MAC80211("leave\n"); |
@@ -6277,8 +2703,9 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw, | |||
6277 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | 2703 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); |
6278 | } | 2704 | } |
6279 | 2705 | ||
6280 | if (iwl_is_ready(priv)) | 2706 | if (iwl4965_set_mode(priv, conf->type) == -EAGAIN) |
6281 | iwl4965_set_mode(priv, conf->type); | 2707 | /* we are not ready, will run again when ready */ |
2708 | set_bit(STATUS_MODE_PENDING, &priv->status); | ||
6282 | 2709 | ||
6283 | mutex_unlock(&priv->mutex); | 2710 | mutex_unlock(&priv->mutex); |
6284 | 2711 | ||
@@ -6299,12 +2726,21 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6299 | const struct iwl_channel_info *ch_info; | 2726 | const struct iwl_channel_info *ch_info; |
6300 | unsigned long flags; | 2727 | unsigned long flags; |
6301 | int ret = 0; | 2728 | int ret = 0; |
2729 | u16 channel; | ||
6302 | 2730 | ||
6303 | mutex_lock(&priv->mutex); | 2731 | mutex_lock(&priv->mutex); |
6304 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); | 2732 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
6305 | 2733 | ||
6306 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 2734 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
6307 | 2735 | ||
2736 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { | ||
2737 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); | ||
2738 | goto out; | ||
2739 | } | ||
2740 | |||
2741 | if (!conf->radio_enabled) | ||
2742 | iwl_radio_kill_sw_disable_radio(priv); | ||
2743 | |||
6308 | if (!iwl_is_ready(priv)) { | 2744 | if (!iwl_is_ready(priv)) { |
6309 | IWL_DEBUG_MAC80211("leave - not ready\n"); | 2745 | IWL_DEBUG_MAC80211("leave - not ready\n"); |
6310 | ret = -EIO; | 2746 | ret = -EIO; |
@@ -6319,33 +2755,37 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6319 | return 0; | 2755 | return 0; |
6320 | } | 2756 | } |
6321 | 2757 | ||
6322 | spin_lock_irqsave(&priv->lock, flags); | 2758 | channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
6323 | 2759 | ch_info = iwl_get_channel_info(priv, conf->channel->band, channel); | |
6324 | ch_info = iwl_get_channel_info(priv, conf->channel->band, | ||
6325 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
6326 | if (!is_channel_valid(ch_info)) { | 2760 | if (!is_channel_valid(ch_info)) { |
6327 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 2761 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
6328 | spin_unlock_irqrestore(&priv->lock, flags); | ||
6329 | ret = -EINVAL; | 2762 | ret = -EINVAL; |
6330 | goto out; | 2763 | goto out; |
6331 | } | 2764 | } |
6332 | 2765 | ||
6333 | #ifdef CONFIG_IWL4965_HT | 2766 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS && |
2767 | !is_channel_ibss(ch_info)) { | ||
2768 | IWL_ERROR("channel %d in band %d not IBSS channel\n", | ||
2769 | conf->channel->hw_value, conf->channel->band); | ||
2770 | ret = -EINVAL; | ||
2771 | goto out; | ||
2772 | } | ||
2773 | |||
2774 | spin_lock_irqsave(&priv->lock, flags); | ||
2775 | |||
6334 | /* if we are switching from ht to 2.4 clear flags | 2776 | /* if we are switching from ht to 2.4 clear flags |
6335 | * from any ht related info since 2.4 does not | 2777 | * from any ht related info since 2.4 does not |
6336 | * support ht */ | 2778 | * support ht */ |
6337 | if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel->hw_value) | 2779 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) |
6338 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH | 2780 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH |
6339 | && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) | 2781 | && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) |
6340 | #endif | 2782 | #endif |
6341 | ) | 2783 | ) |
6342 | priv->staging_rxon.flags = 0; | 2784 | priv->staging_rxon.flags = 0; |
6343 | #endif /* CONFIG_IWL4965_HT */ | ||
6344 | 2785 | ||
6345 | iwlcore_set_rxon_channel(priv, conf->channel->band, | 2786 | iwl_set_rxon_channel(priv, conf->channel->band, channel); |
6346 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
6347 | 2787 | ||
6348 | iwl4965_set_flags_for_phymode(priv, conf->channel->band); | 2788 | iwl_set_flags_for_band(priv, conf->channel->band); |
6349 | 2789 | ||
6350 | /* The list of supported rates and rate mask can be different | 2790 | /* The list of supported rates and rate mask can be different |
6351 | * for each band; since the band may have changed, reset | 2791 | * for each band; since the band may have changed, reset |
@@ -6361,9 +2801,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6361 | } | 2801 | } |
6362 | #endif | 2802 | #endif |
6363 | 2803 | ||
6364 | if (priv->cfg->ops->lib->radio_kill_sw) | ||
6365 | priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled); | ||
6366 | |||
6367 | if (!conf->radio_enabled) { | 2804 | if (!conf->radio_enabled) { |
6368 | IWL_DEBUG_MAC80211("leave - radio disabled\n"); | 2805 | IWL_DEBUG_MAC80211("leave - radio disabled\n"); |
6369 | goto out; | 2806 | goto out; |
@@ -6375,6 +2812,11 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6375 | goto out; | 2812 | goto out; |
6376 | } | 2813 | } |
6377 | 2814 | ||
2815 | IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n", | ||
2816 | priv->tx_power_user_lmt, conf->power_level); | ||
2817 | |||
2818 | iwl_set_tx_power(priv, conf->power_level, false); | ||
2819 | |||
6378 | iwl4965_set_rate(priv); | 2820 | iwl4965_set_rate(priv); |
6379 | 2821 | ||
6380 | if (memcmp(&priv->active_rxon, | 2822 | if (memcmp(&priv->active_rxon, |
@@ -6394,12 +2836,13 @@ out: | |||
6394 | static void iwl4965_config_ap(struct iwl_priv *priv) | 2836 | static void iwl4965_config_ap(struct iwl_priv *priv) |
6395 | { | 2837 | { |
6396 | int ret = 0; | 2838 | int ret = 0; |
2839 | unsigned long flags; | ||
6397 | 2840 | ||
6398 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2841 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6399 | return; | 2842 | return; |
6400 | 2843 | ||
6401 | /* The following should be done only at AP bring up */ | 2844 | /* The following should be done only at AP bring up */ |
6402 | if ((priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) == 0) { | 2845 | if (!(iwl_is_associated(priv))) { |
6403 | 2846 | ||
6404 | /* RXON - unassoc (to set timing command) */ | 2847 | /* RXON - unassoc (to set timing command) */ |
6405 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2848 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
@@ -6414,7 +2857,7 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
6414 | IWL_WARNING("REPLY_RXON_TIMING failed - " | 2857 | IWL_WARNING("REPLY_RXON_TIMING failed - " |
6415 | "Attempting to continue.\n"); | 2858 | "Attempting to continue.\n"); |
6416 | 2859 | ||
6417 | iwl4965_set_rxon_chain(priv); | 2860 | iwl_set_rxon_chain(priv); |
6418 | 2861 | ||
6419 | /* FIXME: what should be the assoc_id for AP? */ | 2862 | /* FIXME: what should be the assoc_id for AP? */ |
6420 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 2863 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
@@ -6441,8 +2884,10 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
6441 | /* restore RXON assoc */ | 2884 | /* restore RXON assoc */ |
6442 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2885 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
6443 | iwl4965_commit_rxon(priv); | 2886 | iwl4965_commit_rxon(priv); |
6444 | iwl4965_activate_qos(priv, 1); | 2887 | spin_lock_irqsave(&priv->lock, flags); |
6445 | iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); | 2888 | iwl_activate_qos(priv, 1); |
2889 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2890 | iwl_rxon_add_station(priv, iwl_bcast_addr, 0); | ||
6446 | } | 2891 | } |
6447 | iwl4965_send_beacon_cmd(priv); | 2892 | iwl4965_send_beacon_cmd(priv); |
6448 | 2893 | ||
@@ -6451,6 +2896,9 @@ static void iwl4965_config_ap(struct iwl_priv *priv) | |||
6451 | * clear sta table, add BCAST sta... */ | 2896 | * clear sta table, add BCAST sta... */ |
6452 | } | 2897 | } |
6453 | 2898 | ||
2899 | /* temporary */ | ||
2900 | static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
2901 | |||
6454 | static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | 2902 | static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, |
6455 | struct ieee80211_vif *vif, | 2903 | struct ieee80211_vif *vif, |
6456 | struct ieee80211_if_conf *conf) | 2904 | struct ieee80211_if_conf *conf) |
@@ -6468,8 +2916,18 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
6468 | return 0; | 2916 | return 0; |
6469 | } | 2917 | } |
6470 | 2918 | ||
2919 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS && | ||
2920 | conf->changed & IEEE80211_IFCC_BEACON) { | ||
2921 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
2922 | if (!beacon) | ||
2923 | return -ENOMEM; | ||
2924 | rc = iwl4965_mac_beacon_update(hw, beacon); | ||
2925 | if (rc) | ||
2926 | return rc; | ||
2927 | } | ||
2928 | |||
6471 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && | 2929 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && |
6472 | (!conf->beacon || !conf->ssid_len)) { | 2930 | (!conf->ssid_len)) { |
6473 | IWL_DEBUG_MAC80211 | 2931 | IWL_DEBUG_MAC80211 |
6474 | ("Leaving in AP mode because HostAPD is not ready.\n"); | 2932 | ("Leaving in AP mode because HostAPD is not ready.\n"); |
6475 | return 0; | 2933 | return 0; |
@@ -6501,7 +2959,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
6501 | if (priv->ibss_beacon) | 2959 | if (priv->ibss_beacon) |
6502 | dev_kfree_skb(priv->ibss_beacon); | 2960 | dev_kfree_skb(priv->ibss_beacon); |
6503 | 2961 | ||
6504 | priv->ibss_beacon = conf->beacon; | 2962 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
6505 | } | 2963 | } |
6506 | 2964 | ||
6507 | if (iwl_is_rfkill(priv)) | 2965 | if (iwl_is_rfkill(priv)) |
@@ -6511,7 +2969,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
6511 | !is_multicast_ether_addr(conf->bssid)) { | 2969 | !is_multicast_ether_addr(conf->bssid)) { |
6512 | /* If there is currently a HW scan going on in the background | 2970 | /* If there is currently a HW scan going on in the background |
6513 | * then we need to cancel it else the RXON below will fail. */ | 2971 | * then we need to cancel it else the RXON below will fail. */ |
6514 | if (iwl4965_scan_cancel_timeout(priv, 100)) { | 2972 | if (iwl_scan_cancel_timeout(priv, 100)) { |
6515 | IWL_WARNING("Aborted scan still in progress " | 2973 | IWL_WARNING("Aborted scan still in progress " |
6516 | "after 100ms\n"); | 2974 | "after 100ms\n"); |
6517 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 2975 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
@@ -6531,12 +2989,12 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
6531 | else { | 2989 | else { |
6532 | rc = iwl4965_commit_rxon(priv); | 2990 | rc = iwl4965_commit_rxon(priv); |
6533 | if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) | 2991 | if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) |
6534 | iwl4965_rxon_add_station( | 2992 | iwl_rxon_add_station( |
6535 | priv, priv->active_rxon.bssid_addr, 1); | 2993 | priv, priv->active_rxon.bssid_addr, 1); |
6536 | } | 2994 | } |
6537 | 2995 | ||
6538 | } else { | 2996 | } else { |
6539 | iwl4965_scan_cancel_timeout(priv, 100); | 2997 | iwl_scan_cancel_timeout(priv, 100); |
6540 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2998 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
6541 | iwl4965_commit_rxon(priv); | 2999 | iwl4965_commit_rxon(priv); |
6542 | } | 3000 | } |
@@ -6562,11 +3020,18 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw, | |||
6562 | unsigned int *total_flags, | 3020 | unsigned int *total_flags, |
6563 | int mc_count, struct dev_addr_list *mc_list) | 3021 | int mc_count, struct dev_addr_list *mc_list) |
6564 | { | 3022 | { |
6565 | /* | 3023 | struct iwl_priv *priv = hw->priv; |
6566 | * XXX: dummy | 3024 | |
6567 | * see also iwl4965_connection_init_rx_config | 3025 | if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { |
6568 | */ | 3026 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", |
6569 | *total_flags = 0; | 3027 | IEEE80211_IF_TYPE_MNTR, |
3028 | changed_flags, *total_flags); | ||
3029 | /* queue work 'cuz mac80211 is holding a lock which | ||
3030 | * prevents us from issuing (synchronous) f/w cmds */ | ||
3031 | queue_work(priv->workqueue, &priv->set_monitor); | ||
3032 | } | ||
3033 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | | ||
3034 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
6570 | } | 3035 | } |
6571 | 3036 | ||
6572 | static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | 3037 | static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -6579,8 +3044,7 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | |||
6579 | mutex_lock(&priv->mutex); | 3044 | mutex_lock(&priv->mutex); |
6580 | 3045 | ||
6581 | if (iwl_is_ready_rf(priv)) { | 3046 | if (iwl_is_ready_rf(priv)) { |
6582 | iwl4965_scan_cancel_timeout(priv, 100); | 3047 | iwl_scan_cancel_timeout(priv, 100); |
6583 | cancel_delayed_work(&priv->post_associate); | ||
6584 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3048 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
6585 | iwl4965_commit_rxon(priv); | 3049 | iwl4965_commit_rxon(priv); |
6586 | } | 3050 | } |
@@ -6596,64 +3060,6 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | |||
6596 | 3060 | ||
6597 | } | 3061 | } |
6598 | 3062 | ||
6599 | |||
6600 | #ifdef CONFIG_IWL4965_HT | ||
6601 | static void iwl4965_ht_conf(struct iwl_priv *priv, | ||
6602 | struct ieee80211_bss_conf *bss_conf) | ||
6603 | { | ||
6604 | struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf; | ||
6605 | struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; | ||
6606 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; | ||
6607 | |||
6608 | IWL_DEBUG_MAC80211("enter: \n"); | ||
6609 | |||
6610 | iwl_conf->is_ht = bss_conf->assoc_ht; | ||
6611 | |||
6612 | if (!iwl_conf->is_ht) | ||
6613 | return; | ||
6614 | |||
6615 | priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
6616 | |||
6617 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) | ||
6618 | iwl_conf->sgf |= 0x1; | ||
6619 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) | ||
6620 | iwl_conf->sgf |= 0x2; | ||
6621 | |||
6622 | iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); | ||
6623 | iwl_conf->max_amsdu_size = | ||
6624 | !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); | ||
6625 | |||
6626 | iwl_conf->supported_chan_width = | ||
6627 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); | ||
6628 | iwl_conf->extension_chan_offset = | ||
6629 | ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; | ||
6630 | /* If no above or below channel supplied disable FAT channel */ | ||
6631 | if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE && | ||
6632 | iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW) | ||
6633 | iwl_conf->supported_chan_width = 0; | ||
6634 | |||
6635 | iwl_conf->tx_mimo_ps_mode = | ||
6636 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
6637 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); | ||
6638 | |||
6639 | iwl_conf->control_channel = ht_bss_conf->primary_channel; | ||
6640 | iwl_conf->tx_chan_width = | ||
6641 | !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); | ||
6642 | iwl_conf->ht_protection = | ||
6643 | ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION; | ||
6644 | iwl_conf->non_GF_STA_present = | ||
6645 | !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT); | ||
6646 | |||
6647 | IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); | ||
6648 | IWL_DEBUG_MAC80211("leave\n"); | ||
6649 | } | ||
6650 | #else | ||
6651 | static inline void iwl4965_ht_conf(struct iwl_priv *priv, | ||
6652 | struct ieee80211_bss_conf *bss_conf) | ||
6653 | { | ||
6654 | } | ||
6655 | #endif | ||
6656 | |||
6657 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | 3063 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) |
6658 | static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | 3064 | static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, |
6659 | struct ieee80211_vif *vif, | 3065 | struct ieee80211_vif *vif, |
@@ -6684,7 +3090,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
6684 | if (changes & BSS_CHANGED_HT) { | 3090 | if (changes & BSS_CHANGED_HT) { |
6685 | IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht); | 3091 | IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht); |
6686 | iwl4965_ht_conf(priv, bss_conf); | 3092 | iwl4965_ht_conf(priv, bss_conf); |
6687 | iwl4965_set_rxon_chain(priv); | 3093 | iwl_set_rxon_chain(priv); |
6688 | } | 3094 | } |
6689 | 3095 | ||
6690 | if (changes & BSS_CHANGED_ASSOC) { | 3096 | if (changes & BSS_CHANGED_ASSOC) { |
@@ -6751,7 +3157,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
6751 | } | 3157 | } |
6752 | if (len) { | 3158 | if (len) { |
6753 | IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", | 3159 | IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", |
6754 | iwl4965_escape_essid(ssid, len), (int)len); | 3160 | iwl_escape_essid(ssid, len), (int)len); |
6755 | 3161 | ||
6756 | priv->one_direct_scan = 1; | 3162 | priv->one_direct_scan = 1; |
6757 | priv->direct_ssid_len = (u8) | 3163 | priv->direct_ssid_len = (u8) |
@@ -6760,7 +3166,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
6760 | } else | 3166 | } else |
6761 | priv->one_direct_scan = 0; | 3167 | priv->one_direct_scan = 0; |
6762 | 3168 | ||
6763 | rc = iwl4965_scan_initiate(priv); | 3169 | rc = iwl_scan_initiate(priv); |
6764 | 3170 | ||
6765 | IWL_DEBUG_MAC80211("leave\n"); | 3171 | IWL_DEBUG_MAC80211("leave\n"); |
6766 | 3172 | ||
@@ -6784,14 +3190,14 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
6784 | 3190 | ||
6785 | IWL_DEBUG_MAC80211("enter\n"); | 3191 | IWL_DEBUG_MAC80211("enter\n"); |
6786 | 3192 | ||
6787 | sta_id = iwl4965_hw_find_station(priv, addr); | 3193 | sta_id = iwl_find_station(priv, addr); |
6788 | if (sta_id == IWL_INVALID_STATION) { | 3194 | if (sta_id == IWL_INVALID_STATION) { |
6789 | IWL_DEBUG_MAC80211("leave - %s not in station map.\n", | 3195 | IWL_DEBUG_MAC80211("leave - %s not in station map.\n", |
6790 | print_mac(mac, addr)); | 3196 | print_mac(mac, addr)); |
6791 | return; | 3197 | return; |
6792 | } | 3198 | } |
6793 | 3199 | ||
6794 | iwl4965_scan_cancel_timeout(priv, 100); | 3200 | iwl_scan_cancel_timeout(priv, 100); |
6795 | 3201 | ||
6796 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); | 3202 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); |
6797 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 3203 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
@@ -6812,7 +3218,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
6812 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 3218 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
6813 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3219 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
6814 | 3220 | ||
6815 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 3221 | iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
6816 | 3222 | ||
6817 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 3223 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
6818 | 3224 | ||
@@ -6831,7 +3237,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
6831 | 3237 | ||
6832 | IWL_DEBUG_MAC80211("enter\n"); | 3238 | IWL_DEBUG_MAC80211("enter\n"); |
6833 | 3239 | ||
6834 | if (priv->cfg->mod_params->sw_crypto) { | 3240 | if (priv->hw_params.sw_crypto) { |
6835 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); | 3241 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); |
6836 | return -EOPNOTSUPP; | 3242 | return -EOPNOTSUPP; |
6837 | } | 3243 | } |
@@ -6840,7 +3246,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
6840 | /* only support pairwise keys */ | 3246 | /* only support pairwise keys */ |
6841 | return -EOPNOTSUPP; | 3247 | return -EOPNOTSUPP; |
6842 | 3248 | ||
6843 | sta_id = iwl4965_hw_find_station(priv, addr); | 3249 | sta_id = iwl_find_station(priv, addr); |
6844 | if (sta_id == IWL_INVALID_STATION) { | 3250 | if (sta_id == IWL_INVALID_STATION) { |
6845 | IWL_DEBUG_MAC80211("leave - %s not in station map.\n", | 3251 | IWL_DEBUG_MAC80211("leave - %s not in station map.\n", |
6846 | print_mac(mac, addr)); | 3252 | print_mac(mac, addr)); |
@@ -6849,7 +3255,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
6849 | } | 3255 | } |
6850 | 3256 | ||
6851 | mutex_lock(&priv->mutex); | 3257 | mutex_lock(&priv->mutex); |
6852 | iwl4965_scan_cancel_timeout(priv, 100); | 3258 | iwl_scan_cancel_timeout(priv, 100); |
6853 | mutex_unlock(&priv->mutex); | 3259 | mutex_unlock(&priv->mutex); |
6854 | 3260 | ||
6855 | /* If we are getting WEP group key and we didn't receive any key mapping | 3261 | /* If we are getting WEP group key and we didn't receive any key mapping |
@@ -6861,7 +3267,8 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
6861 | if (cmd == SET_KEY) | 3267 | if (cmd == SET_KEY) |
6862 | is_default_wep_key = !priv->key_mapping_key; | 3268 | is_default_wep_key = !priv->key_mapping_key; |
6863 | else | 3269 | else |
6864 | is_default_wep_key = priv->default_wep_key; | 3270 | is_default_wep_key = |
3271 | (key->hw_key_idx == HW_KEY_DEFAULT); | ||
6865 | } | 3272 | } |
6866 | 3273 | ||
6867 | switch (cmd) { | 3274 | switch (cmd) { |
@@ -6877,7 +3284,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
6877 | if (is_default_wep_key) | 3284 | if (is_default_wep_key) |
6878 | ret = iwl_remove_default_wep_key(priv, key); | 3285 | ret = iwl_remove_default_wep_key(priv, key); |
6879 | else | 3286 | else |
6880 | ret = iwl_remove_dynamic_key(priv, sta_id); | 3287 | ret = iwl_remove_dynamic_key(priv, key, sta_id); |
6881 | 3288 | ||
6882 | IWL_DEBUG_MAC80211("disable hwcrypto key\n"); | 3289 | IWL_DEBUG_MAC80211("disable hwcrypto key\n"); |
6883 | break; | 3290 | break; |
@@ -6890,7 +3297,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
6890 | return ret; | 3297 | return ret; |
6891 | } | 3298 | } |
6892 | 3299 | ||
6893 | static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | 3300 | static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, |
6894 | const struct ieee80211_tx_queue_params *params) | 3301 | const struct ieee80211_tx_queue_params *params) |
6895 | { | 3302 | { |
6896 | struct iwl_priv *priv = hw->priv; | 3303 | struct iwl_priv *priv = hw->priv; |
@@ -6927,15 +3334,12 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
6927 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 3334 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
6928 | priv->qos_data.qos_active = 1; | 3335 | priv->qos_data.qos_active = 1; |
6929 | 3336 | ||
6930 | spin_unlock_irqrestore(&priv->lock, flags); | ||
6931 | |||
6932 | mutex_lock(&priv->mutex); | ||
6933 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) | 3337 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) |
6934 | iwl4965_activate_qos(priv, 1); | 3338 | iwl_activate_qos(priv, 1); |
6935 | else if (priv->assoc_id && iwl_is_associated(priv)) | 3339 | else if (priv->assoc_id && iwl_is_associated(priv)) |
6936 | iwl4965_activate_qos(priv, 0); | 3340 | iwl_activate_qos(priv, 0); |
6937 | 3341 | ||
6938 | mutex_unlock(&priv->mutex); | 3342 | spin_unlock_irqrestore(&priv->lock, flags); |
6939 | 3343 | ||
6940 | IWL_DEBUG_MAC80211("leave\n"); | 3344 | IWL_DEBUG_MAC80211("leave\n"); |
6941 | return 0; | 3345 | return 0; |
@@ -6946,8 +3350,8 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
6946 | { | 3350 | { |
6947 | struct iwl_priv *priv = hw->priv; | 3351 | struct iwl_priv *priv = hw->priv; |
6948 | int i, avail; | 3352 | int i, avail; |
6949 | struct iwl4965_tx_queue *txq; | 3353 | struct iwl_tx_queue *txq; |
6950 | struct iwl4965_queue *q; | 3354 | struct iwl_queue *q; |
6951 | unsigned long flags; | 3355 | unsigned long flags; |
6952 | 3356 | ||
6953 | IWL_DEBUG_MAC80211("enter\n"); | 3357 | IWL_DEBUG_MAC80211("enter\n"); |
@@ -6962,11 +3366,11 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
6962 | for (i = 0; i < AC_NUM; i++) { | 3366 | for (i = 0; i < AC_NUM; i++) { |
6963 | txq = &priv->txq[i]; | 3367 | txq = &priv->txq[i]; |
6964 | q = &txq->q; | 3368 | q = &txq->q; |
6965 | avail = iwl4965_queue_space(q); | 3369 | avail = iwl_queue_space(q); |
6966 | 3370 | ||
6967 | stats->data[i].len = q->n_window - avail; | 3371 | stats[i].len = q->n_window - avail; |
6968 | stats->data[i].limit = q->n_window - q->high_mark; | 3372 | stats[i].limit = q->n_window - q->high_mark; |
6969 | stats->data[i].count = q->n_window; | 3373 | stats[i].count = q->n_window; |
6970 | 3374 | ||
6971 | } | 3375 | } |
6972 | spin_unlock_irqrestore(&priv->lock, flags); | 3376 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -6979,14 +3383,9 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
6979 | static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, | 3383 | static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, |
6980 | struct ieee80211_low_level_stats *stats) | 3384 | struct ieee80211_low_level_stats *stats) |
6981 | { | 3385 | { |
6982 | IWL_DEBUG_MAC80211("enter\n"); | 3386 | struct iwl_priv *priv = hw->priv; |
6983 | IWL_DEBUG_MAC80211("leave\n"); | ||
6984 | |||
6985 | return 0; | ||
6986 | } | ||
6987 | 3387 | ||
6988 | static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw) | 3388 | priv = hw->priv; |
6989 | { | ||
6990 | IWL_DEBUG_MAC80211("enter\n"); | 3389 | IWL_DEBUG_MAC80211("enter\n"); |
6991 | IWL_DEBUG_MAC80211("leave\n"); | 3390 | IWL_DEBUG_MAC80211("leave\n"); |
6992 | 3391 | ||
@@ -7001,16 +3400,11 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7001 | mutex_lock(&priv->mutex); | 3400 | mutex_lock(&priv->mutex); |
7002 | IWL_DEBUG_MAC80211("enter\n"); | 3401 | IWL_DEBUG_MAC80211("enter\n"); |
7003 | 3402 | ||
7004 | priv->lq_mngr.lq_ready = 0; | ||
7005 | #ifdef CONFIG_IWL4965_HT | ||
7006 | spin_lock_irqsave(&priv->lock, flags); | 3403 | spin_lock_irqsave(&priv->lock, flags); |
7007 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | 3404 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); |
7008 | spin_unlock_irqrestore(&priv->lock, flags); | 3405 | spin_unlock_irqrestore(&priv->lock, flags); |
7009 | #endif /* CONFIG_IWL4965_HT */ | ||
7010 | |||
7011 | iwlcore_reset_qos(priv); | ||
7012 | 3406 | ||
7013 | cancel_delayed_work(&priv->post_associate); | 3407 | iwl_reset_qos(priv); |
7014 | 3408 | ||
7015 | spin_lock_irqsave(&priv->lock, flags); | 3409 | spin_lock_irqsave(&priv->lock, flags); |
7016 | priv->assoc_id = 0; | 3410 | priv->assoc_id = 0; |
@@ -7040,11 +3434,13 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7040 | * clear RXON_FILTER_ASSOC_MSK bit | 3434 | * clear RXON_FILTER_ASSOC_MSK bit |
7041 | */ | 3435 | */ |
7042 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { | 3436 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { |
7043 | iwl4965_scan_cancel_timeout(priv, 100); | 3437 | iwl_scan_cancel_timeout(priv, 100); |
7044 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3438 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
7045 | iwl4965_commit_rxon(priv); | 3439 | iwl4965_commit_rxon(priv); |
7046 | } | 3440 | } |
7047 | 3441 | ||
3442 | iwl_power_update_mode(priv, 0); | ||
3443 | |||
7048 | /* Per mac80211.h: This is only used in IBSS mode... */ | 3444 | /* Per mac80211.h: This is only used in IBSS mode... */ |
7049 | if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) { | 3445 | if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) { |
7050 | 3446 | ||
@@ -7060,11 +3456,11 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7060 | IWL_DEBUG_MAC80211("leave\n"); | 3456 | IWL_DEBUG_MAC80211("leave\n"); |
7061 | } | 3457 | } |
7062 | 3458 | ||
7063 | static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 3459 | static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) |
7064 | struct ieee80211_tx_control *control) | ||
7065 | { | 3460 | { |
7066 | struct iwl_priv *priv = hw->priv; | 3461 | struct iwl_priv *priv = hw->priv; |
7067 | unsigned long flags; | 3462 | unsigned long flags; |
3463 | __le64 timestamp; | ||
7068 | 3464 | ||
7069 | mutex_lock(&priv->mutex); | 3465 | mutex_lock(&priv->mutex); |
7070 | IWL_DEBUG_MAC80211("enter\n"); | 3466 | IWL_DEBUG_MAC80211("enter\n"); |
@@ -7089,13 +3485,15 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7089 | priv->ibss_beacon = skb; | 3485 | priv->ibss_beacon = skb; |
7090 | 3486 | ||
7091 | priv->assoc_id = 0; | 3487 | priv->assoc_id = 0; |
3488 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | ||
3489 | priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000); | ||
7092 | 3490 | ||
7093 | IWL_DEBUG_MAC80211("leave\n"); | 3491 | IWL_DEBUG_MAC80211("leave\n"); |
7094 | spin_unlock_irqrestore(&priv->lock, flags); | 3492 | spin_unlock_irqrestore(&priv->lock, flags); |
7095 | 3493 | ||
7096 | iwlcore_reset_qos(priv); | 3494 | iwl_reset_qos(priv); |
7097 | 3495 | ||
7098 | queue_work(priv->workqueue, &priv->post_associate.work); | 3496 | iwl4965_post_associate(priv); |
7099 | 3497 | ||
7100 | mutex_unlock(&priv->mutex); | 3498 | mutex_unlock(&priv->mutex); |
7101 | 3499 | ||
@@ -7118,13 +3516,18 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7118 | * See the level definitions in iwl for details. | 3516 | * See the level definitions in iwl for details. |
7119 | */ | 3517 | */ |
7120 | 3518 | ||
7121 | static ssize_t show_debug_level(struct device_driver *d, char *buf) | 3519 | static ssize_t show_debug_level(struct device *d, |
3520 | struct device_attribute *attr, char *buf) | ||
7122 | { | 3521 | { |
7123 | return sprintf(buf, "0x%08X\n", iwl_debug_level); | 3522 | struct iwl_priv *priv = d->driver_data; |
3523 | |||
3524 | return sprintf(buf, "0x%08X\n", priv->debug_level); | ||
7124 | } | 3525 | } |
7125 | static ssize_t store_debug_level(struct device_driver *d, | 3526 | static ssize_t store_debug_level(struct device *d, |
3527 | struct device_attribute *attr, | ||
7126 | const char *buf, size_t count) | 3528 | const char *buf, size_t count) |
7127 | { | 3529 | { |
3530 | struct iwl_priv *priv = d->driver_data; | ||
7128 | char *p = (char *)buf; | 3531 | char *p = (char *)buf; |
7129 | u32 val; | 3532 | u32 val; |
7130 | 3533 | ||
@@ -7133,17 +3536,49 @@ static ssize_t store_debug_level(struct device_driver *d, | |||
7133 | printk(KERN_INFO DRV_NAME | 3536 | printk(KERN_INFO DRV_NAME |
7134 | ": %s is not in hex or decimal form.\n", buf); | 3537 | ": %s is not in hex or decimal form.\n", buf); |
7135 | else | 3538 | else |
7136 | iwl_debug_level = val; | 3539 | priv->debug_level = val; |
7137 | 3540 | ||
7138 | return strnlen(buf, count); | 3541 | return strnlen(buf, count); |
7139 | } | 3542 | } |
7140 | 3543 | ||
7141 | static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | 3544 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, |
7142 | show_debug_level, store_debug_level); | 3545 | show_debug_level, store_debug_level); |
3546 | |||
7143 | 3547 | ||
7144 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 3548 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
7145 | 3549 | ||
7146 | 3550 | ||
3551 | static ssize_t show_version(struct device *d, | ||
3552 | struct device_attribute *attr, char *buf) | ||
3553 | { | ||
3554 | struct iwl_priv *priv = d->driver_data; | ||
3555 | struct iwl_alive_resp *palive = &priv->card_alive; | ||
3556 | ssize_t pos = 0; | ||
3557 | u16 eeprom_ver; | ||
3558 | |||
3559 | if (palive->is_valid) | ||
3560 | pos += sprintf(buf + pos, | ||
3561 | "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n" | ||
3562 | "fw type: 0x%01X 0x%01X\n", | ||
3563 | palive->ucode_major, palive->ucode_minor, | ||
3564 | palive->sw_rev[0], palive->sw_rev[1], | ||
3565 | palive->ver_type, palive->ver_subtype); | ||
3566 | else | ||
3567 | pos += sprintf(buf + pos, "fw not loaded\n"); | ||
3568 | |||
3569 | if (priv->eeprom) { | ||
3570 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | ||
3571 | pos += sprintf(buf + pos, "EEPROM version: 0x%x\n", | ||
3572 | eeprom_ver); | ||
3573 | } else { | ||
3574 | pos += sprintf(buf + pos, "EEPROM not initialzed\n"); | ||
3575 | } | ||
3576 | |||
3577 | return pos; | ||
3578 | } | ||
3579 | |||
3580 | static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL); | ||
3581 | |||
7147 | static ssize_t show_temperature(struct device *d, | 3582 | static ssize_t show_temperature(struct device *d, |
7148 | struct device_attribute *attr, char *buf) | 3583 | struct device_attribute *attr, char *buf) |
7149 | { | 3584 | { |
@@ -7152,7 +3587,7 @@ static ssize_t show_temperature(struct device *d, | |||
7152 | if (!iwl_is_alive(priv)) | 3587 | if (!iwl_is_alive(priv)) |
7153 | return -EAGAIN; | 3588 | return -EAGAIN; |
7154 | 3589 | ||
7155 | return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv)); | 3590 | return sprintf(buf, "%d\n", priv->temperature); |
7156 | } | 3591 | } |
7157 | 3592 | ||
7158 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | 3593 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); |
@@ -7170,7 +3605,7 @@ static ssize_t show_tx_power(struct device *d, | |||
7170 | struct device_attribute *attr, char *buf) | 3605 | struct device_attribute *attr, char *buf) |
7171 | { | 3606 | { |
7172 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3607 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7173 | return sprintf(buf, "%d\n", priv->user_txpower_limit); | 3608 | return sprintf(buf, "%d\n", priv->tx_power_user_lmt); |
7174 | } | 3609 | } |
7175 | 3610 | ||
7176 | static ssize_t store_tx_power(struct device *d, | 3611 | static ssize_t store_tx_power(struct device *d, |
@@ -7186,7 +3621,7 @@ static ssize_t store_tx_power(struct device *d, | |||
7186 | printk(KERN_INFO DRV_NAME | 3621 | printk(KERN_INFO DRV_NAME |
7187 | ": %s is not in decimal form.\n", buf); | 3622 | ": %s is not in decimal form.\n", buf); |
7188 | else | 3623 | else |
7189 | iwl4965_hw_reg_set_txpower(priv, val); | 3624 | iwl_set_tx_power(priv, val, false); |
7190 | 3625 | ||
7191 | return count; | 3626 | return count; |
7192 | } | 3627 | } |
@@ -7211,7 +3646,7 @@ static ssize_t store_flags(struct device *d, | |||
7211 | mutex_lock(&priv->mutex); | 3646 | mutex_lock(&priv->mutex); |
7212 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { | 3647 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { |
7213 | /* Cancel any currently running scans... */ | 3648 | /* Cancel any currently running scans... */ |
7214 | if (iwl4965_scan_cancel_timeout(priv, 100)) | 3649 | if (iwl_scan_cancel_timeout(priv, 100)) |
7215 | IWL_WARNING("Could not cancel scan.\n"); | 3650 | IWL_WARNING("Could not cancel scan.\n"); |
7216 | else { | 3651 | else { |
7217 | IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", | 3652 | IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", |
@@ -7246,7 +3681,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
7246 | mutex_lock(&priv->mutex); | 3681 | mutex_lock(&priv->mutex); |
7247 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { | 3682 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { |
7248 | /* Cancel any currently running scans... */ | 3683 | /* Cancel any currently running scans... */ |
7249 | if (iwl4965_scan_cancel_timeout(priv, 100)) | 3684 | if (iwl_scan_cancel_timeout(priv, 100)) |
7250 | IWL_WARNING("Could not cancel scan.\n"); | 3685 | IWL_WARNING("Could not cancel scan.\n"); |
7251 | else { | 3686 | else { |
7252 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " | 3687 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " |
@@ -7376,20 +3811,11 @@ static ssize_t store_power_level(struct device *d, | |||
7376 | goto out; | 3811 | goto out; |
7377 | } | 3812 | } |
7378 | 3813 | ||
7379 | if ((mode < 1) || (mode > IWL_POWER_LIMIT) || (mode == IWL_POWER_AC)) | 3814 | rc = iwl_power_set_user_mode(priv, mode); |
7380 | mode = IWL_POWER_AC; | 3815 | if (rc) { |
7381 | else | 3816 | IWL_DEBUG_MAC80211("failed setting power mode.\n"); |
7382 | mode |= IWL_POWER_ENABLED; | 3817 | goto out; |
7383 | |||
7384 | if (mode != priv->power_mode) { | ||
7385 | rc = iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(mode)); | ||
7386 | if (rc) { | ||
7387 | IWL_DEBUG_MAC80211("failed setting power mode.\n"); | ||
7388 | goto out; | ||
7389 | } | ||
7390 | priv->power_mode = mode; | ||
7391 | } | 3818 | } |
7392 | |||
7393 | rc = count; | 3819 | rc = count; |
7394 | 3820 | ||
7395 | out: | 3821 | out: |
@@ -7419,7 +3845,7 @@ static ssize_t show_power_level(struct device *d, | |||
7419 | struct device_attribute *attr, char *buf) | 3845 | struct device_attribute *attr, char *buf) |
7420 | { | 3846 | { |
7421 | struct iwl_priv *priv = dev_get_drvdata(d); | 3847 | struct iwl_priv *priv = dev_get_drvdata(d); |
7422 | int level = IWL_POWER_LEVEL(priv->power_mode); | 3848 | int level = priv->power_data.power_mode; |
7423 | char *p = buf; | 3849 | char *p = buf; |
7424 | 3850 | ||
7425 | p += sprintf(p, "%d ", level); | 3851 | p += sprintf(p, "%d ", level); |
@@ -7437,14 +3863,14 @@ static ssize_t show_power_level(struct device *d, | |||
7437 | timeout_duration[level - 1] / 1000, | 3863 | timeout_duration[level - 1] / 1000, |
7438 | period_duration[level - 1] / 1000); | 3864 | period_duration[level - 1] / 1000); |
7439 | } | 3865 | } |
7440 | 3866 | /* | |
7441 | if (!(priv->power_mode & IWL_POWER_ENABLED)) | 3867 | if (!(priv->power_mode & IWL_POWER_ENABLED)) |
7442 | p += sprintf(p, " OFF\n"); | 3868 | p += sprintf(p, " OFF\n"); |
7443 | else | 3869 | else |
7444 | p += sprintf(p, " \n"); | 3870 | p += sprintf(p, " \n"); |
7445 | 3871 | */ | |
3872 | p += sprintf(p, " \n"); | ||
7446 | return (p - buf + 1); | 3873 | return (p - buf + 1); |
7447 | |||
7448 | } | 3874 | } |
7449 | 3875 | ||
7450 | static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | 3876 | static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, |
@@ -7453,8 +3879,62 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
7453 | static ssize_t show_channels(struct device *d, | 3879 | static ssize_t show_channels(struct device *d, |
7454 | struct device_attribute *attr, char *buf) | 3880 | struct device_attribute *attr, char *buf) |
7455 | { | 3881 | { |
7456 | /* all this shit doesn't belong into sysfs anyway */ | 3882 | |
7457 | return 0; | 3883 | struct iwl_priv *priv = dev_get_drvdata(d); |
3884 | struct ieee80211_channel *channels = NULL; | ||
3885 | const struct ieee80211_supported_band *supp_band = NULL; | ||
3886 | int len = 0, i; | ||
3887 | int count = 0; | ||
3888 | |||
3889 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) | ||
3890 | return -EAGAIN; | ||
3891 | |||
3892 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); | ||
3893 | channels = supp_band->channels; | ||
3894 | count = supp_band->n_channels; | ||
3895 | |||
3896 | len += sprintf(&buf[len], | ||
3897 | "Displaying %d channels in 2.4GHz band " | ||
3898 | "(802.11bg):\n", count); | ||
3899 | |||
3900 | for (i = 0; i < count; i++) | ||
3901 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
3902 | ieee80211_frequency_to_channel( | ||
3903 | channels[i].center_freq), | ||
3904 | channels[i].max_power, | ||
3905 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
3906 | " (IEEE 802.11h required)" : "", | ||
3907 | (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
3908 | || (channels[i].flags & | ||
3909 | IEEE80211_CHAN_RADAR)) ? "" : | ||
3910 | ", IBSS", | ||
3911 | channels[i].flags & | ||
3912 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
3913 | "passive only" : "active/passive"); | ||
3914 | |||
3915 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); | ||
3916 | channels = supp_band->channels; | ||
3917 | count = supp_band->n_channels; | ||
3918 | |||
3919 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
3920 | "(802.11a):\n", count); | ||
3921 | |||
3922 | for (i = 0; i < count; i++) | ||
3923 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
3924 | ieee80211_frequency_to_channel( | ||
3925 | channels[i].center_freq), | ||
3926 | channels[i].max_power, | ||
3927 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
3928 | " (IEEE 802.11h required)" : "", | ||
3929 | ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
3930 | || (channels[i].flags & | ||
3931 | IEEE80211_CHAN_RADAR)) ? "" : | ||
3932 | ", IBSS", | ||
3933 | channels[i].flags & | ||
3934 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
3935 | "passive only" : "active/passive"); | ||
3936 | |||
3937 | return len; | ||
7458 | } | 3938 | } |
7459 | 3939 | ||
7460 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 3940 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -7463,7 +3943,7 @@ static ssize_t show_statistics(struct device *d, | |||
7463 | struct device_attribute *attr, char *buf) | 3943 | struct device_attribute *attr, char *buf) |
7464 | { | 3944 | { |
7465 | struct iwl_priv *priv = dev_get_drvdata(d); | 3945 | struct iwl_priv *priv = dev_get_drvdata(d); |
7466 | u32 size = sizeof(struct iwl4965_notif_statistics); | 3946 | u32 size = sizeof(struct iwl_notif_statistics); |
7467 | u32 len = 0, ofs = 0; | 3947 | u32 len = 0, ofs = 0; |
7468 | u8 *data = (u8 *) & priv->statistics; | 3948 | u8 *data = (u8 *) & priv->statistics; |
7469 | int rc = 0; | 3949 | int rc = 0; |
@@ -7497,44 +3977,6 @@ static ssize_t show_statistics(struct device *d, | |||
7497 | 3977 | ||
7498 | static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); | 3978 | static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); |
7499 | 3979 | ||
7500 | static ssize_t show_antenna(struct device *d, | ||
7501 | struct device_attribute *attr, char *buf) | ||
7502 | { | ||
7503 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
7504 | |||
7505 | if (!iwl_is_alive(priv)) | ||
7506 | return -EAGAIN; | ||
7507 | |||
7508 | return sprintf(buf, "%d\n", priv->antenna); | ||
7509 | } | ||
7510 | |||
7511 | static ssize_t store_antenna(struct device *d, | ||
7512 | struct device_attribute *attr, | ||
7513 | const char *buf, size_t count) | ||
7514 | { | ||
7515 | int ant; | ||
7516 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
7517 | |||
7518 | if (count == 0) | ||
7519 | return 0; | ||
7520 | |||
7521 | if (sscanf(buf, "%1i", &ant) != 1) { | ||
7522 | IWL_DEBUG_INFO("not in hex or decimal form.\n"); | ||
7523 | return count; | ||
7524 | } | ||
7525 | |||
7526 | if ((ant >= 0) && (ant <= 2)) { | ||
7527 | IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant); | ||
7528 | priv->antenna = (enum iwl4965_antenna)ant; | ||
7529 | } else | ||
7530 | IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant); | ||
7531 | |||
7532 | |||
7533 | return count; | ||
7534 | } | ||
7535 | |||
7536 | static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); | ||
7537 | |||
7538 | static ssize_t show_status(struct device *d, | 3980 | static ssize_t show_status(struct device *d, |
7539 | struct device_attribute *attr, char *buf) | 3981 | struct device_attribute *attr, char *buf) |
7540 | { | 3982 | { |
@@ -7546,41 +3988,13 @@ static ssize_t show_status(struct device *d, | |||
7546 | 3988 | ||
7547 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | 3989 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); |
7548 | 3990 | ||
7549 | static ssize_t dump_error_log(struct device *d, | ||
7550 | struct device_attribute *attr, | ||
7551 | const char *buf, size_t count) | ||
7552 | { | ||
7553 | char *p = (char *)buf; | ||
7554 | |||
7555 | if (p[0] == '1') | ||
7556 | iwl4965_dump_nic_error_log((struct iwl_priv *)d->driver_data); | ||
7557 | |||
7558 | return strnlen(buf, count); | ||
7559 | } | ||
7560 | |||
7561 | static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); | ||
7562 | |||
7563 | static ssize_t dump_event_log(struct device *d, | ||
7564 | struct device_attribute *attr, | ||
7565 | const char *buf, size_t count) | ||
7566 | { | ||
7567 | char *p = (char *)buf; | ||
7568 | |||
7569 | if (p[0] == '1') | ||
7570 | iwl4965_dump_nic_event_log((struct iwl_priv *)d->driver_data); | ||
7571 | |||
7572 | return strnlen(buf, count); | ||
7573 | } | ||
7574 | |||
7575 | static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); | ||
7576 | |||
7577 | /***************************************************************************** | 3991 | /***************************************************************************** |
7578 | * | 3992 | * |
7579 | * driver setup and teardown | 3993 | * driver setup and teardown |
7580 | * | 3994 | * |
7581 | *****************************************************************************/ | 3995 | *****************************************************************************/ |
7582 | 3996 | ||
7583 | static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | 3997 | static void iwl_setup_deferred_work(struct iwl_priv *priv) |
7584 | { | 3998 | { |
7585 | priv->workqueue = create_workqueue(DRV_NAME); | 3999 | priv->workqueue = create_workqueue(DRV_NAME); |
7586 | 4000 | ||
@@ -7589,38 +4003,42 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | |||
7589 | INIT_WORK(&priv->up, iwl4965_bg_up); | 4003 | INIT_WORK(&priv->up, iwl4965_bg_up); |
7590 | INIT_WORK(&priv->restart, iwl4965_bg_restart); | 4004 | INIT_WORK(&priv->restart, iwl4965_bg_restart); |
7591 | INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish); | 4005 | INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish); |
7592 | INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed); | ||
7593 | INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan); | ||
7594 | INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan); | ||
7595 | INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); | 4006 | INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); |
7596 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); | 4007 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); |
7597 | INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); | 4008 | INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); |
7598 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start); | 4009 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
7599 | INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start); | 4010 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
7600 | INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check); | 4011 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
4012 | |||
4013 | /* FIXME : remove when resolved PENDING */ | ||
4014 | INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); | ||
4015 | iwl_setup_scan_deferred_work(priv); | ||
4016 | |||
4017 | if (priv->cfg->ops->lib->setup_deferred_work) | ||
4018 | priv->cfg->ops->lib->setup_deferred_work(priv); | ||
7601 | 4019 | ||
7602 | iwl4965_hw_setup_deferred_work(priv); | 4020 | init_timer(&priv->statistics_periodic); |
4021 | priv->statistics_periodic.data = (unsigned long)priv; | ||
4022 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; | ||
7603 | 4023 | ||
7604 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | 4024 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) |
7605 | iwl4965_irq_tasklet, (unsigned long)priv); | 4025 | iwl4965_irq_tasklet, (unsigned long)priv); |
7606 | } | 4026 | } |
7607 | 4027 | ||
7608 | static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) | 4028 | static void iwl_cancel_deferred_work(struct iwl_priv *priv) |
7609 | { | 4029 | { |
7610 | iwl4965_hw_cancel_deferred_work(priv); | 4030 | if (priv->cfg->ops->lib->cancel_deferred_work) |
4031 | priv->cfg->ops->lib->cancel_deferred_work(priv); | ||
7611 | 4032 | ||
7612 | cancel_delayed_work_sync(&priv->init_alive_start); | 4033 | cancel_delayed_work_sync(&priv->init_alive_start); |
7613 | cancel_delayed_work(&priv->scan_check); | 4034 | cancel_delayed_work(&priv->scan_check); |
7614 | cancel_delayed_work(&priv->alive_start); | 4035 | cancel_delayed_work(&priv->alive_start); |
7615 | cancel_delayed_work(&priv->post_associate); | ||
7616 | cancel_work_sync(&priv->beacon_update); | 4036 | cancel_work_sync(&priv->beacon_update); |
4037 | del_timer_sync(&priv->statistics_periodic); | ||
7617 | } | 4038 | } |
7618 | 4039 | ||
7619 | static struct attribute *iwl4965_sysfs_entries[] = { | 4040 | static struct attribute *iwl4965_sysfs_entries[] = { |
7620 | &dev_attr_antenna.attr, | ||
7621 | &dev_attr_channels.attr, | 4041 | &dev_attr_channels.attr, |
7622 | &dev_attr_dump_errors.attr, | ||
7623 | &dev_attr_dump_events.attr, | ||
7624 | &dev_attr_flags.attr, | 4042 | &dev_attr_flags.attr, |
7625 | &dev_attr_filter_flags.attr, | 4043 | &dev_attr_filter_flags.attr, |
7626 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 4044 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
@@ -7633,6 +4051,10 @@ static struct attribute *iwl4965_sysfs_entries[] = { | |||
7633 | &dev_attr_status.attr, | 4051 | &dev_attr_status.attr, |
7634 | &dev_attr_temperature.attr, | 4052 | &dev_attr_temperature.attr, |
7635 | &dev_attr_tx_power.attr, | 4053 | &dev_attr_tx_power.attr, |
4054 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
4055 | &dev_attr_debug_level.attr, | ||
4056 | #endif | ||
4057 | &dev_attr_version.attr, | ||
7636 | 4058 | ||
7637 | NULL | 4059 | NULL |
7638 | }; | 4060 | }; |
@@ -7656,13 +4078,9 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
7656 | .get_stats = iwl4965_mac_get_stats, | 4078 | .get_stats = iwl4965_mac_get_stats, |
7657 | .get_tx_stats = iwl4965_mac_get_tx_stats, | 4079 | .get_tx_stats = iwl4965_mac_get_tx_stats, |
7658 | .conf_tx = iwl4965_mac_conf_tx, | 4080 | .conf_tx = iwl4965_mac_conf_tx, |
7659 | .get_tsf = iwl4965_mac_get_tsf, | ||
7660 | .reset_tsf = iwl4965_mac_reset_tsf, | 4081 | .reset_tsf = iwl4965_mac_reset_tsf, |
7661 | .beacon_update = iwl4965_mac_beacon_update, | ||
7662 | .bss_info_changed = iwl4965_bss_info_changed, | 4082 | .bss_info_changed = iwl4965_bss_info_changed, |
7663 | #ifdef CONFIG_IWL4965_HT | ||
7664 | .ampdu_action = iwl4965_mac_ampdu_action, | 4083 | .ampdu_action = iwl4965_mac_ampdu_action, |
7665 | #endif /* CONFIG_IWL4965_HT */ | ||
7666 | .hw_scan = iwl4965_mac_hw_scan | 4084 | .hw_scan = iwl4965_mac_hw_scan |
7667 | }; | 4085 | }; |
7668 | 4086 | ||
@@ -7682,7 +4100,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7682 | /* Disabling hardware scan means that mac80211 will perform scans | 4100 | /* Disabling hardware scan means that mac80211 will perform scans |
7683 | * "the hard way", rather than using device's scan. */ | 4101 | * "the hard way", rather than using device's scan. */ |
7684 | if (cfg->mod_params->disable_hw_scan) { | 4102 | if (cfg->mod_params->disable_hw_scan) { |
7685 | IWL_DEBUG_INFO("Disabling hw_scan\n"); | 4103 | if (cfg->mod_params->debug & IWL_DL_INFO) |
4104 | dev_printk(KERN_DEBUG, &(pdev->dev), | ||
4105 | "Disabling hw_scan\n"); | ||
7686 | iwl4965_hw_ops.hw_scan = NULL; | 4106 | iwl4965_hw_ops.hw_scan = NULL; |
7687 | } | 4107 | } |
7688 | 4108 | ||
@@ -7701,7 +4121,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7701 | priv->pci_dev = pdev; | 4121 | priv->pci_dev = pdev; |
7702 | 4122 | ||
7703 | #ifdef CONFIG_IWLWIFI_DEBUG | 4123 | #ifdef CONFIG_IWLWIFI_DEBUG |
7704 | iwl_debug_level = priv->cfg->mod_params->debug; | 4124 | priv->debug_level = priv->cfg->mod_params->debug; |
7705 | atomic_set(&priv->restrict_refcnt, 0); | 4125 | atomic_set(&priv->restrict_refcnt, 0); |
7706 | #endif | 4126 | #endif |
7707 | 4127 | ||
@@ -7715,13 +4135,19 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7715 | 4135 | ||
7716 | pci_set_master(pdev); | 4136 | pci_set_master(pdev); |
7717 | 4137 | ||
7718 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 4138 | err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); |
7719 | if (!err) | 4139 | if (!err) |
7720 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 4140 | err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); |
4141 | if (err) { | ||
4142 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
4143 | if (!err) | ||
4144 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
4145 | /* both attempts failed: */ | ||
7721 | if (err) { | 4146 | if (err) { |
7722 | printk(KERN_WARNING DRV_NAME | 4147 | printk(KERN_WARNING "%s: No suitable DMA available.\n", |
7723 | ": No suitable DMA available.\n"); | 4148 | DRV_NAME); |
7724 | goto out_pci_disable_device; | 4149 | goto out_pci_disable_device; |
4150 | } | ||
7725 | } | 4151 | } |
7726 | 4152 | ||
7727 | err = pci_request_regions(pdev, DRV_NAME); | 4153 | err = pci_request_regions(pdev, DRV_NAME); |
@@ -7747,31 +4173,31 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7747 | (unsigned long long) pci_resource_len(pdev, 0)); | 4173 | (unsigned long long) pci_resource_len(pdev, 0)); |
7748 | IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base); | 4174 | IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base); |
7749 | 4175 | ||
4176 | iwl_hw_detect(priv); | ||
7750 | printk(KERN_INFO DRV_NAME | 4177 | printk(KERN_INFO DRV_NAME |
7751 | ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name); | 4178 | ": Detected Intel Wireless WiFi Link %s REV=0x%X\n", |
4179 | priv->cfg->name, priv->hw_rev); | ||
7752 | 4180 | ||
7753 | /***************** | 4181 | /* amp init */ |
7754 | * 4. Read EEPROM | 4182 | err = priv->cfg->ops->lib->apm_ops.init(priv); |
7755 | *****************/ | ||
7756 | /* nic init */ | ||
7757 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | ||
7758 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | ||
7759 | |||
7760 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
7761 | err = iwl_poll_bit(priv, CSR_GP_CNTRL, | ||
7762 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
7763 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
7764 | if (err < 0) { | 4183 | if (err < 0) { |
7765 | IWL_DEBUG_INFO("Failed to init the card\n"); | 4184 | IWL_DEBUG_INFO("Failed to init APMG\n"); |
7766 | goto out_iounmap; | 4185 | goto out_iounmap; |
7767 | } | 4186 | } |
4187 | /***************** | ||
4188 | * 4. Read EEPROM | ||
4189 | *****************/ | ||
7768 | /* Read the EEPROM */ | 4190 | /* Read the EEPROM */ |
7769 | err = iwl_eeprom_init(priv); | 4191 | err = iwl_eeprom_init(priv); |
7770 | if (err) { | 4192 | if (err) { |
7771 | IWL_ERROR("Unable to init EEPROM\n"); | 4193 | IWL_ERROR("Unable to init EEPROM\n"); |
7772 | goto out_iounmap; | 4194 | goto out_iounmap; |
7773 | } | 4195 | } |
7774 | /* MAC Address location in EEPROM same for 3945/4965 */ | 4196 | err = iwl_eeprom_check_version(priv); |
4197 | if (err) | ||
4198 | goto out_iounmap; | ||
4199 | |||
4200 | /* extract MAC Address */ | ||
7775 | iwl_eeprom_get_mac(priv, priv->mac_addr); | 4201 | iwl_eeprom_get_mac(priv, priv->mac_addr); |
7776 | IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); | 4202 | IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); |
7777 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); | 4203 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); |
@@ -7779,19 +4205,18 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7779 | /************************ | 4205 | /************************ |
7780 | * 5. Setup HW constants | 4206 | * 5. Setup HW constants |
7781 | ************************/ | 4207 | ************************/ |
7782 | /* Device-specific setup */ | 4208 | if (iwl_set_hw_params(priv)) { |
7783 | if (priv->cfg->ops->lib->set_hw_params(priv)) { | ||
7784 | IWL_ERROR("failed to set hw parameters\n"); | 4209 | IWL_ERROR("failed to set hw parameters\n"); |
7785 | goto out_iounmap; | 4210 | goto out_free_eeprom; |
7786 | } | 4211 | } |
7787 | 4212 | ||
7788 | /******************* | 4213 | /******************* |
7789 | * 6. Setup hw/priv | 4214 | * 6. Setup priv |
7790 | *******************/ | 4215 | *******************/ |
7791 | 4216 | ||
7792 | err = iwl_setup(priv); | 4217 | err = iwl_init_drv(priv); |
7793 | if (err) | 4218 | if (err) |
7794 | goto out_unset_hw_params; | 4219 | goto out_free_eeprom; |
7795 | /* At this point both hw and priv are initialized. */ | 4220 | /* At this point both hw and priv are initialized. */ |
7796 | 4221 | ||
7797 | /********************************** | 4222 | /********************************** |
@@ -7804,9 +4229,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7804 | IWL_DEBUG_INFO("Radio disabled.\n"); | 4229 | IWL_DEBUG_INFO("Radio disabled.\n"); |
7805 | } | 4230 | } |
7806 | 4231 | ||
7807 | if (priv->cfg->mod_params->enable_qos) | ||
7808 | priv->qos_data.qos_enable = 1; | ||
7809 | |||
7810 | /******************** | 4232 | /******************** |
7811 | * 8. Setup services | 4233 | * 8. Setup services |
7812 | ********************/ | 4234 | ********************/ |
@@ -7817,17 +4239,12 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7817 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 4239 | err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
7818 | if (err) { | 4240 | if (err) { |
7819 | IWL_ERROR("failed to create sysfs device attributes\n"); | 4241 | IWL_ERROR("failed to create sysfs device attributes\n"); |
7820 | goto out_unset_hw_params; | 4242 | goto out_uninit_drv; |
7821 | } | 4243 | } |
7822 | 4244 | ||
7823 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
7824 | if (err) { | ||
7825 | IWL_ERROR("failed to create debugfs files\n"); | ||
7826 | goto out_remove_sysfs; | ||
7827 | } | ||
7828 | 4245 | ||
7829 | iwl4965_setup_deferred_work(priv); | 4246 | iwl_setup_deferred_work(priv); |
7830 | iwl4965_setup_rx_handlers(priv); | 4247 | iwl_setup_rx_handlers(priv); |
7831 | 4248 | ||
7832 | /******************** | 4249 | /******************** |
7833 | * 9. Conclude | 4250 | * 9. Conclude |
@@ -7835,14 +4252,31 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7835 | pci_save_state(pdev); | 4252 | pci_save_state(pdev); |
7836 | pci_disable_device(pdev); | 4253 | pci_disable_device(pdev); |
7837 | 4254 | ||
7838 | /* notify iwlcore to init */ | 4255 | /********************************** |
7839 | iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT); | 4256 | * 10. Setup and register mac80211 |
4257 | **********************************/ | ||
4258 | |||
4259 | err = iwl_setup_mac(priv); | ||
4260 | if (err) | ||
4261 | goto out_remove_sysfs; | ||
4262 | |||
4263 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
4264 | if (err) | ||
4265 | IWL_ERROR("failed to create debugfs files\n"); | ||
4266 | |||
4267 | err = iwl_rfkill_init(priv); | ||
4268 | if (err) | ||
4269 | IWL_ERROR("Unable to initialize RFKILL system. " | ||
4270 | "Ignoring error: %d\n", err); | ||
4271 | iwl_power_initialize(priv); | ||
7840 | return 0; | 4272 | return 0; |
7841 | 4273 | ||
7842 | out_remove_sysfs: | 4274 | out_remove_sysfs: |
7843 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 4275 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
7844 | out_unset_hw_params: | 4276 | out_uninit_drv: |
7845 | iwl4965_unset_hw_params(priv); | 4277 | iwl_uninit_drv(priv); |
4278 | out_free_eeprom: | ||
4279 | iwl_eeprom_free(priv); | ||
7846 | out_iounmap: | 4280 | out_iounmap: |
7847 | pci_iounmap(pdev, priv->hw_base); | 4281 | pci_iounmap(pdev, priv->hw_base); |
7848 | out_pci_release_regions: | 4282 | out_pci_release_regions: |
@@ -7859,8 +4293,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7859 | static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | 4293 | static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) |
7860 | { | 4294 | { |
7861 | struct iwl_priv *priv = pci_get_drvdata(pdev); | 4295 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
7862 | struct list_head *p, *q; | ||
7863 | int i; | ||
7864 | unsigned long flags; | 4296 | unsigned long flags; |
7865 | 4297 | ||
7866 | if (!priv) | 4298 | if (!priv) |
@@ -7868,6 +4300,9 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
7868 | 4300 | ||
7869 | IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n"); | 4301 | IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n"); |
7870 | 4302 | ||
4303 | iwl_dbgfs_unregister(priv); | ||
4304 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | ||
4305 | |||
7871 | if (priv->mac80211_registered) { | 4306 | if (priv->mac80211_registered) { |
7872 | ieee80211_unregister_hw(priv->hw); | 4307 | ieee80211_unregister_hw(priv->hw); |
7873 | priv->mac80211_registered = 0; | 4308 | priv->mac80211_registered = 0; |
@@ -7886,26 +4321,15 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
7886 | 4321 | ||
7887 | iwl_synchronize_irq(priv); | 4322 | iwl_synchronize_irq(priv); |
7888 | 4323 | ||
7889 | /* Free MAC hash list for ADHOC */ | 4324 | iwl_rfkill_unregister(priv); |
7890 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { | ||
7891 | list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) { | ||
7892 | list_del(p); | ||
7893 | kfree(list_entry(p, struct iwl4965_ibss_seq, list)); | ||
7894 | } | ||
7895 | } | ||
7896 | |||
7897 | iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT); | ||
7898 | iwl_dbgfs_unregister(priv); | ||
7899 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | ||
7900 | |||
7901 | iwl4965_dealloc_ucode_pci(priv); | 4325 | iwl4965_dealloc_ucode_pci(priv); |
7902 | 4326 | ||
7903 | if (priv->rxq.bd) | 4327 | if (priv->rxq.bd) |
7904 | iwl4965_rx_queue_free(priv, &priv->rxq); | 4328 | iwl_rx_queue_free(priv, &priv->rxq); |
7905 | iwl4965_hw_txq_ctx_free(priv); | 4329 | iwl_hw_txq_ctx_free(priv); |
7906 | 4330 | ||
7907 | iwl4965_unset_hw_params(priv); | 4331 | iwl_clear_stations_table(priv); |
7908 | iwlcore_clear_stations_table(priv); | 4332 | iwl_eeprom_free(priv); |
7909 | 4333 | ||
7910 | 4334 | ||
7911 | /*netif_stop_queue(dev); */ | 4335 | /*netif_stop_queue(dev); */ |
@@ -7922,8 +4346,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
7922 | pci_disable_device(pdev); | 4346 | pci_disable_device(pdev); |
7923 | pci_set_drvdata(pdev, NULL); | 4347 | pci_set_drvdata(pdev, NULL); |
7924 | 4348 | ||
7925 | iwl_free_channel_map(priv); | 4349 | iwl_uninit_drv(priv); |
7926 | iwl4965_free_geos(priv); | ||
7927 | 4350 | ||
7928 | if (priv->ibss_beacon) | 4351 | if (priv->ibss_beacon) |
7929 | dev_kfree_skb(priv->ibss_beacon); | 4352 | dev_kfree_skb(priv->ibss_beacon); |
@@ -7973,6 +4396,19 @@ static int iwl4965_pci_resume(struct pci_dev *pdev) | |||
7973 | static struct pci_device_id iwl_hw_card_ids[] = { | 4396 | static struct pci_device_id iwl_hw_card_ids[] = { |
7974 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, | 4397 | {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)}, |
7975 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, | 4398 | {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)}, |
4399 | #ifdef CONFIG_IWL5000 | ||
4400 | {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)}, | ||
4401 | {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)}, | ||
4402 | {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)}, | ||
4403 | {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)}, | ||
4404 | {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)}, | ||
4405 | {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)}, | ||
4406 | {IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)}, | ||
4407 | {IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)}, | ||
4408 | {IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)}, | ||
4409 | {IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)}, | ||
4410 | {IWL_PCI_DEVICE(0x423A, PCI_ANY_ID, iwl5350_agn_cfg)}, | ||
4411 | #endif /* CONFIG_IWL5000 */ | ||
7976 | {0} | 4412 | {0} |
7977 | }; | 4413 | }; |
7978 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); | 4414 | MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); |
@@ -8006,20 +4442,9 @@ static int __init iwl4965_init(void) | |||
8006 | IWL_ERROR("Unable to initialize PCI module\n"); | 4442 | IWL_ERROR("Unable to initialize PCI module\n"); |
8007 | goto error_register; | 4443 | goto error_register; |
8008 | } | 4444 | } |
8009 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
8010 | ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level); | ||
8011 | if (ret) { | ||
8012 | IWL_ERROR("Unable to create driver sysfs file\n"); | ||
8013 | goto error_debug; | ||
8014 | } | ||
8015 | #endif | ||
8016 | 4445 | ||
8017 | return ret; | 4446 | return ret; |
8018 | 4447 | ||
8019 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
8020 | error_debug: | ||
8021 | pci_unregister_driver(&iwl_driver); | ||
8022 | #endif | ||
8023 | error_register: | 4448 | error_register: |
8024 | iwl4965_rate_control_unregister(); | 4449 | iwl4965_rate_control_unregister(); |
8025 | return ret; | 4450 | return ret; |
@@ -8027,9 +4452,6 @@ error_register: | |||
8027 | 4452 | ||
8028 | static void __exit iwl4965_exit(void) | 4453 | static void __exit iwl4965_exit(void) |
8029 | { | 4454 | { |
8030 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
8031 | driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level); | ||
8032 | #endif | ||
8033 | pci_unregister_driver(&iwl_driver); | 4455 | pci_unregister_driver(&iwl_driver); |
8034 | iwl4965_rate_control_unregister(); | 4456 | iwl4965_rate_control_unregister(); |
8035 | } | 4457 | } |