diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 447 |
1 files changed, 385 insertions, 62 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 087e90b328c..a461620b489 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -38,6 +38,13 @@ | |||
38 | #include "rt61pci.h" | 38 | #include "rt61pci.h" |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Allow hardware encryption to be disabled. | ||
42 | */ | ||
43 | static int modparam_nohwcrypt = 0; | ||
44 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | ||
45 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | ||
46 | |||
47 | /* | ||
41 | * Register access. | 48 | * Register access. |
42 | * BBP and RF register require indirect register access, | 49 | * BBP and RF register require indirect register access, |
43 | * and use the CSR registers PHY_CSR3 and PHY_CSR4 to achieve this. | 50 | * and use the CSR registers PHY_CSR3 and PHY_CSR4 to achieve this. |
@@ -156,7 +163,7 @@ rf_write: | |||
156 | rt2x00_rf_write(rt2x00dev, word, value); | 163 | rt2x00_rf_write(rt2x00dev, word, value); |
157 | } | 164 | } |
158 | 165 | ||
159 | #ifdef CONFIG_RT61PCI_LEDS | 166 | #ifdef CONFIG_RT2X00_LIB_LEDS |
160 | /* | 167 | /* |
161 | * This function is only called from rt61pci_led_brightness() | 168 | * This function is only called from rt61pci_led_brightness() |
162 | * make gcc happy by placing this function inside the | 169 | * make gcc happy by placing this function inside the |
@@ -188,7 +195,7 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
188 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | 195 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); |
189 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | 196 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); |
190 | } | 197 | } |
191 | #endif /* CONFIG_RT61PCI_LEDS */ | 198 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
192 | 199 | ||
193 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 200 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
194 | { | 201 | { |
@@ -264,7 +271,7 @@ static const struct rt2x00debug rt61pci_rt2x00debug = { | |||
264 | }; | 271 | }; |
265 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 272 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
266 | 273 | ||
267 | #ifdef CONFIG_RT61PCI_RFKILL | 274 | #ifdef CONFIG_RT2X00_LIB_RFKILL |
268 | static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | 275 | static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) |
269 | { | 276 | { |
270 | u32 reg; | 277 | u32 reg; |
@@ -274,9 +281,9 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
274 | } | 281 | } |
275 | #else | 282 | #else |
276 | #define rt61pci_rfkill_poll NULL | 283 | #define rt61pci_rfkill_poll NULL |
277 | #endif /* CONFIG_RT61PCI_RFKILL */ | 284 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ |
278 | 285 | ||
279 | #ifdef CONFIG_RT61PCI_LEDS | 286 | #ifdef CONFIG_RT2X00_LIB_LEDS |
280 | static void rt61pci_brightness_set(struct led_classdev *led_cdev, | 287 | static void rt61pci_brightness_set(struct led_classdev *led_cdev, |
281 | enum led_brightness brightness) | 288 | enum led_brightness brightness) |
282 | { | 289 | { |
@@ -341,11 +348,209 @@ static void rt61pci_init_led(struct rt2x00_dev *rt2x00dev, | |||
341 | led->led_dev.blink_set = rt61pci_blink_set; | 348 | led->led_dev.blink_set = rt61pci_blink_set; |
342 | led->flags = LED_INITIALIZED; | 349 | led->flags = LED_INITIALIZED; |
343 | } | 350 | } |
344 | #endif /* CONFIG_RT61PCI_LEDS */ | 351 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
345 | 352 | ||
346 | /* | 353 | /* |
347 | * Configuration handlers. | 354 | * Configuration handlers. |
348 | */ | 355 | */ |
356 | static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, | ||
357 | struct rt2x00lib_crypto *crypto, | ||
358 | struct ieee80211_key_conf *key) | ||
359 | { | ||
360 | struct hw_key_entry key_entry; | ||
361 | struct rt2x00_field32 field; | ||
362 | u32 mask; | ||
363 | u32 reg; | ||
364 | |||
365 | if (crypto->cmd == SET_KEY) { | ||
366 | /* | ||
367 | * rt2x00lib can't determine the correct free | ||
368 | * key_idx for shared keys. We have 1 register | ||
369 | * with key valid bits. The goal is simple, read | ||
370 | * the register, if that is full we have no slots | ||
371 | * left. | ||
372 | * Note that each BSS is allowed to have up to 4 | ||
373 | * shared keys, so put a mask over the allowed | ||
374 | * entries. | ||
375 | */ | ||
376 | mask = (0xf << crypto->bssidx); | ||
377 | |||
378 | rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®); | ||
379 | reg &= mask; | ||
380 | |||
381 | if (reg && reg == mask) | ||
382 | return -ENOSPC; | ||
383 | |||
384 | key->hw_key_idx += reg ? ffz(reg) : 0; | ||
385 | |||
386 | /* | ||
387 | * Upload key to hardware | ||
388 | */ | ||
389 | memcpy(key_entry.key, crypto->key, | ||
390 | sizeof(key_entry.key)); | ||
391 | memcpy(key_entry.tx_mic, crypto->tx_mic, | ||
392 | sizeof(key_entry.tx_mic)); | ||
393 | memcpy(key_entry.rx_mic, crypto->rx_mic, | ||
394 | sizeof(key_entry.rx_mic)); | ||
395 | |||
396 | reg = SHARED_KEY_ENTRY(key->hw_key_idx); | ||
397 | rt2x00pci_register_multiwrite(rt2x00dev, reg, | ||
398 | &key_entry, sizeof(key_entry)); | ||
399 | |||
400 | /* | ||
401 | * The cipher types are stored over 2 registers. | ||
402 | * bssidx 0 and 1 keys are stored in SEC_CSR1 and | ||
403 | * bssidx 1 and 2 keys are stored in SEC_CSR5. | ||
404 | * Using the correct defines correctly will cause overhead, | ||
405 | * so just calculate the correct offset. | ||
406 | */ | ||
407 | if (key->hw_key_idx < 8) { | ||
408 | field.bit_offset = (3 * key->hw_key_idx); | ||
409 | field.bit_mask = 0x7 << field.bit_offset; | ||
410 | |||
411 | rt2x00pci_register_read(rt2x00dev, SEC_CSR1, ®); | ||
412 | rt2x00_set_field32(®, field, crypto->cipher); | ||
413 | rt2x00pci_register_write(rt2x00dev, SEC_CSR1, reg); | ||
414 | } else { | ||
415 | field.bit_offset = (3 * (key->hw_key_idx - 8)); | ||
416 | field.bit_mask = 0x7 << field.bit_offset; | ||
417 | |||
418 | rt2x00pci_register_read(rt2x00dev, SEC_CSR5, ®); | ||
419 | rt2x00_set_field32(®, field, crypto->cipher); | ||
420 | rt2x00pci_register_write(rt2x00dev, SEC_CSR5, reg); | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * The driver does not support the IV/EIV generation | ||
425 | * in hardware. However it doesn't support the IV/EIV | ||
426 | * inside the ieee80211 frame either, but requires it | ||
427 | * to be provided seperately for the descriptor. | ||
428 | * rt2x00lib will cut the IV/EIV data out of all frames | ||
429 | * given to us by mac80211, but we must tell mac80211 | ||
430 | * to generate the IV/EIV data. | ||
431 | */ | ||
432 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * SEC_CSR0 contains only single-bit fields to indicate | ||
437 | * a particular key is valid. Because using the FIELD32() | ||
438 | * defines directly will cause a lot of overhead we use | ||
439 | * a calculation to determine the correct bit directly. | ||
440 | */ | ||
441 | mask = 1 << key->hw_key_idx; | ||
442 | |||
443 | rt2x00pci_register_read(rt2x00dev, SEC_CSR0, ®); | ||
444 | if (crypto->cmd == SET_KEY) | ||
445 | reg |= mask; | ||
446 | else if (crypto->cmd == DISABLE_KEY) | ||
447 | reg &= ~mask; | ||
448 | rt2x00pci_register_write(rt2x00dev, SEC_CSR0, reg); | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | ||
454 | struct rt2x00lib_crypto *crypto, | ||
455 | struct ieee80211_key_conf *key) | ||
456 | { | ||
457 | struct hw_pairwise_ta_entry addr_entry; | ||
458 | struct hw_key_entry key_entry; | ||
459 | u32 mask; | ||
460 | u32 reg; | ||
461 | |||
462 | if (crypto->cmd == SET_KEY) { | ||
463 | /* | ||
464 | * rt2x00lib can't determine the correct free | ||
465 | * key_idx for pairwise keys. We have 2 registers | ||
466 | * with key valid bits. The goal is simple, read | ||
467 | * the first register, if that is full move to | ||
468 | * the next register. | ||
469 | * When both registers are full, we drop the key, | ||
470 | * otherwise we use the first invalid entry. | ||
471 | */ | ||
472 | rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); | ||
473 | if (reg && reg == ~0) { | ||
474 | key->hw_key_idx = 32; | ||
475 | rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®); | ||
476 | if (reg && reg == ~0) | ||
477 | return -ENOSPC; | ||
478 | } | ||
479 | |||
480 | key->hw_key_idx += reg ? ffz(reg) : 0; | ||
481 | |||
482 | /* | ||
483 | * Upload key to hardware | ||
484 | */ | ||
485 | memcpy(key_entry.key, crypto->key, | ||
486 | sizeof(key_entry.key)); | ||
487 | memcpy(key_entry.tx_mic, crypto->tx_mic, | ||
488 | sizeof(key_entry.tx_mic)); | ||
489 | memcpy(key_entry.rx_mic, crypto->rx_mic, | ||
490 | sizeof(key_entry.rx_mic)); | ||
491 | |||
492 | memset(&addr_entry, 0, sizeof(addr_entry)); | ||
493 | memcpy(&addr_entry, crypto->address, ETH_ALEN); | ||
494 | addr_entry.cipher = crypto->cipher; | ||
495 | |||
496 | reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); | ||
497 | rt2x00pci_register_multiwrite(rt2x00dev, reg, | ||
498 | &key_entry, sizeof(key_entry)); | ||
499 | |||
500 | reg = PAIRWISE_TA_ENTRY(key->hw_key_idx); | ||
501 | rt2x00pci_register_multiwrite(rt2x00dev, reg, | ||
502 | &addr_entry, sizeof(addr_entry)); | ||
503 | |||
504 | /* | ||
505 | * Enable pairwise lookup table for given BSS idx, | ||
506 | * without this received frames will not be decrypted | ||
507 | * by the hardware. | ||
508 | */ | ||
509 | rt2x00pci_register_read(rt2x00dev, SEC_CSR4, ®); | ||
510 | reg |= (1 << crypto->bssidx); | ||
511 | rt2x00pci_register_write(rt2x00dev, SEC_CSR4, reg); | ||
512 | |||
513 | /* | ||
514 | * The driver does not support the IV/EIV generation | ||
515 | * in hardware. However it doesn't support the IV/EIV | ||
516 | * inside the ieee80211 frame either, but requires it | ||
517 | * to be provided seperately for the descriptor. | ||
518 | * rt2x00lib will cut the IV/EIV data out of all frames | ||
519 | * given to us by mac80211, but we must tell mac80211 | ||
520 | * to generate the IV/EIV data. | ||
521 | */ | ||
522 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
523 | } | ||
524 | |||
525 | /* | ||
526 | * SEC_CSR2 and SEC_CSR3 contain only single-bit fields to indicate | ||
527 | * a particular key is valid. Because using the FIELD32() | ||
528 | * defines directly will cause a lot of overhead we use | ||
529 | * a calculation to determine the correct bit directly. | ||
530 | */ | ||
531 | if (key->hw_key_idx < 32) { | ||
532 | mask = 1 << key->hw_key_idx; | ||
533 | |||
534 | rt2x00pci_register_read(rt2x00dev, SEC_CSR2, ®); | ||
535 | if (crypto->cmd == SET_KEY) | ||
536 | reg |= mask; | ||
537 | else if (crypto->cmd == DISABLE_KEY) | ||
538 | reg &= ~mask; | ||
539 | rt2x00pci_register_write(rt2x00dev, SEC_CSR2, reg); | ||
540 | } else { | ||
541 | mask = 1 << (key->hw_key_idx - 32); | ||
542 | |||
543 | rt2x00pci_register_read(rt2x00dev, SEC_CSR3, ®); | ||
544 | if (crypto->cmd == SET_KEY) | ||
545 | reg |= mask; | ||
546 | else if (crypto->cmd == DISABLE_KEY) | ||
547 | reg &= ~mask; | ||
548 | rt2x00pci_register_write(rt2x00dev, SEC_CSR3, reg); | ||
549 | } | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
349 | static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, | 554 | static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev, |
350 | const unsigned int filter_flags) | 555 | const unsigned int filter_flags) |
351 | { | 556 | { |
@@ -440,6 +645,30 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
440 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 645 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); |
441 | } | 646 | } |
442 | 647 | ||
648 | |||
649 | static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev, | ||
650 | struct rt2x00lib_conf *libconf) | ||
651 | { | ||
652 | u16 eeprom; | ||
653 | short lna_gain = 0; | ||
654 | |||
655 | if (libconf->band == IEEE80211_BAND_2GHZ) { | ||
656 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | ||
657 | lna_gain += 14; | ||
658 | |||
659 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); | ||
660 | lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); | ||
661 | } else { | ||
662 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | ||
663 | lna_gain += 14; | ||
664 | |||
665 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); | ||
666 | lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1); | ||
667 | } | ||
668 | |||
669 | rt2x00dev->lna_gain = lna_gain; | ||
670 | } | ||
671 | |||
443 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 672 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
444 | const int basic_rate_mask) | 673 | const int basic_rate_mask) |
445 | { | 674 | { |
@@ -758,6 +987,9 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | |||
758 | struct rt2x00lib_conf *libconf, | 987 | struct rt2x00lib_conf *libconf, |
759 | const unsigned int flags) | 988 | const unsigned int flags) |
760 | { | 989 | { |
990 | /* Always recalculate LNA gain before changing configuration */ | ||
991 | rt61pci_config_lna_gain(rt2x00dev, libconf); | ||
992 | |||
761 | if (flags & CONFIG_UPDATE_PHYMODE) | 993 | if (flags & CONFIG_UPDATE_PHYMODE) |
762 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); | 994 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); |
763 | if (flags & CONFIG_UPDATE_CHANNEL) | 995 | if (flags & CONFIG_UPDATE_CHANNEL) |
@@ -1246,16 +1478,6 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1246 | 1478 | ||
1247 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); | 1479 | rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); |
1248 | 1480 | ||
1249 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, ®); | ||
1250 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC0_TX_OP, 0); | ||
1251 | rt2x00_set_field32(®, AC_TXOP_CSR0_AC1_TX_OP, 0); | ||
1252 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg); | ||
1253 | |||
1254 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, ®); | ||
1255 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC2_TX_OP, 192); | ||
1256 | rt2x00_set_field32(®, AC_TXOP_CSR1_AC3_TX_OP, 48); | ||
1257 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | ||
1258 | |||
1259 | /* | 1481 | /* |
1260 | * Clear all beacons | 1482 | * Clear all beacons |
1261 | * For the Beacon base registers we only need to clear | 1483 | * For the Beacon base registers we only need to clear |
@@ -1533,8 +1755,8 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1533 | * TX descriptor initialization | 1755 | * TX descriptor initialization |
1534 | */ | 1756 | */ |
1535 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1757 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1536 | struct sk_buff *skb, | 1758 | struct sk_buff *skb, |
1537 | struct txentry_desc *txdesc) | 1759 | struct txentry_desc *txdesc) |
1538 | { | 1760 | { |
1539 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1761 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1540 | __le32 *txd = skbdesc->desc; | 1762 | __le32 *txd = skbdesc->desc; |
@@ -1548,7 +1770,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1548 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); | 1770 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1549 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); | 1771 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1550 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1772 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1551 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1773 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, txdesc->iv_offset); |
1552 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, | 1774 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, |
1553 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); | 1775 | test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags)); |
1554 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | 1776 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); |
@@ -1561,6 +1783,11 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1561 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); | 1783 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1562 | rt2x00_desc_write(txd, 2, word); | 1784 | rt2x00_desc_write(txd, 2, word); |
1563 | 1785 | ||
1786 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags)) { | ||
1787 | _rt2x00_desc_write(txd, 3, skbdesc->iv); | ||
1788 | _rt2x00_desc_write(txd, 4, skbdesc->eiv); | ||
1789 | } | ||
1790 | |||
1564 | rt2x00_desc_read(txd, 5, &word); | 1791 | rt2x00_desc_read(txd, 5, &word); |
1565 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); | 1792 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); |
1566 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, | 1793 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, |
@@ -1595,11 +1822,15 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1595 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1822 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1596 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1823 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1597 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1824 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1598 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1825 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, |
1826 | test_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags)); | ||
1827 | rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, | ||
1828 | test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); | ||
1829 | rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); | ||
1599 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); | 1830 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); |
1600 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1831 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1601 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 1832 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1602 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1833 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); |
1603 | rt2x00_desc_write(txd, 0, word); | 1834 | rt2x00_desc_write(txd, 0, word); |
1604 | } | 1835 | } |
1605 | 1836 | ||
@@ -1676,40 +1907,27 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1676 | */ | 1907 | */ |
1677 | static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | 1908 | static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) |
1678 | { | 1909 | { |
1679 | u16 eeprom; | 1910 | u8 offset = rt2x00dev->lna_gain; |
1680 | u8 offset; | ||
1681 | u8 lna; | 1911 | u8 lna; |
1682 | 1912 | ||
1683 | lna = rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_LNA); | 1913 | lna = rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_LNA); |
1684 | switch (lna) { | 1914 | switch (lna) { |
1685 | case 3: | 1915 | case 3: |
1686 | offset = 90; | 1916 | offset += 90; |
1687 | break; | 1917 | break; |
1688 | case 2: | 1918 | case 2: |
1689 | offset = 74; | 1919 | offset += 74; |
1690 | break; | 1920 | break; |
1691 | case 1: | 1921 | case 1: |
1692 | offset = 64; | 1922 | offset += 64; |
1693 | break; | 1923 | break; |
1694 | default: | 1924 | default: |
1695 | return 0; | 1925 | return 0; |
1696 | } | 1926 | } |
1697 | 1927 | ||
1698 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { | 1928 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1699 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | ||
1700 | offset += 14; | ||
1701 | |||
1702 | if (lna == 3 || lna == 2) | 1929 | if (lna == 3 || lna == 2) |
1703 | offset += 10; | 1930 | offset += 10; |
1704 | |||
1705 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); | ||
1706 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1); | ||
1707 | } else { | ||
1708 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | ||
1709 | offset += 14; | ||
1710 | |||
1711 | rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); | ||
1712 | offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); | ||
1713 | } | 1931 | } |
1714 | 1932 | ||
1715 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1933 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
@@ -1718,6 +1936,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1718 | static void rt61pci_fill_rxdone(struct queue_entry *entry, | 1936 | static void rt61pci_fill_rxdone(struct queue_entry *entry, |
1719 | struct rxdone_entry_desc *rxdesc) | 1937 | struct rxdone_entry_desc *rxdesc) |
1720 | { | 1938 | { |
1939 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1721 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1940 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1722 | u32 word0; | 1941 | u32 word0; |
1723 | u32 word1; | 1942 | u32 word1; |
@@ -1728,6 +1947,38 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, | |||
1728 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1947 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1729 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1948 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1730 | 1949 | ||
1950 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) { | ||
1951 | rxdesc->cipher = | ||
1952 | rt2x00_get_field32(word0, RXD_W0_CIPHER_ALG); | ||
1953 | rxdesc->cipher_status = | ||
1954 | rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR); | ||
1955 | } | ||
1956 | |||
1957 | if (rxdesc->cipher != CIPHER_NONE) { | ||
1958 | _rt2x00_desc_read(entry_priv->desc, 2, &rxdesc->iv); | ||
1959 | _rt2x00_desc_read(entry_priv->desc, 3, &rxdesc->eiv); | ||
1960 | _rt2x00_desc_read(entry_priv->desc, 4, &rxdesc->icv); | ||
1961 | |||
1962 | /* | ||
1963 | * Hardware has stripped IV/EIV data from 802.11 frame during | ||
1964 | * decryption. It has provided the data seperately but rt2x00lib | ||
1965 | * should decide if it should be reinserted. | ||
1966 | */ | ||
1967 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | ||
1968 | |||
1969 | /* | ||
1970 | * FIXME: Legacy driver indicates that the frame does | ||
1971 | * contain the Michael Mic. Unfortunately, in rt2x00 | ||
1972 | * the MIC seems to be missing completely... | ||
1973 | */ | ||
1974 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; | ||
1975 | |||
1976 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) | ||
1977 | rxdesc->flags |= RX_FLAG_DECRYPTED; | ||
1978 | else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) | ||
1979 | rxdesc->flags |= RX_FLAG_MMIC_ERROR; | ||
1980 | } | ||
1981 | |||
1731 | /* | 1982 | /* |
1732 | * Obtain the status about this packet. | 1983 | * Obtain the status about this packet. |
1733 | * When frame was received with an OFDM bitrate, | 1984 | * When frame was received with an OFDM bitrate, |
@@ -1735,11 +1986,13 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, | |||
1735 | * a CCK bitrate the signal is the rate in 100kbit/s. | 1986 | * a CCK bitrate the signal is the rate in 100kbit/s. |
1736 | */ | 1987 | */ |
1737 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1988 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1738 | rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1); | 1989 | rxdesc->rssi = rt61pci_agc_to_rssi(rt2x00dev, word1); |
1739 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1990 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1740 | 1991 | ||
1741 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | 1992 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) |
1742 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | 1993 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; |
1994 | else | ||
1995 | rxdesc->dev_flags |= RXDONE_SIGNAL_BITRATE; | ||
1743 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | 1996 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) |
1744 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 1997 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
1745 | } | 1998 | } |
@@ -1860,7 +2113,7 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | |||
1860 | if (!reg && !reg_mcu) | 2113 | if (!reg && !reg_mcu) |
1861 | return IRQ_NONE; | 2114 | return IRQ_NONE; |
1862 | 2115 | ||
1863 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 2116 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
1864 | return IRQ_HANDLED; | 2117 | return IRQ_HANDLED; |
1865 | 2118 | ||
1866 | /* | 2119 | /* |
@@ -2060,10 +2313,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2060 | /* | 2313 | /* |
2061 | * Detect if this device has an hardware controlled radio. | 2314 | * Detect if this device has an hardware controlled radio. |
2062 | */ | 2315 | */ |
2063 | #ifdef CONFIG_RT61PCI_RFKILL | 2316 | #ifdef CONFIG_RT2X00_LIB_RFKILL |
2064 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | 2317 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) |
2065 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | 2318 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); |
2066 | #endif /* CONFIG_RT61PCI_RFKILL */ | 2319 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ |
2067 | 2320 | ||
2068 | /* | 2321 | /* |
2069 | * Read frequency offset and RF programming sequence. | 2322 | * Read frequency offset and RF programming sequence. |
@@ -2121,7 +2374,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2121 | * If the eeprom value is invalid, | 2374 | * If the eeprom value is invalid, |
2122 | * switch to default led mode. | 2375 | * switch to default led mode. |
2123 | */ | 2376 | */ |
2124 | #ifdef CONFIG_RT61PCI_LEDS | 2377 | #ifdef CONFIG_RT2X00_LIB_LEDS |
2125 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 2378 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
2126 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | 2379 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); |
2127 | 2380 | ||
@@ -2155,7 +2408,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2155 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, | 2408 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
2156 | rt2x00_get_field16(eeprom, | 2409 | rt2x00_get_field16(eeprom, |
2157 | EEPROM_LED_POLARITY_RDY_A)); | 2410 | EEPROM_LED_POLARITY_RDY_A)); |
2158 | #endif /* CONFIG_RT61PCI_LEDS */ | 2411 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
2159 | 2412 | ||
2160 | return 0; | 2413 | return 0; |
2161 | } | 2414 | } |
@@ -2274,10 +2527,11 @@ static const struct rf_channel rf_vals_seq[] = { | |||
2274 | { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000c0a23 }, | 2527 | { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000c0a23 }, |
2275 | }; | 2528 | }; |
2276 | 2529 | ||
2277 | static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | 2530 | static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) |
2278 | { | 2531 | { |
2279 | struct hw_mode_spec *spec = &rt2x00dev->spec; | 2532 | struct hw_mode_spec *spec = &rt2x00dev->spec; |
2280 | u8 *txpower; | 2533 | struct channel_info *info; |
2534 | char *tx_power; | ||
2281 | unsigned int i; | 2535 | unsigned int i; |
2282 | 2536 | ||
2283 | /* | 2537 | /* |
@@ -2294,20 +2548,10 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2294 | EEPROM_MAC_ADDR_0)); | 2548 | EEPROM_MAC_ADDR_0)); |
2295 | 2549 | ||
2296 | /* | 2550 | /* |
2297 | * Convert tx_power array in eeprom. | ||
2298 | */ | ||
2299 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | ||
2300 | for (i = 0; i < 14; i++) | ||
2301 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | ||
2302 | |||
2303 | /* | ||
2304 | * Initialize hw_mode information. | 2551 | * Initialize hw_mode information. |
2305 | */ | 2552 | */ |
2306 | spec->supported_bands = SUPPORT_BAND_2GHZ; | 2553 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
2307 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; | 2554 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
2308 | spec->tx_power_a = NULL; | ||
2309 | spec->tx_power_bg = txpower; | ||
2310 | spec->tx_power_default = DEFAULT_TXPOWER; | ||
2311 | 2555 | ||
2312 | if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) { | 2556 | if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) { |
2313 | spec->num_channels = 14; | 2557 | spec->num_channels = 14; |
@@ -2321,13 +2565,28 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2321 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { | 2565 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { |
2322 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | 2566 | spec->supported_bands |= SUPPORT_BAND_5GHZ; |
2323 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); | 2567 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); |
2568 | } | ||
2324 | 2569 | ||
2325 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2570 | /* |
2326 | for (i = 0; i < 14; i++) | 2571 | * Create channel information array |
2327 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | 2572 | */ |
2573 | info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); | ||
2574 | if (!info) | ||
2575 | return -ENOMEM; | ||
2328 | 2576 | ||
2329 | spec->tx_power_a = txpower; | 2577 | spec->channels_info = info; |
2578 | |||
2579 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); | ||
2580 | for (i = 0; i < 14; i++) | ||
2581 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2582 | |||
2583 | if (spec->num_channels > 14) { | ||
2584 | tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | ||
2585 | for (i = 14; i < spec->num_channels; i++) | ||
2586 | info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); | ||
2330 | } | 2587 | } |
2588 | |||
2589 | return 0; | ||
2331 | } | 2590 | } |
2332 | 2591 | ||
2333 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 2592 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
@@ -2348,13 +2607,17 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2348 | /* | 2607 | /* |
2349 | * Initialize hw specifications. | 2608 | * Initialize hw specifications. |
2350 | */ | 2609 | */ |
2351 | rt61pci_probe_hw_mode(rt2x00dev); | 2610 | retval = rt61pci_probe_hw_mode(rt2x00dev); |
2611 | if (retval) | ||
2612 | return retval; | ||
2352 | 2613 | ||
2353 | /* | 2614 | /* |
2354 | * This device requires firmware and DMA mapped skbs. | 2615 | * This device requires firmware and DMA mapped skbs. |
2355 | */ | 2616 | */ |
2356 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2617 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2357 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 2618 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); |
2619 | if (!modparam_nohwcrypt) | ||
2620 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | ||
2358 | 2621 | ||
2359 | /* | 2622 | /* |
2360 | * Set the rssi offset. | 2623 | * Set the rssi offset. |
@@ -2381,6 +2644,63 @@ static int rt61pci_set_retry_limit(struct ieee80211_hw *hw, | |||
2381 | return 0; | 2644 | return 0; |
2382 | } | 2645 | } |
2383 | 2646 | ||
2647 | static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | ||
2648 | const struct ieee80211_tx_queue_params *params) | ||
2649 | { | ||
2650 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2651 | struct data_queue *queue; | ||
2652 | struct rt2x00_field32 field; | ||
2653 | int retval; | ||
2654 | u32 reg; | ||
2655 | |||
2656 | /* | ||
2657 | * First pass the configuration through rt2x00lib, that will | ||
2658 | * update the queue settings and validate the input. After that | ||
2659 | * we are free to update the registers based on the value | ||
2660 | * in the queue parameter. | ||
2661 | */ | ||
2662 | retval = rt2x00mac_conf_tx(hw, queue_idx, params); | ||
2663 | if (retval) | ||
2664 | return retval; | ||
2665 | |||
2666 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | ||
2667 | |||
2668 | /* Update WMM TXOP register */ | ||
2669 | if (queue_idx < 2) { | ||
2670 | field.bit_offset = queue_idx * 16; | ||
2671 | field.bit_mask = 0xffff << field.bit_offset; | ||
2672 | |||
2673 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, ®); | ||
2674 | rt2x00_set_field32(®, field, queue->txop); | ||
2675 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg); | ||
2676 | } else if (queue_idx < 4) { | ||
2677 | field.bit_offset = (queue_idx - 2) * 16; | ||
2678 | field.bit_mask = 0xffff << field.bit_offset; | ||
2679 | |||
2680 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, ®); | ||
2681 | rt2x00_set_field32(®, field, queue->txop); | ||
2682 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | ||
2683 | } | ||
2684 | |||
2685 | /* Update WMM registers */ | ||
2686 | field.bit_offset = queue_idx * 4; | ||
2687 | field.bit_mask = 0xf << field.bit_offset; | ||
2688 | |||
2689 | rt2x00pci_register_read(rt2x00dev, AIFSN_CSR, ®); | ||
2690 | rt2x00_set_field32(®, field, queue->aifs); | ||
2691 | rt2x00pci_register_write(rt2x00dev, AIFSN_CSR, reg); | ||
2692 | |||
2693 | rt2x00pci_register_read(rt2x00dev, CWMIN_CSR, ®); | ||
2694 | rt2x00_set_field32(®, field, queue->cw_min); | ||
2695 | rt2x00pci_register_write(rt2x00dev, CWMIN_CSR, reg); | ||
2696 | |||
2697 | rt2x00pci_register_read(rt2x00dev, CWMAX_CSR, ®); | ||
2698 | rt2x00_set_field32(®, field, queue->cw_max); | ||
2699 | rt2x00pci_register_write(rt2x00dev, CWMAX_CSR, reg); | ||
2700 | |||
2701 | return 0; | ||
2702 | } | ||
2703 | |||
2384 | static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | 2704 | static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) |
2385 | { | 2705 | { |
2386 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2706 | struct rt2x00_dev *rt2x00dev = hw->priv; |
@@ -2404,10 +2724,11 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2404 | .config = rt2x00mac_config, | 2724 | .config = rt2x00mac_config, |
2405 | .config_interface = rt2x00mac_config_interface, | 2725 | .config_interface = rt2x00mac_config_interface, |
2406 | .configure_filter = rt2x00mac_configure_filter, | 2726 | .configure_filter = rt2x00mac_configure_filter, |
2727 | .set_key = rt2x00mac_set_key, | ||
2407 | .get_stats = rt2x00mac_get_stats, | 2728 | .get_stats = rt2x00mac_get_stats, |
2408 | .set_retry_limit = rt61pci_set_retry_limit, | 2729 | .set_retry_limit = rt61pci_set_retry_limit, |
2409 | .bss_info_changed = rt2x00mac_bss_info_changed, | 2730 | .bss_info_changed = rt2x00mac_bss_info_changed, |
2410 | .conf_tx = rt2x00mac_conf_tx, | 2731 | .conf_tx = rt61pci_conf_tx, |
2411 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2732 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2412 | .get_tsf = rt61pci_get_tsf, | 2733 | .get_tsf = rt61pci_get_tsf, |
2413 | }; | 2734 | }; |
@@ -2432,6 +2753,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2432 | .write_beacon = rt61pci_write_beacon, | 2753 | .write_beacon = rt61pci_write_beacon, |
2433 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2754 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2434 | .fill_rxdone = rt61pci_fill_rxdone, | 2755 | .fill_rxdone = rt61pci_fill_rxdone, |
2756 | .config_shared_key = rt61pci_config_shared_key, | ||
2757 | .config_pairwise_key = rt61pci_config_pairwise_key, | ||
2435 | .config_filter = rt61pci_config_filter, | 2758 | .config_filter = rt61pci_config_filter, |
2436 | .config_intf = rt61pci_config_intf, | 2759 | .config_intf = rt61pci_config_intf, |
2437 | .config_erp = rt61pci_config_erp, | 2760 | .config_erp = rt61pci_config_erp, |