diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 124 |
1 files changed, 60 insertions, 64 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 0ae56cb6b0b..b20820a015c 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -92,8 +92,7 @@ struct mwl8k_device_info { | |||
92 | char *part_name; | 92 | char *part_name; |
93 | char *helper_image; | 93 | char *helper_image; |
94 | char *fw_image; | 94 | char *fw_image; |
95 | struct rxd_ops *rxd_ops; | 95 | struct rxd_ops *ap_rxd_ops; |
96 | u16 modes; | ||
97 | }; | 96 | }; |
98 | 97 | ||
99 | struct mwl8k_rx_queue { | 98 | struct mwl8k_rx_queue { |
@@ -580,10 +579,7 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw) | |||
580 | return rc; | 579 | return rc; |
581 | } | 580 | } |
582 | 581 | ||
583 | if (priv->device_info->modes & BIT(NL80211_IFTYPE_AP)) | 582 | iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); |
584 | iowrite32(MWL8K_MODE_AP, priv->regs + MWL8K_HIU_GEN_PTR); | ||
585 | else | ||
586 | iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR); | ||
587 | 583 | ||
588 | loops = 500000; | 584 | loops = 500000; |
589 | do { | 585 | do { |
@@ -720,9 +716,9 @@ static inline void mwl8k_add_dma_header(struct sk_buff *skb) | |||
720 | 716 | ||
721 | 717 | ||
722 | /* | 718 | /* |
723 | * Packet reception for 88w8366. | 719 | * Packet reception for 88w8366 AP firmware. |
724 | */ | 720 | */ |
725 | struct mwl8k_rxd_8366 { | 721 | struct mwl8k_rxd_8366_ap { |
726 | __le16 pkt_len; | 722 | __le16 pkt_len; |
727 | __u8 sq2; | 723 | __u8 sq2; |
728 | __u8 rate; | 724 | __u8 rate; |
@@ -740,23 +736,23 @@ struct mwl8k_rxd_8366 { | |||
740 | __u8 rx_ctrl; | 736 | __u8 rx_ctrl; |
741 | } __attribute__((packed)); | 737 | } __attribute__((packed)); |
742 | 738 | ||
743 | #define MWL8K_8366_RATE_INFO_MCS_FORMAT 0x80 | 739 | #define MWL8K_8366_AP_RATE_INFO_MCS_FORMAT 0x80 |
744 | #define MWL8K_8366_RATE_INFO_40MHZ 0x40 | 740 | #define MWL8K_8366_AP_RATE_INFO_40MHZ 0x40 |
745 | #define MWL8K_8366_RATE_INFO_RATEID(x) ((x) & 0x3f) | 741 | #define MWL8K_8366_AP_RATE_INFO_RATEID(x) ((x) & 0x3f) |
746 | 742 | ||
747 | #define MWL8K_8366_RX_CTRL_OWNED_BY_HOST 0x80 | 743 | #define MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST 0x80 |
748 | 744 | ||
749 | static void mwl8k_rxd_8366_init(void *_rxd, dma_addr_t next_dma_addr) | 745 | static void mwl8k_rxd_8366_ap_init(void *_rxd, dma_addr_t next_dma_addr) |
750 | { | 746 | { |
751 | struct mwl8k_rxd_8366 *rxd = _rxd; | 747 | struct mwl8k_rxd_8366_ap *rxd = _rxd; |
752 | 748 | ||
753 | rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); | 749 | rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); |
754 | rxd->rx_ctrl = MWL8K_8366_RX_CTRL_OWNED_BY_HOST; | 750 | rxd->rx_ctrl = MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST; |
755 | } | 751 | } |
756 | 752 | ||
757 | static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len) | 753 | static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len) |
758 | { | 754 | { |
759 | struct mwl8k_rxd_8366 *rxd = _rxd; | 755 | struct mwl8k_rxd_8366_ap *rxd = _rxd; |
760 | 756 | ||
761 | rxd->pkt_len = cpu_to_le16(len); | 757 | rxd->pkt_len = cpu_to_le16(len); |
762 | rxd->pkt_phys_addr = cpu_to_le32(addr); | 758 | rxd->pkt_phys_addr = cpu_to_le32(addr); |
@@ -765,12 +761,12 @@ static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len) | |||
765 | } | 761 | } |
766 | 762 | ||
767 | static int | 763 | static int |
768 | mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status, | 764 | mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status, |
769 | __le16 *qos) | 765 | __le16 *qos) |
770 | { | 766 | { |
771 | struct mwl8k_rxd_8366 *rxd = _rxd; | 767 | struct mwl8k_rxd_8366_ap *rxd = _rxd; |
772 | 768 | ||
773 | if (!(rxd->rx_ctrl & MWL8K_8366_RX_CTRL_OWNED_BY_HOST)) | 769 | if (!(rxd->rx_ctrl & MWL8K_8366_AP_RX_CTRL_OWNED_BY_HOST)) |
774 | return -1; | 770 | return -1; |
775 | rmb(); | 771 | rmb(); |
776 | 772 | ||
@@ -779,11 +775,11 @@ mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status, | |||
779 | status->signal = -rxd->rssi; | 775 | status->signal = -rxd->rssi; |
780 | status->noise = -rxd->noise_floor; | 776 | status->noise = -rxd->noise_floor; |
781 | 777 | ||
782 | if (rxd->rate & MWL8K_8366_RATE_INFO_MCS_FORMAT) { | 778 | if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) { |
783 | status->flag |= RX_FLAG_HT; | 779 | status->flag |= RX_FLAG_HT; |
784 | if (rxd->rate & MWL8K_8366_RATE_INFO_40MHZ) | 780 | if (rxd->rate & MWL8K_8366_AP_RATE_INFO_40MHZ) |
785 | status->flag |= RX_FLAG_40MHZ; | 781 | status->flag |= RX_FLAG_40MHZ; |
786 | status->rate_idx = MWL8K_8366_RATE_INFO_RATEID(rxd->rate); | 782 | status->rate_idx = MWL8K_8366_AP_RATE_INFO_RATEID(rxd->rate); |
787 | } else { | 783 | } else { |
788 | int i; | 784 | int i; |
789 | 785 | ||
@@ -803,17 +799,17 @@ mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status, | |||
803 | return le16_to_cpu(rxd->pkt_len); | 799 | return le16_to_cpu(rxd->pkt_len); |
804 | } | 800 | } |
805 | 801 | ||
806 | static struct rxd_ops rxd_8366_ops = { | 802 | static struct rxd_ops rxd_8366_ap_ops = { |
807 | .rxd_size = sizeof(struct mwl8k_rxd_8366), | 803 | .rxd_size = sizeof(struct mwl8k_rxd_8366_ap), |
808 | .rxd_init = mwl8k_rxd_8366_init, | 804 | .rxd_init = mwl8k_rxd_8366_ap_init, |
809 | .rxd_refill = mwl8k_rxd_8366_refill, | 805 | .rxd_refill = mwl8k_rxd_8366_ap_refill, |
810 | .rxd_process = mwl8k_rxd_8366_process, | 806 | .rxd_process = mwl8k_rxd_8366_ap_process, |
811 | }; | 807 | }; |
812 | 808 | ||
813 | /* | 809 | /* |
814 | * Packet reception for 88w8687. | 810 | * Packet reception for STA firmware. |
815 | */ | 811 | */ |
816 | struct mwl8k_rxd_8687 { | 812 | struct mwl8k_rxd_sta { |
817 | __le16 pkt_len; | 813 | __le16 pkt_len; |
818 | __u8 link_quality; | 814 | __u8 link_quality; |
819 | __u8 noise_level; | 815 | __u8 noise_level; |
@@ -830,26 +826,26 @@ struct mwl8k_rxd_8687 { | |||
830 | __u8 pad2[2]; | 826 | __u8 pad2[2]; |
831 | } __attribute__((packed)); | 827 | } __attribute__((packed)); |
832 | 828 | ||
833 | #define MWL8K_8687_RATE_INFO_SHORTPRE 0x8000 | 829 | #define MWL8K_STA_RATE_INFO_SHORTPRE 0x8000 |
834 | #define MWL8K_8687_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3) | 830 | #define MWL8K_STA_RATE_INFO_ANTSELECT(x) (((x) >> 11) & 0x3) |
835 | #define MWL8K_8687_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f) | 831 | #define MWL8K_STA_RATE_INFO_RATEID(x) (((x) >> 3) & 0x3f) |
836 | #define MWL8K_8687_RATE_INFO_40MHZ 0x0004 | 832 | #define MWL8K_STA_RATE_INFO_40MHZ 0x0004 |
837 | #define MWL8K_8687_RATE_INFO_SHORTGI 0x0002 | 833 | #define MWL8K_STA_RATE_INFO_SHORTGI 0x0002 |
838 | #define MWL8K_8687_RATE_INFO_MCS_FORMAT 0x0001 | 834 | #define MWL8K_STA_RATE_INFO_MCS_FORMAT 0x0001 |
839 | 835 | ||
840 | #define MWL8K_8687_RX_CTRL_OWNED_BY_HOST 0x02 | 836 | #define MWL8K_STA_RX_CTRL_OWNED_BY_HOST 0x02 |
841 | 837 | ||
842 | static void mwl8k_rxd_8687_init(void *_rxd, dma_addr_t next_dma_addr) | 838 | static void mwl8k_rxd_sta_init(void *_rxd, dma_addr_t next_dma_addr) |
843 | { | 839 | { |
844 | struct mwl8k_rxd_8687 *rxd = _rxd; | 840 | struct mwl8k_rxd_sta *rxd = _rxd; |
845 | 841 | ||
846 | rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); | 842 | rxd->next_rxd_phys_addr = cpu_to_le32(next_dma_addr); |
847 | rxd->rx_ctrl = MWL8K_8687_RX_CTRL_OWNED_BY_HOST; | 843 | rxd->rx_ctrl = MWL8K_STA_RX_CTRL_OWNED_BY_HOST; |
848 | } | 844 | } |
849 | 845 | ||
850 | static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len) | 846 | static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len) |
851 | { | 847 | { |
852 | struct mwl8k_rxd_8687 *rxd = _rxd; | 848 | struct mwl8k_rxd_sta *rxd = _rxd; |
853 | 849 | ||
854 | rxd->pkt_len = cpu_to_le16(len); | 850 | rxd->pkt_len = cpu_to_le16(len); |
855 | rxd->pkt_phys_addr = cpu_to_le32(addr); | 851 | rxd->pkt_phys_addr = cpu_to_le32(addr); |
@@ -858,13 +854,13 @@ static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len) | |||
858 | } | 854 | } |
859 | 855 | ||
860 | static int | 856 | static int |
861 | mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status, | 857 | mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status, |
862 | __le16 *qos) | 858 | __le16 *qos) |
863 | { | 859 | { |
864 | struct mwl8k_rxd_8687 *rxd = _rxd; | 860 | struct mwl8k_rxd_sta *rxd = _rxd; |
865 | u16 rate_info; | 861 | u16 rate_info; |
866 | 862 | ||
867 | if (!(rxd->rx_ctrl & MWL8K_8687_RX_CTRL_OWNED_BY_HOST)) | 863 | if (!(rxd->rx_ctrl & MWL8K_STA_RX_CTRL_OWNED_BY_HOST)) |
868 | return -1; | 864 | return -1; |
869 | rmb(); | 865 | rmb(); |
870 | 866 | ||
@@ -874,16 +870,16 @@ mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status, | |||
874 | 870 | ||
875 | status->signal = -rxd->rssi; | 871 | status->signal = -rxd->rssi; |
876 | status->noise = -rxd->noise_level; | 872 | status->noise = -rxd->noise_level; |
877 | status->antenna = MWL8K_8687_RATE_INFO_ANTSELECT(rate_info); | 873 | status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info); |
878 | status->rate_idx = MWL8K_8687_RATE_INFO_RATEID(rate_info); | 874 | status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info); |
879 | 875 | ||
880 | if (rate_info & MWL8K_8687_RATE_INFO_SHORTPRE) | 876 | if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE) |
881 | status->flag |= RX_FLAG_SHORTPRE; | 877 | status->flag |= RX_FLAG_SHORTPRE; |
882 | if (rate_info & MWL8K_8687_RATE_INFO_40MHZ) | 878 | if (rate_info & MWL8K_STA_RATE_INFO_40MHZ) |
883 | status->flag |= RX_FLAG_40MHZ; | 879 | status->flag |= RX_FLAG_40MHZ; |
884 | if (rate_info & MWL8K_8687_RATE_INFO_SHORTGI) | 880 | if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI) |
885 | status->flag |= RX_FLAG_SHORT_GI; | 881 | status->flag |= RX_FLAG_SHORT_GI; |
886 | if (rate_info & MWL8K_8687_RATE_INFO_MCS_FORMAT) | 882 | if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT) |
887 | status->flag |= RX_FLAG_HT; | 883 | status->flag |= RX_FLAG_HT; |
888 | 884 | ||
889 | status->band = IEEE80211_BAND_2GHZ; | 885 | status->band = IEEE80211_BAND_2GHZ; |
@@ -894,11 +890,11 @@ mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status, | |||
894 | return le16_to_cpu(rxd->pkt_len); | 890 | return le16_to_cpu(rxd->pkt_len); |
895 | } | 891 | } |
896 | 892 | ||
897 | static struct rxd_ops rxd_8687_ops = { | 893 | static struct rxd_ops rxd_sta_ops = { |
898 | .rxd_size = sizeof(struct mwl8k_rxd_8687), | 894 | .rxd_size = sizeof(struct mwl8k_rxd_sta), |
899 | .rxd_init = mwl8k_rxd_8687_init, | 895 | .rxd_init = mwl8k_rxd_sta_init, |
900 | .rxd_refill = mwl8k_rxd_8687_refill, | 896 | .rxd_refill = mwl8k_rxd_sta_refill, |
901 | .rxd_process = mwl8k_rxd_8687_process, | 897 | .rxd_process = mwl8k_rxd_sta_process, |
902 | }; | 898 | }; |
903 | 899 | ||
904 | 900 | ||
@@ -3267,15 +3263,12 @@ static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { | |||
3267 | .part_name = "88w8687", | 3263 | .part_name = "88w8687", |
3268 | .helper_image = "mwl8k/helper_8687.fw", | 3264 | .helper_image = "mwl8k/helper_8687.fw", |
3269 | .fw_image = "mwl8k/fmimage_8687.fw", | 3265 | .fw_image = "mwl8k/fmimage_8687.fw", |
3270 | .rxd_ops = &rxd_8687_ops, | ||
3271 | .modes = BIT(NL80211_IFTYPE_STATION), | ||
3272 | }, | 3266 | }, |
3273 | [MWL8366] = { | 3267 | [MWL8366] = { |
3274 | .part_name = "88w8366", | 3268 | .part_name = "88w8366", |
3275 | .helper_image = "mwl8k/helper_8366.fw", | 3269 | .helper_image = "mwl8k/helper_8366.fw", |
3276 | .fw_image = "mwl8k/fmimage_8366.fw", | 3270 | .fw_image = "mwl8k/fmimage_8366.fw", |
3277 | .rxd_ops = &rxd_8366_ops, | 3271 | .ap_rxd_ops = &rxd_8366_ap_ops, |
3278 | .modes = 0, | ||
3279 | }, | 3272 | }, |
3280 | }; | 3273 | }; |
3281 | 3274 | ||
@@ -3380,7 +3373,10 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3380 | mwl8k_release_firmware(priv); | 3373 | mwl8k_release_firmware(priv); |
3381 | 3374 | ||
3382 | 3375 | ||
3383 | priv->rxd_ops = priv->device_info->rxd_ops; | 3376 | if (priv->ap_fw) |
3377 | priv->rxd_ops = priv->device_info->ap_rxd_ops; | ||
3378 | else | ||
3379 | priv->rxd_ops = &rxd_sta_ops; | ||
3384 | 3380 | ||
3385 | priv->sniffer_enabled = false; | 3381 | priv->sniffer_enabled = false; |
3386 | priv->wmm_enabled = false; | 3382 | priv->wmm_enabled = false; |
@@ -3409,8 +3405,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3409 | 3405 | ||
3410 | hw->queues = MWL8K_TX_QUEUES; | 3406 | hw->queues = MWL8K_TX_QUEUES; |
3411 | 3407 | ||
3412 | hw->wiphy->interface_modes = priv->device_info->modes; | ||
3413 | |||
3414 | /* Set rssi and noise values to dBm */ | 3408 | /* Set rssi and noise values to dBm */ |
3415 | hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; | 3409 | hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; |
3416 | hw->vif_data_size = sizeof(struct mwl8k_vif); | 3410 | hw->vif_data_size = sizeof(struct mwl8k_vif); |
@@ -3480,6 +3474,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3480 | rc = mwl8k_cmd_set_hw_spec(hw); | 3474 | rc = mwl8k_cmd_set_hw_spec(hw); |
3481 | } else { | 3475 | } else { |
3482 | rc = mwl8k_cmd_get_hw_spec_sta(hw); | 3476 | rc = mwl8k_cmd_get_hw_spec_sta(hw); |
3477 | |||
3478 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | ||
3483 | } | 3479 | } |
3484 | if (rc) { | 3480 | if (rc) { |
3485 | printk(KERN_ERR "%s: Cannot initialise firmware\n", | 3481 | printk(KERN_ERR "%s: Cannot initialise firmware\n", |