diff options
Diffstat (limited to 'drivers/net/wireless/rtl818x/rtl8180/dev.c')
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8180/dev.c | 342 |
1 files changed, 258 insertions, 84 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 3867d1470b36..0b405b8c8d70 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
@@ -148,7 +148,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
148 | rx_status.antenna = (flags2 >> 15) & 1; | 148 | rx_status.antenna = (flags2 >> 15) & 1; |
149 | rx_status.rate_idx = (flags >> 20) & 0xF; | 149 | rx_status.rate_idx = (flags >> 20) & 0xF; |
150 | agc = (flags2 >> 17) & 0x7F; | 150 | agc = (flags2 >> 17) & 0x7F; |
151 | if (priv->r8185) { | 151 | |
152 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { | ||
152 | if (rx_status.rate_idx > 3) | 153 | if (rx_status.rate_idx > 3) |
153 | signal = 90 - clamp_t(u8, agc, 25, 90); | 154 | signal = 90 - clamp_t(u8, agc, 25, 90); |
154 | else | 155 | else |
@@ -288,7 +289,7 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
288 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | | 289 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | |
289 | skb->len; | 290 | skb->len; |
290 | 291 | ||
291 | if (priv->r8185) | 292 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) |
292 | tx_flags |= RTL818X_TX_DESC_FLAG_DMA | | 293 | tx_flags |= RTL818X_TX_DESC_FLAG_DMA | |
293 | RTL818X_TX_DESC_FLAG_NO_ENC; | 294 | RTL818X_TX_DESC_FLAG_NO_ENC; |
294 | 295 | ||
@@ -305,7 +306,7 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
305 | rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, | 306 | rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, |
306 | info); | 307 | info); |
307 | 308 | ||
308 | if (!priv->r8185) { | 309 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) { |
309 | unsigned int remainder; | 310 | unsigned int remainder; |
310 | 311 | ||
311 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), | 312 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), |
@@ -335,7 +336,18 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
335 | entry->flags2 = info->control.rates[1].idx >= 0 ? | 336 | entry->flags2 = info->control.rates[1].idx >= 0 ? |
336 | ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; | 337 | ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; |
337 | entry->retry_limit = info->control.rates[0].count; | 338 | entry->retry_limit = info->control.rates[0].count; |
339 | |||
340 | /* We must be sure that tx_flags is written last because the HW | ||
341 | * looks at it to check if the rest of data is valid or not | ||
342 | */ | ||
343 | wmb(); | ||
338 | entry->flags = cpu_to_le32(tx_flags); | 344 | entry->flags = cpu_to_le32(tx_flags); |
345 | /* We must be sure this has been written before followings HW | ||
346 | * register write, because this write will made the HW attempts | ||
347 | * to DMA the just-written data | ||
348 | */ | ||
349 | wmb(); | ||
350 | |||
339 | __skb_queue_tail(&ring->queue, skb); | 351 | __skb_queue_tail(&ring->queue, skb); |
340 | if (ring->entries - skb_queue_len(&ring->queue) < 2) | 352 | if (ring->entries - skb_queue_len(&ring->queue) < 2) |
341 | ieee80211_stop_queue(dev, prio); | 353 | ieee80211_stop_queue(dev, prio); |
@@ -359,6 +371,36 @@ void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) | |||
359 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 371 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
360 | } | 372 | } |
361 | 373 | ||
374 | static void rtl8180_conf_basic_rates(struct ieee80211_hw *dev, | ||
375 | u32 rates_mask) | ||
376 | { | ||
377 | struct rtl8180_priv *priv = dev->priv; | ||
378 | |||
379 | u8 max, min; | ||
380 | u16 reg; | ||
381 | |||
382 | max = fls(rates_mask) - 1; | ||
383 | min = ffs(rates_mask) - 1; | ||
384 | |||
385 | switch (priv->chip_family) { | ||
386 | |||
387 | case RTL818X_CHIP_FAMILY_RTL8180: | ||
388 | /* in 8180 this is NOT a BITMAP */ | ||
389 | reg = rtl818x_ioread16(priv, &priv->map->BRSR); | ||
390 | reg &= ~3; | ||
391 | reg |= max; | ||
392 | rtl818x_iowrite16(priv, &priv->map->BRSR, reg); | ||
393 | |||
394 | break; | ||
395 | |||
396 | case RTL818X_CHIP_FAMILY_RTL8185: | ||
397 | /* in 8185 this is a BITMAP */ | ||
398 | rtl818x_iowrite16(priv, &priv->map->BRSR, rates_mask); | ||
399 | rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (max << 4) | min); | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | |||
362 | static int rtl8180_init_hw(struct ieee80211_hw *dev) | 404 | static int rtl8180_init_hw(struct ieee80211_hw *dev) |
363 | { | 405 | { |
364 | struct rtl8180_priv *priv = dev->priv; | 406 | struct rtl8180_priv *priv = dev->priv; |
@@ -401,7 +443,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
401 | 443 | ||
402 | rtl818x_iowrite8(priv, &priv->map->MSR, 0); | 444 | rtl818x_iowrite8(priv, &priv->map->MSR, 0); |
403 | 445 | ||
404 | if (!priv->r8185) | 446 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) |
405 | rtl8180_set_anaparam(priv, priv->anaparam); | 447 | rtl8180_set_anaparam(priv, priv->anaparam); |
406 | 448 | ||
407 | rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); | 449 | rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); |
@@ -414,7 +456,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
414 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 456 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
415 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); | 457 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); |
416 | rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3)); | 458 | rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3)); |
417 | if (priv->r8185) { | 459 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { |
418 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); | 460 | reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); |
419 | rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4)); | 461 | rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4)); |
420 | } | 462 | } |
@@ -426,12 +468,9 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
426 | 468 | ||
427 | rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); | 469 | rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); |
428 | 470 | ||
429 | if (priv->r8185) { | 471 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { |
430 | rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); | 472 | rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); |
431 | rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); | 473 | rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); |
432 | rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); | ||
433 | |||
434 | rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); | ||
435 | 474 | ||
436 | /* TODO: set ClkRun enable? necessary? */ | 475 | /* TODO: set ClkRun enable? necessary? */ |
437 | reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); | 476 | reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); |
@@ -441,7 +480,6 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
441 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); | 480 | rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); |
442 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 481 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
443 | } else { | 482 | } else { |
444 | rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1); | ||
445 | rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); | 483 | rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); |
446 | 484 | ||
447 | rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); | 485 | rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); |
@@ -449,8 +487,18 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) | |||
449 | } | 487 | } |
450 | 488 | ||
451 | priv->rf->init(dev); | 489 | priv->rf->init(dev); |
452 | if (priv->r8185) | 490 | |
453 | rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); | 491 | /* default basic rates are 1,2 Mbps for rtl8180. 1,2,6,9,12,18,24 Mbps |
492 | * otherwise. bitmask 0x3 and 0x01f3 respectively. | ||
493 | * NOTE: currenty rtl8225 RF code changes basic rates, so we need to do | ||
494 | * this after rf init. | ||
495 | * TODO: try to find out whether RF code really needs to do this.. | ||
496 | */ | ||
497 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) | ||
498 | rtl8180_conf_basic_rates(dev, 0x3); | ||
499 | else | ||
500 | rtl8180_conf_basic_rates(dev, 0x1f3); | ||
501 | |||
454 | return 0; | 502 | return 0; |
455 | } | 503 | } |
456 | 504 | ||
@@ -476,13 +524,21 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) | |||
476 | struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); | 524 | struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); |
477 | dma_addr_t *mapping; | 525 | dma_addr_t *mapping; |
478 | entry = &priv->rx_ring[i]; | 526 | entry = &priv->rx_ring[i]; |
479 | if (!skb) | 527 | if (!skb) { |
480 | return 0; | 528 | wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); |
481 | 529 | return -ENOMEM; | |
530 | } | ||
482 | priv->rx_buf[i] = skb; | 531 | priv->rx_buf[i] = skb; |
483 | mapping = (dma_addr_t *)skb->cb; | 532 | mapping = (dma_addr_t *)skb->cb; |
484 | *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), | 533 | *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), |
485 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 534 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); |
535 | |||
536 | if (pci_dma_mapping_error(priv->pdev, *mapping)) { | ||
537 | kfree_skb(skb); | ||
538 | wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); | ||
539 | return -ENOMEM; | ||
540 | } | ||
541 | |||
486 | entry->rx_buf = cpu_to_le32(*mapping); | 542 | entry->rx_buf = cpu_to_le32(*mapping); |
487 | entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | | 543 | entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | |
488 | MAX_RX_SIZE); | 544 | MAX_RX_SIZE); |
@@ -605,7 +661,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
605 | RTL818X_RX_CONF_BROADCAST | | 661 | RTL818X_RX_CONF_BROADCAST | |
606 | RTL818X_RX_CONF_NICMAC; | 662 | RTL818X_RX_CONF_NICMAC; |
607 | 663 | ||
608 | if (priv->r8185) | 664 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) |
609 | reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; | 665 | reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; |
610 | else { | 666 | else { |
611 | reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) | 667 | reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) |
@@ -617,15 +673,27 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
617 | priv->rx_conf = reg; | 673 | priv->rx_conf = reg; |
618 | rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); | 674 | rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); |
619 | 675 | ||
620 | if (priv->r8185) { | 676 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { |
621 | reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); | 677 | reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); |
622 | reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT; | 678 | |
623 | reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; | 679 | /* CW is not on per-packet basis. |
680 | * in rtl8185 the CW_VALUE reg is used. | ||
681 | */ | ||
682 | reg &= ~RTL818X_CW_CONF_PERPACKET_CW; | ||
683 | /* retry limit IS on per-packet basis. | ||
684 | * the short and long retry limit in TX_CONF | ||
685 | * reg are ignored | ||
686 | */ | ||
687 | reg |= RTL818X_CW_CONF_PERPACKET_RETRY; | ||
624 | rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); | 688 | rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); |
625 | 689 | ||
626 | reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); | 690 | reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); |
627 | reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; | 691 | /* TX antenna and TX gain are not on per-packet basis. |
628 | reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; | 692 | * TX Antenna is selected by ANTSEL reg (RX in BB regs). |
693 | * TX gain is selected with CCK_TX_AGC and OFDM_TX_AGC regs | ||
694 | */ | ||
695 | reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN; | ||
696 | reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL; | ||
629 | reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT; | 697 | reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT; |
630 | rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); | 698 | rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); |
631 | 699 | ||
@@ -637,11 +705,15 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
637 | reg |= (6 << 21 /* MAX TX DMA */) | | 705 | reg |= (6 << 21 /* MAX TX DMA */) | |
638 | RTL818X_TX_CONF_NO_ICV; | 706 | RTL818X_TX_CONF_NO_ICV; |
639 | 707 | ||
640 | if (priv->r8185) | 708 | |
709 | |||
710 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) | ||
641 | reg &= ~RTL818X_TX_CONF_PROBE_DTS; | 711 | reg &= ~RTL818X_TX_CONF_PROBE_DTS; |
642 | else | 712 | else |
643 | reg &= ~RTL818X_TX_CONF_HW_SEQNUM; | 713 | reg &= ~RTL818X_TX_CONF_HW_SEQNUM; |
644 | 714 | ||
715 | reg &= ~RTL818X_TX_CONF_DISCW; | ||
716 | |||
645 | /* different meaning, same value on both rtl8185 and rtl8180 */ | 717 | /* different meaning, same value on both rtl8185 and rtl8180 */ |
646 | reg &= ~RTL818X_TX_CONF_SAT_HWPLCP; | 718 | reg &= ~RTL818X_TX_CONF_SAT_HWPLCP; |
647 | 719 | ||
@@ -794,6 +866,72 @@ static int rtl8180_config(struct ieee80211_hw *dev, u32 changed) | |||
794 | return 0; | 866 | return 0; |
795 | } | 867 | } |
796 | 868 | ||
869 | static int rtl8180_conf_tx(struct ieee80211_hw *dev, | ||
870 | struct ieee80211_vif *vif, u16 queue, | ||
871 | const struct ieee80211_tx_queue_params *params) | ||
872 | { | ||
873 | struct rtl8180_priv *priv = dev->priv; | ||
874 | u8 cw_min, cw_max; | ||
875 | |||
876 | /* nothing to do ? */ | ||
877 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) | ||
878 | return 0; | ||
879 | |||
880 | cw_min = fls(params->cw_min); | ||
881 | cw_max = fls(params->cw_max); | ||
882 | |||
883 | rtl818x_iowrite8(priv, &priv->map->CW_VAL, (cw_max << 4) | cw_min); | ||
884 | |||
885 | return 0; | ||
886 | } | ||
887 | |||
888 | static void rtl8180_conf_erp(struct ieee80211_hw *dev, | ||
889 | struct ieee80211_bss_conf *info) | ||
890 | { | ||
891 | struct rtl8180_priv *priv = dev->priv; | ||
892 | u8 sifs, difs; | ||
893 | int eifs; | ||
894 | u8 hw_eifs; | ||
895 | |||
896 | /* TODO: should we do something ? */ | ||
897 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) | ||
898 | return; | ||
899 | |||
900 | /* I _hope_ this means 10uS for the HW. | ||
901 | * In reference code it is 0x22 for | ||
902 | * both rtl8187L and rtl8187SE | ||
903 | */ | ||
904 | sifs = 0x22; | ||
905 | |||
906 | if (info->use_short_slot) | ||
907 | priv->slot_time = 9; | ||
908 | else | ||
909 | priv->slot_time = 20; | ||
910 | |||
911 | /* 10 is SIFS time in uS */ | ||
912 | difs = 10 + 2 * priv->slot_time; | ||
913 | eifs = 10 + difs + priv->ack_time; | ||
914 | |||
915 | /* HW should use 4uS units for EIFS (I'm sure for rtl8185)*/ | ||
916 | hw_eifs = DIV_ROUND_UP(eifs, 4); | ||
917 | |||
918 | |||
919 | rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time); | ||
920 | rtl818x_iowrite8(priv, &priv->map->SIFS, sifs); | ||
921 | rtl818x_iowrite8(priv, &priv->map->DIFS, difs); | ||
922 | |||
923 | /* from reference code. set ack timeout reg = eifs reg */ | ||
924 | rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, hw_eifs); | ||
925 | |||
926 | /* rtl8187/rtl8185 HW bug. After EIFS is elapsed, | ||
927 | * the HW still wait for DIFS. | ||
928 | * HW uses 4uS units for EIFS. | ||
929 | */ | ||
930 | hw_eifs = DIV_ROUND_UP(eifs - difs, 4); | ||
931 | |||
932 | rtl818x_iowrite8(priv, &priv->map->EIFS, hw_eifs); | ||
933 | } | ||
934 | |||
797 | static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, | 935 | static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, |
798 | struct ieee80211_vif *vif, | 936 | struct ieee80211_vif *vif, |
799 | struct ieee80211_bss_conf *info, | 937 | struct ieee80211_bss_conf *info, |
@@ -821,8 +959,23 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, | |||
821 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); | 959 | rtl818x_iowrite8(priv, &priv->map->MSR, reg); |
822 | } | 960 | } |
823 | 961 | ||
824 | if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) | 962 | if (changed & BSS_CHANGED_BASIC_RATES) |
825 | priv->rf->conf_erp(dev, info); | 963 | rtl8180_conf_basic_rates(dev, info->basic_rates); |
964 | |||
965 | if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) { | ||
966 | |||
967 | /* when preamble changes, acktime duration changes, and erp must | ||
968 | * be recalculated. ACK time is calculated at lowest rate. | ||
969 | * Since mac80211 include SIFS time we remove it (-10) | ||
970 | */ | ||
971 | priv->ack_time = | ||
972 | le16_to_cpu(ieee80211_generic_frame_duration(dev, | ||
973 | priv->vif, | ||
974 | IEEE80211_BAND_2GHZ, 10, | ||
975 | &priv->rates[0])) - 10; | ||
976 | |||
977 | rtl8180_conf_erp(dev, info); | ||
978 | } | ||
826 | 979 | ||
827 | if (changed & BSS_CHANGED_BEACON_ENABLED) | 980 | if (changed & BSS_CHANGED_BEACON_ENABLED) |
828 | vif_priv->enable_beacon = info->enable_beacon; | 981 | vif_priv->enable_beacon = info->enable_beacon; |
@@ -880,6 +1033,7 @@ static const struct ieee80211_ops rtl8180_ops = { | |||
880 | .remove_interface = rtl8180_remove_interface, | 1033 | .remove_interface = rtl8180_remove_interface, |
881 | .config = rtl8180_config, | 1034 | .config = rtl8180_config, |
882 | .bss_info_changed = rtl8180_bss_info_changed, | 1035 | .bss_info_changed = rtl8180_bss_info_changed, |
1036 | .conf_tx = rtl8180_conf_tx, | ||
883 | .prepare_multicast = rtl8180_prepare_multicast, | 1037 | .prepare_multicast = rtl8180_prepare_multicast, |
884 | .configure_filter = rtl8180_configure_filter, | 1038 | .configure_filter = rtl8180_configure_filter, |
885 | .get_tsf = rtl8180_get_tsf, | 1039 | .get_tsf = rtl8180_get_tsf, |
@@ -887,8 +1041,7 @@ static const struct ieee80211_ops rtl8180_ops = { | |||
887 | 1041 | ||
888 | static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) | 1042 | static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) |
889 | { | 1043 | { |
890 | struct ieee80211_hw *dev = eeprom->data; | 1044 | struct rtl8180_priv *priv = eeprom->data; |
891 | struct rtl8180_priv *priv = dev->priv; | ||
892 | u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); | 1045 | u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); |
893 | 1046 | ||
894 | eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; | 1047 | eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; |
@@ -899,8 +1052,7 @@ static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) | |||
899 | 1052 | ||
900 | static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom) | 1053 | static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom) |
901 | { | 1054 | { |
902 | struct ieee80211_hw *dev = eeprom->data; | 1055 | struct rtl8180_priv *priv = eeprom->data; |
903 | struct rtl8180_priv *priv = dev->priv; | ||
904 | u8 reg = 2 << 6; | 1056 | u8 reg = 2 << 6; |
905 | 1057 | ||
906 | if (eeprom->reg_data_in) | 1058 | if (eeprom->reg_data_in) |
@@ -917,6 +1069,67 @@ static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom) | |||
917 | udelay(10); | 1069 | udelay(10); |
918 | } | 1070 | } |
919 | 1071 | ||
1072 | static void rtl8180_eeprom_read(struct rtl8180_priv *priv) | ||
1073 | { | ||
1074 | struct eeprom_93cx6 eeprom; | ||
1075 | int eeprom_cck_table_adr; | ||
1076 | u16 eeprom_val; | ||
1077 | int i; | ||
1078 | |||
1079 | eeprom.data = priv; | ||
1080 | eeprom.register_read = rtl8180_eeprom_register_read; | ||
1081 | eeprom.register_write = rtl8180_eeprom_register_write; | ||
1082 | if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) | ||
1083 | eeprom.width = PCI_EEPROM_WIDTH_93C66; | ||
1084 | else | ||
1085 | eeprom.width = PCI_EEPROM_WIDTH_93C46; | ||
1086 | |||
1087 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | ||
1088 | RTL818X_EEPROM_CMD_PROGRAM); | ||
1089 | rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); | ||
1090 | udelay(10); | ||
1091 | |||
1092 | eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val); | ||
1093 | eeprom_val &= 0xFF; | ||
1094 | priv->rf_type = eeprom_val; | ||
1095 | |||
1096 | eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val); | ||
1097 | priv->csthreshold = eeprom_val >> 8; | ||
1098 | |||
1099 | eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)priv->mac_addr, 3); | ||
1100 | |||
1101 | eeprom_cck_table_adr = 0x10; | ||
1102 | |||
1103 | /* CCK TX power */ | ||
1104 | for (i = 0; i < 14; i += 2) { | ||
1105 | u16 txpwr; | ||
1106 | eeprom_93cx6_read(&eeprom, eeprom_cck_table_adr + (i >> 1), | ||
1107 | &txpwr); | ||
1108 | priv->channels[i].hw_value = txpwr & 0xFF; | ||
1109 | priv->channels[i + 1].hw_value = txpwr >> 8; | ||
1110 | } | ||
1111 | |||
1112 | /* OFDM TX power */ | ||
1113 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { | ||
1114 | for (i = 0; i < 14; i += 2) { | ||
1115 | u16 txpwr; | ||
1116 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); | ||
1117 | priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; | ||
1118 | priv->channels[i + 1].hw_value |= txpwr & 0xFF00; | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) { | ||
1123 | __le32 anaparam; | ||
1124 | eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2); | ||
1125 | priv->anaparam = le32_to_cpu(anaparam); | ||
1126 | eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); | ||
1127 | } | ||
1128 | |||
1129 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, | ||
1130 | RTL818X_EEPROM_CMD_NORMAL); | ||
1131 | } | ||
1132 | |||
920 | static int rtl8180_probe(struct pci_dev *pdev, | 1133 | static int rtl8180_probe(struct pci_dev *pdev, |
921 | const struct pci_device_id *id) | 1134 | const struct pci_device_id *id) |
922 | { | 1135 | { |
@@ -924,12 +1137,9 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
924 | struct rtl8180_priv *priv; | 1137 | struct rtl8180_priv *priv; |
925 | unsigned long mem_addr, mem_len; | 1138 | unsigned long mem_addr, mem_len; |
926 | unsigned int io_addr, io_len; | 1139 | unsigned int io_addr, io_len; |
927 | int err, i; | 1140 | int err; |
928 | struct eeprom_93cx6 eeprom; | ||
929 | const char *chip_name, *rf_name = NULL; | 1141 | const char *chip_name, *rf_name = NULL; |
930 | u32 reg; | 1142 | u32 reg; |
931 | u16 eeprom_val; | ||
932 | u8 mac_addr[ETH_ALEN]; | ||
933 | 1143 | ||
934 | err = pci_enable_device(pdev); | 1144 | err = pci_enable_device(pdev); |
935 | if (err) { | 1145 | if (err) { |
@@ -1019,15 +1229,22 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1019 | switch (reg) { | 1229 | switch (reg) { |
1020 | case RTL818X_TX_CONF_R8180_ABCD: | 1230 | case RTL818X_TX_CONF_R8180_ABCD: |
1021 | chip_name = "RTL8180"; | 1231 | chip_name = "RTL8180"; |
1232 | priv->chip_family = RTL818X_CHIP_FAMILY_RTL8180; | ||
1022 | break; | 1233 | break; |
1234 | |||
1023 | case RTL818X_TX_CONF_R8180_F: | 1235 | case RTL818X_TX_CONF_R8180_F: |
1024 | chip_name = "RTL8180vF"; | 1236 | chip_name = "RTL8180vF"; |
1237 | priv->chip_family = RTL818X_CHIP_FAMILY_RTL8180; | ||
1025 | break; | 1238 | break; |
1239 | |||
1026 | case RTL818X_TX_CONF_R8185_ABC: | 1240 | case RTL818X_TX_CONF_R8185_ABC: |
1027 | chip_name = "RTL8185"; | 1241 | chip_name = "RTL8185"; |
1242 | priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185; | ||
1028 | break; | 1243 | break; |
1244 | |||
1029 | case RTL818X_TX_CONF_R8185_D: | 1245 | case RTL818X_TX_CONF_R8185_D: |
1030 | chip_name = "RTL8185vD"; | 1246 | chip_name = "RTL8185vD"; |
1247 | priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185; | ||
1031 | break; | 1248 | break; |
1032 | default: | 1249 | default: |
1033 | printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", | 1250 | printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", |
@@ -1035,27 +1252,14 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1035 | goto err_iounmap; | 1252 | goto err_iounmap; |
1036 | } | 1253 | } |
1037 | 1254 | ||
1038 | priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; | 1255 | if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { |
1039 | if (priv->r8185) { | ||
1040 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); | 1256 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); |
1041 | pci_try_set_mwi(pdev); | 1257 | pci_try_set_mwi(pdev); |
1042 | } | 1258 | } |
1043 | 1259 | ||
1044 | eeprom.data = dev; | 1260 | rtl8180_eeprom_read(priv); |
1045 | eeprom.register_read = rtl8180_eeprom_register_read; | ||
1046 | eeprom.register_write = rtl8180_eeprom_register_write; | ||
1047 | if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) | ||
1048 | eeprom.width = PCI_EEPROM_WIDTH_93C66; | ||
1049 | else | ||
1050 | eeprom.width = PCI_EEPROM_WIDTH_93C46; | ||
1051 | |||
1052 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM); | ||
1053 | rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); | ||
1054 | udelay(10); | ||
1055 | 1261 | ||
1056 | eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val); | 1262 | switch (priv->rf_type) { |
1057 | eeprom_val &= 0xFF; | ||
1058 | switch (eeprom_val) { | ||
1059 | case 1: rf_name = "Intersil"; | 1263 | case 1: rf_name = "Intersil"; |
1060 | break; | 1264 | break; |
1061 | case 2: rf_name = "RFMD"; | 1265 | case 2: rf_name = "RFMD"; |
@@ -1073,7 +1277,7 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1073 | break; | 1277 | break; |
1074 | default: | 1278 | default: |
1075 | printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n", | 1279 | printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n", |
1076 | pci_name(pdev), eeprom_val); | 1280 | pci_name(pdev), priv->rf_type); |
1077 | goto err_iounmap; | 1281 | goto err_iounmap; |
1078 | } | 1282 | } |
1079 | 1283 | ||
@@ -1083,42 +1287,12 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1083 | goto err_iounmap; | 1287 | goto err_iounmap; |
1084 | } | 1288 | } |
1085 | 1289 | ||
1086 | eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val); | 1290 | if (!is_valid_ether_addr(priv->mac_addr)) { |
1087 | priv->csthreshold = eeprom_val >> 8; | ||
1088 | if (!priv->r8185) { | ||
1089 | __le32 anaparam; | ||
1090 | eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2); | ||
1091 | priv->anaparam = le32_to_cpu(anaparam); | ||
1092 | eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); | ||
1093 | } | ||
1094 | |||
1095 | eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)mac_addr, 3); | ||
1096 | if (!is_valid_ether_addr(mac_addr)) { | ||
1097 | printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" | 1291 | printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" |
1098 | " randomly generated MAC addr\n", pci_name(pdev)); | 1292 | " randomly generated MAC addr\n", pci_name(pdev)); |
1099 | eth_random_addr(mac_addr); | 1293 | eth_random_addr(priv->mac_addr); |
1100 | } | 1294 | } |
1101 | SET_IEEE80211_PERM_ADDR(dev, mac_addr); | 1295 | SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr); |
1102 | |||
1103 | /* CCK TX power */ | ||
1104 | for (i = 0; i < 14; i += 2) { | ||
1105 | u16 txpwr; | ||
1106 | eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); | ||
1107 | priv->channels[i].hw_value = txpwr & 0xFF; | ||
1108 | priv->channels[i + 1].hw_value = txpwr >> 8; | ||
1109 | } | ||
1110 | |||
1111 | /* OFDM TX power */ | ||
1112 | if (priv->r8185) { | ||
1113 | for (i = 0; i < 14; i += 2) { | ||
1114 | u16 txpwr; | ||
1115 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); | ||
1116 | priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; | ||
1117 | priv->channels[i + 1].hw_value |= txpwr & 0xFF00; | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1121 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | ||
1122 | 1296 | ||
1123 | spin_lock_init(&priv->lock); | 1297 | spin_lock_init(&priv->lock); |
1124 | 1298 | ||
@@ -1130,12 +1304,12 @@ static int rtl8180_probe(struct pci_dev *pdev, | |||
1130 | } | 1304 | } |
1131 | 1305 | ||
1132 | wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", | 1306 | wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n", |
1133 | mac_addr, chip_name, priv->rf->name); | 1307 | priv->mac_addr, chip_name, priv->rf->name); |
1134 | 1308 | ||
1135 | return 0; | 1309 | return 0; |
1136 | 1310 | ||
1137 | err_iounmap: | 1311 | err_iounmap: |
1138 | iounmap(priv->map); | 1312 | pci_iounmap(pdev, priv->map); |
1139 | 1313 | ||
1140 | err_free_dev: | 1314 | err_free_dev: |
1141 | ieee80211_free_hw(dev); | 1315 | ieee80211_free_hw(dev); |