aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c124
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
99struct mwl8k_rx_queue { 98struct 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 */
725struct mwl8k_rxd_8366 { 721struct 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
749static void mwl8k_rxd_8366_init(void *_rxd, dma_addr_t next_dma_addr) 745static 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
757static void mwl8k_rxd_8366_refill(void *_rxd, dma_addr_t addr, int len) 753static 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
767static int 763static int
768mwl8k_rxd_8366_process(void *_rxd, struct ieee80211_rx_status *status, 764mwl8k_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
806static struct rxd_ops rxd_8366_ops = { 802static 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 */
816struct mwl8k_rxd_8687 { 812struct 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
842static void mwl8k_rxd_8687_init(void *_rxd, dma_addr_t next_dma_addr) 838static 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
850static void mwl8k_rxd_8687_refill(void *_rxd, dma_addr_t addr, int len) 846static 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
860static int 856static int
861mwl8k_rxd_8687_process(void *_rxd, struct ieee80211_rx_status *status, 857mwl8k_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
897static struct rxd_ops rxd_8687_ops = { 893static 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",