aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-29 17:02:13 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 17:02:13 -0400
commit143b11c03cd42f2284efe5128afc057d8fc86c78 (patch)
tree8186830c461b7933c26cdd00b69e4c737c5c88e7 /drivers
parentaf01d537463714e36e2c96d2da35902b76cd6827 (diff)
parent18c8adeb0244f823ba78a51e23f813fe68bc3c54 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h55
-rw-r--r--drivers/net/wireless/ath9k/beacon.c259
-rw-r--r--drivers/net/wireless/ath9k/core.c306
-rw-r--r--drivers/net/wireless/ath9k/core.h248
-rw-r--r--drivers/net/wireless/ath9k/hw.c150
-rw-r--r--drivers/net/wireless/ath9k/hw.h120
-rw-r--r--drivers/net/wireless/ath9k/main.c256
-rw-r--r--drivers/net/wireless/ath9k/phy.h12
-rw-r--r--drivers/net/wireless/ath9k/rc.c183
-rw-r--r--drivers/net/wireless/ath9k/rc.h222
-rw-r--r--drivers/net/wireless/ath9k/recv.c81
-rw-r--r--drivers/net/wireless/ath9k/reg.h6
-rw-r--r--drivers/net/wireless/ath9k/xmit.c404
-rw-r--r--drivers/net/wireless/b43/Makefile4
-rw-r--r--drivers/net/wireless/b43/b43.h137
-rw-r--r--drivers/net/wireless/b43/debugfs.c79
-rw-r--r--drivers/net/wireless/b43/lo.c120
-rw-r--r--drivers/net/wireless/b43/lo.h4
-rw-r--r--drivers/net/wireless/b43/main.c184
-rw-r--r--drivers/net/wireless/b43/nphy.c148
-rw-r--r--drivers/net/wireless/b43/nphy.h54
-rw-r--r--drivers/net/wireless/b43/phy.c3421
-rw-r--r--drivers/net/wireless/b43/phy.h340
-rw-r--r--drivers/net/wireless/b43/phy_a.c543
-rw-r--r--drivers/net/wireless/b43/phy_a.h124
-rw-r--r--drivers/net/wireless/b43/phy_common.c367
-rw-r--r--drivers/net/wireless/b43/phy_common.h381
-rw-r--r--drivers/net/wireless/b43/phy_g.c3251
-rw-r--r--drivers/net/wireless/b43/phy_g.h209
-rw-r--r--drivers/net/wireless/b43/rfkill.c5
-rw-r--r--drivers/net/wireless/b43/sysfs.c23
-rw-r--r--drivers/net/wireless/b43/tables.c43
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c2
-rw-r--r--drivers/net/wireless/b43/wa.c2
-rw-r--r--drivers/net/wireless/b43/xmit.c8
-rw-r--r--drivers/net/wireless/b43legacy/main.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c1
-rw-r--r--drivers/net/wireless/libertas/assoc.c744
-rw-r--r--drivers/net/wireless/libertas/assoc.h18
-rw-r--r--drivers/net/wireless/libertas/cmd.c147
-rw-r--r--drivers/net/wireless/libertas/cmd.h6
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c33
-rw-r--r--drivers/net/wireless/libertas/decl.h1
-rw-r--r--drivers/net/wireless/libertas/dev.h7
-rw-r--r--drivers/net/wireless/libertas/host.h26
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h50
-rw-r--r--drivers/net/wireless/libertas/main.c21
-rw-r--r--drivers/net/wireless/libertas/scan.c5
-rw-r--r--drivers/net/wireless/libertas/wext.c148
-rw-r--r--drivers/net/wireless/libertas_tf/main.c20
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c16
-rw-r--r--drivers/net/wireless/p54/p54.h2
-rw-r--r--drivers/net/wireless/p54/p54common.c170
-rw-r--r--drivers/net/wireless/p54/p54common.h23
-rw-r--r--drivers/net/wireless/p54/p54pci.c242
-rw-r--r--drivers/net/wireless/p54/p54pci.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c68
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c75
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c31
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c21
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c73
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c74
-rw-r--r--drivers/ssb/pci.c84
72 files changed, 7384 insertions, 6535 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index d1b0fbae5a32..28b8d84f49b4 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -144,6 +144,7 @@ struct ath_desc {
144#define ATH9K_TXDESC_EXT_AND_CTL 0x0080 144#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
145#define ATH9K_TXDESC_VMF 0x0100 145#define ATH9K_TXDESC_VMF 0x0100
146#define ATH9K_TXDESC_FRAG_IS_ON 0x0200 146#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
147#define ATH9K_TXDESC_CAB 0x0400
147 148
148#define ATH9K_RXDESC_INTREQ 0x0020 149#define ATH9K_RXDESC_INTREQ 0x0020
149 150
@@ -564,8 +565,6 @@ enum ath9k_cipher {
564#define CTL_5GHT40 8 565#define CTL_5GHT40 8
565 566
566#define AR_EEPROM_MAC(i) (0x1d+(i)) 567#define AR_EEPROM_MAC(i) (0x1d+(i))
567#define EEP_SCALE 100
568#define EEP_DELTA 10
569 568
570#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c 569#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
571#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2 570#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
@@ -606,9 +605,6 @@ struct ath9k_country_entry {
606#define REG_CLR_BIT(_a, _r, _f) \ 605#define REG_CLR_BIT(_a, _r, _f) \
607 REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f) 606 REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
608 607
609#define ATH9K_COMP_BUF_MAX_SIZE 9216
610#define ATH9K_COMP_BUF_ALIGN_SIZE 512
611
612#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001 608#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
613 609
614#define INIT_AIFS 2 610#define INIT_AIFS 2
@@ -632,12 +628,6 @@ struct ath9k_country_entry {
632 (IEEE80211_WEP_IVLEN + \ 628 (IEEE80211_WEP_IVLEN + \
633 IEEE80211_WEP_KIDLEN + \ 629 IEEE80211_WEP_KIDLEN + \
634 IEEE80211_WEP_CRCLEN)) 630 IEEE80211_WEP_CRCLEN))
635#define IEEE80211_MAX_LEN (2300 + FCS_LEN + \
636 (IEEE80211_WEP_IVLEN + \
637 IEEE80211_WEP_KIDLEN + \
638 IEEE80211_WEP_CRCLEN))
639
640#define MAX_REG_ADD_COUNT 129
641#define MAX_RATE_POWER 63 631#define MAX_RATE_POWER 63
642 632
643enum ath9k_power_mode { 633enum ath9k_power_mode {
@@ -707,13 +697,6 @@ enum phytype {
707}; 697};
708#define PHY_CCK PHY_DS 698#define PHY_CCK PHY_DS
709 699
710enum start_adhoc_option {
711 START_ADHOC_NO_11A,
712 START_ADHOC_PER_11D,
713 START_ADHOC_IN_11A,
714 START_ADHOC_IN_11B,
715};
716
717enum ath9k_tp_scale { 700enum ath9k_tp_scale {
718 ATH9K_TP_SCALE_MAX = 0, 701 ATH9K_TP_SCALE_MAX = 0,
719 ATH9K_TP_SCALE_50, 702 ATH9K_TP_SCALE_50,
@@ -769,14 +752,11 @@ struct ath9k_node_stats {
769 752
770#define ATH9K_RSSI_EP_MULTIPLIER (1<<7) 753#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
771 754
772enum ath9k_gpio_output_mux_type { 755#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
773 ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT, 756#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
774 ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED, 757#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
775 ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED, 758#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
776 ATH9K_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED, 759#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
777 ATH9K_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
778 ATH9K_GPIO_OUTPUT_MUX_NUM_ENTRIES
779};
780 760
781enum { 761enum {
782 ATH9K_RESET_POWER_ON, 762 ATH9K_RESET_POWER_ON,
@@ -790,19 +770,20 @@ struct ath_hal {
790 u32 ah_magic; 770 u32 ah_magic;
791 u16 ah_devid; 771 u16 ah_devid;
792 u16 ah_subvendorid; 772 u16 ah_subvendorid;
793 struct ath_softc *ah_sc;
794 void __iomem *ah_sh;
795 u16 ah_countryCode;
796 u32 ah_macVersion; 773 u32 ah_macVersion;
797 u16 ah_macRev; 774 u16 ah_macRev;
798 u16 ah_phyRev; 775 u16 ah_phyRev;
799 u16 ah_analog5GhzRev; 776 u16 ah_analog5GhzRev;
800 u16 ah_analog2GhzRev; 777 u16 ah_analog2GhzRev;
801 u8 ah_decompMask[ATH9K_DECOMP_MASK_SIZE]; 778
802 u32 ah_flags; 779 void __iomem *ah_sh;
780 struct ath_softc *ah_sc;
803 enum ath9k_opmode ah_opmode; 781 enum ath9k_opmode ah_opmode;
804 struct ath9k_ops_config ah_config; 782 struct ath9k_ops_config ah_config;
805 struct ath9k_hw_capabilities ah_caps; 783 struct ath9k_hw_capabilities ah_caps;
784
785 u16 ah_countryCode;
786 u32 ah_flags;
806 int16_t ah_powerLimit; 787 int16_t ah_powerLimit;
807 u16 ah_maxPowerLevel; 788 u16 ah_maxPowerLevel;
808 u32 ah_tpScale; 789 u32 ah_tpScale;
@@ -812,15 +793,16 @@ struct ath_hal {
812 u16 ah_currentRD5G; 793 u16 ah_currentRD5G;
813 u16 ah_currentRD2G; 794 u16 ah_currentRD2G;
814 char ah_iso[4]; 795 char ah_iso[4];
815 enum start_adhoc_option ah_adHocMode; 796
816 bool ah_commonMode;
817 struct ath9k_channel ah_channels[150]; 797 struct ath9k_channel ah_channels[150];
818 u32 ah_nchan;
819 struct ath9k_channel *ah_curchan; 798 struct ath9k_channel *ah_curchan;
799 u32 ah_nchan;
800
820 u16 ah_rfsilent; 801 u16 ah_rfsilent;
821 bool ah_rfkillEnabled; 802 bool ah_rfkillEnabled;
822 bool ah_isPciExpress; 803 bool ah_isPciExpress;
823 u16 ah_txTrigLevel; 804 u16 ah_txTrigLevel;
805
824#ifndef ATH_NF_PER_CHAN 806#ifndef ATH_NF_PER_CHAN
825 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; 807 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
826#endif 808#endif
@@ -853,7 +835,7 @@ bool ath9k_regd_init_channels(struct ath_hal *ah,
853u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags); 835u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
854enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, 836enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah,
855 enum ath9k_int ints); 837 enum ath9k_int ints);
856bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, 838bool ath9k_hw_reset(struct ath_hal *ah,
857 struct ath9k_channel *chan, 839 struct ath9k_channel *chan,
858 enum ath9k_ht_macmode macmode, 840 enum ath9k_ht_macmode macmode,
859 u8 txchainmask, u8 rxchainmask, 841 u8 txchainmask, u8 rxchainmask,
@@ -1018,4 +1000,7 @@ void ath9k_hw_get_channel_centers(struct ath_hal *ah,
1018bool ath9k_get_channel_edges(struct ath_hal *ah, 1000bool ath9k_get_channel_edges(struct ath_hal *ah,
1019 u16 flags, u16 *low, 1001 u16 flags, u16 *low,
1020 u16 *high); 1002 u16 *high);
1003void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
1004 u32 ah_signal_type);
1005void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 value);
1021#endif 1006#endif
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index caf569401a34..c43fd5861163 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -33,7 +33,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
33 struct ath9k_tx_queue_info qi; 33 struct ath9k_tx_queue_info qi;
34 34
35 ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi); 35 ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi);
36 if (sc->sc_opmode == ATH9K_M_HOSTAP) { 36 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
37 /* Always burst out beacon and CAB traffic. */ 37 /* Always burst out beacon and CAB traffic. */
38 qi.tqi_aifs = 1; 38 qi.tqi_aifs = 1;
39 qi.tqi_cwmin = 0; 39 qi.tqi_cwmin = 0;
@@ -85,7 +85,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
85 85
86 flags = ATH9K_TXDESC_NOACK; 86 flags = ATH9K_TXDESC_NOACK;
87 87
88 if (sc->sc_opmode == ATH9K_M_IBSS && 88 if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
89 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { 89 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
90 ds->ds_link = bf->bf_daddr; /* self-linked */ 90 ds->ds_link = bf->bf_daddr; /* self-linked */
91 flags |= ATH9K_TXDESC_VEOL; 91 flags |= ATH9K_TXDESC_VEOL;
@@ -111,24 +111,24 @@ static void ath_beacon_setup(struct ath_softc *sc,
111 rix = 0; 111 rix = 0;
112 rt = sc->sc_currates; 112 rt = sc->sc_currates;
113 rate = rt->info[rix].rateCode; 113 rate = rt->info[rix].rateCode;
114 if (sc->sc_flags & ATH_PREAMBLE_SHORT) 114 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
115 rate |= rt->info[rix].shortPreamble; 115 rate |= rt->info[rix].shortPreamble;
116 116
117 ath9k_hw_set11n_txdesc(ah, ds 117 ath9k_hw_set11n_txdesc(ah, ds,
118 , skb->len + FCS_LEN /* frame length */ 118 skb->len + FCS_LEN, /* frame length */
119 , ATH9K_PKT_TYPE_BEACON /* Atheros packet type */ 119 ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */
120 , avp->av_btxctl.txpower /* txpower XXX */ 120 avp->av_btxctl.txpower, /* txpower XXX */
121 , ATH9K_TXKEYIX_INVALID /* no encryption */ 121 ATH9K_TXKEYIX_INVALID, /* no encryption */
122 , ATH9K_KEY_TYPE_CLEAR /* no encryption */ 122 ATH9K_KEY_TYPE_CLEAR, /* no encryption */
123 , flags /* no ack, veol for beacons */ 123 flags /* no ack, veol for beacons */
124 ); 124 );
125 125
126 /* NB: beacon's BufLen must be a multiple of 4 bytes */ 126 /* NB: beacon's BufLen must be a multiple of 4 bytes */
127 ath9k_hw_filltxdesc(ah, ds 127 ath9k_hw_filltxdesc(ah, ds,
128 , roundup(skb->len, 4) /* buffer length */ 128 roundup(skb->len, 4), /* buffer length */
129 , true /* first segment */ 129 true, /* first segment */
130 , true /* last segment */ 130 true, /* last segment */
131 , ds /* first descriptor */ 131 ds /* first descriptor */
132 ); 132 );
133 133
134 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); 134 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
@@ -140,55 +140,6 @@ static void ath_beacon_setup(struct ath_softc *sc,
140 ctsrate, ctsduration, series, 4, 0); 140 ctsrate, ctsduration, series, 4, 0);
141} 141}
142 142
143/* Move everything from the vap's mcast queue to the hardware cab queue.
144 * Caller must hold mcasq lock and cabq lock
145 * XXX MORE_DATA bit?
146 */
147static void empty_mcastq_into_cabq(struct ath_hal *ah,
148 struct ath_txq *mcastq, struct ath_txq *cabq)
149{
150 struct ath_buf *bfmcast;
151
152 BUG_ON(list_empty(&mcastq->axq_q));
153
154 bfmcast = list_first_entry(&mcastq->axq_q, struct ath_buf, list);
155
156 /* link the descriptors */
157 if (!cabq->axq_link)
158 ath9k_hw_puttxbuf(ah, cabq->axq_qnum, bfmcast->bf_daddr);
159 else
160 *cabq->axq_link = bfmcast->bf_daddr;
161
162 /* append the private vap mcast list to the cabq */
163
164 cabq->axq_depth += mcastq->axq_depth;
165 cabq->axq_totalqueued += mcastq->axq_totalqueued;
166 cabq->axq_linkbuf = mcastq->axq_linkbuf;
167 cabq->axq_link = mcastq->axq_link;
168 list_splice_tail_init(&mcastq->axq_q, &cabq->axq_q);
169 mcastq->axq_depth = 0;
170 mcastq->axq_totalqueued = 0;
171 mcastq->axq_linkbuf = NULL;
172 mcastq->axq_link = NULL;
173}
174
175/* This is only run at DTIM. We move everything from the vap's mcast queue
176 * to the hardware cab queue. Caller must hold the mcastq lock. */
177static void trigger_mcastq(struct ath_hal *ah,
178 struct ath_txq *mcastq, struct ath_txq *cabq)
179{
180 spin_lock_bh(&cabq->axq_lock);
181
182 if (!list_empty(&mcastq->axq_q))
183 empty_mcastq_into_cabq(ah, mcastq, cabq);
184
185 /* cabq is gated by beacon so it is safe to start here */
186 if (!list_empty(&cabq->axq_q))
187 ath9k_hw_txstart(ah, cabq->axq_qnum);
188
189 spin_unlock_bh(&cabq->axq_lock);
190}
191
192/* 143/*
193 * Generate beacon frame and queue cab data for a vap. 144 * Generate beacon frame and queue cab data for a vap.
194 * 145 *
@@ -199,19 +150,14 @@ static void trigger_mcastq(struct ath_hal *ah,
199*/ 150*/
200static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) 151static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
201{ 152{
202 struct ath_hal *ah = sc->sc_ah;
203 struct ath_buf *bf; 153 struct ath_buf *bf;
204 struct ath_vap *avp; 154 struct ath_vap *avp;
205 struct sk_buff *skb; 155 struct sk_buff *skb;
206 int cabq_depth; 156 int cabq_depth;
207 int mcastq_depth;
208 int is_beacon_dtim = 0;
209 unsigned int curlen;
210 struct ath_txq *cabq; 157 struct ath_txq *cabq;
211 struct ath_txq *mcastq; 158 struct ieee80211_tx_info *info;
212 avp = sc->sc_vaps[if_id]; 159 avp = sc->sc_vaps[if_id];
213 160
214 mcastq = &avp->av_mcastq;
215 cabq = sc->sc_cabq; 161 cabq = sc->sc_cabq;
216 162
217 ASSERT(avp); 163 ASSERT(avp);
@@ -223,32 +169,33 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
223 } 169 }
224 bf = avp->av_bcbuf; 170 bf = avp->av_bcbuf;
225 skb = (struct sk_buff *) bf->bf_mpdu; 171 skb = (struct sk_buff *) bf->bf_mpdu;
172 if (skb) {
173 pci_unmap_single(sc->pdev, bf->bf_dmacontext,
174 skb_end_pointer(skb) - skb->head,
175 PCI_DMA_TODEVICE);
176 }
226 177
227 /* 178 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
228 * Update dynamic beacon contents. If this returns 179 bf->bf_mpdu = skb;
229 * non-zero then we need to remap the memory because 180 if (skb == NULL)
230 * the beacon frame changed size (probably because 181 return NULL;
231 * of the TIM bitmap). 182 info = IEEE80211_SKB_CB(skb);
232 */ 183 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
233 curlen = skb->len; 184 /*
234 185 * TODO: make sure the seq# gets assigned properly (vs. other
235 /* XXX: spin_lock_bh should not be used here, but sparse bitches 186 * TX frames)
236 * otherwise. We should fix sparse :) */ 187 */
237 spin_lock_bh(&mcastq->axq_lock); 188 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
238 mcastq_depth = avp->av_mcastq.axq_depth; 189 sc->seq_no += 0x10;
239 190 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
240 if (ath_update_beacon(sc, if_id, &avp->av_boff, skb, mcastq_depth) == 191 hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
241 1) {
242 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
243 get_dma_mem_context(bf, bf_dmacontext));
244 bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
245 get_dma_mem_context(bf, bf_dmacontext));
246 } else {
247 pci_dma_sync_single_for_cpu(sc->pdev,
248 bf->bf_buf_addr,
249 skb_tailroom(skb),
250 PCI_DMA_TODEVICE);
251 } 192 }
193 bf->bf_buf_addr = bf->bf_dmacontext =
194 pci_map_single(sc->pdev, skb->data,
195 skb_end_pointer(skb) - skb->head,
196 PCI_DMA_TODEVICE);
197
198 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
252 199
253 /* 200 /*
254 * if the CABQ traffic from previous DTIM is pending and the current 201 * if the CABQ traffic from previous DTIM is pending and the current
@@ -262,9 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
262 cabq_depth = cabq->axq_depth; 209 cabq_depth = cabq->axq_depth;
263 spin_unlock_bh(&cabq->axq_lock); 210 spin_unlock_bh(&cabq->axq_lock);
264 211
265 is_beacon_dtim = avp->av_boff.bo_tim[4] & 1; 212 if (skb && cabq_depth) {
266
267 if (mcastq_depth && is_beacon_dtim && cabq_depth) {
268 /* 213 /*
269 * Unlock the cabq lock as ath_tx_draintxq acquires 214 * Unlock the cabq lock as ath_tx_draintxq acquires
270 * the lock again which is a common function and that 215 * the lock again which is a common function and that
@@ -284,10 +229,11 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
284 * Enable the CAB queue before the beacon queue to 229 * Enable the CAB queue before the beacon queue to
285 * insure cab frames are triggered by this beacon. 230 * insure cab frames are triggered by this beacon.
286 */ 231 */
287 if (is_beacon_dtim) 232 while (skb) {
288 trigger_mcastq(ah, mcastq, cabq); 233 ath_tx_cabq(sc, skb);
234 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
235 }
289 236
290 spin_unlock_bh(&mcastq->axq_lock);
291 return bf; 237 return bf;
292} 238}
293 239
@@ -375,7 +321,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
375 struct ath_buf, list); 321 struct ath_buf, list);
376 list_del(&avp->av_bcbuf->list); 322 list_del(&avp->av_bcbuf->list);
377 323
378 if (sc->sc_opmode == ATH9K_M_HOSTAP || 324 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
379 !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { 325 !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
380 int slot; 326 int slot;
381 /* 327 /*
@@ -408,8 +354,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
408 bf = avp->av_bcbuf; 354 bf = avp->av_bcbuf;
409 if (bf->bf_mpdu != NULL) { 355 if (bf->bf_mpdu != NULL) {
410 skb = (struct sk_buff *)bf->bf_mpdu; 356 skb = (struct sk_buff *)bf->bf_mpdu;
411 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, 357 pci_unmap_single(sc->pdev, bf->bf_dmacontext,
412 get_dma_mem_context(bf, bf_dmacontext)); 358 skb_end_pointer(skb) - skb->head,
359 PCI_DMA_TODEVICE);
413 dev_kfree_skb_any(skb); 360 dev_kfree_skb_any(skb);
414 bf->bf_mpdu = NULL; 361 bf->bf_mpdu = NULL;
415 } 362 }
@@ -418,7 +365,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
418 * NB: the beacon data buffer must be 32-bit aligned; 365 * NB: the beacon data buffer must be 32-bit aligned;
419 * we assume the wbuf routines will return us something 366 * we assume the wbuf routines will return us something
420 * with this alignment (perhaps should assert). 367 * with this alignment (perhaps should assert).
421 * FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and 368 * FIXME: Fill avp->av_btxctl.txpower and
422 * avp->av_btxctl.shortPreamble 369 * avp->av_btxctl.shortPreamble
423 */ 370 */
424 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data); 371 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
@@ -439,9 +386,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
439 __le64 val; 386 __le64 val;
440 int intval; 387 int intval;
441 388
442 /* FIXME: Use default value for now: Sujith */ 389 intval = sc->hw->conf.beacon_int ?
443 390 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
444 intval = ATH_DEFAULT_BINTVAL;
445 391
446 /* 392 /*
447 * The beacon interval is in TU's; the TSF in usecs. 393 * The beacon interval is in TU's; the TSF in usecs.
@@ -466,8 +412,10 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
466 memcpy(&wh[1], &val, sizeof(val)); 412 memcpy(&wh[1], &val, sizeof(val));
467 } 413 }
468 414
469 bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE, 415 bf->bf_buf_addr = bf->bf_dmacontext =
470 get_dma_mem_context(bf, bf_dmacontext)); 416 pci_map_single(sc->pdev, skb->data,
417 skb_end_pointer(skb) - skb->head,
418 PCI_DMA_TODEVICE);
471 bf->bf_mpdu = skb; 419 bf->bf_mpdu = skb;
472 420
473 return 0; 421 return 0;
@@ -493,8 +441,9 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
493 bf = avp->av_bcbuf; 441 bf = avp->av_bcbuf;
494 if (bf->bf_mpdu != NULL) { 442 if (bf->bf_mpdu != NULL) {
495 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; 443 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
496 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE, 444 pci_unmap_single(sc->pdev, bf->bf_dmacontext,
497 get_dma_mem_context(bf, bf_dmacontext)); 445 skb_end_pointer(skb) - skb->head,
446 PCI_DMA_TODEVICE);
498 dev_kfree_skb_any(skb); 447 dev_kfree_skb_any(skb);
499 bf->bf_mpdu = NULL; 448 bf->bf_mpdu = NULL;
500 } 449 }
@@ -505,30 +454,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
505} 454}
506 455
507/* 456/*
508 * Reclaim beacon resources and return buffer to the pool.
509 *
510 * This function will free any wbuf frames that are still attached to the
511 * beacon buffers in the ATH object. Note that this does not de-allocate
512 * any wbuf objects that are in the transmit queue and have not yet returned
513 * to the ATH object.
514*/
515
516void ath_beacon_free(struct ath_softc *sc)
517{
518 struct ath_buf *bf;
519
520 list_for_each_entry(bf, &sc->sc_bbuf, list) {
521 if (bf->bf_mpdu != NULL) {
522 struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
523 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
524 get_dma_mem_context(bf, bf_dmacontext));
525 dev_kfree_skb_any(skb);
526 bf->bf_mpdu = NULL;
527 }
528 }
529}
530
531/*
532 * Tasklet for Sending Beacons 457 * Tasklet for Sending Beacons
533 * 458 *
534 * Transmit one or more beacon frames at SWBA. Dynamic updates to the frame 459 * Transmit one or more beacon frames at SWBA. Dynamic updates to the frame
@@ -540,9 +465,6 @@ void ath_beacon_free(struct ath_softc *sc)
540 465
541void ath9k_beacon_tasklet(unsigned long data) 466void ath9k_beacon_tasklet(unsigned long data)
542{ 467{
543#define TSF_TO_TU(_h,_l) \
544 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
545
546 struct ath_softc *sc = (struct ath_softc *)data; 468 struct ath_softc *sc = (struct ath_softc *)data;
547 struct ath_hal *ah = sc->sc_ah; 469 struct ath_hal *ah = sc->sc_ah;
548 struct ath_buf *bf = NULL; 470 struct ath_buf *bf = NULL;
@@ -555,7 +477,7 @@ void ath9k_beacon_tasklet(unsigned long data)
555 u32 tsftu; 477 u32 tsftu;
556 u16 intval; 478 u16 intval;
557 479
558 if (sc->sc_noreset) { 480 if (sc->sc_flags & SC_OP_NO_RESET) {
559 show_cycles = ath9k_hw_GetMibCycleCountsPct(ah, 481 show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
560 &rx_clear, 482 &rx_clear,
561 &rx_frame, 483 &rx_frame,
@@ -577,7 +499,7 @@ void ath9k_beacon_tasklet(unsigned long data)
577 * (in that layer). 499 * (in that layer).
578 */ 500 */
579 if (sc->sc_bmisscount < BSTUCK_THRESH) { 501 if (sc->sc_bmisscount < BSTUCK_THRESH) {
580 if (sc->sc_noreset) { 502 if (sc->sc_flags & SC_OP_NO_RESET) {
581 DPRINTF(sc, ATH_DBG_BEACON, 503 DPRINTF(sc, ATH_DBG_BEACON,
582 "%s: missed %u consecutive beacons\n", 504 "%s: missed %u consecutive beacons\n",
583 __func__, sc->sc_bmisscount); 505 __func__, sc->sc_bmisscount);
@@ -605,7 +527,7 @@ void ath9k_beacon_tasklet(unsigned long data)
605 __func__, sc->sc_bmisscount); 527 __func__, sc->sc_bmisscount);
606 } 528 }
607 } else if (sc->sc_bmisscount >= BSTUCK_THRESH) { 529 } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
608 if (sc->sc_noreset) { 530 if (sc->sc_flags & SC_OP_NO_RESET) {
609 if (sc->sc_bmisscount == BSTUCK_THRESH) { 531 if (sc->sc_bmisscount == BSTUCK_THRESH) {
610 DPRINTF(sc, 532 DPRINTF(sc,
611 ATH_DBG_BEACON, 533 ATH_DBG_BEACON,
@@ -624,7 +546,7 @@ void ath9k_beacon_tasklet(unsigned long data)
624 return; 546 return;
625 } 547 }
626 if (sc->sc_bmisscount != 0) { 548 if (sc->sc_bmisscount != 0) {
627 if (sc->sc_noreset) { 549 if (sc->sc_flags & SC_OP_NO_RESET) {
628 DPRINTF(sc, 550 DPRINTF(sc,
629 ATH_DBG_BEACON, 551 ATH_DBG_BEACON,
630 "%s: resume beacon xmit after %u misses\n", 552 "%s: resume beacon xmit after %u misses\n",
@@ -643,8 +565,8 @@ void ath9k_beacon_tasklet(unsigned long data)
643 * on the tsf to safeguard against missing an swba. 565 * on the tsf to safeguard against missing an swba.
644 */ 566 */
645 567
646 /* FIXME: Use default value for now - Sujith */ 568 intval = sc->hw->conf.beacon_int ?
647 intval = ATH_DEFAULT_BINTVAL; 569 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
648 570
649 tsf = ath9k_hw_gettsf64(ah); 571 tsf = ath9k_hw_gettsf64(ah);
650 tsftu = TSF_TO_TU(tsf>>32, tsf); 572 tsftu = TSF_TO_TU(tsf>>32, tsf);
@@ -704,7 +626,6 @@ void ath9k_beacon_tasklet(unsigned long data)
704 626
705 sc->ast_be_xmit += bc; /* XXX per-vap? */ 627 sc->ast_be_xmit += bc; /* XXX per-vap? */
706 } 628 }
707#undef TSF_TO_TU
708} 629}
709 630
710/* 631/*
@@ -719,7 +640,7 @@ void ath_bstuck_process(struct ath_softc *sc)
719 DPRINTF(sc, ATH_DBG_BEACON, 640 DPRINTF(sc, ATH_DBG_BEACON,
720 "%s: stuck beacon; resetting (bmiss count %u)\n", 641 "%s: stuck beacon; resetting (bmiss count %u)\n",
721 __func__, sc->sc_bmisscount); 642 __func__, sc->sc_bmisscount);
722 ath_internal_reset(sc); 643 ath_reset(sc, false);
723} 644}
724 645
725/* 646/*
@@ -740,8 +661,6 @@ void ath_bstuck_process(struct ath_softc *sc)
740 661
741void ath_beacon_config(struct ath_softc *sc, int if_id) 662void ath_beacon_config(struct ath_softc *sc, int if_id)
742{ 663{
743#define TSF_TO_TU(_h,_l) \
744 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
745 struct ath_hal *ah = sc->sc_ah; 664 struct ath_hal *ah = sc->sc_ah;
746 u32 nexttbtt, intval; 665 u32 nexttbtt, intval;
747 struct ath_beacon_config conf; 666 struct ath_beacon_config conf;
@@ -750,7 +669,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
750 if (if_id != ATH_IF_ID_ANY) 669 if (if_id != ATH_IF_ID_ANY)
751 av_opmode = sc->sc_vaps[if_id]->av_opmode; 670 av_opmode = sc->sc_vaps[if_id]->av_opmode;
752 else 671 else
753 av_opmode = sc->sc_opmode; 672 av_opmode = sc->sc_ah->ah_opmode;
754 673
755 memzero(&conf, sizeof(struct ath_beacon_config)); 674 memzero(&conf, sizeof(struct ath_beacon_config));
756 675
@@ -760,7 +679,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
760 * Protocol stack doesn't support dynamic beacon configuration, 679 * Protocol stack doesn't support dynamic beacon configuration,
761 * use default configurations. 680 * use default configurations.
762 */ 681 */
763 conf.beacon_interval = ATH_DEFAULT_BINTVAL; 682 conf.beacon_interval = sc->hw->conf.beacon_int ?
683 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
764 conf.listen_interval = 1; 684 conf.listen_interval = 1;
765 conf.dtim_period = conf.beacon_interval; 685 conf.dtim_period = conf.beacon_interval;
766 conf.dtim_count = 1; 686 conf.dtim_count = 1;
@@ -770,7 +690,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
770 nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4), 690 nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4),
771 get_unaligned_le32(conf.u.last_tstamp)); 691 get_unaligned_le32(conf.u.last_tstamp));
772 /* XXX conditionalize multi-bss support? */ 692 /* XXX conditionalize multi-bss support? */
773 if (sc->sc_opmode == ATH9K_M_HOSTAP) { 693 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
774 /* 694 /*
775 * For multi-bss ap support beacons are either staggered 695 * For multi-bss ap support beacons are either staggered
776 * evenly over N slots or burst together. For the former 696 * evenly over N slots or burst together. For the former
@@ -791,7 +711,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
791 DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", 711 DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
792 __func__, nexttbtt, intval, conf.beacon_interval); 712 __func__, nexttbtt, intval, conf.beacon_interval);
793 /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ 713 /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
794 if (sc->sc_opmode == ATH9K_M_STA) { 714 if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
795 struct ath9k_beacon_state bs; 715 struct ath9k_beacon_state bs;
796 u64 tsf; 716 u64 tsf;
797 u32 tsftu; 717 u32 tsftu;
@@ -886,19 +806,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
886 "cfp:period %u " 806 "cfp:period %u "
887 "maxdur %u " 807 "maxdur %u "
888 "next %u " 808 "next %u "
889 "timoffset %u\n" 809 "timoffset %u\n",
890 , __func__ 810 __func__,
891 , (unsigned long long)tsf, tsftu 811 (unsigned long long)tsf, tsftu,
892 , bs.bs_intval 812 bs.bs_intval,
893 , bs.bs_nexttbtt 813 bs.bs_nexttbtt,
894 , bs.bs_dtimperiod 814 bs.bs_dtimperiod,
895 , bs.bs_nextdtim 815 bs.bs_nextdtim,
896 , bs.bs_bmissthreshold 816 bs.bs_bmissthreshold,
897 , bs.bs_sleepduration 817 bs.bs_sleepduration,
898 , bs.bs_cfpperiod 818 bs.bs_cfpperiod,
899 , bs.bs_cfpmaxduration 819 bs.bs_cfpmaxduration,
900 , bs.bs_cfpnext 820 bs.bs_cfpnext,
901 , bs.bs_timoffset 821 bs.bs_timoffset
902 ); 822 );
903 823
904 ath9k_hw_set_interrupts(ah, 0); 824 ath9k_hw_set_interrupts(ah, 0);
@@ -911,7 +831,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
911 ath9k_hw_set_interrupts(ah, 0); 831 ath9k_hw_set_interrupts(ah, 0);
912 if (nexttbtt == intval) 832 if (nexttbtt == intval)
913 intval |= ATH9K_BEACON_RESET_TSF; 833 intval |= ATH9K_BEACON_RESET_TSF;
914 if (sc->sc_opmode == ATH9K_M_IBSS) { 834 if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
915 /* 835 /*
916 * Pull nexttbtt forward to reflect the current 836 * Pull nexttbtt forward to reflect the current
917 * TSF . 837 * TSF .
@@ -943,7 +863,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
943 if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) 863 if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
944 sc->sc_imask |= ATH9K_INT_SWBA; 864 sc->sc_imask |= ATH9K_INT_SWBA;
945 ath_beaconq_config(sc); 865 ath_beaconq_config(sc);
946 } else if (sc->sc_opmode == ATH9K_M_HOSTAP) { 866 } else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
947 /* 867 /*
948 * In AP mode we enable the beacon timers and 868 * In AP mode we enable the beacon timers and
949 * SWBA interrupts to prepare beacon frames. 869 * SWBA interrupts to prepare beacon frames.
@@ -959,11 +879,10 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
959 * When using a self-linked beacon descriptor in 879 * When using a self-linked beacon descriptor in
960 * ibss mode load it once here. 880 * ibss mode load it once here.
961 */ 881 */
962 if (sc->sc_opmode == ATH9K_M_IBSS && 882 if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
963 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) 883 (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
964 ath_beacon_start_adhoc(sc, 0); 884 ath_beacon_start_adhoc(sc, 0);
965 } 885 }
966#undef TSF_TO_TU
967} 886}
968 887
969/* Function to collect beacon rssi data and resync beacon if necessary */ 888/* Function to collect beacon rssi data and resync beacon if necessary */
@@ -975,5 +894,5 @@ void ath_beacon_sync(struct ath_softc *sc, int if_id)
975 * beacon frame we just received. 894 * beacon frame we just received.
976 */ 895 */
977 ath_beacon_config(sc, if_id); 896 ath_beacon_config(sc, if_id);
978 sc->sc_beacons = 1; 897 sc->sc_flags |= SC_OP_BEACONS;
979} 898}
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index f6c45288d0e7..c262ef279ff3 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -21,9 +21,6 @@
21 21
22static int ath_outdoor; /* enable outdoor use */ 22static int ath_outdoor; /* enable outdoor use */
23 23
24static const u8 ath_bcast_mac[ETH_ALEN] =
25 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
26
27static u32 ath_chainmask_sel_up_rssi_thres = 24static u32 ath_chainmask_sel_up_rssi_thres =
28 ATH_CHAINMASK_SEL_UP_RSSI_THRES; 25 ATH_CHAINMASK_SEL_UP_RSSI_THRES;
29static u32 ath_chainmask_sel_down_rssi_thres = 26static u32 ath_chainmask_sel_down_rssi_thres =
@@ -54,10 +51,8 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz)
54 * Set current operating mode 51 * Set current operating mode
55 * 52 *
56 * This function initializes and fills the rate table in the ATH object based 53 * This function initializes and fills the rate table in the ATH object based
57 * on the operating mode. The blink rates are also set up here, although 54 * on the operating mode.
58 * they have been superceeded by the ath_led module.
59*/ 55*/
60
61static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) 56static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
62{ 57{
63 const struct ath9k_rate_table *rt; 58 const struct ath9k_rate_table *rt;
@@ -235,7 +230,7 @@ static int ath_setup_channels(struct ath_softc *sc)
235 * Determine mode from channel flags 230 * Determine mode from channel flags
236 * 231 *
237 * This routine will provide the enumerated WIRELESSS_MODE value based 232 * This routine will provide the enumerated WIRELESSS_MODE value based
238 * on the settings of the channel flags. If ho valid set of flags 233 * on the settings of the channel flags. If no valid set of flags
239 * exist, the lowest mode (11b) is selected. 234 * exist, the lowest mode (11b) is selected.
240*/ 235*/
241 236
@@ -260,7 +255,8 @@ static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
260 else if (chan->chanmode == CHANNEL_G_HT40MINUS) 255 else if (chan->chanmode == CHANNEL_G_HT40MINUS)
261 return ATH9K_MODE_11NG_HT40MINUS; 256 return ATH9K_MODE_11NG_HT40MINUS;
262 257
263 /* NB: should not get here */ 258 WARN_ON(1); /* should not get here */
259
264 return ATH9K_MODE_11B; 260 return ATH9K_MODE_11B;
265} 261}
266 262
@@ -275,14 +271,12 @@ static int ath_stop(struct ath_softc *sc)
275{ 271{
276 struct ath_hal *ah = sc->sc_ah; 272 struct ath_hal *ah = sc->sc_ah;
277 273
278 DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %u\n", 274 DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %ld\n",
279 __func__, sc->sc_invalid); 275 __func__, sc->sc_flags & SC_OP_INVALID);
280 276
281 /* 277 /*
282 * Shutdown the hardware and driver: 278 * Shutdown the hardware and driver:
283 * stop output from above 279 * stop output from above
284 * reset 802.11 state machine
285 * (sends station deassoc/deauth frames)
286 * turn off timers 280 * turn off timers
287 * disable interrupts 281 * disable interrupts
288 * clear transmit machinery 282 * clear transmit machinery
@@ -294,10 +288,10 @@ static int ath_stop(struct ath_softc *sc)
294 * hardware is gone (invalid). 288 * hardware is gone (invalid).
295 */ 289 */
296 290
297 if (!sc->sc_invalid) 291 if (!(sc->sc_flags & SC_OP_INVALID))
298 ath9k_hw_set_interrupts(ah, 0); 292 ath9k_hw_set_interrupts(ah, 0);
299 ath_draintxq(sc, false); 293 ath_draintxq(sc, false);
300 if (!sc->sc_invalid) { 294 if (!(sc->sc_flags & SC_OP_INVALID)) {
301 ath_stoprecv(sc); 295 ath_stoprecv(sc);
302 ath9k_hw_phy_disable(ah); 296 ath9k_hw_phy_disable(ah);
303 } else 297 } else
@@ -307,56 +301,6 @@ static int ath_stop(struct ath_softc *sc)
307} 301}
308 302
309/* 303/*
310 * Start Scan
311 *
312 * This function is called when starting a channel scan. It will perform
313 * power save wakeup processing, set the filter for the scan, and get the
314 * chip ready to send broadcast packets out during the scan.
315*/
316
317void ath_scan_start(struct ath_softc *sc)
318{
319 struct ath_hal *ah = sc->sc_ah;
320 u32 rfilt;
321 u32 now = (u32) jiffies_to_msecs(get_timestamp());
322
323 sc->sc_scanning = 1;
324 rfilt = ath_calcrxfilter(sc);
325 ath9k_hw_setrxfilter(ah, rfilt);
326 ath9k_hw_write_associd(ah, ath_bcast_mac, 0);
327
328 /* Restore previous power management state. */
329
330 DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0\n",
331 now / 1000, now % 1000, __func__, rfilt);
332}
333
334/*
335 * Scan End
336 *
337 * This routine is called by the upper layer when the scan is completed. This
338 * will set the filters back to normal operating mode, set the BSSID to the
339 * correct value, and restore the power save state.
340*/
341
342void ath_scan_end(struct ath_softc *sc)
343{
344 struct ath_hal *ah = sc->sc_ah;
345 u32 rfilt;
346 u32 now = (u32) jiffies_to_msecs(get_timestamp());
347
348 sc->sc_scanning = 0;
349 /* Request for a full reset due to rx packet filter changes */
350 sc->sc_full_reset = 1;
351 rfilt = ath_calcrxfilter(sc);
352 ath9k_hw_setrxfilter(ah, rfilt);
353 ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
354
355 DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0x%x\n",
356 now / 1000, now % 1000, __func__, rfilt, sc->sc_curaid);
357}
358
359/*
360 * Set the current channel 304 * Set the current channel
361 * 305 *
362 * Set/change channels. If the channel is really being changed, it's done 306 * Set/change channels. If the channel is really being changed, it's done
@@ -367,25 +311,23 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
367{ 311{
368 struct ath_hal *ah = sc->sc_ah; 312 struct ath_hal *ah = sc->sc_ah;
369 bool fastcc = true, stopped; 313 bool fastcc = true, stopped;
370 enum ath9k_ht_macmode ht_macmode;
371 314
372 if (sc->sc_invalid) /* if the device is invalid or removed */ 315 if (sc->sc_flags & SC_OP_INVALID) /* the device is invalid or removed */
373 return -EIO; 316 return -EIO;
374 317
375 DPRINTF(sc, ATH_DBG_CONFIG, 318 DPRINTF(sc, ATH_DBG_CONFIG,
376 "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n", 319 "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n",
377 __func__, 320 __func__,
378 ath9k_hw_mhz2ieee(ah, sc->sc_curchan.channel, 321 ath9k_hw_mhz2ieee(ah, sc->sc_ah->ah_curchan->channel,
379 sc->sc_curchan.channelFlags), 322 sc->sc_ah->ah_curchan->channelFlags),
380 sc->sc_curchan.channel, 323 sc->sc_ah->ah_curchan->channel,
381 ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags), 324 ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags),
382 hchan->channel, hchan->channelFlags); 325 hchan->channel, hchan->channelFlags);
383 326
384 ht_macmode = ath_cwm_macmode(sc); 327 if (hchan->channel != sc->sc_ah->ah_curchan->channel ||
385 328 hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
386 if (hchan->channel != sc->sc_curchan.channel || 329 (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
387 hchan->channelFlags != sc->sc_curchan.channelFlags || 330 (sc->sc_flags & SC_OP_FULL_RESET)) {
388 sc->sc_update_chainmask || sc->sc_full_reset) {
389 int status; 331 int status;
390 /* 332 /*
391 * This is only performed if the channel settings have 333 * This is only performed if the channel settings have
@@ -404,15 +346,16 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
404 * to flush data frames already in queue because of 346 * to flush data frames already in queue because of
405 * changing channel. */ 347 * changing channel. */
406 348
407 if (!stopped || sc->sc_full_reset) 349 if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
408 fastcc = false; 350 fastcc = false;
409 351
410 spin_lock_bh(&sc->sc_resetlock); 352 spin_lock_bh(&sc->sc_resetlock);
411 if (!ath9k_hw_reset(ah, sc->sc_opmode, hchan, 353 if (!ath9k_hw_reset(ah, hchan,
412 ht_macmode, sc->sc_tx_chainmask, 354 sc->sc_ht_info.tx_chan_width,
413 sc->sc_rx_chainmask, 355 sc->sc_tx_chainmask,
414 sc->sc_ht_extprotspacing, 356 sc->sc_rx_chainmask,
415 fastcc, &status)) { 357 sc->sc_ht_extprotspacing,
358 fastcc, &status)) {
416 DPRINTF(sc, ATH_DBG_FATAL, 359 DPRINTF(sc, ATH_DBG_FATAL,
417 "%s: unable to reset channel %u (%uMhz) " 360 "%s: unable to reset channel %u (%uMhz) "
418 "flags 0x%x hal status %u\n", __func__, 361 "flags 0x%x hal status %u\n", __func__,
@@ -424,9 +367,8 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
424 } 367 }
425 spin_unlock_bh(&sc->sc_resetlock); 368 spin_unlock_bh(&sc->sc_resetlock);
426 369
427 sc->sc_curchan = *hchan; 370 sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
428 sc->sc_update_chainmask = 0; 371 sc->sc_flags &= ~SC_OP_FULL_RESET;
429 sc->sc_full_reset = 0;
430 372
431 /* Re-enable rx framework */ 373 /* Re-enable rx framework */
432 if (ath_startrecv(sc) != 0) { 374 if (ath_startrecv(sc) != 0) {
@@ -537,7 +479,7 @@ int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an)
537 479
538void ath_update_chainmask(struct ath_softc *sc, int is_ht) 480void ath_update_chainmask(struct ath_softc *sc, int is_ht)
539{ 481{
540 sc->sc_update_chainmask = 1; 482 sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
541 if (is_ht) { 483 if (is_ht) {
542 sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; 484 sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask;
543 sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; 485 sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask;
@@ -554,62 +496,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
554/* VAP management */ 496/* VAP management */
555/******************/ 497/******************/
556 498
557/*
558 * VAP in Listen mode
559 *
560 * This routine brings the VAP out of the down state into a "listen" state
561 * where it waits for association requests. This is used in AP and AdHoc
562 * modes.
563*/
564
565int ath_vap_listen(struct ath_softc *sc, int if_id)
566{
567 struct ath_hal *ah = sc->sc_ah;
568 struct ath_vap *avp;
569 u32 rfilt = 0;
570 DECLARE_MAC_BUF(mac);
571
572 avp = sc->sc_vaps[if_id];
573 if (avp == NULL) {
574 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
575 __func__, if_id);
576 return -EINVAL;
577 }
578
579#ifdef CONFIG_SLOW_ANT_DIV
580 ath_slow_ant_div_stop(&sc->sc_antdiv);
581#endif
582
583 /* update ratectrl about the new state */
584 ath_rate_newstate(sc, avp);
585
586 rfilt = ath_calcrxfilter(sc);
587 ath9k_hw_setrxfilter(ah, rfilt);
588
589 if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS) {
590 memcpy(sc->sc_curbssid, ath_bcast_mac, ETH_ALEN);
591 ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
592 } else
593 sc->sc_curaid = 0;
594
595 DPRINTF(sc, ATH_DBG_CONFIG,
596 "%s: RX filter 0x%x bssid %s aid 0x%x\n",
597 __func__, rfilt, print_mac(mac,
598 sc->sc_curbssid), sc->sc_curaid);
599
600 /*
601 * XXXX
602 * Disable BMISS interrupt when we're not associated
603 */
604 ath9k_hw_set_interrupts(ah,
605 sc->sc_imask & ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
606 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
607 /* need to reconfigure the beacons when it moves to RUN */
608 sc->sc_beacons = 0;
609
610 return 0;
611}
612
613int ath_vap_attach(struct ath_softc *sc, 499int ath_vap_attach(struct ath_softc *sc,
614 int if_id, 500 int if_id,
615 struct ieee80211_vif *if_data, 501 struct ieee80211_vif *if_data,
@@ -647,16 +533,13 @@ int ath_vap_attach(struct ath_softc *sc,
647 /* Set the VAP opmode */ 533 /* Set the VAP opmode */
648 avp->av_opmode = opmode; 534 avp->av_opmode = opmode;
649 avp->av_bslot = -1; 535 avp->av_bslot = -1;
650 INIT_LIST_HEAD(&avp->av_mcastq.axq_q);
651 INIT_LIST_HEAD(&avp->av_mcastq.axq_acq);
652 spin_lock_init(&avp->av_mcastq.axq_lock);
653 536
654 ath9k_hw_set_tsfadjust(sc->sc_ah, 1); 537 ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
655 538
656 sc->sc_vaps[if_id] = avp; 539 sc->sc_vaps[if_id] = avp;
657 sc->sc_nvaps++; 540 sc->sc_nvaps++;
658 /* Set the device opmode */ 541 /* Set the device opmode */
659 sc->sc_opmode = opmode; 542 sc->sc_ah->ah_opmode = opmode;
660 543
661 /* default VAP configuration */ 544 /* default VAP configuration */
662 avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE; 545 avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
@@ -689,9 +572,6 @@ int ath_vap_detach(struct ath_softc *sc, int if_id)
689 ath_stoprecv(sc); /* stop recv side */ 572 ath_stoprecv(sc); /* stop recv side */
690 ath_flushrecv(sc); /* flush recv queue */ 573 ath_flushrecv(sc); /* flush recv queue */
691 574
692 /* Reclaim any pending mcast bufs on the vap. */
693 ath_tx_draintxq(sc, &avp->av_mcastq, false);
694
695 kfree(avp); 575 kfree(avp);
696 sc->sc_vaps[if_id] = NULL; 576 sc->sc_vaps[if_id] = NULL;
697 sc->sc_nvaps--; 577 sc->sc_nvaps--;
@@ -728,9 +608,9 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
728 struct ath_hal *ah = sc->sc_ah; 608 struct ath_hal *ah = sc->sc_ah;
729 int status; 609 int status;
730 int error = 0; 610 int error = 0;
731 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
732 611
733 DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n", __func__, sc->sc_opmode); 612 DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n",
613 __func__, sc->sc_ah->ah_opmode);
734 614
735 /* 615 /*
736 * Stop anything previously setup. This is safe 616 * Stop anything previously setup. This is safe
@@ -752,16 +632,16 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
752 * be followed by initialization of the appropriate bits 632 * be followed by initialization of the appropriate bits
753 * and then setup of the interrupt mask. 633 * and then setup of the interrupt mask.
754 */ 634 */
755 sc->sc_curchan = *initial_chan;
756 635
757 spin_lock_bh(&sc->sc_resetlock); 636 spin_lock_bh(&sc->sc_resetlock);
758 if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan, ht_macmode, 637 if (!ath9k_hw_reset(ah, initial_chan,
759 sc->sc_tx_chainmask, sc->sc_rx_chainmask, 638 sc->sc_ht_info.tx_chan_width,
760 sc->sc_ht_extprotspacing, false, &status)) { 639 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
640 sc->sc_ht_extprotspacing, false, &status)) {
761 DPRINTF(sc, ATH_DBG_FATAL, 641 DPRINTF(sc, ATH_DBG_FATAL,
762 "%s: unable to reset hardware; hal status %u " 642 "%s: unable to reset hardware; hal status %u "
763 "(freq %u flags 0x%x)\n", __func__, status, 643 "(freq %u flags 0x%x)\n", __func__, status,
764 sc->sc_curchan.channel, sc->sc_curchan.channelFlags); 644 initial_chan->channel, initial_chan->channelFlags);
765 error = -EIO; 645 error = -EIO;
766 spin_unlock_bh(&sc->sc_resetlock); 646 spin_unlock_bh(&sc->sc_resetlock);
767 goto done; 647 goto done;
@@ -802,7 +682,8 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
802 * Note we only do this (at the moment) for station mode. 682 * Note we only do this (at the moment) for station mode.
803 */ 683 */
804 if (ath9k_hw_phycounters(ah) && 684 if (ath9k_hw_phycounters(ah) &&
805 ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS))) 685 ((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
686 (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)))
806 sc->sc_imask |= ATH9K_INT_MIB; 687 sc->sc_imask |= ATH9K_INT_MIB;
807 /* 688 /*
808 * Some hardware processes the TIM IE and fires an 689 * Some hardware processes the TIM IE and fires an
@@ -811,7 +692,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
811 * enable the TIM interrupt when operating as station. 692 * enable the TIM interrupt when operating as station.
812 */ 693 */
813 if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && 694 if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
814 (sc->sc_opmode == ATH9K_M_STA) && 695 (sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
815 !sc->sc_config.swBeaconProcess) 696 !sc->sc_config.swBeaconProcess)
816 sc->sc_imask |= ATH9K_INT_TIM; 697 sc->sc_imask |= ATH9K_INT_TIM;
817 /* 698 /*
@@ -823,34 +704,34 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
823 704
824 /* XXX: we must make sure h/w is ready and clear invalid flag 705 /* XXX: we must make sure h/w is ready and clear invalid flag
825 * before turning on interrupt. */ 706 * before turning on interrupt. */
826 sc->sc_invalid = 0; 707 sc->sc_flags &= ~SC_OP_INVALID;
827done: 708done:
828 return error; 709 return error;
829} 710}
830 711
831/* 712int ath_reset(struct ath_softc *sc, bool retry_tx)
832 * Reset the hardware w/o losing operational state. This is
833 * basically a more efficient way of doing ath_stop, ath_init,
834 * followed by state transitions to the current 802.11
835 * operational state. Used to recover from errors rx overrun
836 * and to reset the hardware when rf gain settings must be reset.
837 */
838
839static int ath_reset_start(struct ath_softc *sc, u32 flag)
840{ 713{
841 struct ath_hal *ah = sc->sc_ah; 714 struct ath_hal *ah = sc->sc_ah;
715 int status;
716 int error = 0;
842 717
843 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */ 718 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
844 ath_draintxq(sc, flag & RESET_RETRY_TXQ); /* stop xmit side */ 719 ath_draintxq(sc, retry_tx); /* stop xmit */
845 ath_stoprecv(sc); /* stop recv side */ 720 ath_stoprecv(sc); /* stop recv */
846 ath_flushrecv(sc); /* flush recv queue */ 721 ath_flushrecv(sc); /* flush recv queue */
847 722
848 return 0; 723 /* Reset chip */
849} 724 spin_lock_bh(&sc->sc_resetlock);
850 725 if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan,
851static int ath_reset_end(struct ath_softc *sc, u32 flag) 726 sc->sc_ht_info.tx_chan_width,
852{ 727 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
853 struct ath_hal *ah = sc->sc_ah; 728 sc->sc_ht_extprotspacing, false, &status)) {
729 DPRINTF(sc, ATH_DBG_FATAL,
730 "%s: unable to reset hardware; hal status %u\n",
731 __func__, status);
732 error = -EIO;
733 }
734 spin_unlock_bh(&sc->sc_resetlock);
854 735
855 if (ath_startrecv(sc) != 0) /* restart recv */ 736 if (ath_startrecv(sc) != 0) /* restart recv */
856 DPRINTF(sc, ATH_DBG_FATAL, 737 DPRINTF(sc, ATH_DBG_FATAL,
@@ -861,16 +742,17 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag)
861 * that changes the channel so update any state that 742 * that changes the channel so update any state that
862 * might change as a result. 743 * might change as a result.
863 */ 744 */
864 ath_setcurmode(sc, ath_chan2mode(&sc->sc_curchan)); 745 ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan));
865 746
866 ath_update_txpow(sc); /* update tx power state */ 747 ath_update_txpow(sc);
867 748
868 if (sc->sc_beacons) 749 if (sc->sc_flags & SC_OP_BEACONS)
869 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */ 750 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
751
870 ath9k_hw_set_interrupts(ah, sc->sc_imask); 752 ath9k_hw_set_interrupts(ah, sc->sc_imask);
871 753
872 /* Restart the txq */ 754 /* Restart the txq */
873 if (flag & RESET_RETRY_TXQ) { 755 if (retry_tx) {
874 int i; 756 int i;
875 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 757 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
876 if (ATH_TXQ_SETUP(sc, i)) { 758 if (ATH_TXQ_SETUP(sc, i)) {
@@ -880,28 +762,6 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag)
880 } 762 }
881 } 763 }
882 } 764 }
883 return 0;
884}
885
886int ath_reset(struct ath_softc *sc)
887{
888 struct ath_hal *ah = sc->sc_ah;
889 int status;
890 int error = 0;
891 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
892
893 /* NB: indicate channel change so we do a full reset */
894 spin_lock_bh(&sc->sc_resetlock);
895 if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan,
896 ht_macmode,
897 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
898 sc->sc_ht_extprotspacing, false, &status)) {
899 DPRINTF(sc, ATH_DBG_FATAL,
900 "%s: unable to reset hardware; hal status %u\n",
901 __func__, status);
902 error = -EIO;
903 }
904 spin_unlock_bh(&sc->sc_resetlock);
905 765
906 return error; 766 return error;
907} 767}
@@ -911,7 +771,7 @@ int ath_suspend(struct ath_softc *sc)
911 struct ath_hal *ah = sc->sc_ah; 771 struct ath_hal *ah = sc->sc_ah;
912 772
913 /* No I/O if device has been surprise removed */ 773 /* No I/O if device has been surprise removed */
914 if (sc->sc_invalid) 774 if (sc->sc_flags & SC_OP_INVALID)
915 return -EIO; 775 return -EIO;
916 776
917 /* Shut off the interrupt before setting sc->sc_invalid to '1' */ 777 /* Shut off the interrupt before setting sc->sc_invalid to '1' */
@@ -919,7 +779,7 @@ int ath_suspend(struct ath_softc *sc)
919 779
920 /* XXX: we must make sure h/w will not generate any interrupt 780 /* XXX: we must make sure h/w will not generate any interrupt
921 * before setting the invalid flag. */ 781 * before setting the invalid flag. */
922 sc->sc_invalid = 1; 782 sc->sc_flags |= SC_OP_INVALID;
923 783
924 /* disable HAL and put h/w to sleep */ 784 /* disable HAL and put h/w to sleep */
925 ath9k_hw_disable(sc->sc_ah); 785 ath9k_hw_disable(sc->sc_ah);
@@ -940,7 +800,7 @@ irqreturn_t ath_isr(int irq, void *dev)
940 bool sched = false; 800 bool sched = false;
941 801
942 do { 802 do {
943 if (sc->sc_invalid) { 803 if (sc->sc_flags & SC_OP_INVALID) {
944 /* 804 /*
945 * The hardware is not ready/present, don't 805 * The hardware is not ready/present, don't
946 * touch anything. Note this can happen early 806 * touch anything. Note this can happen early
@@ -1050,7 +910,7 @@ static void ath9k_tasklet(unsigned long data)
1050 910
1051 if (status & ATH9K_INT_FATAL) { 911 if (status & ATH9K_INT_FATAL) {
1052 /* need a chip reset */ 912 /* need a chip reset */
1053 ath_internal_reset(sc); 913 ath_reset(sc, false);
1054 return; 914 return;
1055 } else { 915 } else {
1056 916
@@ -1093,10 +953,9 @@ int ath_init(u16 devid, struct ath_softc *sc)
1093 int status; 953 int status;
1094 int error = 0, i; 954 int error = 0, i;
1095 int csz = 0; 955 int csz = 0;
1096 u32 rd;
1097 956
1098 /* XXX: hardware will not be ready until ath_open() being called */ 957 /* XXX: hardware will not be ready until ath_open() being called */
1099 sc->sc_invalid = 1; 958 sc->sc_flags |= SC_OP_INVALID;
1100 959
1101 sc->sc_debug = DBG_DEFAULT; 960 sc->sc_debug = DBG_DEFAULT;
1102 DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid); 961 DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid);
@@ -1126,9 +985,6 @@ int ath_init(u16 devid, struct ath_softc *sc)
1126 } 985 }
1127 sc->sc_ah = ah; 986 sc->sc_ah = ah;
1128 987
1129 /* Get the chipset-specific aggr limit. */
1130 sc->sc_rtsaggrlimit = ah->ah_caps.rts_aggr_limit;
1131
1132 /* Get the hardware key cache size. */ 988 /* Get the hardware key cache size. */
1133 sc->sc_keymax = ah->ah_caps.keycache_size; 989 sc->sc_keymax = ah->ah_caps.keycache_size;
1134 if (sc->sc_keymax > ATH_KEYMAX) { 990 if (sc->sc_keymax > ATH_KEYMAX) {
@@ -1162,14 +1018,12 @@ int ath_init(u16 devid, struct ath_softc *sc)
1162 * is resposible for filtering this list based on settings 1018 * is resposible for filtering this list based on settings
1163 * like the phy mode. 1019 * like the phy mode.
1164 */ 1020 */
1165 rd = ah->ah_currentRD;
1166
1167 error = ath_setup_channels(sc); 1021 error = ath_setup_channels(sc);
1168 if (error) 1022 if (error)
1169 goto bad; 1023 goto bad;
1170 1024
1171 /* default to STA mode */ 1025 /* default to STA mode */
1172 sc->sc_opmode = ATH9K_M_MONITOR; 1026 sc->sc_ah->ah_opmode = ATH9K_M_MONITOR;
1173 1027
1174 /* Setup rate tables */ 1028 /* Setup rate tables */
1175 1029
@@ -1240,7 +1094,7 @@ int ath_init(u16 devid, struct ath_softc *sc)
1240 1094
1241 sc->sc_rc = ath_rate_attach(ah); 1095 sc->sc_rc = ath_rate_attach(ah);
1242 if (sc->sc_rc == NULL) { 1096 if (sc->sc_rc == NULL) {
1243 error = EIO; 1097 error = -EIO;
1244 goto bad2; 1098 goto bad2;
1245 } 1099 }
1246 1100
@@ -1280,20 +1134,13 @@ int ath_init(u16 devid, struct ath_softc *sc)
1280 1134
1281 /* 11n Capabilities */ 1135 /* 11n Capabilities */
1282 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { 1136 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
1283 sc->sc_txaggr = 1; 1137 sc->sc_flags |= SC_OP_TXAGGR;
1284 sc->sc_rxaggr = 1; 1138 sc->sc_flags |= SC_OP_RXAGGR;
1285 } 1139 }
1286 1140
1287 sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask; 1141 sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
1288 sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask; 1142 sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
1289 1143
1290 /* Configuration for rx chain detection */
1291 sc->sc_rxchaindetect_ref = 0;
1292 sc->sc_rxchaindetect_thresh5GHz = 35;
1293 sc->sc_rxchaindetect_thresh2GHz = 35;
1294 sc->sc_rxchaindetect_delta5GHz = 30;
1295 sc->sc_rxchaindetect_delta2GHz = 30;
1296
1297 ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); 1144 ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
1298 sc->sc_defant = ath9k_hw_getdefantenna(ah); 1145 sc->sc_defant = ath9k_hw_getdefantenna(ah);
1299 1146
@@ -1337,7 +1184,7 @@ void ath_deinit(struct ath_softc *sc)
1337 DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); 1184 DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__);
1338 1185
1339 ath_stop(sc); 1186 ath_stop(sc);
1340 if (!sc->sc_invalid) 1187 if (!(sc->sc_flags & SC_OP_INVALID))
1341 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 1188 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
1342 ath_rate_detach(sc->sc_rc); 1189 ath_rate_detach(sc->sc_rc);
1343 /* cleanup tx queues */ 1190 /* cleanup tx queues */
@@ -1464,9 +1311,9 @@ void ath_newassoc(struct ath_softc *sc,
1464 /* if station reassociates, tear down the aggregation state. */ 1311 /* if station reassociates, tear down the aggregation state. */
1465 if (!isnew) { 1312 if (!isnew) {
1466 for (tidno = 0; tidno < WME_NUM_TID; tidno++) { 1313 for (tidno = 0; tidno < WME_NUM_TID; tidno++) {
1467 if (sc->sc_txaggr) 1314 if (sc->sc_flags & SC_OP_TXAGGR)
1468 ath_tx_aggr_teardown(sc, an, tidno); 1315 ath_tx_aggr_teardown(sc, an, tidno);
1469 if (sc->sc_rxaggr) 1316 if (sc->sc_flags & SC_OP_RXAGGR)
1470 ath_rx_aggr_teardown(sc, an, tidno); 1317 ath_rx_aggr_teardown(sc, an, tidno);
1471 } 1318 }
1472 } 1319 }
@@ -1815,13 +1662,6 @@ void ath_descdma_cleanup(struct ath_softc *sc,
1815/* Utilities */ 1662/* Utilities */
1816/*************/ 1663/*************/
1817 1664
1818void ath_internal_reset(struct ath_softc *sc)
1819{
1820 ath_reset_start(sc, 0);
1821 ath_reset(sc);
1822 ath_reset_end(sc, 0);
1823}
1824
1825int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) 1665int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
1826{ 1666{
1827 int qnum; 1667 int qnum;
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 673b3d81133a..1faa1effa02c 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -39,6 +39,7 @@
39#include <linux/scatterlist.h> 39#include <linux/scatterlist.h>
40#include <asm/page.h> 40#include <asm/page.h>
41#include <net/mac80211.h> 41#include <net/mac80211.h>
42#include <linux/leds.h>
42 43
43#include "ath9k.h" 44#include "ath9k.h"
44#include "rc.h" 45#include "rc.h"
@@ -79,12 +80,12 @@ struct ath_node;
79 } \ 80 } \
80 } while (0) 81 } while (0)
81 82
83#define TSF_TO_TU(_h,_l) \
84 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
85
82/* XXX: remove */ 86/* XXX: remove */
83#define memzero(_buf, _len) memset(_buf, 0, _len) 87#define memzero(_buf, _len) memset(_buf, 0, _len)
84 88
85#define get_dma_mem_context(var, field) (&((var)->field))
86#define copy_dma_mem_context(dst, src) (*dst = *src)
87
88#define ATH9K_BH_STATUS_INTACT 0 89#define ATH9K_BH_STATUS_INTACT 0
89#define ATH9K_BH_STATUS_CHANGE 1 90#define ATH9K_BH_STATUS_CHANGE 1
90 91
@@ -95,6 +96,8 @@ static inline unsigned long get_timestamp(void)
95 return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ); 96 return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ);
96} 97}
97 98
99static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
100
98/*************/ 101/*************/
99/* Debugging */ 102/* Debugging */
100/*************/ 103/*************/
@@ -175,11 +178,6 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht);
175/* Descriptor Management */ 178/* Descriptor Management */
176/*************************/ 179/*************************/
177 180
178/* Number of descriptors per buffer. The only case where we see skbuff
179chains is due to FF aggregation in the driver. */
180#define ATH_TXDESC 1
181/* if there's more fragment for this MSDU */
182#define ATH_BF_MORE_MPDU 1
183#define ATH_TXBUF_RESET(_bf) do { \ 181#define ATH_TXBUF_RESET(_bf) do { \
184 (_bf)->bf_status = 0; \ 182 (_bf)->bf_status = 0; \
185 (_bf)->bf_lastbf = NULL; \ 183 (_bf)->bf_lastbf = NULL; \
@@ -189,28 +187,29 @@ chains is due to FF aggregation in the driver. */
189 sizeof(struct ath_buf_state)); \ 187 sizeof(struct ath_buf_state)); \
190 } while (0) 188 } while (0)
191 189
190enum buffer_type {
191 BUF_DATA = BIT(0),
192 BUF_AGGR = BIT(1),
193 BUF_AMPDU = BIT(2),
194 BUF_HT = BIT(3),
195 BUF_RETRY = BIT(4),
196 BUF_XRETRY = BIT(5),
197 BUF_SHORT_PREAMBLE = BIT(6),
198 BUF_BAR = BIT(7),
199 BUF_PSPOLL = BIT(8),
200 BUF_AGGR_BURST = BIT(9),
201 BUF_CALC_AIRTIME = BIT(10),
202};
203
192struct ath_buf_state { 204struct ath_buf_state {
193 int bfs_nframes; /* # frames in aggregate */ 205 int bfs_nframes; /* # frames in aggregate */
194 u16 bfs_al; /* length of aggregate */ 206 u16 bfs_al; /* length of aggregate */
195 u16 bfs_frmlen; /* length of frame */ 207 u16 bfs_frmlen; /* length of frame */
196 int bfs_seqno; /* sequence number */ 208 int bfs_seqno; /* sequence number */
197 int bfs_tidno; /* tid of this frame */ 209 int bfs_tidno; /* tid of this frame */
198 int bfs_retries; /* current retries */ 210 int bfs_retries; /* current retries */
199 struct ath_rc_series bfs_rcs[4]; /* rate series */ 211 struct ath_rc_series bfs_rcs[4]; /* rate series */
200 u8 bfs_isdata:1; /* is a data frame/aggregate */ 212 u32 bf_type; /* BUF_* (enum buffer_type) */
201 u8 bfs_isaggr:1; /* is an aggregate */
202 u8 bfs_isampdu:1; /* is an a-mpdu, aggregate or not */
203 u8 bfs_ht:1; /* is an HT frame */
204 u8 bfs_isretried:1; /* is retried */
205 u8 bfs_isxretried:1; /* is excessive retried */
206 u8 bfs_shpreamble:1; /* is short preamble */
207 u8 bfs_isbar:1; /* is a BAR */
208 u8 bfs_ispspoll:1; /* is a PS-Poll */
209 u8 bfs_aggrburst:1; /* is a aggr burst */
210 u8 bfs_calcairtime:1; /* requests airtime be calculated
211 when set for tx frame */
212 int bfs_rifsburst_elem; /* RIFS burst/bar */
213 int bfs_nrifsubframes; /* # of elements in burst */
214 /* key type use to encrypt this frame */ 213 /* key type use to encrypt this frame */
215 enum ath9k_key_type bfs_keytype; 214 enum ath9k_key_type bfs_keytype;
216}; 215};
@@ -222,26 +221,22 @@ struct ath_buf_state {
222#define bf_seqno bf_state.bfs_seqno 221#define bf_seqno bf_state.bfs_seqno
223#define bf_tidno bf_state.bfs_tidno 222#define bf_tidno bf_state.bfs_tidno
224#define bf_rcs bf_state.bfs_rcs 223#define bf_rcs bf_state.bfs_rcs
225#define bf_isdata bf_state.bfs_isdata
226#define bf_isaggr bf_state.bfs_isaggr
227#define bf_isampdu bf_state.bfs_isampdu
228#define bf_ht bf_state.bfs_ht
229#define bf_isretried bf_state.bfs_isretried
230#define bf_isxretried bf_state.bfs_isxretried
231#define bf_shpreamble bf_state.bfs_shpreamble
232#define bf_rifsburst_elem bf_state.bfs_rifsburst_elem
233#define bf_nrifsubframes bf_state.bfs_nrifsubframes
234#define bf_keytype bf_state.bfs_keytype 224#define bf_keytype bf_state.bfs_keytype
235#define bf_isbar bf_state.bfs_isbar 225#define bf_isdata(bf) (bf->bf_state.bf_type & BUF_DATA)
236#define bf_ispspoll bf_state.bfs_ispspoll 226#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
237#define bf_aggrburst bf_state.bfs_aggrburst 227#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
238#define bf_calcairtime bf_state.bfs_calcairtime 228#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
229#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
230#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
231#define bf_isshpreamble(bf) (bf->bf_state.bf_type & BUF_SHORT_PREAMBLE)
232#define bf_isbar(bf) (bf->bf_state.bf_type & BUF_BAR)
233#define bf_ispspoll(bf) (bf->bf_state.bf_type & BUF_PSPOLL)
234#define bf_isaggrburst(bf) (bf->bf_state.bf_type & BUF_AGGR_BURST)
239 235
240/* 236/*
241 * Abstraction of a contiguous buffer to transmit/receive. There is only 237 * Abstraction of a contiguous buffer to transmit/receive. There is only
242 * a single hw descriptor encapsulated here. 238 * a single hw descriptor encapsulated here.
243 */ 239 */
244
245struct ath_buf { 240struct ath_buf {
246 struct list_head list; 241 struct list_head list;
247 struct list_head *last; 242 struct list_head *last;
@@ -391,10 +386,10 @@ int ath_rx_input(struct ath_softc *sc,
391 struct sk_buff *skb, 386 struct sk_buff *skb,
392 struct ath_recv_status *rx_status, 387 struct ath_recv_status *rx_status,
393 enum ATH_RX_TYPE *status); 388 enum ATH_RX_TYPE *status);
394int ath__rx_indicate(struct ath_softc *sc, 389int _ath_rx_indicate(struct ath_softc *sc,
395 struct sk_buff *skb, 390 struct sk_buff *skb,
396 struct ath_recv_status *status, 391 struct ath_recv_status *status,
397 u16 keyix); 392 u16 keyix);
398int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb, 393int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
399 struct ath_recv_status *status); 394 struct ath_recv_status *status);
400 395
@@ -402,8 +397,7 @@ int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
402/* TX */ 397/* TX */
403/******/ 398/******/
404 399
405#define ATH_FRAG_PER_MSDU 1 400#define ATH_TXBUF 512
406#define ATH_TXBUF (512/ATH_FRAG_PER_MSDU)
407/* max number of transmit attempts (tries) */ 401/* max number of transmit attempts (tries) */
408#define ATH_TXMAXTRY 13 402#define ATH_TXMAXTRY 13
409/* max number of 11n transmit attempts (tries) */ 403/* max number of 11n transmit attempts (tries) */
@@ -522,7 +516,6 @@ struct ath_tx_control {
522 u32 keyix; 516 u32 keyix;
523 int min_rate; 517 int min_rate;
524 int mcast_rate; 518 int mcast_rate;
525 u16 nextfraglen;
526 struct ath_softc *dev; 519 struct ath_softc *dev;
527 dma_addr_t dmacontext; 520 dma_addr_t dmacontext;
528}; 521};
@@ -557,10 +550,10 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
557int ath_tx_setup(struct ath_softc *sc, int haltype); 550int ath_tx_setup(struct ath_softc *sc, int haltype);
558void ath_draintxq(struct ath_softc *sc, bool retry_tx); 551void ath_draintxq(struct ath_softc *sc, bool retry_tx);
559void ath_tx_draintxq(struct ath_softc *sc, 552void ath_tx_draintxq(struct ath_softc *sc,
560 struct ath_txq *txq, bool retry_tx); 553 struct ath_txq *txq, bool retry_tx);
561void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); 554void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
562void ath_tx_node_cleanup(struct ath_softc *sc, 555void ath_tx_node_cleanup(struct ath_softc *sc,
563 struct ath_node *an, bool bh_flag); 556 struct ath_node *an, bool bh_flag);
564void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an); 557void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an);
565void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); 558void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
566int ath_tx_init(struct ath_softc *sc, int nbufs); 559int ath_tx_init(struct ath_softc *sc, int nbufs);
@@ -575,6 +568,7 @@ u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
575void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth); 568void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth);
576void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 569void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
577 struct ath_xmit_status *tx_status, struct ath_node *an); 570 struct ath_xmit_status *tx_status, struct ath_node *an);
571void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
578 572
579/**********************/ 573/**********************/
580/* Node / Aggregation */ 574/* Node / Aggregation */
@@ -585,7 +579,6 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
585/* indicates the node is 80211 power save */ 579/* indicates the node is 80211 power save */
586#define ATH_NODE_PWRSAVE 0x2 580#define ATH_NODE_PWRSAVE 0x2
587 581
588#define ADDBA_TIMEOUT 200 /* 200 milliseconds */
589#define ADDBA_EXCHANGE_ATTEMPTS 10 582#define ADDBA_EXCHANGE_ATTEMPTS 10
590#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ 583#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */
591#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ 584#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
@@ -705,9 +698,6 @@ struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr);
705#define ATH_BCBUF 4 /* number of beacon buffers */ 698#define ATH_BCBUF 4 /* number of beacon buffers */
706#define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */ 699#define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */
707#define ATH_DEFAULT_BMISS_LIMIT 10 700#define ATH_DEFAULT_BMISS_LIMIT 10
708#define ATH_BEACON_AIFS_DEFAULT 0 /* Default aifs for ap beacon q */
709#define ATH_BEACON_CWMIN_DEFAULT 0 /* Default cwmin for ap beacon q */
710#define ATH_BEACON_CWMAX_DEFAULT 0 /* Default cwmax for ap beacon q */
711#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) 701#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
712 702
713/* beacon configuration */ 703/* beacon configuration */
@@ -724,30 +714,16 @@ struct ath_beacon_config {
724 } u; /* last received beacon/probe response timestamp of this BSS. */ 714 } u; /* last received beacon/probe response timestamp of this BSS. */
725}; 715};
726 716
727/* offsets in a beacon frame for
728 * quick acess of beacon content by low-level driver */
729struct ath_beacon_offset {
730 u8 *bo_tim; /* start of atim/dtim */
731};
732
733void ath9k_beacon_tasklet(unsigned long data); 717void ath9k_beacon_tasklet(unsigned long data);
734void ath_beacon_config(struct ath_softc *sc, int if_id); 718void ath_beacon_config(struct ath_softc *sc, int if_id);
735int ath_beaconq_setup(struct ath_hal *ah); 719int ath_beaconq_setup(struct ath_hal *ah);
736int ath_beacon_alloc(struct ath_softc *sc, int if_id); 720int ath_beacon_alloc(struct ath_softc *sc, int if_id);
737void ath_bstuck_process(struct ath_softc *sc); 721void ath_bstuck_process(struct ath_softc *sc);
738void ath_beacon_tasklet(struct ath_softc *sc, int *needmark);
739void ath_beacon_free(struct ath_softc *sc);
740void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp); 722void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
741void ath_beacon_sync(struct ath_softc *sc, int if_id); 723void ath_beacon_sync(struct ath_softc *sc, int if_id);
742void ath_update_beacon_info(struct ath_softc *sc, int avgbrssi);
743void ath_get_beaconconfig(struct ath_softc *sc, 724void ath_get_beaconconfig(struct ath_softc *sc,
744 int if_id, 725 int if_id,
745 struct ath_beacon_config *conf); 726 struct ath_beacon_config *conf);
746int ath_update_beacon(struct ath_softc *sc,
747 int if_id,
748 struct ath_beacon_offset *bo,
749 struct sk_buff *skb,
750 int mcast);
751/********/ 727/********/
752/* VAPs */ 728/* VAPs */
753/********/ 729/********/
@@ -774,10 +750,8 @@ struct ath_vap {
774 struct ieee80211_vif *av_if_data; 750 struct ieee80211_vif *av_if_data;
775 enum ath9k_opmode av_opmode; /* VAP operational mode */ 751 enum ath9k_opmode av_opmode; /* VAP operational mode */
776 struct ath_buf *av_bcbuf; /* beacon buffer */ 752 struct ath_buf *av_bcbuf; /* beacon buffer */
777 struct ath_beacon_offset av_boff; /* dynamic update state */
778 struct ath_tx_control av_btxctl; /* txctl information for beacon */ 753 struct ath_tx_control av_btxctl; /* txctl information for beacon */
779 int av_bslot; /* beacon slot index */ 754 int av_bslot; /* beacon slot index */
780 struct ath_txq av_mcastq; /* multicast transmit queue */
781 struct ath_vap_config av_config;/* vap configuration parameters*/ 755 struct ath_vap_config av_config;/* vap configuration parameters*/
782 struct ath_rate_node *rc_node; 756 struct ath_rate_node *rc_node;
783}; 757};
@@ -788,8 +762,7 @@ int ath_vap_attach(struct ath_softc *sc,
788 enum ath9k_opmode opmode); 762 enum ath9k_opmode opmode);
789int ath_vap_detach(struct ath_softc *sc, int if_id); 763int ath_vap_detach(struct ath_softc *sc, int if_id);
790int ath_vap_config(struct ath_softc *sc, 764int ath_vap_config(struct ath_softc *sc,
791 int if_id, struct ath_vap_config *if_config); 765 int if_id, struct ath_vap_config *if_config);
792int ath_vap_listen(struct ath_softc *sc, int if_id);
793 766
794/*********************/ 767/*********************/
795/* Antenna diversity */ 768/* Antenna diversity */
@@ -830,6 +803,27 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv,
830void ath_setdefantenna(void *sc, u32 antenna); 803void ath_setdefantenna(void *sc, u32 antenna);
831 804
832/********************/ 805/********************/
806/* LED Control */
807/********************/
808
809#define ATH_LED_PIN 1
810
811enum ath_led_type {
812 ATH_LED_RADIO,
813 ATH_LED_ASSOC,
814 ATH_LED_TX,
815 ATH_LED_RX
816};
817
818struct ath_led {
819 struct ath_softc *sc;
820 struct led_classdev led_cdev;
821 enum ath_led_type led_type;
822 char name[32];
823 bool registered;
824};
825
826/********************/
833/* Main driver core */ 827/* Main driver core */
834/********************/ 828/********************/
835 829
@@ -841,11 +835,7 @@ void ath_setdefantenna(void *sc, u32 antenna);
841#define ATH_DEFAULT_NOISE_FLOOR -95 835#define ATH_DEFAULT_NOISE_FLOOR -95
842#define ATH_REGCLASSIDS_MAX 10 836#define ATH_REGCLASSIDS_MAX 10
843#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ 837#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
844#define ATH_PREAMBLE_SHORT (1<<0)
845#define ATH_PROTECT_ENABLE (1<<1)
846#define ATH_MAX_SW_RETRIES 10 838#define ATH_MAX_SW_RETRIES 10
847/* Num farmes difference in tx to flip default recv */
848#define ATH_ANTENNA_DIFF 2
849#define ATH_CHAN_MAX 255 839#define ATH_CHAN_MAX 255
850#define IEEE80211_WEP_NKID 4 /* number of key ids */ 840#define IEEE80211_WEP_NKID 4 /* number of key ids */
851#define IEEE80211_RATE_VAL 0x7f 841#define IEEE80211_RATE_VAL 0x7f
@@ -859,9 +849,7 @@ void ath_setdefantenna(void *sc, u32 antenna);
859 */ 849 */
860#define ATH_KEYMAX 128 /* max key cache size we handle */ 850#define ATH_KEYMAX 128 /* max key cache size we handle */
861 851
862#define RESET_RETRY_TXQ 0x00000001
863#define ATH_IF_ID_ANY 0xff 852#define ATH_IF_ID_ANY 0xff
864
865#define ATH_TXPOWER_MAX 100 /* .5 dBm units */ 853#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
866 854
867#define RSSI_LPF_THRESHOLD -20 855#define RSSI_LPF_THRESHOLD -20
@@ -907,60 +895,61 @@ struct ath_ht_info {
907 u8 ext_chan_offset; 895 u8 ext_chan_offset;
908}; 896};
909 897
898#define SC_OP_INVALID BIT(0)
899#define SC_OP_BEACONS BIT(1)
900#define SC_OP_RXAGGR BIT(2)
901#define SC_OP_TXAGGR BIT(3)
902#define SC_OP_CHAINMASK_UPDATE BIT(4)
903#define SC_OP_FULL_RESET BIT(5)
904#define SC_OP_NO_RESET BIT(6)
905#define SC_OP_PREAMBLE_SHORT BIT(7)
906#define SC_OP_PROTECT_ENABLE BIT(8)
907#define SC_OP_RXFLUSH BIT(9)
908#define SC_OP_LED_ASSOCIATED BIT(10)
909
910struct ath_softc { 910struct ath_softc {
911 struct ieee80211_hw *hw; 911 struct ieee80211_hw *hw;
912 struct pci_dev *pdev; 912 struct pci_dev *pdev;
913 void __iomem *mem;
914 struct tasklet_struct intr_tq; 913 struct tasklet_struct intr_tq;
915 struct tasklet_struct bcon_tasklet; 914 struct tasklet_struct bcon_tasklet;
916 struct ath_config sc_config; /* load-time parameters */ 915 struct ath_config sc_config;
917 int sc_debug;
918 struct ath_hal *sc_ah; 916 struct ath_hal *sc_ah;
919 struct ath_rate_softc *sc_rc; /* tx rate control support */ 917 struct ath_rate_softc *sc_rc;
918 void __iomem *mem;
919
920 u8 sc_curbssid[ETH_ALEN];
921 u8 sc_myaddr[ETH_ALEN];
922 u8 sc_bssidmask[ETH_ALEN];
923
924 int sc_debug;
920 u32 sc_intrstatus; 925 u32 sc_intrstatus;
921 enum ath9k_opmode sc_opmode; /* current operating mode */ 926 u32 sc_flags; /* SC_OP_* */
922 927 unsigned int rx_filter;
923 u8 sc_invalid; /* being detached */
924 u8 sc_beacons; /* beacons running */
925 u8 sc_scanning; /* scanning active */
926 u8 sc_txaggr; /* enable 11n tx aggregation */
927 u8 sc_rxaggr; /* enable 11n rx aggregation */
928 u8 sc_update_chainmask; /* change chain mask */
929 u8 sc_full_reset; /* force full reset */
930 enum wireless_mode sc_curmode; /* current phy mode */
931 u16 sc_curtxpow; 928 u16 sc_curtxpow;
932 u16 sc_curaid; 929 u16 sc_curaid;
933 u8 sc_curbssid[ETH_ALEN]; 930 u16 sc_cachelsz;
934 u8 sc_myaddr[ETH_ALEN]; 931 int sc_slotupdate; /* slot to next advance fsm */
932 int sc_slottime;
933 int sc_bslot[ATH_BCBUF];
934 u8 sc_tx_chainmask;
935 u8 sc_rx_chainmask;
936 enum ath9k_int sc_imask;
937 enum wireless_mode sc_curmode; /* current phy mode */
935 enum PROT_MODE sc_protmode; 938 enum PROT_MODE sc_protmode;
936 u8 sc_mcastantenna; 939
937 u8 sc_txantenna; /* data tx antenna (fixed or auto) */
938 u8 sc_nbcnvaps; /* # of vaps sending beacons */ 940 u8 sc_nbcnvaps; /* # of vaps sending beacons */
939 u16 sc_nvaps; /* # of active virtual ap's */ 941 u16 sc_nvaps; /* # of active virtual ap's */
940 struct ath_vap *sc_vaps[ATH_BCBUF]; 942 struct ath_vap *sc_vaps[ATH_BCBUF];
941 enum ath9k_int sc_imask; 943
942 u8 sc_bssidmask[ETH_ALEN]; 944 u8 sc_mcastantenna;
943 u8 sc_defant; /* current default antenna */ 945 u8 sc_defant; /* current default antenna */
944 u8 sc_rxotherant; /* rx's on non-default antenna */ 946 u8 sc_rxotherant; /* rx's on non-default antenna */
945 u16 sc_cachelsz; 947
946 int sc_slotupdate; /* slot to next advance fsm */
947 int sc_slottime;
948 u8 sc_noreset;
949 int sc_bslot[ATH_BCBUF];
950 struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ 948 struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */
951 struct list_head node_list; 949 struct list_head node_list;
952 struct ath_ht_info sc_ht_info; 950 struct ath_ht_info sc_ht_info;
953 int16_t sc_noise_floor; /* signal noise floor in dBm */
954 enum ath9k_ht_extprotspacing sc_ht_extprotspacing; 951 enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
955 u8 sc_tx_chainmask; 952
956 u8 sc_rx_chainmask;
957 u8 sc_rxchaindetect_ref;
958 u8 sc_rxchaindetect_thresh5GHz;
959 u8 sc_rxchaindetect_thresh2GHz;
960 u8 sc_rxchaindetect_delta5GHz;
961 u8 sc_rxchaindetect_delta2GHz;
962 u32 sc_rtsaggrlimit; /* Chipset specific aggr limit */
963 u32 sc_flags;
964#ifdef CONFIG_SLOW_ANT_DIV 953#ifdef CONFIG_SLOW_ANT_DIV
965 struct ath_antdiv sc_antdiv; 954 struct ath_antdiv sc_antdiv;
966#endif 955#endif
@@ -981,8 +970,6 @@ struct ath_softc {
981 struct ath_descdma sc_rxdma; 970 struct ath_descdma sc_rxdma;
982 int sc_rxbufsize; /* rx size based on mtu */ 971 int sc_rxbufsize; /* rx size based on mtu */
983 u32 *sc_rxlink; /* link ptr in last RX desc */ 972 u32 *sc_rxlink; /* link ptr in last RX desc */
984 u32 sc_rxflush; /* rx flush in progress */
985 u64 sc_lastrx; /* tsf of last rx'd frame */
986 973
987 /* TX */ 974 /* TX */
988 struct list_head sc_txbuf; 975 struct list_head sc_txbuf;
@@ -991,7 +978,7 @@ struct ath_softc {
991 u32 sc_txqsetup; 978 u32 sc_txqsetup;
992 u32 sc_txintrperiod; /* tx interrupt batching */ 979 u32 sc_txintrperiod; /* tx interrupt batching */
993 int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ 980 int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
994 u32 sc_ant_tx[8]; /* recent tx frames/antenna */ 981 u16 seq_no; /* TX sequence number */
995 982
996 /* Beacon */ 983 /* Beacon */
997 struct ath9k_tx_queue_info sc_beacon_qi; 984 struct ath9k_tx_queue_info sc_beacon_qi;
@@ -1015,7 +1002,6 @@ struct ath_softc {
1015 /* Channel, Band */ 1002 /* Channel, Band */
1016 struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; 1003 struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
1017 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 1004 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
1018 struct ath9k_channel sc_curchan;
1019 1005
1020 /* Locks */ 1006 /* Locks */
1021 spinlock_t sc_rxflushlock; 1007 spinlock_t sc_rxflushlock;
@@ -1023,6 +1009,12 @@ struct ath_softc {
1023 spinlock_t sc_txbuflock; 1009 spinlock_t sc_txbuflock;
1024 spinlock_t sc_resetlock; 1010 spinlock_t sc_resetlock;
1025 spinlock_t node_lock; 1011 spinlock_t node_lock;
1012
1013 /* LEDs */
1014 struct ath_led radio_led;
1015 struct ath_led assoc_led;
1016 struct ath_led tx_led;
1017 struct ath_led rx_led;
1026}; 1018};
1027 1019
1028int ath_init(u16 devid, struct ath_softc *sc); 1020int ath_init(u16 devid, struct ath_softc *sc);
@@ -1030,14 +1022,8 @@ void ath_deinit(struct ath_softc *sc);
1030int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan); 1022int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan);
1031int ath_suspend(struct ath_softc *sc); 1023int ath_suspend(struct ath_softc *sc);
1032irqreturn_t ath_isr(int irq, void *dev); 1024irqreturn_t ath_isr(int irq, void *dev);
1033int ath_reset(struct ath_softc *sc); 1025int ath_reset(struct ath_softc *sc, bool retry_tx);
1034void ath_scan_start(struct ath_softc *sc);
1035void ath_scan_end(struct ath_softc *sc);
1036int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan); 1026int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan);
1037void ath_setup_rate(struct ath_softc *sc,
1038 enum wireless_mode wMode,
1039 enum RATE_TYPE type,
1040 const struct ath9k_rate_table *rt);
1041 1027
1042/*********************/ 1028/*********************/
1043/* Utility Functions */ 1029/* Utility Functions */
@@ -1056,17 +1042,5 @@ int ath_cabq_update(struct ath_softc *);
1056void ath_get_currentCountry(struct ath_softc *sc, 1042void ath_get_currentCountry(struct ath_softc *sc,
1057 struct ath9k_country_entry *ctry); 1043 struct ath9k_country_entry *ctry);
1058u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp); 1044u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp);
1059void ath_internal_reset(struct ath_softc *sc);
1060u32 ath_chan2flags(struct ieee80211_channel *chan, struct ath_softc *sc);
1061dma_addr_t ath_skb_map_single(struct ath_softc *sc,
1062 struct sk_buff *skb,
1063 int direction,
1064 dma_addr_t *pa);
1065void ath_skb_unmap_single(struct ath_softc *sc,
1066 struct sk_buff *skb,
1067 int direction,
1068 dma_addr_t *pa);
1069void ath_mcast_merge(struct ath_softc *sc, u32 mfilt[2]);
1070enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc);
1071 1045
1072#endif /* CORE_H */ 1046#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index a17eb130f574..2578411c6019 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -85,29 +85,6 @@ static const struct hal_percal_data adc_init_dc_cal = {
85 ath9k_hw_adc_dccal_calibrate 85 ath9k_hw_adc_dccal_calibrate
86}; 86};
87 87
88static const struct ath_hal ar5416hal = {
89 AR5416_MAGIC,
90 0,
91 0,
92 NULL,
93 NULL,
94 CTRY_DEFAULT,
95 0,
96 0,
97 0,
98 0,
99 0,
100 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 },
109};
110
111static struct ath9k_rate_table ar5416_11a_table = { 88static struct ath9k_rate_table ar5416_11a_table = {
112 8, 89 8,
113 {0}, 90 {0},
@@ -371,7 +348,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah)
371 ah->ah_config.intr_mitigation = 0; 348 ah->ah_config.intr_mitigation = 0;
372} 349}
373 350
374static inline void ath9k_hw_override_ini(struct ath_hal *ah, 351static void ath9k_hw_override_ini(struct ath_hal *ah,
375 struct ath9k_channel *chan) 352 struct ath9k_channel *chan)
376{ 353{
377 if (!AR_SREV_5416_V20_OR_LATER(ah) 354 if (!AR_SREV_5416_V20_OR_LATER(ah)
@@ -381,8 +358,8 @@ static inline void ath9k_hw_override_ini(struct ath_hal *ah,
381 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); 358 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
382} 359}
383 360
384static inline void ath9k_hw_init_bb(struct ath_hal *ah, 361static void ath9k_hw_init_bb(struct ath_hal *ah,
385 struct ath9k_channel *chan) 362 struct ath9k_channel *chan)
386{ 363{
387 u32 synthDelay; 364 u32 synthDelay;
388 365
@@ -397,8 +374,8 @@ static inline void ath9k_hw_init_bb(struct ath_hal *ah,
397 udelay(synthDelay + BASE_ACTIVATE_DELAY); 374 udelay(synthDelay + BASE_ACTIVATE_DELAY);
398} 375}
399 376
400static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, 377static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
401 enum ath9k_opmode opmode) 378 enum ath9k_opmode opmode)
402{ 379{
403 struct ath_hal_5416 *ahp = AH5416(ah); 380 struct ath_hal_5416 *ahp = AH5416(ah);
404 381
@@ -428,7 +405,7 @@ static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
428 } 405 }
429} 406}
430 407
431static inline void ath9k_hw_init_qos(struct ath_hal *ah) 408static void ath9k_hw_init_qos(struct ath_hal *ah)
432{ 409{
433 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); 410 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
434 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); 411 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
@@ -523,7 +500,7 @@ static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
523 return ath9k_hw_eeprom_read(ah, off, data); 500 return ath9k_hw_eeprom_read(ah, off, data);
524} 501}
525 502
526static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah) 503static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
527{ 504{
528 struct ath_hal_5416 *ahp = AH5416(ah); 505 struct ath_hal_5416 *ahp = AH5416(ah);
529 struct ar5416_eeprom *eep = &ahp->ah_eeprom; 506 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
@@ -790,7 +767,7 @@ ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
790 return true; 767 return true;
791} 768}
792 769
793static inline int ath9k_hw_check_eeprom(struct ath_hal *ah) 770static int ath9k_hw_check_eeprom(struct ath_hal *ah)
794{ 771{
795 u32 sum = 0, el; 772 u32 sum = 0, el;
796 u16 *eepdata; 773 u16 *eepdata;
@@ -1196,11 +1173,12 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
1196 1173
1197 ah = &ahp->ah; 1174 ah = &ahp->ah;
1198 1175
1199 memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
1200
1201 ah->ah_sc = sc; 1176 ah->ah_sc = sc;
1202 ah->ah_sh = mem; 1177 ah->ah_sh = mem;
1203 1178
1179 ah->ah_magic = AR5416_MAGIC;
1180 ah->ah_countryCode = CTRY_DEFAULT;
1181
1204 ah->ah_devid = devid; 1182 ah->ah_devid = devid;
1205 ah->ah_subvendorid = 0; 1183 ah->ah_subvendorid = 0;
1206 1184
@@ -1294,7 +1272,7 @@ u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
1294 } 1272 }
1295} 1273}
1296 1274
1297static inline int ath9k_hw_get_radiorev(struct ath_hal *ah) 1275static int ath9k_hw_get_radiorev(struct ath_hal *ah)
1298{ 1276{
1299 u32 val; 1277 u32 val;
1300 int i; 1278 int i;
@@ -1307,7 +1285,7 @@ static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
1307 return ath9k_hw_reverse_bits(val, 8); 1285 return ath9k_hw_reverse_bits(val, 8);
1308} 1286}
1309 1287
1310static inline int ath9k_hw_init_macaddr(struct ath_hal *ah) 1288static int ath9k_hw_init_macaddr(struct ath_hal *ah)
1311{ 1289{
1312 u32 sum; 1290 u32 sum;
1313 int i; 1291 int i;
@@ -1389,7 +1367,7 @@ static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
1389 return spur_val; 1367 return spur_val;
1390} 1368}
1391 1369
1392static inline int ath9k_hw_rfattach(struct ath_hal *ah) 1370static int ath9k_hw_rfattach(struct ath_hal *ah)
1393{ 1371{
1394 bool rfStatus = false; 1372 bool rfStatus = false;
1395 int ecode = 0; 1373 int ecode = 0;
@@ -1434,8 +1412,8 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah)
1434 return 0; 1412 return 0;
1435} 1413}
1436 1414
1437static inline void ath9k_hw_init_pll(struct ath_hal *ah, 1415static void ath9k_hw_init_pll(struct ath_hal *ah,
1438 struct ath9k_channel *chan) 1416 struct ath9k_channel *chan)
1439{ 1417{
1440 u32 pll; 1418 u32 pll;
1441 1419
@@ -1553,7 +1531,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1553 } 1531 }
1554} 1532}
1555 1533
1556static inline void 1534static void
1557ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan) 1535ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1558{ 1536{
1559 u32 rfMode = 0; 1537 u32 rfMode = 0;
@@ -1623,7 +1601,7 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1623 return true; 1601 return true;
1624} 1602}
1625 1603
1626static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah) 1604static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1627{ 1605{
1628 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | 1606 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1629 AR_RTC_FORCE_WAKE_ON_INT); 1607 AR_RTC_FORCE_WAKE_ON_INT);
@@ -1664,7 +1642,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
1664 } 1642 }
1665} 1643}
1666 1644
1667static inline 1645static
1668struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah, 1646struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
1669 struct ath9k_channel *chan) 1647 struct ath9k_channel *chan)
1670{ 1648{
@@ -2098,7 +2076,7 @@ static void ath9k_hw_ani_attach(struct ath_hal *ah)
2098 ahp->ah_procPhyErr |= HAL_PROCESS_ANI; 2076 ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
2099} 2077}
2100 2078
2101static inline void ath9k_hw_ani_setup(struct ath_hal *ah) 2079static void ath9k_hw_ani_setup(struct ath_hal *ah)
2102{ 2080{
2103 struct ath_hal_5416 *ahp = AH5416(ah); 2081 struct ath_hal_5416 *ahp = AH5416(ah);
2104 int i; 2082 int i;
@@ -2822,32 +2800,11 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
2822 } 2800 }
2823} 2801}
2824 2802
2825static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, 2803void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2826 enum ath9k_gpio_output_mux_type 2804 u32 ah_signal_type)
2827 halSignalType)
2828{ 2805{
2829 u32 ah_signal_type;
2830 u32 gpio_shift; 2806 u32 gpio_shift;
2831 2807
2832 static u32 MuxSignalConversionTable[] = {
2833
2834 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
2835
2836 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
2837
2838 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
2839
2840 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
2841
2842 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
2843 };
2844
2845 if ((halSignalType >= 0)
2846 && (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
2847 ah_signal_type = MuxSignalConversionTable[halSignalType];
2848 else
2849 return false;
2850
2851 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type); 2808 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
2852 2809
2853 gpio_shift = 2 * gpio; 2810 gpio_shift = 2 * gpio;
@@ -2856,16 +2813,12 @@ static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2856 AR_GPIO_OE_OUT, 2813 AR_GPIO_OE_OUT,
2857 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift), 2814 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
2858 (AR_GPIO_OE_OUT_DRV << gpio_shift)); 2815 (AR_GPIO_OE_OUT_DRV << gpio_shift));
2859
2860 return true;
2861} 2816}
2862 2817
2863static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, 2818void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
2864 u32 val)
2865{ 2819{
2866 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), 2820 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
2867 AR_GPIO_BIT(gpio)); 2821 AR_GPIO_BIT(gpio));
2868 return true;
2869} 2822}
2870 2823
2871static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) 2824static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
@@ -2883,7 +2836,7 @@ static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
2883 } 2836 }
2884} 2837}
2885 2838
2886static inline int ath9k_hw_post_attach(struct ath_hal *ah) 2839static int ath9k_hw_post_attach(struct ath_hal *ah)
2887{ 2840{
2888 int ecode; 2841 int ecode;
2889 2842
@@ -3595,7 +3548,7 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3595 return true; 3548 return true;
3596} 3549}
3597 3550
3598static inline void 3551static void
3599ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah, 3552ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3600 struct ath9k_channel *chan, 3553 struct ath9k_channel *chan,
3601 struct cal_data_per_freq *pRawDataSet, 3554 struct cal_data_per_freq *pRawDataSet,
@@ -3777,7 +3730,7 @@ ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3777 return; 3730 return;
3778} 3731}
3779 3732
3780static inline bool 3733static bool
3781ath9k_hw_set_power_cal_table(struct ath_hal *ah, 3734ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3782 struct ar5416_eeprom *pEepData, 3735 struct ar5416_eeprom *pEepData,
3783 struct ath9k_channel *chan, 3736 struct ath9k_channel *chan,
@@ -3980,7 +3933,7 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3980 } 3933 }
3981} 3934}
3982 3935
3983static inline void 3936static void
3984ath9k_hw_get_legacy_target_powers(struct ath_hal *ah, 3937ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3985 struct ath9k_channel *chan, 3938 struct ath9k_channel *chan,
3986 struct cal_target_power_leg *powInfo, 3939 struct cal_target_power_leg *powInfo,
@@ -4046,7 +3999,7 @@ ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
4046 } 3999 }
4047} 4000}
4048 4001
4049static inline void 4002static void
4050ath9k_hw_get_target_powers(struct ath_hal *ah, 4003ath9k_hw_get_target_powers(struct ath_hal *ah,
4051 struct ath9k_channel *chan, 4004 struct ath9k_channel *chan,
4052 struct cal_target_power_ht *powInfo, 4005 struct cal_target_power_ht *powInfo,
@@ -4113,7 +4066,7 @@ ath9k_hw_get_target_powers(struct ath_hal *ah,
4113 } 4066 }
4114} 4067}
4115 4068
4116static inline u16 4069static u16
4117ath9k_hw_get_max_edge_power(u16 freq, 4070ath9k_hw_get_max_edge_power(u16 freq,
4118 struct cal_ctl_edges *pRdEdgesPower, 4071 struct cal_ctl_edges *pRdEdgesPower,
4119 bool is2GHz) 4072 bool is2GHz)
@@ -4143,7 +4096,7 @@ ath9k_hw_get_max_edge_power(u16 freq,
4143 return twiceMaxEdgePower; 4096 return twiceMaxEdgePower;
4144} 4097}
4145 4098
4146static inline bool 4099static bool
4147ath9k_hw_set_power_per_rate_table(struct ath_hal *ah, 4100ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4148 struct ar5416_eeprom *pEepData, 4101 struct ar5416_eeprom *pEepData,
4149 struct ath9k_channel *chan, 4102 struct ath9k_channel *chan,
@@ -5122,7 +5075,7 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
5122 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 5075 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5123} 5076}
5124 5077
5125static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah) 5078static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5126{ 5079{
5127 struct ath_hal_5416 *ahp = AH5416(ah); 5080 struct ath_hal_5416 *ahp = AH5416(ah);
5128 int rx_chainmask, tx_chainmask; 5081 int rx_chainmask, tx_chainmask;
@@ -5326,7 +5279,7 @@ bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5326 } 5279 }
5327} 5280}
5328 5281
5329static inline void ath9k_hw_init_user_settings(struct ath_hal *ah) 5282static void ath9k_hw_init_user_settings(struct ath_hal *ah)
5330{ 5283{
5331 struct ath_hal_5416 *ahp = AH5416(ah); 5284 struct ath_hal_5416 *ahp = AH5416(ah);
5332 5285
@@ -5345,7 +5298,7 @@ static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5345 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout); 5298 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5346} 5299}
5347 5300
5348static inline int 5301static int
5349ath9k_hw_process_ini(struct ath_hal *ah, 5302ath9k_hw_process_ini(struct ath_hal *ah,
5350 struct ath9k_channel *chan, 5303 struct ath9k_channel *chan,
5351 enum ath9k_ht_macmode macmode) 5304 enum ath9k_ht_macmode macmode)
@@ -5476,7 +5429,7 @@ ath9k_hw_process_ini(struct ath_hal *ah,
5476 return 0; 5429 return 0;
5477} 5430}
5478 5431
5479static inline void ath9k_hw_setup_calibration(struct ath_hal *ah, 5432static void ath9k_hw_setup_calibration(struct ath_hal *ah,
5480 struct hal_cal_list *currCal) 5433 struct hal_cal_list *currCal)
5481{ 5434{
5482 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), 5435 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
@@ -5512,8 +5465,8 @@ static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5512 AR_PHY_TIMING_CTRL4_DO_CAL); 5465 AR_PHY_TIMING_CTRL4_DO_CAL);
5513} 5466}
5514 5467
5515static inline void ath9k_hw_reset_calibration(struct ath_hal *ah, 5468static void ath9k_hw_reset_calibration(struct ath_hal *ah,
5516 struct hal_cal_list *currCal) 5469 struct hal_cal_list *currCal)
5517{ 5470{
5518 struct ath_hal_5416 *ahp = AH5416(ah); 5471 struct ath_hal_5416 *ahp = AH5416(ah);
5519 int i; 5472 int i;
@@ -5532,7 +5485,7 @@ static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5532 ahp->ah_CalSamples = 0; 5485 ahp->ah_CalSamples = 0;
5533} 5486}
5534 5487
5535static inline void 5488static void
5536ath9k_hw_per_calibration(struct ath_hal *ah, 5489ath9k_hw_per_calibration(struct ath_hal *ah,
5537 struct ath9k_channel *ichan, 5490 struct ath9k_channel *ichan,
5538 u8 rxchainmask, 5491 u8 rxchainmask,
@@ -5622,7 +5575,7 @@ static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5622 return true; 5575 return true;
5623} 5576}
5624 5577
5625static inline bool 5578static bool
5626ath9k_hw_channel_change(struct ath_hal *ah, 5579ath9k_hw_channel_change(struct ath_hal *ah,
5627 struct ath9k_channel *chan, 5580 struct ath9k_channel *chan,
5628 enum ath9k_ht_macmode macmode) 5581 enum ath9k_ht_macmode macmode)
@@ -5799,8 +5752,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5799 return retval; 5752 return retval;
5800} 5753}
5801 5754
5802static inline bool ath9k_hw_init_cal(struct ath_hal *ah, 5755static bool ath9k_hw_init_cal(struct ath_hal *ah,
5803 struct ath9k_channel *chan) 5756 struct ath9k_channel *chan)
5804{ 5757{
5805 struct ath_hal_5416 *ahp = AH5416(ah); 5758 struct ath_hal_5416 *ahp = AH5416(ah);
5806 struct ath9k_channel *ichan = 5759 struct ath9k_channel *ichan =
@@ -5861,7 +5814,7 @@ static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5861} 5814}
5862 5815
5863 5816
5864bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode, 5817bool ath9k_hw_reset(struct ath_hal *ah,
5865 struct ath9k_channel *chan, 5818 struct ath9k_channel *chan,
5866 enum ath9k_ht_macmode macmode, 5819 enum ath9k_ht_macmode macmode,
5867 u8 txchainmask, u8 rxchainmask, 5820 u8 txchainmask, u8 rxchainmask,
@@ -5945,7 +5898,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5945 else 5898 else
5946 ath9k_hw_set_gpio(ah, 9, 1); 5899 ath9k_hw_set_gpio(ah, 9, 1);
5947 } 5900 }
5948 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT); 5901 ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
5949 } 5902 }
5950 5903
5951 ecode = ath9k_hw_process_ini(ah, chan, macmode); 5904 ecode = ath9k_hw_process_ini(ah, chan, macmode);
@@ -5975,7 +5928,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5975 | (ah->ah_config. 5928 | (ah->ah_config.
5976 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) 5929 ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
5977 | ahp->ah_staId1Defaults); 5930 | ahp->ah_staId1Defaults);
5978 ath9k_hw_set_operating_mode(ah, opmode); 5931 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
5979 5932
5980 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask)); 5933 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5981 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4)); 5934 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
@@ -6005,13 +5958,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
6005 for (i = 0; i < ah->ah_caps.total_queues; i++) 5958 for (i = 0; i < ah->ah_caps.total_queues; i++)
6006 ath9k_hw_resettxqueue(ah, i); 5959 ath9k_hw_resettxqueue(ah, i);
6007 5960
6008 ath9k_hw_init_interrupt_masks(ah, opmode); 5961 ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode);
6009 ath9k_hw_init_qos(ah); 5962 ath9k_hw_init_qos(ah);
6010 5963
6011 ath9k_hw_init_user_settings(ah); 5964 ath9k_hw_init_user_settings(ah);
6012 5965
6013 ah->ah_opmode = opmode;
6014
6015 REG_WRITE(ah, AR_STA_ID1, 5966 REG_WRITE(ah, AR_STA_ID1,
6016 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 5967 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6017 5968
@@ -7678,8 +7629,7 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7678 REG_WRITE(ah, AR_DRETRY_LIMIT(q), 7629 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7679 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) 7630 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7680 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) 7631 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7681 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH) 7632 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
7682 );
7683 7633
7684 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); 7634 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7685 REG_WRITE(ah, AR_DMISC(q), 7635 REG_WRITE(ah, AR_DMISC(q),
@@ -8324,15 +8274,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid,
8324 *error = -ENXIO; 8274 *error = -ENXIO;
8325 break; 8275 break;
8326 } 8276 }
8327 if (ah != NULL) { 8277
8328 ah->ah_devid = ah->ah_devid;
8329 ah->ah_subvendorid = ah->ah_subvendorid;
8330 ah->ah_macVersion = ah->ah_macVersion;
8331 ah->ah_macRev = ah->ah_macRev;
8332 ah->ah_phyRev = ah->ah_phyRev;
8333 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8334 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8335 }
8336 return ah; 8278 return ah;
8337} 8279}
8338 8280
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index ae680f21ba7e..2113818ee934 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -314,14 +314,11 @@ struct ar5416_desc {
314#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \ 314#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
315 MS(ads->ds_rxstatus0, AR_RxRate) : \ 315 MS(ads->ds_rxstatus0, AR_RxRate) : \
316 (ads->ds_rxstatus3 >> 2) & 0xFF) 316 (ads->ds_rxstatus3 >> 2) & 0xFF)
317#define RXSTATUS_DUPLICATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
318 MS(ads->ds_rxstatus3, AR_Parallel40) : \
319 (ads->ds_rxstatus3 >> 10) & 0x1)
320 317
321#define set11nTries(_series, _index) \ 318#define set11nTries(_series, _index) \
322 (SM((_series)[_index].Tries, AR_XmitDataTries##_index)) 319 (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
323 320
324#define set11nRate(_series, _index) \ 321#define set11nRate(_series, _index) \
325 (SM((_series)[_index].Rate, AR_XmitRate##_index)) 322 (SM((_series)[_index].Rate, AR_XmitRate##_index))
326 323
327#define set11nPktDurRTSCTS(_series, _index) \ 324#define set11nPktDurRTSCTS(_series, _index) \
@@ -330,11 +327,11 @@ struct ar5416_desc {
330 AR_RTSCTSQual##_index : 0)) 327 AR_RTSCTSQual##_index : 0))
331 328
332#define set11nRateFlags(_series, _index) \ 329#define set11nRateFlags(_series, _index) \
333 (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \ 330 (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
334 AR_2040_##_index : 0) \ 331 AR_2040_##_index : 0) \
335 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ 332 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
336 AR_GI##_index : 0) \ 333 AR_GI##_index : 0) \
337 |SM((_series)[_index].ChSel, AR_ChainSel##_index)) 334 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
338 335
339#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100) 336#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
340 337
@@ -346,9 +343,6 @@ struct ar5416_desc {
346#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1) 343#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
347#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD 344#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
348 345
349#define NUM_CORNER_FIX_BITS_2133 7
350#define CCK_OFDM_GAIN_DELTA 15
351
352struct ar5416AniState { 346struct ar5416AniState {
353 struct ath9k_channel c; 347 struct ath9k_channel c;
354 u8 noiseImmunityLevel; 348 u8 noiseImmunityLevel;
@@ -377,11 +371,8 @@ struct ar5416AniState {
377}; 371};
378 372
379#define HAL_PROCESS_ANI 0x00000001 373#define HAL_PROCESS_ANI 0x00000001
380#define HAL_RADAR_EN 0x80000000
381#define HAL_AR_EN 0x40000000
382
383#define DO_ANI(ah) \ 374#define DO_ANI(ah) \
384 ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI)) 375 ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
385 376
386struct ar5416Stats { 377struct ar5416Stats {
387 u32 ast_ani_niup; 378 u32 ast_ani_niup;
@@ -425,7 +416,6 @@ struct ar5416Stats {
425#define AR5416_EEP_MINOR_VER_7 0x7 416#define AR5416_EEP_MINOR_VER_7 0x7
426#define AR5416_EEP_MINOR_VER_9 0x9 417#define AR5416_EEP_MINOR_VER_9 0x9
427 418
428#define AR5416_EEP_START_LOC 256
429#define AR5416_NUM_5G_CAL_PIERS 8 419#define AR5416_NUM_5G_CAL_PIERS 8
430#define AR5416_NUM_2G_CAL_PIERS 4 420#define AR5416_NUM_2G_CAL_PIERS 4
431#define AR5416_NUM_5G_20_TARGET_POWERS 8 421#define AR5416_NUM_5G_20_TARGET_POWERS 8
@@ -441,25 +431,10 @@ struct ar5416Stats {
441#define AR5416_EEPROM_MODAL_SPURS 5 431#define AR5416_EEPROM_MODAL_SPURS 5
442#define AR5416_MAX_RATE_POWER 63 432#define AR5416_MAX_RATE_POWER 63
443#define AR5416_NUM_PDADC_VALUES 128 433#define AR5416_NUM_PDADC_VALUES 128
444#define AR5416_NUM_RATES 16
445#define AR5416_BCHAN_UNUSED 0xFF 434#define AR5416_BCHAN_UNUSED 0xFF
446#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 435#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
447#define AR5416_EEPMISC_BIG_ENDIAN 0x01
448#define AR5416_MAX_CHAINS 3 436#define AR5416_MAX_CHAINS 3
449#define AR5416_ANT_16S 25
450
451#define AR5416_NUM_ANT_CHAIN_FIELDS 7
452#define AR5416_NUM_ANT_COMMON_FIELDS 4
453#define AR5416_SIZE_ANT_CHAIN_FIELD 3
454#define AR5416_SIZE_ANT_COMMON_FIELD 4
455#define AR5416_ANT_CHAIN_MASK 0x7
456#define AR5416_ANT_COMMON_MASK 0xf
457#define AR5416_CHAIN_0_IDX 0
458#define AR5416_CHAIN_1_IDX 1
459#define AR5416_CHAIN_2_IDX 2
460
461#define AR5416_PWR_TABLE_OFFSET -5 437#define AR5416_PWR_TABLE_OFFSET -5
462#define AR5416_LEGACY_CHAINMASK 1
463 438
464enum eeprom_param { 439enum eeprom_param {
465 EEP_NFTHRESH_5, 440 EEP_NFTHRESH_5,
@@ -633,7 +608,7 @@ struct ar5416IniArray {
633}; 608};
634 609
635#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \ 610#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
636 (iniarray)->ia_array = (u32 *)(array); \ 611 (iniarray)->ia_array = (u32 *)(array); \
637 (iniarray)->ia_rows = (rows); \ 612 (iniarray)->ia_rows = (rows); \
638 (iniarray)->ia_columns = (columns); \ 613 (iniarray)->ia_columns = (columns); \
639 } while (0) 614 } while (0)
@@ -641,16 +616,16 @@ struct ar5416IniArray {
641#define INI_RA(iniarray, row, column) \ 616#define INI_RA(iniarray, row, column) \
642 (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)]) 617 (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
643 618
644#define INIT_CAL(_perCal) do { \ 619#define INIT_CAL(_perCal) do { \
645 (_perCal)->calState = CAL_WAITING; \ 620 (_perCal)->calState = CAL_WAITING; \
646 (_perCal)->calNext = NULL; \ 621 (_perCal)->calNext = NULL; \
647 } while (0) 622 } while (0)
648 623
649#define INSERT_CAL(_ahp, _perCal) \ 624#define INSERT_CAL(_ahp, _perCal) \
650 do { \ 625 do { \
651 if ((_ahp)->ah_cal_list_last == NULL) { \ 626 if ((_ahp)->ah_cal_list_last == NULL) { \
652 (_ahp)->ah_cal_list = \ 627 (_ahp)->ah_cal_list = \
653 (_ahp)->ah_cal_list_last = (_perCal); \ 628 (_ahp)->ah_cal_list_last = (_perCal); \
654 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \ 629 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
655 } else { \ 630 } else { \
656 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \ 631 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
@@ -696,25 +671,29 @@ struct hal_cal_list {
696struct ath_hal_5416 { 671struct ath_hal_5416 {
697 struct ath_hal ah; 672 struct ath_hal ah;
698 struct ar5416_eeprom ah_eeprom; 673 struct ar5416_eeprom ah_eeprom;
674 struct ar5416Stats ah_stats;
675 struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
676 void __iomem *ah_cal_mem;
677
699 u8 ah_macaddr[ETH_ALEN]; 678 u8 ah_macaddr[ETH_ALEN];
700 u8 ah_bssid[ETH_ALEN]; 679 u8 ah_bssid[ETH_ALEN];
701 u8 ah_bssidmask[ETH_ALEN]; 680 u8 ah_bssidmask[ETH_ALEN];
702 u16 ah_assocId; 681 u16 ah_assocId;
682
703 int16_t ah_curchanRadIndex; 683 int16_t ah_curchanRadIndex;
704 u32 ah_maskReg; 684 u32 ah_maskReg;
705 struct ar5416Stats ah_stats;
706 u32 ah_txDescMask;
707 u32 ah_txOkInterruptMask; 685 u32 ah_txOkInterruptMask;
708 u32 ah_txErrInterruptMask; 686 u32 ah_txErrInterruptMask;
709 u32 ah_txDescInterruptMask; 687 u32 ah_txDescInterruptMask;
710 u32 ah_txEolInterruptMask; 688 u32 ah_txEolInterruptMask;
711 u32 ah_txUrnInterruptMask; 689 u32 ah_txUrnInterruptMask;
712 struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
713 enum ath9k_power_mode ah_powerMode;
714 bool ah_chipFullSleep; 690 bool ah_chipFullSleep;
715 u32 ah_atimWindow; 691 u32 ah_atimWindow;
716 enum ath9k_ant_setting ah_diversityControl;
717 u16 ah_antennaSwitchSwap; 692 u16 ah_antennaSwitchSwap;
693 enum ath9k_power_mode ah_powerMode;
694 enum ath9k_ant_setting ah_diversityControl;
695
696 /* Calibration */
718 enum hal_cal_types ah_suppCals; 697 enum hal_cal_types ah_suppCals;
719 struct hal_cal_list ah_iqCalData; 698 struct hal_cal_list ah_iqCalData;
720 struct hal_cal_list ah_adcGainCalData; 699 struct hal_cal_list ah_adcGainCalData;
@@ -751,16 +730,16 @@ struct ath_hal_5416 {
751 int32_t sign[AR5416_MAX_CHAINS]; 730 int32_t sign[AR5416_MAX_CHAINS];
752 } ah_Meas3; 731 } ah_Meas3;
753 u16 ah_CalSamples; 732 u16 ah_CalSamples;
754 u32 ah_tx6PowerInHalfDbm; 733
755 u32 ah_staId1Defaults; 734 u32 ah_staId1Defaults;
756 u32 ah_miscMode; 735 u32 ah_miscMode;
757 bool ah_tpcEnabled;
758 u32 ah_beaconInterval;
759 enum { 736 enum {
760 AUTO_32KHZ, 737 AUTO_32KHZ,
761 USE_32KHZ, 738 USE_32KHZ,
762 DONT_USE_32KHZ, 739 DONT_USE_32KHZ,
763 } ah_enable32kHzClock; 740 } ah_enable32kHzClock;
741
742 /* RF */
764 u32 *ah_analogBank0Data; 743 u32 *ah_analogBank0Data;
765 u32 *ah_analogBank1Data; 744 u32 *ah_analogBank1Data;
766 u32 *ah_analogBank2Data; 745 u32 *ah_analogBank2Data;
@@ -770,8 +749,9 @@ struct ath_hal_5416 {
770 u32 *ah_analogBank7Data; 749 u32 *ah_analogBank7Data;
771 u32 *ah_addac5416_21; 750 u32 *ah_addac5416_21;
772 u32 *ah_bank6Temp; 751 u32 *ah_bank6Temp;
773 u32 ah_ofdmTxPower; 752
774 int16_t ah_txPowerIndexOffset; 753 int16_t ah_txPowerIndexOffset;
754 u32 ah_beaconInterval;
775 u32 ah_slottime; 755 u32 ah_slottime;
776 u32 ah_acktimeout; 756 u32 ah_acktimeout;
777 u32 ah_ctstimeout; 757 u32 ah_ctstimeout;
@@ -780,7 +760,8 @@ struct ath_hal_5416 {
780 u32 ah_gpioSelect; 760 u32 ah_gpioSelect;
781 u32 ah_polarity; 761 u32 ah_polarity;
782 u32 ah_gpioBit; 762 u32 ah_gpioBit;
783 bool ah_eepEnabled; 763
764 /* ANI */
784 u32 ah_procPhyErr; 765 u32 ah_procPhyErr;
785 bool ah_hasHwPhyCounters; 766 bool ah_hasHwPhyCounters;
786 u32 ah_aniPeriod; 767 u32 ah_aniPeriod;
@@ -790,18 +771,14 @@ struct ath_hal_5416 {
790 int ah_coarseHigh[5]; 771 int ah_coarseHigh[5];
791 int ah_coarseLow[5]; 772 int ah_coarseLow[5];
792 int ah_firpwr[5]; 773 int ah_firpwr[5];
793 u16 ah_ratesArray[16]; 774 enum ath9k_ani_cmd ah_ani_function;
775
794 u32 ah_intrTxqs; 776 u32 ah_intrTxqs;
795 bool ah_intrMitigation; 777 bool ah_intrMitigation;
796 u32 ah_cycleCount;
797 u32 ah_ctlBusy;
798 u32 ah_extBusy;
799 enum ath9k_ht_extprotspacing ah_extprotspacing; 778 enum ath9k_ht_extprotspacing ah_extprotspacing;
800 u8 ah_txchainmask; 779 u8 ah_txchainmask;
801 u8 ah_rxchainmask; 780 u8 ah_rxchainmask;
802 int ah_hwp; 781
803 void __iomem *ah_cal_mem;
804 enum ath9k_ani_cmd ah_ani_function;
805 struct ar5416IniArray ah_iniModes; 782 struct ar5416IniArray ah_iniModes;
806 struct ar5416IniArray ah_iniCommon; 783 struct ar5416IniArray ah_iniCommon;
807 struct ar5416IniArray ah_iniBank0; 784 struct ar5416IniArray ah_iniBank0;
@@ -820,10 +797,6 @@ struct ath_hal_5416 {
820 797
821#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) 798#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
822 799
823#define IS_5416_EMU(ah) \
824 ((ah->ah_devid == AR5416_DEVID_EMU) || \
825 (ah->ah_devid == AR5416_DEVID_EMU_PCIE))
826
827#define ar5416RfDetach(ah) do { \ 800#define ar5416RfDetach(ah) do { \
828 if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \ 801 if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
829 AH5416(ah)->ah_rfHal.rfDetach(ah); \ 802 AH5416(ah)->ah_rfHal.rfDetach(ah); \
@@ -841,8 +814,8 @@ struct ath_hal_5416 {
841#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \ 814#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
842 int r; \ 815 int r; \
843 for (r = 0; r < ((iniarray)->ia_rows); r++) { \ 816 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
844 REG_WRITE(ah, INI_RA((iniarray), (r), 0), \ 817 REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
845 INI_RA((iniarray), r, (column))); \ 818 INI_RA((iniarray), r, (column))); \
846 DO_DELAY(regWr); \ 819 DO_DELAY(regWr); \
847 } \ 820 } \
848 } while (0) 821 } while (0)
@@ -852,30 +825,21 @@ struct ath_hal_5416 {
852#define COEF_SCALE_S 24 825#define COEF_SCALE_S 24
853#define HT40_CHANNEL_CENTER_SHIFT 10 826#define HT40_CHANNEL_CENTER_SHIFT 10
854 827
855#define ar5416CheckOpMode(_opmode) \
856 ((_opmode == ATH9K_M_STA) || (_opmode == ATH9K_M_IBSS) || \
857 (_opmode == ATH9K_M_HOSTAP) || (_opmode == ATH9K_M_MONITOR))
858
859#define AR5416_EEPROM_MAGIC_OFFSET 0x0 828#define AR5416_EEPROM_MAGIC_OFFSET 0x0
860 829
861#define AR5416_EEPROM_S 2 830#define AR5416_EEPROM_S 2
862#define AR5416_EEPROM_OFFSET 0x2000 831#define AR5416_EEPROM_OFFSET 0x2000
863#define AR5416_EEPROM_START_ADDR \ 832#define AR5416_EEPROM_START_ADDR \
864 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200 833 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
865#define AR5416_EEPROM_MAX 0xae0 834#define AR5416_EEPROM_MAX 0xae0
866#define ar5416_get_eep_ver(_ahp) \ 835#define ar5416_get_eep_ver(_ahp) \
867 (((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF) 836 (((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF)
868#define ar5416_get_eep_rev(_ahp) \ 837#define ar5416_get_eep_rev(_ahp) \
869 (((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF) 838 (((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF)
870#define ar5416_get_ntxchains(_txchainmask) \ 839#define ar5416_get_ntxchains(_txchainmask) \
871 (((_txchainmask >> 2) & 1) + \ 840 (((_txchainmask >> 2) & 1) + \
872 ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) 841 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
873 842
874#define IS_EEP_MINOR_V3(_ahp) \
875 (ath9k_hw_get_eeprom((_ahp), EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_3)
876
877#define FIXED_CCA_THRESHOLD 15
878
879#ifdef __BIG_ENDIAN 843#ifdef __BIG_ENDIAN
880#define AR5416_EEPROM_MAGIC 0x5aa5 844#define AR5416_EEPROM_MAGIC 0x5aa5
881#else 845#else
@@ -910,8 +874,6 @@ struct ath_hal_5416 {
910#define AR_GPIOD_MASK 0x00001FFF 874#define AR_GPIOD_MASK 0x00001FFF
911#define AR_GPIO_BIT(_gpio) (1 << (_gpio)) 875#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
912 876
913#define MAX_ANALOG_START 319
914
915#define HAL_EP_RND(x, mul) \ 877#define HAL_EP_RND(x, mul) \
916 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) 878 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
917#define BEACON_RSSI(ahp) \ 879#define BEACON_RSSI(ahp) \
@@ -923,8 +885,6 @@ struct ath_hal_5416 {
923#define AH_TIMEOUT 100000 885#define AH_TIMEOUT 100000
924#define AH_TIME_QUANTUM 10 886#define AH_TIME_QUANTUM 10
925 887
926#define IS(_c, _f) (((_c)->channelFlags & _f) || 0)
927
928#define AR_KEYTABLE_SIZE 128 888#define AR_KEYTABLE_SIZE 128
929#define POWER_UP_TIME 200000 889#define POWER_UP_TIME 200000
930 890
@@ -964,6 +924,6 @@ struct ath_hal_5416 {
964#define OFDM_SYMBOL_TIME_QUARTER 16 924#define OFDM_SYMBOL_TIME_QUARTER 16
965 925
966u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp, 926u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
967 enum eeprom_param param); 927 enum eeprom_param param);
968 928
969#endif 929#endif
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 2888778040e4..dc45eef3289a 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -22,8 +22,6 @@
22#define ATH_PCI_VERSION "0.1" 22#define ATH_PCI_VERSION "0.1"
23 23
24#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13 24#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
25#define IEEE80211_ACTION_CAT_HT 7
26#define IEEE80211_ACTION_HT_TXCHWIDTH 0
27 25
28static char *dev_info = "ath9k"; 26static char *dev_info = "ath9k";
29 27
@@ -212,21 +210,16 @@ static int ath_key_config(struct ath_softc *sc,
212 210
213static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) 211static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
214{ 212{
215#define ATH_MAX_NUM_KEYS 4
216 int freeslot; 213 int freeslot;
217 214
218 freeslot = (key->keyidx >= ATH_MAX_NUM_KEYS) ? 1 : 0; 215 freeslot = (key->keyidx >= 4) ? 1 : 0;
219 ath_key_reset(sc, key->keyidx, freeslot); 216 ath_key_reset(sc, key->keyidx, freeslot);
220#undef ATH_MAX_NUM_KEYS
221} 217}
222 218
223static void setup_ht_cap(struct ieee80211_ht_info *ht_info) 219static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
224{ 220{
225/* Until mac80211 includes these fields */ 221#define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
226 222#define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
227#define IEEE80211_HT_CAP_DSSSCCK40 0x1000
228#define IEEE80211_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
229#define IEEE80211_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
230 223
231 ht_info->ht_supported = 1; 224 ht_info->ht_supported = 1;
232 ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH 225 ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
@@ -234,8 +227,8 @@ static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
234 |(u16)IEEE80211_HT_CAP_SGI_40 227 |(u16)IEEE80211_HT_CAP_SGI_40
235 |(u16)IEEE80211_HT_CAP_DSSSCCK40; 228 |(u16)IEEE80211_HT_CAP_DSSSCCK40;
236 229
237 ht_info->ampdu_factor = IEEE80211_HT_CAP_MAXRXAMPDU_65536; 230 ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
238 ht_info->ampdu_density = IEEE80211_HT_CAP_MPDUDENSITY_8; 231 ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
239 /* setup supported mcs set */ 232 /* setup supported mcs set */
240 memset(ht_info->supp_mcs_set, 0, 16); 233 memset(ht_info->supp_mcs_set, 0, 16);
241 ht_info->supp_mcs_set[0] = 0xff; 234 ht_info->supp_mcs_set[0] = 0xff;
@@ -368,6 +361,20 @@ static int ath9k_tx(struct ieee80211_hw *hw,
368{ 361{
369 struct ath_softc *sc = hw->priv; 362 struct ath_softc *sc = hw->priv;
370 int hdrlen, padsize; 363 int hdrlen, padsize;
364 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
365
366 /*
367 * As a temporary workaround, assign seq# here; this will likely need
368 * to be cleaned up to work better with Beacon transmission and virtual
369 * BSSes.
370 */
371 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
372 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
373 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
374 sc->seq_no += 0x10;
375 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
376 hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
377 }
371 378
372 /* Add the padding after the header if this is not already done */ 379 /* Add the padding after the header if this is not already done */
373 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 380 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -426,10 +433,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
426 case IEEE80211_IF_TYPE_IBSS: 433 case IEEE80211_IF_TYPE_IBSS:
427 ic_opmode = ATH9K_M_IBSS; 434 ic_opmode = ATH9K_M_IBSS;
428 break; 435 break;
436 case IEEE80211_IF_TYPE_AP:
437 ic_opmode = ATH9K_M_HOSTAP;
438 break;
429 default: 439 default:
430 DPRINTF(sc, ATH_DBG_FATAL, 440 DPRINTF(sc, ATH_DBG_FATAL,
431 "%s: Only STA and IBSS are supported currently\n", 441 "%s: Interface type %d not yet supported\n",
432 __func__); 442 __func__, conf->type);
433 return -EOPNOTSUPP; 443 return -EOPNOTSUPP;
434 } 444 }
435 445
@@ -472,7 +482,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
472 ath_rate_newstate(sc, avp); 482 ath_rate_newstate(sc, avp);
473 483
474 /* Reclaim beacon resources */ 484 /* Reclaim beacon resources */
475 if (sc->sc_opmode == ATH9K_M_HOSTAP || sc->sc_opmode == ATH9K_M_IBSS) { 485 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
486 sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
476 ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); 487 ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
477 ath_beacon_return(sc, avp); 488 ath_beacon_return(sc, avp);
478 } 489 }
@@ -480,7 +491,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
480 /* Set interrupt mask */ 491 /* Set interrupt mask */
481 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 492 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
482 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL); 493 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
483 sc->sc_beacons = 0; 494 sc->sc_flags &= ~SC_OP_BEACONS;
484 495
485 error = ath_vap_detach(sc, 0); 496 error = ath_vap_detach(sc, 0);
486 if (error) 497 if (error)
@@ -529,6 +540,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
529 struct ieee80211_if_conf *conf) 540 struct ieee80211_if_conf *conf)
530{ 541{
531 struct ath_softc *sc = hw->priv; 542 struct ath_softc *sc = hw->priv;
543 struct ath_hal *ah = sc->sc_ah;
532 struct ath_vap *avp; 544 struct ath_vap *avp;
533 u32 rfilt = 0; 545 u32 rfilt = 0;
534 int error, i; 546 int error, i;
@@ -541,6 +553,17 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
541 return -EINVAL; 553 return -EINVAL;
542 } 554 }
543 555
556 /* TODO: Need to decide which hw opmode to use for multi-interface
557 * cases */
558 if (vif->type == IEEE80211_IF_TYPE_AP &&
559 ah->ah_opmode != ATH9K_M_HOSTAP) {
560 ah->ah_opmode = ATH9K_M_HOSTAP;
561 ath9k_hw_setopmode(ah);
562 ath9k_hw_write_associd(ah, sc->sc_myaddr, 0);
563 /* Request full reset to get hw opmode changed properly */
564 sc->sc_flags |= SC_OP_FULL_RESET;
565 }
566
544 if ((conf->changed & IEEE80211_IFCC_BSSID) && 567 if ((conf->changed & IEEE80211_IFCC_BSSID) &&
545 !is_zero_ether_addr(conf->bssid)) { 568 !is_zero_ether_addr(conf->bssid)) {
546 switch (vif->type) { 569 switch (vif->type) {
@@ -549,10 +572,6 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
549 /* Update ratectrl about the new state */ 572 /* Update ratectrl about the new state */
550 ath_rate_newstate(sc, avp); 573 ath_rate_newstate(sc, avp);
551 574
552 /* Set rx filter */
553 rfilt = ath_calcrxfilter(sc);
554 ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
555
556 /* Set BSSID */ 575 /* Set BSSID */
557 memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN); 576 memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN);
558 sc->sc_curaid = 0; 577 sc->sc_curaid = 0;
@@ -585,7 +604,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
585 print_mac(mac, sc->sc_curbssid), sc->sc_curaid); 604 print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
586 605
587 /* need to reconfigure the beacon */ 606 /* need to reconfigure the beacon */
588 sc->sc_beacons = 0; 607 sc->sc_flags &= ~SC_OP_BEACONS ;
589 608
590 break; 609 break;
591 default: 610 default:
@@ -594,7 +613,8 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
594 } 613 }
595 614
596 if ((conf->changed & IEEE80211_IFCC_BEACON) && 615 if ((conf->changed & IEEE80211_IFCC_BEACON) &&
597 (vif->type == IEEE80211_IF_TYPE_IBSS)) { 616 ((vif->type == IEEE80211_IF_TYPE_IBSS) ||
617 (vif->type == IEEE80211_IF_TYPE_AP))) {
598 /* 618 /*
599 * Allocate and setup the beacon frame. 619 * Allocate and setup the beacon frame.
600 * 620 *
@@ -636,8 +656,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
636 FIF_BCN_PRBRESP_PROMISC | \ 656 FIF_BCN_PRBRESP_PROMISC | \
637 FIF_FCSFAIL) 657 FIF_FCSFAIL)
638 658
639/* Accept unicast, bcast and mcast frames */ 659/* FIXME: sc->sc_full_reset ? */
640
641static void ath9k_configure_filter(struct ieee80211_hw *hw, 660static void ath9k_configure_filter(struct ieee80211_hw *hw,
642 unsigned int changed_flags, 661 unsigned int changed_flags,
643 unsigned int *total_flags, 662 unsigned int *total_flags,
@@ -645,16 +664,22 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
645 struct dev_mc_list *mclist) 664 struct dev_mc_list *mclist)
646{ 665{
647 struct ath_softc *sc = hw->priv; 666 struct ath_softc *sc = hw->priv;
667 u32 rfilt;
648 668
649 changed_flags &= SUPPORTED_FILTERS; 669 changed_flags &= SUPPORTED_FILTERS;
650 *total_flags &= SUPPORTED_FILTERS; 670 *total_flags &= SUPPORTED_FILTERS;
651 671
672 sc->rx_filter = *total_flags;
673 rfilt = ath_calcrxfilter(sc);
674 ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
675
652 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 676 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
653 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) 677 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
654 ath_scan_start(sc); 678 ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
655 else
656 ath_scan_end(sc);
657 } 679 }
680
681 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set HW RX filter: 0x%x\n",
682 __func__, sc->rx_filter);
658} 683}
659 684
660static void ath9k_sta_notify(struct ieee80211_hw *hw, 685static void ath9k_sta_notify(struct ieee80211_hw *hw,
@@ -831,7 +856,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
831 856
832 /* Configure the beacon */ 857 /* Configure the beacon */
833 ath_beacon_config(sc, 0); 858 ath_beacon_config(sc, 0);
834 sc->sc_beacons = 1; 859 sc->sc_flags |= SC_OP_BEACONS;
835 860
836 /* Reset rssi stats */ 861 /* Reset rssi stats */
837 sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; 862 sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
@@ -894,9 +919,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
894 __func__, 919 __func__,
895 bss_conf->use_short_preamble); 920 bss_conf->use_short_preamble);
896 if (bss_conf->use_short_preamble) 921 if (bss_conf->use_short_preamble)
897 sc->sc_flags |= ATH_PREAMBLE_SHORT; 922 sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
898 else 923 else
899 sc->sc_flags &= ~ATH_PREAMBLE_SHORT; 924 sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
900 } 925 }
901 926
902 if (changed & BSS_CHANGED_ERP_CTS_PROT) { 927 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
@@ -905,9 +930,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
905 bss_conf->use_cts_prot); 930 bss_conf->use_cts_prot);
906 if (bss_conf->use_cts_prot && 931 if (bss_conf->use_cts_prot &&
907 hw->conf.channel->band != IEEE80211_BAND_5GHZ) 932 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
908 sc->sc_flags |= ATH_PROTECT_ENABLE; 933 sc->sc_flags |= SC_OP_PROTECT_ENABLE;
909 else 934 else
910 sc->sc_flags &= ~ATH_PROTECT_ENABLE; 935 sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
911 } 936 }
912 937
913 if (changed & BSS_CHANGED_HT) { 938 if (changed & BSS_CHANGED_HT) {
@@ -1035,15 +1060,6 @@ void ath_get_beaconconfig(struct ath_softc *sc,
1035 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; 1060 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
1036} 1061}
1037 1062
1038int ath_update_beacon(struct ath_softc *sc,
1039 int if_id,
1040 struct ath_beacon_offset *bo,
1041 struct sk_buff *skb,
1042 int mcast)
1043{
1044 return 0;
1045}
1046
1047void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, 1063void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1048 struct ath_xmit_status *tx_status, struct ath_node *an) 1064 struct ath_xmit_status *tx_status, struct ath_node *an)
1049{ 1065{
@@ -1065,8 +1081,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1065 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 1081 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1066 tx_status->flags &= ~ATH_TX_BAR; 1082 tx_status->flags &= ~ATH_TX_BAR;
1067 } 1083 }
1068 if (tx_status->flags) 1084
1069 tx_info->status.excessive_retries = 1; 1085 if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
1086 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
1087 /* Frame was not ACKed, but an ACK was expected */
1088 tx_info->status.excessive_retries = 1;
1089 }
1090 } else {
1091 /* Frame was ACKed */
1092 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1093 }
1070 1094
1071 tx_info->status.retry_count = tx_status->retries; 1095 tx_info->status.retry_count = tx_status->retries;
1072 1096
@@ -1075,7 +1099,7 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1075 ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE); 1099 ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE);
1076} 1100}
1077 1101
1078int ath__rx_indicate(struct ath_softc *sc, 1102int _ath_rx_indicate(struct ath_softc *sc,
1079 struct sk_buff *skb, 1103 struct sk_buff *skb,
1080 struct ath_recv_status *status, 1104 struct ath_recv_status *status,
1081 u16 keyix) 1105 u16 keyix)
@@ -1095,9 +1119,6 @@ int ath__rx_indicate(struct ath_softc *sc,
1095 skb_pull(skb, padsize); 1119 skb_pull(skb, padsize);
1096 } 1120 }
1097 1121
1098 /* remove FCS before passing up to protocol stack */
1099 skb_trim(skb, (skb->len - FCS_LEN));
1100
1101 /* Prepare rx status */ 1122 /* Prepare rx status */
1102 ath9k_rx_prepare(sc, skb, status, &rx_status); 1123 ath9k_rx_prepare(sc, skb, status, &rx_status);
1103 1124
@@ -1146,9 +1167,119 @@ int ath_rx_subframe(struct ath_node *an,
1146 return 0; 1167 return 0;
1147} 1168}
1148 1169
1149enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc) 1170/********************************/
1171/* LED functions */
1172/********************************/
1173
1174static void ath_led_brightness(struct led_classdev *led_cdev,
1175 enum led_brightness brightness)
1150{ 1176{
1151 return sc->sc_ht_info.tx_chan_width; 1177 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
1178 struct ath_softc *sc = led->sc;
1179
1180 switch (brightness) {
1181 case LED_OFF:
1182 if (led->led_type == ATH_LED_ASSOC ||
1183 led->led_type == ATH_LED_RADIO)
1184 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1185 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
1186 (led->led_type == ATH_LED_RADIO) ? 1 :
1187 !!(sc->sc_flags & SC_OP_LED_ASSOCIATED));
1188 break;
1189 case LED_FULL:
1190 if (led->led_type == ATH_LED_ASSOC)
1191 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
1192 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
1193 break;
1194 default:
1195 break;
1196 }
1197}
1198
1199static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
1200 char *trigger)
1201{
1202 int ret;
1203
1204 led->sc = sc;
1205 led->led_cdev.name = led->name;
1206 led->led_cdev.default_trigger = trigger;
1207 led->led_cdev.brightness_set = ath_led_brightness;
1208
1209 ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
1210 if (ret)
1211 DPRINTF(sc, ATH_DBG_FATAL,
1212 "Failed to register led:%s", led->name);
1213 else
1214 led->registered = 1;
1215 return ret;
1216}
1217
1218static void ath_unregister_led(struct ath_led *led)
1219{
1220 if (led->registered) {
1221 led_classdev_unregister(&led->led_cdev);
1222 led->registered = 0;
1223 }
1224}
1225
1226static void ath_deinit_leds(struct ath_softc *sc)
1227{
1228 ath_unregister_led(&sc->assoc_led);
1229 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1230 ath_unregister_led(&sc->tx_led);
1231 ath_unregister_led(&sc->rx_led);
1232 ath_unregister_led(&sc->radio_led);
1233 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1234}
1235
1236static void ath_init_leds(struct ath_softc *sc)
1237{
1238 char *trigger;
1239 int ret;
1240
1241 /* Configure gpio 1 for output */
1242 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
1243 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1244 /* LED off, active low */
1245 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1246
1247 trigger = ieee80211_get_radio_led_name(sc->hw);
1248 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
1249 "ath9k-%s:radio", wiphy_name(sc->hw->wiphy));
1250 ret = ath_register_led(sc, &sc->radio_led, trigger);
1251 sc->radio_led.led_type = ATH_LED_RADIO;
1252 if (ret)
1253 goto fail;
1254
1255 trigger = ieee80211_get_assoc_led_name(sc->hw);
1256 snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
1257 "ath9k-%s:assoc", wiphy_name(sc->hw->wiphy));
1258 ret = ath_register_led(sc, &sc->assoc_led, trigger);
1259 sc->assoc_led.led_type = ATH_LED_ASSOC;
1260 if (ret)
1261 goto fail;
1262
1263 trigger = ieee80211_get_tx_led_name(sc->hw);
1264 snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
1265 "ath9k-%s:tx", wiphy_name(sc->hw->wiphy));
1266 ret = ath_register_led(sc, &sc->tx_led, trigger);
1267 sc->tx_led.led_type = ATH_LED_TX;
1268 if (ret)
1269 goto fail;
1270
1271 trigger = ieee80211_get_rx_led_name(sc->hw);
1272 snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
1273 "ath9k-%s:rx", wiphy_name(sc->hw->wiphy));
1274 ret = ath_register_led(sc, &sc->rx_led, trigger);
1275 sc->rx_led.led_type = ATH_LED_RX;
1276 if (ret)
1277 goto fail;
1278
1279 return;
1280
1281fail:
1282 ath_deinit_leds(sc);
1152} 1283}
1153 1284
1154static int ath_detach(struct ath_softc *sc) 1285static int ath_detach(struct ath_softc *sc)
@@ -1157,6 +1288,9 @@ static int ath_detach(struct ath_softc *sc)
1157 1288
1158 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); 1289 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
1159 1290
1291 /* Deinit LED control */
1292 ath_deinit_leds(sc);
1293
1160 /* Unregister hw */ 1294 /* Unregister hw */
1161 1295
1162 ieee80211_unregister_hw(hw); 1296 ieee80211_unregister_hw(hw);
@@ -1250,18 +1384,21 @@ static int ath_attach(u16 devid,
1250 goto bad; 1384 goto bad;
1251 } 1385 }
1252 1386
1387 /* Initialize LED control */
1388 ath_init_leds(sc);
1389
1253 /* initialize tx/rx engine */ 1390 /* initialize tx/rx engine */
1254 1391
1255 error = ath_tx_init(sc, ATH_TXBUF); 1392 error = ath_tx_init(sc, ATH_TXBUF);
1256 if (error != 0) 1393 if (error != 0)
1257 goto bad1; 1394 goto detach;
1258 1395
1259 error = ath_rx_init(sc, ATH_RXBUF); 1396 error = ath_rx_init(sc, ATH_RXBUF);
1260 if (error != 0) 1397 if (error != 0)
1261 goto bad1; 1398 goto detach;
1262 1399
1263 return 0; 1400 return 0;
1264bad1: 1401detach:
1265 ath_detach(sc); 1402 ath_detach(sc);
1266bad: 1403bad:
1267 return error; 1404 return error;
@@ -1340,7 +1477,9 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1340 goto bad2; 1477 goto bad2;
1341 } 1478 }
1342 1479
1343 hw->flags = IEEE80211_HW_SIGNAL_DBM | 1480 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1481 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1482 IEEE80211_HW_SIGNAL_DBM |
1344 IEEE80211_HW_NOISE_DBM; 1483 IEEE80211_HW_NOISE_DBM;
1345 1484
1346 SET_IEEE80211_DEV(hw, &pdev->dev); 1485 SET_IEEE80211_DEV(hw, &pdev->dev);
@@ -1404,6 +1543,10 @@ static void ath_pci_remove(struct pci_dev *pdev)
1404 1543
1405static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) 1544static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1406{ 1545{
1546 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
1547 struct ath_softc *sc = hw->priv;
1548
1549 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1407 pci_save_state(pdev); 1550 pci_save_state(pdev);
1408 pci_disable_device(pdev); 1551 pci_disable_device(pdev);
1409 pci_set_power_state(pdev, 3); 1552 pci_set_power_state(pdev, 3);
@@ -1413,6 +1556,8 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1413 1556
1414static int ath_pci_resume(struct pci_dev *pdev) 1557static int ath_pci_resume(struct pci_dev *pdev)
1415{ 1558{
1559 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
1560 struct ath_softc *sc = hw->priv;
1416 u32 val; 1561 u32 val;
1417 int err; 1562 int err;
1418 1563
@@ -1429,6 +1574,11 @@ static int ath_pci_resume(struct pci_dev *pdev)
1429 if ((val & 0x0000ff00) != 0) 1574 if ((val & 0x0000ff00) != 0)
1430 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); 1575 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1431 1576
1577 /* Enable LED */
1578 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
1579 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1580 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1581
1432 return 0; 1582 return 0;
1433} 1583}
1434 1584
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
index 0cd399a5344a..14702344448b 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -18,19 +18,19 @@
18#define PHY_H 18#define PHY_H
19 19
20bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah, 20bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
21 struct ath9k_channel 21 struct ath9k_channel
22 *chan); 22 *chan);
23bool ath9k_hw_set_channel(struct ath_hal *ah, 23bool ath9k_hw_set_channel(struct ath_hal *ah,
24 struct ath9k_channel *chan); 24 struct ath9k_channel *chan);
25void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, 25void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
26 u32 freqIndex, int regWrites); 26 u32 freqIndex, int regWrites);
27bool ath9k_hw_set_rf_regs(struct ath_hal *ah, 27bool ath9k_hw_set_rf_regs(struct ath_hal *ah,
28 struct ath9k_channel *chan, 28 struct ath9k_channel *chan,
29 u16 modesIndex); 29 u16 modesIndex);
30void ath9k_hw_decrease_chain_power(struct ath_hal *ah, 30void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
31 struct ath9k_channel *chan); 31 struct ath9k_channel *chan);
32bool ath9k_hw_init_rf(struct ath_hal *ah, 32bool ath9k_hw_init_rf(struct ath_hal *ah,
33 int *status); 33 int *status);
34 34
35#define AR_PHY_BASE 0x9800 35#define AR_PHY_BASE 0x9800
36#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) 36#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2))
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 73c460ad355f..390019ed398e 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -653,8 +653,8 @@ ath_rc_sib_init_validrates(struct ath_rate_node *ath_rc_priv,
653 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv); 653 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
654 for (i = 0; i < rate_table->rate_cnt; i++) { 654 for (i = 0; i < rate_table->rate_cnt; i++) {
655 valid = (ath_rc_priv->single_stream ? 655 valid = (ath_rc_priv->single_stream ?
656 rate_table->info[i].valid_single_stream : 656 rate_table->info[i].valid_single_stream :
657 rate_table->info[i].valid); 657 rate_table->info[i].valid);
658 if (valid == TRUE) { 658 if (valid == TRUE) {
659 u32 phy = rate_table->info[i].phy; 659 u32 phy = rate_table->info[i].phy;
660 u8 valid_rate_count = 0; 660 u8 valid_rate_count = 0;
@@ -740,14 +740,14 @@ ath_rc_sib_setvalid_htrates(struct ath_rate_node *ath_rc_priv,
740 for (j = 0; j < rate_table->rate_cnt; j++) { 740 for (j = 0; j < rate_table->rate_cnt; j++) {
741 u32 phy = rate_table->info[j].phy; 741 u32 phy = rate_table->info[j].phy;
742 u32 valid = (ath_rc_priv->single_stream ? 742 u32 valid = (ath_rc_priv->single_stream ?
743 rate_table->info[j].valid_single_stream : 743 rate_table->info[j].valid_single_stream :
744 rate_table->info[j].valid); 744 rate_table->info[j].valid);
745 745
746 if (((((struct ath_rateset *) 746 if (((((struct ath_rateset *)
747 mcs_set)->rs_rates[i] & 0x7F) != 747 mcs_set)->rs_rates[i] & 0x7F) !=
748 (rate_table->info[j].dot11rate & 0x7F)) || 748 (rate_table->info[j].dot11rate & 0x7F)) ||
749 !WLAN_RC_PHY_HT(phy) || 749 !WLAN_RC_PHY_HT(phy) ||
750 !WLAN_RC_PHY_HT_VALID(valid, capflag)) 750 !WLAN_RC_PHY_HT_VALID(valid, capflag))
751 continue; 751 continue;
752 752
753 if (!ath_rc_valid_phyrate(phy, capflag, FALSE)) 753 if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
@@ -847,9 +847,9 @@ void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp)
847 /* For half and quarter rate channles use different 847 /* For half and quarter rate channles use different
848 * rate tables 848 * rate tables
849 */ 849 */
850 if (sc->sc_curchan.channelFlags & CHANNEL_HALF) 850 if (sc->sc_ah->ah_curchan->channelFlags & CHANNEL_HALF)
851 ar5416_sethalf_ratetable(asc); 851 ar5416_sethalf_ratetable(asc);
852 else if (sc->sc_curchan.channelFlags & CHANNEL_QUARTER) 852 else if (sc->sc_ah->ah_curchan->channelFlags & CHANNEL_QUARTER)
853 ar5416_setquarter_ratetable(asc); 853 ar5416_setquarter_ratetable(asc);
854 else /* full rate */ 854 else /* full rate */
855 ar5416_setfull_ratetable(asc); 855 ar5416_setfull_ratetable(asc);
@@ -866,10 +866,10 @@ void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp)
866} 866}
867 867
868static u8 ath_rc_ratefind_ht(struct ath_softc *sc, 868static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
869 struct ath_rate_node *ath_rc_priv, 869 struct ath_rate_node *ath_rc_priv,
870 const struct ath_rate_table *rate_table, 870 const struct ath_rate_table *rate_table,
871 int probe_allowed, int *is_probing, 871 int probe_allowed, int *is_probing,
872 int is_retry) 872 int is_retry)
873{ 873{
874 u32 dt, best_thruput, this_thruput, now_msec; 874 u32 dt, best_thruput, this_thruput, now_msec;
875 u8 rate, next_rate, best_rate, maxindex, minindex; 875 u8 rate, next_rate, best_rate, maxindex, minindex;
@@ -997,8 +997,8 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
997 rate = rate_ctrl->rate_table_size - 1; 997 rate = rate_ctrl->rate_table_size - 1;
998 998
999 ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) || 999 ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
1000 (rate_table->info[rate].valid_single_stream && 1000 (rate_table->info[rate].valid_single_stream &&
1001 ath_rc_priv->single_stream)); 1001 ath_rc_priv->single_stream));
1002 1002
1003 return rate; 1003 return rate;
1004} 1004}
@@ -1023,10 +1023,10 @@ static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table ,
1023} 1023}
1024 1024
1025static u8 ath_rc_rate_getidx(struct ath_softc *sc, 1025static u8 ath_rc_rate_getidx(struct ath_softc *sc,
1026 struct ath_rate_node *ath_rc_priv, 1026 struct ath_rate_node *ath_rc_priv,
1027 const struct ath_rate_table *rate_table, 1027 const struct ath_rate_table *rate_table,
1028 u8 rix, u16 stepdown, 1028 u8 rix, u16 stepdown,
1029 u16 min_rate) 1029 u16 min_rate)
1030{ 1030{
1031 u32 j; 1031 u32 j;
1032 u8 nextindex; 1032 u8 nextindex;
@@ -1066,8 +1066,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
1066 rate_table = 1066 rate_table =
1067 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode]; 1067 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
1068 rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1068 rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table,
1069 (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0, 1069 (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0,
1070 is_probe, is_retry); 1070 is_probe, is_retry);
1071 nrix = rix; 1071 nrix = rix;
1072 1072
1073 if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*is_probe)) { 1073 if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*is_probe)) {
@@ -1099,13 +1099,13 @@ static void ath_rc_ratefind(struct ath_softc *sc,
1099 try_num = ((i + 1) == num_rates) ? 1099 try_num = ((i + 1) == num_rates) ?
1100 num_tries - (try_per_rate * i) : try_per_rate ; 1100 num_tries - (try_per_rate * i) : try_per_rate ;
1101 min_rate = (((i + 1) == num_rates) && 1101 min_rate = (((i + 1) == num_rates) &&
1102 (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0; 1102 (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0;
1103 1103
1104 nrix = ath_rc_rate_getidx(sc, ath_rc_priv, 1104 nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
1105 rate_table, nrix, 1, min_rate); 1105 rate_table, nrix, 1, min_rate);
1106 /* All other rates in the series have RTS enabled */ 1106 /* All other rates in the series have RTS enabled */
1107 ath_rc_rate_set_series(rate_table, 1107 ath_rc_rate_set_series(rate_table,
1108 &series[i], try_num, nrix, TRUE); 1108 &series[i], try_num, nrix, TRUE);
1109 } 1109 }
1110 1110
1111 /* 1111 /*
@@ -1124,13 +1124,13 @@ static void ath_rc_ratefind(struct ath_softc *sc,
1124 * above conditions. 1124 * above conditions.
1125 */ 1125 */
1126 if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) || 1126 if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) ||
1127 (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) || 1127 (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) ||
1128 (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) { 1128 (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) {
1129 u8 dot11rate = rate_table->info[rix].dot11rate; 1129 u8 dot11rate = rate_table->info[rix].dot11rate;
1130 u8 phy = rate_table->info[rix].phy; 1130 u8 phy = rate_table->info[rix].phy;
1131 if (i == 4 && 1131 if (i == 4 &&
1132 ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) || 1132 ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
1133 (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) { 1133 (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
1134 series[3].rix = series[2].rix; 1134 series[3].rix = series[2].rix;
1135 series[3].flags = series[2].flags; 1135 series[3].flags = series[2].flags;
1136 series[3].max_4ms_framelen = series[2].max_4ms_framelen; 1136 series[3].max_4ms_framelen = series[2].max_4ms_framelen;
@@ -1141,18 +1141,19 @@ static void ath_rc_ratefind(struct ath_softc *sc,
1141/* 1141/*
1142 * Return the Tx rate series. 1142 * Return the Tx rate series.
1143 */ 1143 */
1144void ath_rate_findrate(struct ath_softc *sc, 1144static void ath_rate_findrate(struct ath_softc *sc,
1145 struct ath_rate_node *ath_rc_priv, 1145 struct ath_rate_node *ath_rc_priv,
1146 int num_tries, 1146 int num_tries,
1147 int num_rates, 1147 int num_rates,
1148 unsigned int rcflag, 1148 unsigned int rcflag,
1149 struct ath_rc_series series[], 1149 struct ath_rc_series series[],
1150 int *is_probe, 1150 int *is_probe,
1151 int is_retry) 1151 int is_retry)
1152{ 1152{
1153 struct ath_vap *avp = ath_rc_priv->avp; 1153 struct ath_vap *avp = ath_rc_priv->avp;
1154 1154
1155 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); 1155 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
1156
1156 if (!num_rates || !num_tries) 1157 if (!num_rates || !num_tries)
1157 return; 1158 return;
1158 1159
@@ -1174,9 +1175,8 @@ void ath_rate_findrate(struct ath_softc *sc,
1174 unsigned int mcs; 1175 unsigned int mcs;
1175 u8 series_rix = 0; 1176 u8 series_rix = 0;
1176 1177
1177 series[idx].tries = 1178 series[idx].tries = IEEE80211_RATE_IDX_ENTRY(
1178 IEEE80211_RATE_IDX_ENTRY( 1179 avp->av_config.av_fixed_retryset, idx);
1179 avp->av_config.av_fixed_retryset, idx);
1180 1180
1181 mcs = IEEE80211_RATE_IDX_ENTRY( 1181 mcs = IEEE80211_RATE_IDX_ENTRY(
1182 avp->av_config.av_fixed_rateset, idx); 1182 avp->av_config.av_fixed_rateset, idx);
@@ -1228,7 +1228,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1228 u32 now_msec = jiffies_to_msecs(jiffies); 1228 u32 now_msec = jiffies_to_msecs(jiffies);
1229 int state_change = FALSE, rate, count; 1229 int state_change = FALSE, rate, count;
1230 u8 last_per; 1230 u8 last_per;
1231 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; 1231 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1232 struct ath_rate_table *rate_table = 1232 struct ath_rate_table *rate_table =
1233 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode]; 1233 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
1234 1234
@@ -1272,14 +1272,14 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1272 } else { 1272 } else {
1273 /* xretries == 2 */ 1273 /* xretries == 2 */
1274 count = sizeof(nretry_to_per_lookup) / 1274 count = sizeof(nretry_to_per_lookup) /
1275 sizeof(nretry_to_per_lookup[0]); 1275 sizeof(nretry_to_per_lookup[0]);
1276 if (retries >= count) 1276 if (retries >= count)
1277 retries = count - 1; 1277 retries = count - 1;
1278 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 1278 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
1279 rate_ctrl->state[tx_rate].per = 1279 rate_ctrl->state[tx_rate].per =
1280 (u8)(rate_ctrl->state[tx_rate].per - 1280 (u8)(rate_ctrl->state[tx_rate].per -
1281 (rate_ctrl->state[tx_rate].per >> 3) + 1281 (rate_ctrl->state[tx_rate].per >> 3) +
1282 ((100) >> 3)); 1282 ((100) >> 3));
1283 } 1283 }
1284 1284
1285 /* xretries == 1 or 2 */ 1285 /* xretries == 1 or 2 */
@@ -1295,8 +1295,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1295 if (retries >= count) 1295 if (retries >= count)
1296 retries = count - 1; 1296 retries = count - 1;
1297 if (info_priv->n_bad_frames) { 1297 if (info_priv->n_bad_frames) {
1298 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 1298 /* new_PER = 7/8*old_PER + 1/8*(currentPER)
1299 /*
1300 * Assuming that n_frames is not 0. The current PER 1299 * Assuming that n_frames is not 0. The current PER
1301 * from the retries is 100 * retries / (retries+1), 1300 * from the retries is 100 * retries / (retries+1),
1302 * since the first retries attempts failed, and the 1301 * since the first retries attempts failed, and the
@@ -1386,7 +1385,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1386 * rssi_ack values. 1385 * rssi_ack values.
1387 */ 1386 */
1388 if (tx_rate == rate_ctrl->rate_max_phy && 1387 if (tx_rate == rate_ctrl->rate_max_phy &&
1389 rate_ctrl->hw_maxretry_pktcnt < 255) { 1388 rate_ctrl->hw_maxretry_pktcnt < 255) {
1390 rate_ctrl->hw_maxretry_pktcnt++; 1389 rate_ctrl->hw_maxretry_pktcnt++;
1391 } 1390 }
1392 1391
@@ -1418,7 +1417,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1418 /* Now reduce the current 1417 /* Now reduce the current
1419 * rssi threshold. */ 1418 * rssi threshold. */
1420 if ((rssi_ackAvg < rssi_thres + 2) && 1419 if ((rssi_ackAvg < rssi_thres + 2) &&
1421 (rssi_thres > rssi_ack_vmin)) { 1420 (rssi_thres > rssi_ack_vmin)) {
1422 rate_ctrl->state[tx_rate]. 1421 rate_ctrl->state[tx_rate].
1423 rssi_thres--; 1422 rssi_thres--;
1424 } 1423 }
@@ -1436,10 +1435,10 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1436 * a while (except if we are probing). 1435 * a while (except if we are probing).
1437 */ 1436 */
1438 if (rate_ctrl->state[tx_rate].per >= 55 && tx_rate > 0 && 1437 if (rate_ctrl->state[tx_rate].per >= 55 && tx_rate > 0 &&
1439 rate_table->info[tx_rate].ratekbps <= 1438 rate_table->info[tx_rate].ratekbps <=
1440 rate_table->info[rate_ctrl->rate_max_phy].ratekbps) { 1439 rate_table->info[rate_ctrl->rate_max_phy].ratekbps) {
1441 ath_rc_get_nextlowervalid_txrate(rate_table, rate_ctrl, 1440 ath_rc_get_nextlowervalid_txrate(rate_table, rate_ctrl,
1442 (u8) tx_rate, &rate_ctrl->rate_max_phy); 1441 (u8) tx_rate, &rate_ctrl->rate_max_phy);
1443 1442
1444 /* Don't probe for a little while. */ 1443 /* Don't probe for a little while. */
1445 rate_ctrl->probe_time = now_msec; 1444 rate_ctrl->probe_time = now_msec;
@@ -1460,43 +1459,43 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1460 break; 1459 break;
1461 1460
1462 if (rate_ctrl->state[rate].rssi_thres + 1461 if (rate_ctrl->state[rate].rssi_thres +
1463 rate_table->info[rate].rssi_ack_deltamin > 1462 rate_table->info[rate].rssi_ack_deltamin >
1464 rate_ctrl->state[rate+1].rssi_thres) { 1463 rate_ctrl->state[rate+1].rssi_thres) {
1465 rate_ctrl->state[rate+1].rssi_thres = 1464 rate_ctrl->state[rate+1].rssi_thres =
1466 rate_ctrl->state[rate]. 1465 rate_ctrl->state[rate].
1467 rssi_thres + 1466 rssi_thres +
1468 rate_table->info[rate]. 1467 rate_table->info[rate].
1469 rssi_ack_deltamin; 1468 rssi_ack_deltamin;
1470 } 1469 }
1471 } 1470 }
1472 1471
1473 /* Make sure the rates below this have lower rssi thresholds. */ 1472 /* Make sure the rates below this have lower rssi thresholds. */
1474 for (rate = tx_rate - 1; rate >= 0; rate--) { 1473 for (rate = tx_rate - 1; rate >= 0; rate--) {
1475 if (rate_table->info[rate].phy != 1474 if (rate_table->info[rate].phy !=
1476 rate_table->info[tx_rate].phy) 1475 rate_table->info[tx_rate].phy)
1477 break; 1476 break;
1478 1477
1479 if (rate_ctrl->state[rate].rssi_thres + 1478 if (rate_ctrl->state[rate].rssi_thres +
1480 rate_table->info[rate].rssi_ack_deltamin > 1479 rate_table->info[rate].rssi_ack_deltamin >
1481 rate_ctrl->state[rate+1].rssi_thres) { 1480 rate_ctrl->state[rate+1].rssi_thres) {
1482 if (rate_ctrl->state[rate+1].rssi_thres < 1481 if (rate_ctrl->state[rate+1].rssi_thres <
1483 rate_table->info[rate]. 1482 rate_table->info[rate].
1484 rssi_ack_deltamin) 1483 rssi_ack_deltamin)
1485 rate_ctrl->state[rate].rssi_thres = 0; 1484 rate_ctrl->state[rate].rssi_thres = 0;
1486 else { 1485 else {
1487 rate_ctrl->state[rate].rssi_thres = 1486 rate_ctrl->state[rate].rssi_thres =
1488 rate_ctrl->state[rate+1]. 1487 rate_ctrl->state[rate+1].
1489 rssi_thres - 1488 rssi_thres -
1490 rate_table->info[rate]. 1489 rate_table->info[rate].
1491 rssi_ack_deltamin; 1490 rssi_ack_deltamin;
1492 } 1491 }
1493 1492
1494 if (rate_ctrl->state[rate].rssi_thres < 1493 if (rate_ctrl->state[rate].rssi_thres <
1495 rate_table->info[rate]. 1494 rate_table->info[rate].
1496 rssi_ack_validmin) { 1495 rssi_ack_validmin) {
1497 rate_ctrl->state[rate].rssi_thres = 1496 rate_ctrl->state[rate].rssi_thres =
1498 rate_table->info[rate]. 1497 rate_table->info[rate].
1499 rssi_ack_validmin; 1498 rssi_ack_validmin;
1500 } 1499 }
1501 } 1500 }
1502 } 1501 }
@@ -1507,11 +1506,11 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1507 if (rate_ctrl->state[tx_rate].per < last_per) { 1506 if (rate_ctrl->state[tx_rate].per < last_per) {
1508 for (rate = tx_rate - 1; rate >= 0; rate--) { 1507 for (rate = tx_rate - 1; rate >= 0; rate--) {
1509 if (rate_table->info[rate].phy != 1508 if (rate_table->info[rate].phy !=
1510 rate_table->info[tx_rate].phy) 1509 rate_table->info[tx_rate].phy)
1511 break; 1510 break;
1512 1511
1513 if (rate_ctrl->state[rate].per > 1512 if (rate_ctrl->state[rate].per >
1514 rate_ctrl->state[rate+1].per) { 1513 rate_ctrl->state[rate+1].per) {
1515 rate_ctrl->state[rate].per = 1514 rate_ctrl->state[rate].per =
1516 rate_ctrl->state[rate+1].per; 1515 rate_ctrl->state[rate+1].per;
1517 } 1516 }
@@ -1528,11 +1527,11 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1528 /* Every so often, we reduce the thresholds and 1527 /* Every so often, we reduce the thresholds and
1529 * PER (different for CCK and OFDM). */ 1528 * PER (different for CCK and OFDM). */
1530 if (now_msec - rate_ctrl->rssi_down_time >= 1529 if (now_msec - rate_ctrl->rssi_down_time >=
1531 rate_table->rssi_reduce_interval) { 1530 rate_table->rssi_reduce_interval) {
1532 1531
1533 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) { 1532 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
1534 if (rate_ctrl->state[rate].rssi_thres > 1533 if (rate_ctrl->state[rate].rssi_thres >
1535 rate_table->info[rate].rssi_ack_validmin) 1534 rate_table->info[rate].rssi_ack_validmin)
1536 rate_ctrl->state[rate].rssi_thres -= 1; 1535 rate_ctrl->state[rate].rssi_thres -= 1;
1537 } 1536 }
1538 rate_ctrl->rssi_down_time = now_msec; 1537 rate_ctrl->rssi_down_time = now_msec;
@@ -1541,7 +1540,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1541 /* Every so often, we reduce the thresholds 1540 /* Every so often, we reduce the thresholds
1542 * and PER (different for CCK and OFDM). */ 1541 * and PER (different for CCK and OFDM). */
1543 if (now_msec - rate_ctrl->per_down_time >= 1542 if (now_msec - rate_ctrl->per_down_time >=
1544 rate_table->rssi_reduce_interval) { 1543 rate_table->rssi_reduce_interval) {
1545 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) { 1544 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
1546 rate_ctrl->state[rate].per = 1545 rate_ctrl->state[rate].per =
1547 7 * rate_ctrl->state[rate].per / 8; 1546 7 * rate_ctrl->state[rate].per / 8;
@@ -1560,7 +1559,7 @@ static void ath_rc_update(struct ath_softc *sc,
1560 struct ath_tx_info_priv *info_priv, int final_ts_idx, 1559 struct ath_tx_info_priv *info_priv, int final_ts_idx,
1561 int xretries, int long_retry) 1560 int xretries, int long_retry)
1562{ 1561{
1563 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; 1562 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1564 struct ath_rate_table *rate_table; 1563 struct ath_rate_table *rate_table;
1565 struct ath_tx_ratectrl *rate_ctrl; 1564 struct ath_tx_ratectrl *rate_ctrl;
1566 struct ath_rc_series rcs[4]; 1565 struct ath_rc_series rcs[4];
@@ -1637,7 +1636,6 @@ static void ath_rc_update(struct ath_softc *sc,
1637 xretries, long_retry); 1636 xretries, long_retry);
1638} 1637}
1639 1638
1640
1641/* 1639/*
1642 * Process a tx descriptor for a completed transmit (success or failure). 1640 * Process a tx descriptor for a completed transmit (success or failure).
1643 */ 1641 */
@@ -1651,13 +1649,13 @@ static void ath_rate_tx_complete(struct ath_softc *sc,
1651 struct ath_vap *avp; 1649 struct ath_vap *avp;
1652 1650
1653 avp = rc_priv->avp; 1651 avp = rc_priv->avp;
1654 if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) 1652 if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) ||
1655 || info_priv->tx.ts_status & ATH9K_TXERR_FILT) 1653 (info_priv->tx.ts_status & ATH9K_TXERR_FILT))
1656 return; 1654 return;
1657 1655
1658 if (info_priv->tx.ts_rssi > 0) { 1656 if (info_priv->tx.ts_rssi > 0) {
1659 ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi, 1657 ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi,
1660 info_priv->tx.ts_rssi); 1658 info_priv->tx.ts_rssi);
1661 } 1659 }
1662 1660
1663 /* 1661 /*
@@ -1682,7 +1680,6 @@ static void ath_rate_tx_complete(struct ath_softc *sc,
1682 info_priv->tx.ts_longretry); 1680 info_priv->tx.ts_longretry);
1683} 1681}
1684 1682
1685
1686/* 1683/*
1687 * Update the SIB's rate control information 1684 * Update the SIB's rate control information
1688 * 1685 *
@@ -1701,8 +1698,8 @@ static void ath_rc_sib_update(struct ath_softc *sc,
1701 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc; 1698 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1702 struct ath_rateset *rateset = negotiated_rates; 1699 struct ath_rateset *rateset = negotiated_rates;
1703 u8 *ht_mcs = (u8 *)negotiated_htrates; 1700 u8 *ht_mcs = (u8 *)negotiated_htrates;
1704 struct ath_tx_ratectrl *rate_ctrl = (struct ath_tx_ratectrl *) 1701 struct ath_tx_ratectrl *rate_ctrl =
1705 (ath_rc_priv); 1702 (struct ath_tx_ratectrl *)ath_rc_priv;
1706 u8 i, j, k, hi = 0, hthi = 0; 1703 u8 i, j, k, hi = 0, hthi = 0;
1707 1704
1708 rate_table = (struct ath_rate_table *) 1705 rate_table = (struct ath_rate_table *)
@@ -1824,7 +1821,8 @@ static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta)
1824 struct ath_rate_node *rc_priv = sta->rate_ctrl_priv; 1821 struct ath_rate_node *rc_priv = sta->rate_ctrl_priv;
1825 int i, j = 0; 1822 int i, j = 0;
1826 1823
1827 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); 1824 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
1825
1828 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1826 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1829 for (i = 0; i < sband->n_bitrates; i++) { 1827 for (i = 0; i < sband->n_bitrates; i++) {
1830 if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) { 1828 if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) {
@@ -1903,7 +1901,7 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
1903 int state; 1901 int state;
1904 DECLARE_MAC_BUF(mac); 1902 DECLARE_MAC_BUF(mac);
1905 1903
1906 if (!sc->sc_txaggr) 1904 if (!(sc->sc_flags & SC_OP_TXAGGR))
1907 return; 1905 return;
1908 1906
1909 txtid = ATH_AN_2_TID(an, tidno); 1907 txtid = ATH_AN_2_TID(an, tidno);
@@ -1944,7 +1942,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
1944 struct ath_rate_node *ath_rc_priv; 1942 struct ath_rate_node *ath_rc_priv;
1945 struct ath_node *an; 1943 struct ath_node *an;
1946 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1944 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1947 int is_probe, chk, ret; 1945 int is_probe = FALSE, chk, ret;
1948 s8 lowest_idx; 1946 s8 lowest_idx;
1949 __le16 fc = hdr->frame_control; 1947 __le16 fc = hdr->frame_control;
1950 u8 *qc, tid; 1948 u8 *qc, tid;
@@ -1962,7 +1960,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
1962 tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10; 1960 tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10;
1963 /* lowest rate for management and multicast/broadcast frames */ 1961 /* lowest rate for management and multicast/broadcast frames */
1964 if (!ieee80211_is_data(fc) || 1962 if (!ieee80211_is_data(fc) ||
1965 is_multicast_ether_addr(hdr->addr1) || !sta) { 1963 is_multicast_ether_addr(hdr->addr1) || !sta) {
1966 sel->rate_idx = lowest_idx; 1964 sel->rate_idx = lowest_idx;
1967 return; 1965 return;
1968 } 1966 }
@@ -1978,7 +1976,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
1978 false); 1976 false);
1979 if (is_probe) 1977 if (is_probe)
1980 sel->probe_idx = ((struct ath_tx_ratectrl *) 1978 sel->probe_idx = ((struct ath_tx_ratectrl *)
1981 sta->rate_ctrl_priv)->probe_rate; 1979 sta->rate_ctrl_priv)->probe_rate;
1982 1980
1983 /* Ratecontrol sometimes returns invalid rate index */ 1981 /* Ratecontrol sometimes returns invalid rate index */
1984 if (tx_info_priv->rcs[0].rix != 0xff) 1982 if (tx_info_priv->rcs[0].rix != 0xff)
@@ -2035,6 +2033,7 @@ static void ath_rate_init(void *priv, void *priv_sta,
2035 struct ieee80211_hw *hw = local_to_hw(local); 2033 struct ieee80211_hw *hw = local_to_hw(local);
2036 struct ieee80211_conf *conf = &local->hw.conf; 2034 struct ieee80211_conf *conf = &local->hw.conf;
2037 struct ath_softc *sc = hw->priv; 2035 struct ath_softc *sc = hw->priv;
2036 struct ath_rate_node *ath_rc_priv = priv_sta;
2038 int i, j = 0; 2037 int i, j = 0;
2039 2038
2040 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); 2039 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
@@ -2046,12 +2045,11 @@ static void ath_rate_init(void *priv, void *priv_sta,
2046 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { 2045 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
2047 for (i = 0; i < MCS_SET_SIZE; i++) { 2046 for (i = 0; i < MCS_SET_SIZE; i++) {
2048 if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) 2047 if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
2049 ((struct ath_rate_node *) 2048 ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
2050 priv_sta)->neg_ht_rates.rs_rates[j++] = i;
2051 if (j == ATH_RATE_MAX) 2049 if (j == ATH_RATE_MAX)
2052 break; 2050 break;
2053 } 2051 }
2054 ((struct ath_rate_node *)priv_sta)->neg_ht_rates.rs_nrates = j; 2052 ath_rc_priv->neg_ht_rates.rs_nrates = j;
2055 } 2053 }
2056 ath_rc_node_update(hw, priv_sta); 2054 ath_rc_node_update(hw, priv_sta);
2057} 2055}
@@ -2066,7 +2064,7 @@ static void *ath_rate_alloc(struct ieee80211_local *local)
2066 struct ieee80211_hw *hw = local_to_hw(local); 2064 struct ieee80211_hw *hw = local_to_hw(local);
2067 struct ath_softc *sc = hw->priv; 2065 struct ath_softc *sc = hw->priv;
2068 2066
2069 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); 2067 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
2070 return local->hw.priv; 2068 return local->hw.priv;
2071} 2069}
2072 2070
@@ -2081,14 +2079,17 @@ static void *ath_rate_alloc_sta(void *priv, gfp_t gfp)
2081 struct ath_vap *avp = sc->sc_vaps[0]; 2079 struct ath_vap *avp = sc->sc_vaps[0];
2082 struct ath_rate_node *rate_priv; 2080 struct ath_rate_node *rate_priv;
2083 2081
2084 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__); 2082 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
2083
2085 rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp); 2084 rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp);
2086 if (!rate_priv) { 2085 if (!rate_priv) {
2087 DPRINTF(sc, ATH_DBG_FATAL, "%s:Unable to allocate" 2086 DPRINTF(sc, ATH_DBG_FATAL,
2088 "private rate control structure", __func__); 2087 "%s: Unable to allocate private rc structure\n",
2088 __func__);
2089 return NULL; 2089 return NULL;
2090 } 2090 }
2091 ath_rc_sib_init(rate_priv); 2091 ath_rc_sib_init(rate_priv);
2092
2092 return rate_priv; 2093 return rate_priv;
2093} 2094}
2094 2095
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index 71aef9c75232..b95b41508b98 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -71,9 +71,6 @@ enum ieee80211_fixed_rate_mode {
71 */ 71 */
72#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8))) 72#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8)))
73 73
74#define SHORT_PRE 1
75#define LONG_PRE 0
76
77#define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS 74#define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS
78#define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS 75#define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS
79#define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI 76#define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI
@@ -102,18 +99,18 @@ enum {
102 WLAN_RC_PHY_MAX 99 WLAN_RC_PHY_MAX
103}; 100};
104 101
105#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \ 102#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
106 || (_phy == WLAN_RC_PHY_HT_40_DS) \ 103 || (_phy == WLAN_RC_PHY_HT_40_DS) \
107 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ 104 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
108 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) 105 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
109#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \ 106#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
110 || (_phy == WLAN_RC_PHY_HT_40_DS) \ 107 || (_phy == WLAN_RC_PHY_HT_40_DS) \
111 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ 108 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
112 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) 109 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
113#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \ 110#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
114 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \ 111 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
115 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \ 112 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
116 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI)) 113 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
117 114
118#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS) 115#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
119 116
@@ -135,56 +132,59 @@ enum {
135#define WLAN_RC_SGI_FLAG (0x04) 132#define WLAN_RC_SGI_FLAG (0x04)
136#define WLAN_RC_HT_FLAG (0x08) 133#define WLAN_RC_HT_FLAG (0x08)
137 134
138/* Index into the rate table */
139#define INIT_RATE_MAX_20 23
140#define INIT_RATE_MAX_40 40
141
142#define RATE_TABLE_SIZE 64 135#define RATE_TABLE_SIZE 64
143 136
144/* XXX: Convert to kdoc */ 137/**
138 * struct ath_rate_table - Rate Control table
139 * @valid: valid for use in rate control
140 * @valid_single_stream: valid for use in rate control for
141 * single stream operation
142 * @phy: CCK/OFDM
143 * @ratekbps: rate in Kbits per second
144 * @user_ratekbps: user rate in Kbits per second
145 * @ratecode: rate that goes into HW descriptors
146 * @short_preamble: Mask for enabling short preamble in ratecode for CCK
147 * @dot11rate: value that goes into supported
148 * rates info element of MLME
149 * @ctrl_rate: Index of next lower basic rate, used for duration computation
150 * @max_4ms_framelen: maximum frame length(bytes) for tx duration
151 * @probe_interval: interval for rate control to probe for other rates
152 * @rssi_reduce_interval: interval for rate control to reduce rssi
153 * @initial_ratemax: initial ratemax value used in ath_rc_sib_update()
154 */
145struct ath_rate_table { 155struct ath_rate_table {
146 int rate_cnt; 156 int rate_cnt;
147 struct { 157 struct {
148 int valid; /* Valid for use in rate control */ 158 int valid;
149 int valid_single_stream;/* Valid for use in rate control 159 int valid_single_stream;
150 for single stream operation */ 160 u8 phy;
151 u8 phy; /* CCK/OFDM/TURBO/XR */ 161 u32 ratekbps;
152 u32 ratekbps; /* Rate in Kbits per second */ 162 u32 user_ratekbps;
153 u32 user_ratekbps; /* User rate in KBits per second */ 163 u8 ratecode;
154 u8 ratecode; /* rate that goes into 164 u8 short_preamble;
155 hw descriptors */ 165 u8 dot11rate;
156 u8 short_preamble; /* Mask for enabling short preamble 166 u8 ctrl_rate;
157 in rate code for CCK */ 167 int8_t rssi_ack_validmin;
158 u8 dot11rate; /* Value that goes into supported 168 int8_t rssi_ack_deltamin;
159 rates info element of MLME */ 169 u8 base_index;
160 u8 ctrl_rate; /* Index of next lower basic rate, 170 u8 cw40index;
161 used for duration computation */ 171 u8 sgi_index;
162 int8_t rssi_ack_validmin; /* Rate control related */ 172 u8 ht_index;
163 int8_t rssi_ack_deltamin; /* Rate control related */ 173 u32 max_4ms_framelen;
164 u8 base_index; /* base rate index */
165 u8 cw40index; /* 40cap rate index */
166 u8 sgi_index; /* shortgi rate index */
167 u8 ht_index; /* shortgi rate index */
168 u32 max_4ms_framelen; /* Maximum frame length(bytes)
169 for 4ms tx duration */
170 } info[RATE_TABLE_SIZE]; 174 } info[RATE_TABLE_SIZE];
171 u32 probe_interval; /* interval for ratectrl to 175 u32 probe_interval;
172 probe for other rates */ 176 u32 rssi_reduce_interval;
173 u32 rssi_reduce_interval; /* interval for ratectrl 177 u8 initial_ratemax;
174 to reduce RSSI */
175 u8 initial_ratemax; /* the initial ratemax value used
176 in ath_rc_sib_update() */
177}; 178};
178 179
179#define ATH_RC_PROBE_ALLOWED 0x00000001 180#define ATH_RC_PROBE_ALLOWED 0x00000001
180#define ATH_RC_MINRATE_LASTRATE 0x00000002 181#define ATH_RC_MINRATE_LASTRATE 0x00000002
181#define ATH_RC_SHORT_PREAMBLE 0x00000004
182 182
183struct ath_rc_series { 183struct ath_rc_series {
184 u8 rix; 184 u8 rix;
185 u8 tries; 185 u8 tries;
186 u8 flags; 186 u8 flags;
187 u32 max_4ms_framelen; 187 u32 max_4ms_framelen;
188}; 188};
189 189
190/* rcs_flags definition */ 190/* rcs_flags definition */
@@ -201,42 +201,56 @@ struct ath_rc_series {
201#define MAX_TX_RATE_PHY 48 201#define MAX_TX_RATE_PHY 48
202 202
203struct ath_tx_ratectrl_state { 203struct ath_tx_ratectrl_state {
204 int8_t rssi_thres; /* required rssi for this rate (dB) */ 204 int8_t rssi_thres; /* required rssi for this rate (dB) */
205 u8 per; /* recent estimate of packet error rate (%) */ 205 u8 per; /* recent estimate of packet error rate (%) */
206}; 206};
207 207
208/**
209 * struct ath_tx_ratectrl - TX Rate control Information
210 * @state: RC state
211 * @rssi_last: last ACK rssi
212 * @rssi_last_lookup: last ACK rssi used for lookup
213 * @rssi_last_prev: previous last ACK rssi
214 * @rssi_last_prev2: 2nd previous last ACK rssi
215 * @rssi_sum_cnt: count of rssi_sum for averaging
216 * @rssi_sum_rate: rate that we are averaging
217 * @rssi_sum: running sum of rssi for averaging
218 * @probe_rate: rate we are probing at
219 * @rssi_time: msec timestamp for last ack rssi
220 * @rssi_down_time: msec timestamp for last down step
221 * @probe_time: msec timestamp for last probe
222 * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
223 * @max_valid_rate: maximum number of valid rate
224 * @per_down_time: msec timestamp for last PER down step
225 * @valid_phy_ratecnt: valid rate count
226 * @rate_max_phy: phy index for the max rate
227 * @probe_interval: interval for ratectrl to probe for other rates
228 */
208struct ath_tx_ratectrl { 229struct ath_tx_ratectrl {
209 struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL]; /* state */ 230 struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL];
210 int8_t rssi_last; /* last ack rssi */ 231 int8_t rssi_last;
211 int8_t rssi_last_lookup; /* last ack rssi used for lookup */ 232 int8_t rssi_last_lookup;
212 int8_t rssi_last_prev; /* previous last ack rssi */ 233 int8_t rssi_last_prev;
213 int8_t rssi_last_prev2; /* 2nd previous last ack rssi */ 234 int8_t rssi_last_prev2;
214 int32_t rssi_sum_cnt; /* count of rssi_sum for averaging */ 235 int32_t rssi_sum_cnt;
215 int32_t rssi_sum_rate; /* rate that we are averaging */ 236 int32_t rssi_sum_rate;
216 int32_t rssi_sum; /* running sum of rssi for averaging */ 237 int32_t rssi_sum;
217 u32 valid_txrate_mask; /* mask of valid rates */ 238 u8 rate_table_size;
218 u8 rate_table_size; /* rate table size */ 239 u8 probe_rate;
219 u8 rate_max; /* max rate that has recently worked */ 240 u32 rssi_time;
220 u8 probe_rate; /* rate we are probing at */ 241 u32 rssi_down_time;
221 u32 rssi_time; /* msec timestamp for last ack rssi */ 242 u32 probe_time;
222 u32 rssi_down_time; /* msec timestamp for last down step */ 243 u8 hw_maxretry_pktcnt;
223 u32 probe_time; /* msec timestamp for last probe */ 244 u8 max_valid_rate;
224 u8 hw_maxretry_pktcnt; /* num packets since we got 245 u8 valid_rate_index[MAX_TX_RATE_TBL];
225 HW max retry error */ 246 u32 per_down_time;
226 u8 max_valid_rate; /* maximum number of valid rate */
227 u8 valid_rate_index[MAX_TX_RATE_TBL]; /* valid rate index */
228 u32 per_down_time; /* msec timstamp for last
229 PER down step */
230 247
231 /* 11n state */ 248 /* 11n state */
232 u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; /* valid rate count */ 249 u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
233 u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL]; 250 u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL];
234 u8 rc_phy_mode; 251 u8 rc_phy_mode;
235 u8 rate_max_phy; /* Phy index for the max rate */ 252 u8 rate_max_phy;
236 u32 rate_max_lastused; /* msec timstamp of when we 253 u32 probe_interval;
237 last used rateMaxPhy */
238 u32 probe_interval; /* interval for ratectrl to probe
239 for other rates */
240}; 254};
241 255
242struct ath_rateset { 256struct ath_rateset {
@@ -248,29 +262,32 @@ struct ath_rateset {
248struct ath_rate_softc { 262struct ath_rate_softc {
249 /* phy tables that contain rate control data */ 263 /* phy tables that contain rate control data */
250 const void *hw_rate_table[ATH9K_MODE_MAX]; 264 const void *hw_rate_table[ATH9K_MODE_MAX];
251 int fixedrix; /* -1 or index of fixed rate */ 265
266 /* -1 or index of fixed rate */
267 int fixedrix;
252}; 268};
253 269
254/* per-node state */ 270/* per-node state */
255struct ath_rate_node { 271struct ath_rate_node {
256 struct ath_tx_ratectrl tx_ratectrl; /* rate control state proper */ 272 struct ath_tx_ratectrl tx_ratectrl;
257 u32 prev_data_rix; /* rate idx of last data frame */
258 273
259 /* map of rate ix -> negotiated rate set ix */ 274 /* rate idx of last data frame */
260 u8 rixmap[MAX_TX_RATE_TBL]; 275 u32 prev_data_rix;
261 276
262 /* map of ht rate ix -> negotiated rate set ix */ 277 /* ht capabilities */
263 u8 ht_rixmap[MAX_TX_RATE_TBL]; 278 u8 ht_cap;
264 279
265 u8 ht_cap; /* ht capabilities */ 280 /* When TRUE, only single stream Tx possible */
266 u8 ant_tx; /* current transmit antenna */ 281 u8 single_stream;
267 282
268 u8 single_stream; /* When TRUE, only single 283 /* Negotiated rates */
269 stream Tx possible */ 284 struct ath_rateset neg_rates;
270 struct ath_rateset neg_rates; /* Negotiated rates */ 285
271 struct ath_rateset neg_ht_rates; /* Negotiated HT rates */ 286 /* Negotiated HT rates */
272 struct ath_rate_softc *asc; /* back pointer to atheros softc */ 287 struct ath_rateset neg_ht_rates;
273 struct ath_vap *avp; /* back pointer to vap */ 288
289 struct ath_rate_softc *asc;
290 struct ath_vap *avp;
274}; 291};
275 292
276/* Driver data of ieee80211_tx_info */ 293/* Driver data of ieee80211_tx_info */
@@ -297,17 +314,10 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv);
297void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp); 314void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp);
298 315
299/* 316/*
300 * Return the tx rate series.
301 */
302void ath_rate_findrate(struct ath_softc *sc, struct ath_rate_node *ath_rc_priv,
303 int num_tries, int num_rates,
304 unsigned int rcflag, struct ath_rc_series[],
305 int *is_probe, int isretry);
306/*
307 * Return rate index for given Dot11 Rate. 317 * Return rate index for given Dot11 Rate.
308 */ 318 */
309u8 ath_rate_findrateix(struct ath_softc *sc, 319u8 ath_rate_findrateix(struct ath_softc *sc,
310 u8 dot11_rate); 320 u8 dot11_rate);
311 321
312/* Routines to register/unregister rate control algorithm */ 322/* Routines to register/unregister rate control algorithm */
313int ath_rate_control_register(void); 323int ath_rate_control_register(void);
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 2fe806175c01..6e13c638cc0b 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -184,7 +184,7 @@ static int ath_ampdu_input(struct ath_softc *sc,
184 tid = qc[0] & 0xf; 184 tid = qc[0] & 0xf;
185 } 185 }
186 186
187 if (sc->sc_opmode == ATH9K_M_STA) { 187 if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
188 /* Drop the frame not belonging to me. */ 188 /* Drop the frame not belonging to me. */
189 if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) { 189 if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) {
190 dev_kfree_skb(skb); 190 dev_kfree_skb(skb);
@@ -448,17 +448,16 @@ static int ath_rx_indicate(struct ath_softc *sc,
448 int type; 448 int type;
449 449
450 /* indicate frame to the stack, which will free the old skb. */ 450 /* indicate frame to the stack, which will free the old skb. */
451 type = ath__rx_indicate(sc, skb, status, keyix); 451 type = _ath_rx_indicate(sc, skb, status, keyix);
452 452
453 /* allocate a new skb and queue it to for H/W processing */ 453 /* allocate a new skb and queue it to for H/W processing */
454 nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize); 454 nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
455 if (nskb != NULL) { 455 if (nskb != NULL) {
456 bf->bf_mpdu = nskb; 456 bf->bf_mpdu = nskb;
457 bf->bf_buf_addr = ath_skb_map_single(sc, 457 bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data,
458 nskb, 458 skb_end_pointer(nskb) - nskb->head,
459 PCI_DMA_FROMDEVICE, 459 PCI_DMA_FROMDEVICE);
460 /* XXX: Remove get_dma_mem_context() */ 460 bf->bf_dmacontext = bf->bf_buf_addr;
461 get_dma_mem_context(bf, bf_dmacontext));
462 ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; 461 ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf;
463 462
464 /* queue the new wbuf to H/W */ 463 /* queue the new wbuf to H/W */
@@ -504,7 +503,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
504 503
505 do { 504 do {
506 spin_lock_init(&sc->sc_rxflushlock); 505 spin_lock_init(&sc->sc_rxflushlock);
507 sc->sc_rxflush = 0; 506 sc->sc_flags &= ~SC_OP_RXFLUSH;
508 spin_lock_init(&sc->sc_rxbuflock); 507 spin_lock_init(&sc->sc_rxbuflock);
509 508
510 /* 509 /*
@@ -541,9 +540,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
541 } 540 }
542 541
543 bf->bf_mpdu = skb; 542 bf->bf_mpdu = skb;
544 bf->bf_buf_addr = 543 bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
545 ath_skb_map_single(sc, skb, PCI_DMA_FROMDEVICE, 544 skb_end_pointer(skb) - skb->head,
546 get_dma_mem_context(bf, bf_dmacontext)); 545 PCI_DMA_FROMDEVICE);
546 bf->bf_dmacontext = bf->bf_buf_addr;
547 ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; 547 ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf;
548 } 548 }
549 sc->sc_rxlink = NULL; 549 sc->sc_rxlink = NULL;
@@ -597,6 +597,7 @@ void ath_rx_cleanup(struct ath_softc *sc)
597u32 ath_calcrxfilter(struct ath_softc *sc) 597u32 ath_calcrxfilter(struct ath_softc *sc)
598{ 598{
599#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR) 599#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
600
600 u32 rfilt; 601 u32 rfilt;
601 602
602 rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) 603 rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
@@ -604,25 +605,29 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
604 | ATH9K_RX_FILTER_MCAST; 605 | ATH9K_RX_FILTER_MCAST;
605 606
606 /* If not a STA, enable processing of Probe Requests */ 607 /* If not a STA, enable processing of Probe Requests */
607 if (sc->sc_opmode != ATH9K_M_STA) 608 if (sc->sc_ah->ah_opmode != ATH9K_M_STA)
608 rfilt |= ATH9K_RX_FILTER_PROBEREQ; 609 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
609 610
610 /* Can't set HOSTAP into promiscous mode */ 611 /* Can't set HOSTAP into promiscous mode */
611 if (sc->sc_opmode == ATH9K_M_MONITOR) { 612 if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) &&
613 (sc->rx_filter & FIF_PROMISC_IN_BSS)) ||
614 (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) {
612 rfilt |= ATH9K_RX_FILTER_PROM; 615 rfilt |= ATH9K_RX_FILTER_PROM;
613 /* ??? To prevent from sending ACK */ 616 /* ??? To prevent from sending ACK */
614 rfilt &= ~ATH9K_RX_FILTER_UCAST; 617 rfilt &= ~ATH9K_RX_FILTER_UCAST;
615 } 618 }
616 619
617 if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS || 620 if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
618 sc->sc_scanning) 621 (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) ||
622 (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))
619 rfilt |= ATH9K_RX_FILTER_BEACON; 623 rfilt |= ATH9K_RX_FILTER_BEACON;
620 624
621 /* If in HOSTAP mode, want to enable reception of PSPOLL frames 625 /* If in HOSTAP mode, want to enable reception of PSPOLL frames
622 & beacon frames */ 626 & beacon frames */
623 if (sc->sc_opmode == ATH9K_M_HOSTAP) 627 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP)
624 rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); 628 rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
625 return rfilt; 629 return rfilt;
630
626#undef RX_FILTER_PRESERVE 631#undef RX_FILTER_PRESERVE
627} 632}
628 633
@@ -702,11 +707,11 @@ void ath_flushrecv(struct ath_softc *sc)
702 * progress (see references to sc_rxflush) 707 * progress (see references to sc_rxflush)
703 */ 708 */
704 spin_lock_bh(&sc->sc_rxflushlock); 709 spin_lock_bh(&sc->sc_rxflushlock);
705 sc->sc_rxflush = 1; 710 sc->sc_flags |= SC_OP_RXFLUSH;
706 711
707 ath_rx_tasklet(sc, 1); 712 ath_rx_tasklet(sc, 1);
708 713
709 sc->sc_rxflush = 0; 714 sc->sc_flags &= ~SC_OP_RXFLUSH;
710 spin_unlock_bh(&sc->sc_rxflushlock); 715 spin_unlock_bh(&sc->sc_rxflushlock);
711} 716}
712 717
@@ -719,7 +724,7 @@ int ath_rx_input(struct ath_softc *sc,
719 struct ath_recv_status *rx_status, 724 struct ath_recv_status *rx_status,
720 enum ATH_RX_TYPE *status) 725 enum ATH_RX_TYPE *status)
721{ 726{
722 if (is_ampdu && sc->sc_rxaggr) { 727 if (is_ampdu && (sc->sc_flags & SC_OP_RXAGGR)) {
723 *status = ATH_RX_CONSUMED; 728 *status = ATH_RX_CONSUMED;
724 return ath_ampdu_input(sc, an, skb, rx_status); 729 return ath_ampdu_input(sc, an, skb, rx_status);
725 } else { 730 } else {
@@ -750,7 +755,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
750 755
751 do { 756 do {
752 /* If handling rx interrupt and flush is in progress => exit */ 757 /* If handling rx interrupt and flush is in progress => exit */
753 if (sc->sc_rxflush && (flush == 0)) 758 if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
754 break; 759 break;
755 760
756 spin_lock_bh(&sc->sc_rxbuflock); 761 spin_lock_bh(&sc->sc_rxbuflock);
@@ -900,7 +905,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
900 * Enable this if you want to see 905 * Enable this if you want to see
901 * error frames in Monitor mode. 906 * error frames in Monitor mode.
902 */ 907 */
903 if (sc->sc_opmode != ATH9K_M_MONITOR) 908 if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR)
904 goto rx_next; 909 goto rx_next;
905#endif 910#endif
906 /* fall thru for monitor mode handling... */ 911 /* fall thru for monitor mode handling... */
@@ -945,7 +950,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
945 * decryption and MIC failures. For monitor mode, 950 * decryption and MIC failures. For monitor mode,
946 * we also ignore the CRC error. 951 * we also ignore the CRC error.
947 */ 952 */
948 if (sc->sc_opmode == ATH9K_M_MONITOR) { 953 if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) {
949 if (ds->ds_rxstat.rs_status & 954 if (ds->ds_rxstat.rs_status &
950 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | 955 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
951 ATH9K_RXERR_CRC)) 956 ATH9K_RXERR_CRC))
@@ -1089,7 +1094,7 @@ rx_next:
1089 "%s: Reset rx chain mask. " 1094 "%s: Reset rx chain mask. "
1090 "Do internal reset\n", __func__); 1095 "Do internal reset\n", __func__);
1091 ASSERT(flush == 0); 1096 ASSERT(flush == 0);
1092 ath_internal_reset(sc); 1097 ath_reset(sc, false);
1093 } 1098 }
1094 1099
1095 return 0; 1100 return 0;
@@ -1127,7 +1132,7 @@ int ath_rx_aggr_start(struct ath_softc *sc,
1127 rxtid = &an->an_aggr.rx.tid[tid]; 1132 rxtid = &an->an_aggr.rx.tid[tid];
1128 1133
1129 spin_lock_bh(&rxtid->tidlock); 1134 spin_lock_bh(&rxtid->tidlock);
1130 if (sc->sc_rxaggr) { 1135 if (sc->sc_flags & SC_OP_RXAGGR) {
1131 /* Allow aggregation reception 1136 /* Allow aggregation reception
1132 * Adjust rx BA window size. Peer might indicate a 1137 * Adjust rx BA window size. Peer might indicate a
1133 * zero buffer size for a _dont_care_ condition. 1138 * zero buffer size for a _dont_care_ condition.
@@ -1227,7 +1232,7 @@ void ath_rx_aggr_teardown(struct ath_softc *sc,
1227 1232
1228void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an) 1233void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
1229{ 1234{
1230 if (sc->sc_rxaggr) { 1235 if (sc->sc_flags & SC_OP_RXAGGR) {
1231 struct ath_arx_tid *rxtid; 1236 struct ath_arx_tid *rxtid;
1232 int tidno; 1237 int tidno;
1233 1238
@@ -1259,7 +1264,7 @@ void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
1259 1264
1260void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an) 1265void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
1261{ 1266{
1262 if (sc->sc_rxaggr) { 1267 if (sc->sc_flags & SC_OP_RXAGGR) {
1263 struct ath_arx_tid *rxtid; 1268 struct ath_arx_tid *rxtid;
1264 int tidno, i; 1269 int tidno, i;
1265 1270
@@ -1292,27 +1297,3 @@ void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an)
1292{ 1297{
1293 ath_rx_node_cleanup(sc, an); 1298 ath_rx_node_cleanup(sc, an);
1294} 1299}
1295
1296dma_addr_t ath_skb_map_single(struct ath_softc *sc,
1297 struct sk_buff *skb,
1298 int direction,
1299 dma_addr_t *pa)
1300{
1301 /*
1302 * NB: do NOT use skb->len, which is 0 on initialization.
1303 * Use skb's entire data area instead.
1304 */
1305 *pa = pci_map_single(sc->pdev, skb->data,
1306 skb_end_pointer(skb) - skb->head, direction);
1307 return *pa;
1308}
1309
1310void ath_skb_unmap_single(struct ath_softc *sc,
1311 struct sk_buff *skb,
1312 int direction,
1313 dma_addr_t *pa)
1314{
1315 /* Unmap skb's entire data area */
1316 pci_unmap_single(sc->pdev, *pa,
1317 skb_end_pointer(skb) - skb->head, direction);
1318}
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
index 42b0890a4685..60617ae66209 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -899,12 +899,6 @@ enum {
899#define AR_GPIO_OUTPUT_MUX2 0x4064 899#define AR_GPIO_OUTPUT_MUX2 0x4064
900#define AR_GPIO_OUTPUT_MUX3 0x4068 900#define AR_GPIO_OUTPUT_MUX3 0x4068
901 901
902#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
903#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
904#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
905#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
906#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
907
908#define AR_INPUT_STATE 0x406c 902#define AR_INPUT_STATE 0x406c
909 903
910#define AR_EEPROM_STATUS_DATA 0x407c 904#define AR_EEPROM_STATUS_DATA 0x407c
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 157f830ee6b8..3fc6641e8bf7 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -60,79 +60,6 @@ static u32 bits_per_symbol[][2] = {
60#define IS_HT_RATE(_rate) ((_rate) & 0x80) 60#define IS_HT_RATE(_rate) ((_rate) & 0x80)
61 61
62/* 62/*
63 * Insert a chain of ath_buf (descriptors) on a multicast txq
64 * but do NOT start tx DMA on this queue.
65 * NB: must be called with txq lock held
66 */
67
68static void ath_tx_mcastqaddbuf(struct ath_softc *sc,
69 struct ath_txq *txq,
70 struct list_head *head)
71{
72 struct ath_hal *ah = sc->sc_ah;
73 struct ath_buf *bf;
74
75 if (list_empty(head))
76 return;
77
78 /*
79 * Insert the frame on the outbound list and
80 * pass it on to the hardware.
81 */
82 bf = list_first_entry(head, struct ath_buf, list);
83
84 /*
85 * The CAB queue is started from the SWBA handler since
86 * frames only go out on DTIM and to avoid possible races.
87 */
88 ath9k_hw_set_interrupts(ah, 0);
89
90 /*
91 * If there is anything in the mcastq, we want to set
92 * the "more data" bit in the last item in the queue to
93 * indicate that there is "more data". It makes sense to add
94 * it here since you are *always* going to have
95 * more data when adding to this queue, no matter where
96 * you call from.
97 */
98
99 if (txq->axq_depth) {
100 struct ath_buf *lbf;
101 struct ieee80211_hdr *hdr;
102
103 /*
104 * Add the "more data flag" to the last frame
105 */
106
107 lbf = list_entry(txq->axq_q.prev, struct ath_buf, list);
108 hdr = (struct ieee80211_hdr *)
109 ((struct sk_buff *)(lbf->bf_mpdu))->data;
110 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
111 }
112
113 /*
114 * Now, concat the frame onto the queue
115 */
116 list_splice_tail_init(head, &txq->axq_q);
117 txq->axq_depth++;
118 txq->axq_totalqueued++;
119 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
120
121 DPRINTF(sc, ATH_DBG_QUEUE,
122 "%s: txq depth = %d\n", __func__, txq->axq_depth);
123 if (txq->axq_link != NULL) {
124 *txq->axq_link = bf->bf_daddr;
125 DPRINTF(sc, ATH_DBG_XMIT,
126 "%s: link[%u](%p)=%llx (%p)\n",
127 __func__,
128 txq->axq_qnum, txq->axq_link,
129 ito64(bf->bf_daddr), bf->bf_desc);
130 }
131 txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
132 ath9k_hw_set_interrupts(ah, sc->sc_imask);
133}
134
135/*
136 * Insert a chain of ath_buf (descriptors) on a txq and 63 * Insert a chain of ath_buf (descriptors) on a txq and
137 * assume the descriptors are already chained together by caller. 64 * assume the descriptors are already chained together by caller.
138 * NB: must be called with txq lock held 65 * NB: must be called with txq lock held
@@ -277,8 +204,6 @@ static int ath_tx_prepare(struct ath_softc *sc,
277 __le16 fc; 204 __le16 fc;
278 u8 *qc; 205 u8 *qc;
279 206
280 memset(txctl, 0, sizeof(struct ath_tx_control));
281
282 txctl->dev = sc; 207 txctl->dev = sc;
283 hdr = (struct ieee80211_hdr *)skb->data; 208 hdr = (struct ieee80211_hdr *)skb->data;
284 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 209 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -302,7 +227,6 @@ static int ath_tx_prepare(struct ath_softc *sc,
302 } 227 }
303 228
304 txctl->if_id = 0; 229 txctl->if_id = 0;
305 txctl->nextfraglen = 0;
306 txctl->frmlen = skb->len + FCS_LEN - (hdrlen & 3); 230 txctl->frmlen = skb->len + FCS_LEN - (hdrlen & 3);
307 txctl->txpower = MAX_RATE_POWER; /* FIXME */ 231 txctl->txpower = MAX_RATE_POWER; /* FIXME */
308 232
@@ -329,12 +253,18 @@ static int ath_tx_prepare(struct ath_softc *sc,
329 253
330 /* Fill qnum */ 254 /* Fill qnum */
331 255
332 txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); 256 if (unlikely(txctl->flags & ATH9K_TXDESC_CAB)) {
333 txq = &sc->sc_txq[txctl->qnum]; 257 txctl->qnum = 0;
258 txq = sc->sc_cabq;
259 } else {
260 txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
261 txq = &sc->sc_txq[txctl->qnum];
262 }
334 spin_lock_bh(&txq->axq_lock); 263 spin_lock_bh(&txq->axq_lock);
335 264
336 /* Try to avoid running out of descriptors */ 265 /* Try to avoid running out of descriptors */
337 if (txq->axq_depth >= (ATH_TXBUF - 20)) { 266 if (txq->axq_depth >= (ATH_TXBUF - 20) &&
267 !(txctl->flags & ATH9K_TXDESC_CAB)) {
338 DPRINTF(sc, ATH_DBG_FATAL, 268 DPRINTF(sc, ATH_DBG_FATAL,
339 "%s: TX queue: %d is full, depth: %d\n", 269 "%s: TX queue: %d is full, depth: %d\n",
340 __func__, 270 __func__,
@@ -354,12 +284,12 @@ static int ath_tx_prepare(struct ath_softc *sc,
354 284
355 /* Fill flags */ 285 /* Fill flags */
356 286
357 txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ 287 txctl->flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
358 288
359 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) 289 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
360 tx_info->flags |= ATH9K_TXDESC_NOACK; 290 txctl->flags |= ATH9K_TXDESC_NOACK;
361 if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) 291 if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
362 tx_info->flags |= ATH9K_TXDESC_RTSENA; 292 txctl->flags |= ATH9K_TXDESC_RTSENA;
363 293
364 /* 294 /*
365 * Setup for rate calculations. 295 * Setup for rate calculations.
@@ -392,7 +322,7 @@ static int ath_tx_prepare(struct ath_softc *sc,
392 * incremented by the fragmentation routine. 322 * incremented by the fragmentation routine.
393 */ 323 */
394 if (likely(!(txctl->flags & ATH9K_TXDESC_FRAG_IS_ON)) && 324 if (likely(!(txctl->flags & ATH9K_TXDESC_FRAG_IS_ON)) &&
395 txctl->ht && sc->sc_txaggr) { 325 txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
396 struct ath_atx_tid *tid; 326 struct ath_atx_tid *tid;
397 327
398 tid = ATH_AN_2_TID(txctl->an, txctl->tidno); 328 tid = ATH_AN_2_TID(txctl->an, txctl->tidno);
@@ -413,50 +343,18 @@ static int ath_tx_prepare(struct ath_softc *sc,
413 } 343 }
414 rix = rcs[0].rix; 344 rix = rcs[0].rix;
415 345
416 /* 346 if (ieee80211_has_morefrags(fc) ||
417 * Calculate duration. This logically belongs in the 802.11 347 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
418 * layer but it lacks sufficient information to calculate it.
419 */
420 if ((txctl->flags & ATH9K_TXDESC_NOACK) == 0 && !ieee80211_is_ctl(fc)) {
421 u16 dur;
422 /* 348 /*
423 * XXX not right with fragmentation. 349 ** Force hardware to use computed duration for next
424 */ 350 ** fragment by disabling multi-rate retry, which
425 if (sc->sc_flags & ATH_PREAMBLE_SHORT) 351 ** updates duration based on the multi-rate
426 dur = rt->info[rix].spAckDuration; 352 ** duration table.
427 else 353 */
428 dur = rt->info[rix].lpAckDuration; 354 rcs[1].tries = rcs[2].tries = rcs[3].tries = 0;
429 355 rcs[1].rix = rcs[2].rix = rcs[3].rix = 0;
430 if (le16_to_cpu(hdr->frame_control) & 356 /* reset tries but keep rate index */
431 IEEE80211_FCTL_MOREFRAGS) { 357 rcs[0].tries = ATH_TXMAXTRY;
432 dur += dur; /* Add additional 'SIFS + ACK' */
433
434 /*
435 ** Compute size of next fragment in order to compute
436 ** durations needed to update NAV.
437 ** The last fragment uses the ACK duration only.
438 ** Add time for next fragment.
439 */
440 dur += ath9k_hw_computetxtime(sc->sc_ah, rt,
441 txctl->nextfraglen,
442 rix, sc->sc_flags & ATH_PREAMBLE_SHORT);
443 }
444
445 if (ieee80211_has_morefrags(fc) ||
446 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
447 /*
448 ** Force hardware to use computed duration for next
449 ** fragment by disabling multi-rate retry, which
450 ** updates duration based on the multi-rate
451 ** duration table.
452 */
453 rcs[1].tries = rcs[2].tries = rcs[3].tries = 0;
454 rcs[1].rix = rcs[2].rix = rcs[3].rix = 0;
455 /* reset tries but keep rate index */
456 rcs[0].tries = ATH_TXMAXTRY;
457 }
458
459 hdr->duration_id = cpu_to_le16(dur);
460 } 358 }
461 359
462 /* 360 /*
@@ -484,12 +382,8 @@ static int ath_tx_prepare(struct ath_softc *sc,
484 if (is_multicast_ether_addr(hdr->addr1)) { 382 if (is_multicast_ether_addr(hdr->addr1)) {
485 antenna = sc->sc_mcastantenna + 1; 383 antenna = sc->sc_mcastantenna + 1;
486 sc->sc_mcastantenna = (sc->sc_mcastantenna + 1) & 0x1; 384 sc->sc_mcastantenna = (sc->sc_mcastantenna + 1) & 0x1;
487 } else 385 }
488 antenna = sc->sc_txantenna;
489 386
490#ifdef USE_LEGACY_HAL
491 txctl->antenna = antenna;
492#endif
493 return 0; 387 return 0;
494} 388}
495 389
@@ -502,7 +396,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
502{ 396{
503 struct sk_buff *skb = bf->bf_mpdu; 397 struct sk_buff *skb = bf->bf_mpdu;
504 struct ath_xmit_status tx_status; 398 struct ath_xmit_status tx_status;
505 dma_addr_t *pa;
506 399
507 /* 400 /*
508 * Set retry information. 401 * Set retry information.
@@ -518,13 +411,12 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
518 if (!txok) { 411 if (!txok) {
519 tx_status.flags |= ATH_TX_ERROR; 412 tx_status.flags |= ATH_TX_ERROR;
520 413
521 if (bf->bf_isxretried) 414 if (bf_isxretried(bf))
522 tx_status.flags |= ATH_TX_XRETRY; 415 tx_status.flags |= ATH_TX_XRETRY;
523 } 416 }
524 /* Unmap this frame */ 417 /* Unmap this frame */
525 pa = get_dma_mem_context(bf, bf_dmacontext);
526 pci_unmap_single(sc->pdev, 418 pci_unmap_single(sc->pdev,
527 *pa, 419 bf->bf_dmacontext,
528 skb->len, 420 skb->len,
529 PCI_DMA_TODEVICE); 421 PCI_DMA_TODEVICE);
530 /* complete this frame */ 422 /* complete this frame */
@@ -629,7 +521,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc,
629 if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) 521 if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
630 return 0; 522 return 0;
631 523
632 isaggr = bf->bf_isaggr; 524 isaggr = bf_isaggr(bf);
633 if (isaggr) { 525 if (isaggr) {
634 seq_st = ATH_DS_BA_SEQ(ds); 526 seq_st = ATH_DS_BA_SEQ(ds);
635 memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); 527 memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
@@ -651,7 +543,7 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
651 struct sk_buff *skb; 543 struct sk_buff *skb;
652 struct ieee80211_hdr *hdr; 544 struct ieee80211_hdr *hdr;
653 545
654 bf->bf_isretried = 1; 546 bf->bf_state.bf_type |= BUF_RETRY;
655 bf->bf_retries++; 547 bf->bf_retries++;
656 548
657 skb = bf->bf_mpdu; 549 skb = bf->bf_mpdu;
@@ -698,7 +590,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc,
698 u8 rc; 590 u8 rc;
699 int streams, pktlen; 591 int streams, pktlen;
700 592
701 pktlen = bf->bf_isaggr ? bf->bf_al : bf->bf_frmlen; 593 pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
702 rc = rt->info[rix].rateCode; 594 rc = rt->info[rix].rateCode;
703 595
704 /* 596 /*
@@ -742,7 +634,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
742 int i, flags, rtsctsena = 0, dynamic_mimops = 0; 634 int i, flags, rtsctsena = 0, dynamic_mimops = 0;
743 u32 ctsduration = 0; 635 u32 ctsduration = 0;
744 u8 rix = 0, cix, ctsrate = 0; 636 u8 rix = 0, cix, ctsrate = 0;
745 u32 aggr_limit_with_rts = sc->sc_rtsaggrlimit; 637 u32 aggr_limit_with_rts = ah->ah_caps.rts_aggr_limit;
746 struct ath_node *an = (struct ath_node *) bf->bf_node; 638 struct ath_node *an = (struct ath_node *) bf->bf_node;
747 639
748 /* 640 /*
@@ -781,7 +673,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
781 * let rate series flags determine which rates will actually 673 * let rate series flags determine which rates will actually
782 * use RTS. 674 * use RTS.
783 */ 675 */
784 if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf->bf_isdata) { 676 if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) {
785 BUG_ON(!an); 677 BUG_ON(!an);
786 /* 678 /*
787 * 802.11g protection not needed, use our default behavior 679 * 802.11g protection not needed, use our default behavior
@@ -793,7 +685,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
793 * and the second aggregate should have any protection at all. 685 * and the second aggregate should have any protection at all.
794 */ 686 */
795 if (an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) { 687 if (an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) {
796 if (!bf->bf_aggrburst) { 688 if (!bf_isaggrburst(bf)) {
797 flags = ATH9K_TXDESC_RTSENA; 689 flags = ATH9K_TXDESC_RTSENA;
798 dynamic_mimops = 1; 690 dynamic_mimops = 1;
799 } else { 691 } else {
@@ -806,7 +698,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
806 * Set protection if aggregate protection on 698 * Set protection if aggregate protection on
807 */ 699 */
808 if (sc->sc_config.ath_aggr_prot && 700 if (sc->sc_config.ath_aggr_prot &&
809 (!bf->bf_isaggr || (bf->bf_isaggr && bf->bf_al < 8192))) { 701 (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
810 flags = ATH9K_TXDESC_RTSENA; 702 flags = ATH9K_TXDESC_RTSENA;
811 cix = rt->info[sc->sc_protrix].controlRate; 703 cix = rt->info[sc->sc_protrix].controlRate;
812 rtsctsena = 1; 704 rtsctsena = 1;
@@ -815,7 +707,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
815 /* 707 /*
816 * For AR5416 - RTS cannot be followed by a frame larger than 8K. 708 * For AR5416 - RTS cannot be followed by a frame larger than 8K.
817 */ 709 */
818 if (bf->bf_isaggr && (bf->bf_al > aggr_limit_with_rts)) { 710 if (bf_isaggr(bf) && (bf->bf_al > aggr_limit_with_rts)) {
819 /* 711 /*
820 * Ensure that in the case of SM Dynamic power save 712 * Ensure that in the case of SM Dynamic power save
821 * while we are bursting the second aggregate the 713 * while we are bursting the second aggregate the
@@ -832,7 +724,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
832 /* NB: cix is set above where RTS/CTS is enabled */ 724 /* NB: cix is set above where RTS/CTS is enabled */
833 BUG_ON(cix == 0xff); 725 BUG_ON(cix == 0xff);
834 ctsrate = rt->info[cix].rateCode | 726 ctsrate = rt->info[cix].rateCode |
835 (bf->bf_shpreamble ? rt->info[cix].shortPreamble : 0); 727 (bf_isshpreamble(bf) ? rt->info[cix].shortPreamble : 0);
836 728
837 /* 729 /*
838 * Setup HAL rate series 730 * Setup HAL rate series
@@ -846,7 +738,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
846 rix = bf->bf_rcs[i].rix; 738 rix = bf->bf_rcs[i].rix;
847 739
848 series[i].Rate = rt->info[rix].rateCode | 740 series[i].Rate = rt->info[rix].rateCode |
849 (bf->bf_shpreamble ? rt->info[rix].shortPreamble : 0); 741 (bf_isshpreamble(bf) ? rt->info[rix].shortPreamble : 0);
850 742
851 series[i].Tries = bf->bf_rcs[i].tries; 743 series[i].Tries = bf->bf_rcs[i].tries;
852 744
@@ -862,7 +754,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
862 sc, rix, bf, 754 sc, rix, bf,
863 (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0, 755 (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0,
864 (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG), 756 (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG),
865 bf->bf_shpreamble); 757 bf_isshpreamble(bf));
866 758
867 if ((an->an_smmode == ATH_SM_PWRSAV_STATIC) && 759 if ((an->an_smmode == ATH_SM_PWRSAV_STATIC) &&
868 (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG) == 0) { 760 (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG) == 0) {
@@ -875,7 +767,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
875 */ 767 */
876 series[i].ChSel = sc->sc_tx_chainmask; 768 series[i].ChSel = sc->sc_tx_chainmask;
877 } else { 769 } else {
878 if (bf->bf_ht) 770 if (bf_isht(bf))
879 series[i].ChSel = 771 series[i].ChSel =
880 ath_chainmask_sel_logic(sc, an); 772 ath_chainmask_sel_logic(sc, an);
881 else 773 else
@@ -908,7 +800,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
908 * use the precalculated ACK durations. 800 * use the precalculated ACK durations.
909 */ 801 */
910 if (flags & ATH9K_TXDESC_RTSENA) { /* SIFS + CTS */ 802 if (flags & ATH9K_TXDESC_RTSENA) { /* SIFS + CTS */
911 ctsduration += bf->bf_shpreamble ? 803 ctsduration += bf_isshpreamble(bf) ?
912 rt->info[cix].spAckDuration : 804 rt->info[cix].spAckDuration :
913 rt->info[cix].lpAckDuration; 805 rt->info[cix].lpAckDuration;
914 } 806 }
@@ -916,7 +808,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
916 ctsduration += series[0].PktDuration; 808 ctsduration += series[0].PktDuration;
917 809
918 if ((bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { /* SIFS + ACK */ 810 if ((bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { /* SIFS + ACK */
919 ctsduration += bf->bf_shpreamble ? 811 ctsduration += bf_isshpreamble(bf) ?
920 rt->info[rix].spAckDuration : 812 rt->info[rix].spAckDuration :
921 rt->info[rix].lpAckDuration; 813 rt->info[rix].lpAckDuration;
922 } 814 }
@@ -932,10 +824,10 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
932 * set dur_update_en for l-sig computation except for PS-Poll frames 824 * set dur_update_en for l-sig computation except for PS-Poll frames
933 */ 825 */
934 ath9k_hw_set11n_ratescenario(ah, ds, lastds, 826 ath9k_hw_set11n_ratescenario(ah, ds, lastds,
935 !bf->bf_ispspoll, 827 !bf_ispspoll(bf),
936 ctsrate, 828 ctsrate,
937 ctsduration, 829 ctsduration,
938 series, 4, flags); 830 series, 4, flags);
939 if (sc->sc_config.ath_aggr_prot && flags) 831 if (sc->sc_config.ath_aggr_prot && flags)
940 ath9k_hw_set11n_burstduration(ah, ds, 8192); 832 ath9k_hw_set11n_burstduration(ah, ds, 8192);
941} 833}
@@ -958,7 +850,7 @@ static int ath_tx_send_normal(struct ath_softc *sc,
958 BUG_ON(list_empty(bf_head)); 850 BUG_ON(list_empty(bf_head));
959 851
960 bf = list_first_entry(bf_head, struct ath_buf, list); 852 bf = list_first_entry(bf_head, struct ath_buf, list);
961 bf->bf_isampdu = 0; /* regular HT frame */ 853 bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */
962 854
963 skb = (struct sk_buff *)bf->bf_mpdu; 855 skb = (struct sk_buff *)bf->bf_mpdu;
964 tx_info = IEEE80211_SKB_CB(skb); 856 tx_info = IEEE80211_SKB_CB(skb);
@@ -998,7 +890,7 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
998 890
999 while (!list_empty(&tid->buf_q)) { 891 while (!list_empty(&tid->buf_q)) {
1000 bf = list_first_entry(&tid->buf_q, struct ath_buf, list); 892 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
1001 ASSERT(!bf->bf_isretried); 893 ASSERT(!bf_isretried(bf));
1002 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list); 894 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1003 ath_tx_send_normal(sc, txq, tid, &bf_head); 895 ath_tx_send_normal(sc, txq, tid, &bf_head);
1004 } 896 }
@@ -1025,7 +917,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1025 int isaggr, txfail, txpending, sendbar = 0, needreset = 0; 917 int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
1026 int isnodegone = (an->an_flags & ATH_NODE_CLEAN); 918 int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
1027 919
1028 isaggr = bf->bf_isaggr; 920 isaggr = bf_isaggr(bf);
1029 if (isaggr) { 921 if (isaggr) {
1030 if (txok) { 922 if (txok) {
1031 if (ATH_DS_TX_BA(ds)) { 923 if (ATH_DS_TX_BA(ds)) {
@@ -1047,7 +939,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1047 * when perform internal reset in this routine. 939 * when perform internal reset in this routine.
1048 * Only enable reset in STA mode for now. 940 * Only enable reset in STA mode for now.
1049 */ 941 */
1050 if (sc->sc_opmode == ATH9K_M_STA) 942 if (sc->sc_ah->ah_opmode == ATH9K_M_STA)
1051 needreset = 1; 943 needreset = 1;
1052 } 944 }
1053 } else { 945 } else {
@@ -1075,7 +967,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1075 ath_tx_set_retry(sc, bf); 967 ath_tx_set_retry(sc, bf);
1076 txpending = 1; 968 txpending = 1;
1077 } else { 969 } else {
1078 bf->bf_isxretried = 1; 970 bf->bf_state.bf_type |= BUF_XRETRY;
1079 txfail = 1; 971 txfail = 1;
1080 sendbar = 1; 972 sendbar = 1;
1081 } 973 }
@@ -1175,11 +1067,8 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1175 tbf->bf_lastfrm->bf_desc); 1067 tbf->bf_lastfrm->bf_desc);
1176 1068
1177 /* copy the DMA context */ 1069 /* copy the DMA context */
1178 copy_dma_mem_context( 1070 tbf->bf_dmacontext =
1179 get_dma_mem_context(tbf, 1071 bf_last->bf_dmacontext;
1180 bf_dmacontext),
1181 get_dma_mem_context(bf_last,
1182 bf_dmacontext));
1183 } 1072 }
1184 list_add_tail(&tbf->list, &bf_head); 1073 list_add_tail(&tbf->list, &bf_head);
1185 } else { 1074 } else {
@@ -1188,7 +1077,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1188 * software retry 1077 * software retry
1189 */ 1078 */
1190 ath9k_hw_cleartxdesc(sc->sc_ah, 1079 ath9k_hw_cleartxdesc(sc->sc_ah,
1191 bf->bf_lastfrm->bf_desc); 1080 bf->bf_lastfrm->bf_desc);
1192 } 1081 }
1193 1082
1194 /* 1083 /*
@@ -1242,7 +1131,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1242 } 1131 }
1243 1132
1244 if (needreset) 1133 if (needreset)
1245 ath_internal_reset(sc); 1134 ath_reset(sc, false);
1246 1135
1247 return; 1136 return;
1248} 1137}
@@ -1331,7 +1220,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1331 1220
1332 txq->axq_depth--; 1221 txq->axq_depth--;
1333 1222
1334 if (bf->bf_isaggr) 1223 if (bf_isaggr(bf))
1335 txq->axq_aggr_depth--; 1224 txq->axq_aggr_depth--;
1336 1225
1337 txok = (ds->ds_txstat.ts_status == 0); 1226 txok = (ds->ds_txstat.ts_status == 0);
@@ -1345,14 +1234,14 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1345 spin_unlock_bh(&sc->sc_txbuflock); 1234 spin_unlock_bh(&sc->sc_txbuflock);
1346 } 1235 }
1347 1236
1348 if (!bf->bf_isampdu) { 1237 if (!bf_isampdu(bf)) {
1349 /* 1238 /*
1350 * This frame is sent out as a single frame. 1239 * This frame is sent out as a single frame.
1351 * Use hardware retry status for this frame. 1240 * Use hardware retry status for this frame.
1352 */ 1241 */
1353 bf->bf_retries = ds->ds_txstat.ts_longretry; 1242 bf->bf_retries = ds->ds_txstat.ts_longretry;
1354 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) 1243 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
1355 bf->bf_isxretried = 1; 1244 bf->bf_state.bf_type |= BUF_XRETRY;
1356 nbad = 0; 1245 nbad = 0;
1357 } else { 1246 } else {
1358 nbad = ath_tx_num_badfrms(sc, bf, txok); 1247 nbad = ath_tx_num_badfrms(sc, bf, txok);
@@ -1368,7 +1257,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1368 if (ds->ds_txstat.ts_status == 0) 1257 if (ds->ds_txstat.ts_status == 0)
1369 nacked++; 1258 nacked++;
1370 1259
1371 if (bf->bf_isdata) { 1260 if (bf_isdata(bf)) {
1372 if (isrifs) 1261 if (isrifs)
1373 tmp_ds = bf->bf_rifslast->bf_desc; 1262 tmp_ds = bf->bf_rifslast->bf_desc;
1374 else 1263 else
@@ -1384,7 +1273,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1384 /* 1273 /*
1385 * Complete this transmit unit 1274 * Complete this transmit unit
1386 */ 1275 */
1387 if (bf->bf_isampdu) 1276 if (bf_isampdu(bf))
1388 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok); 1277 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok);
1389 else 1278 else
1390 ath_tx_complete_buf(sc, bf, &bf_head, txok, 0); 1279 ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
@@ -1406,7 +1295,7 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1406 /* 1295 /*
1407 * schedule any pending packets if aggregation is enabled 1296 * schedule any pending packets if aggregation is enabled
1408 */ 1297 */
1409 if (sc->sc_txaggr) 1298 if (sc->sc_flags & SC_OP_TXAGGR)
1410 ath_txq_schedule(sc, txq); 1299 ath_txq_schedule(sc, txq);
1411 spin_unlock_bh(&txq->axq_lock); 1300 spin_unlock_bh(&txq->axq_lock);
1412 } 1301 }
@@ -1430,10 +1319,9 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
1430 struct ath_hal *ah = sc->sc_ah; 1319 struct ath_hal *ah = sc->sc_ah;
1431 int i; 1320 int i;
1432 int npend = 0; 1321 int npend = 0;
1433 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
1434 1322
1435 /* XXX return value */ 1323 /* XXX return value */
1436 if (!sc->sc_invalid) { 1324 if (!(sc->sc_flags & SC_OP_INVALID)) {
1437 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 1325 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1438 if (ATH_TXQ_SETUP(sc, i)) { 1326 if (ATH_TXQ_SETUP(sc, i)) {
1439 ath_tx_stopdma(sc, &sc->sc_txq[i]); 1327 ath_tx_stopdma(sc, &sc->sc_txq[i]);
@@ -1454,10 +1342,11 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
1454 "%s: Unable to stop TxDMA. Reset HAL!\n", __func__); 1342 "%s: Unable to stop TxDMA. Reset HAL!\n", __func__);
1455 1343
1456 spin_lock_bh(&sc->sc_resetlock); 1344 spin_lock_bh(&sc->sc_resetlock);
1457 if (!ath9k_hw_reset(ah, sc->sc_opmode, 1345 if (!ath9k_hw_reset(ah,
1458 &sc->sc_curchan, ht_macmode, 1346 sc->sc_ah->ah_curchan,
1459 sc->sc_tx_chainmask, sc->sc_rx_chainmask, 1347 sc->sc_ht_info.tx_chan_width,
1460 sc->sc_ht_extprotspacing, true, &status)) { 1348 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
1349 sc->sc_ht_extprotspacing, true, &status)) {
1461 1350
1462 DPRINTF(sc, ATH_DBG_FATAL, 1351 DPRINTF(sc, ATH_DBG_FATAL,
1463 "%s: unable to reset hardware; hal status %u\n", 1352 "%s: unable to reset hardware; hal status %u\n",
@@ -1481,7 +1370,7 @@ static void ath_tx_addto_baw(struct ath_softc *sc,
1481{ 1370{
1482 int index, cindex; 1371 int index, cindex;
1483 1372
1484 if (bf->bf_isretried) 1373 if (bf_isretried(bf))
1485 return; 1374 return;
1486 1375
1487 index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); 1376 index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
@@ -1516,7 +1405,7 @@ static int ath_tx_send_ampdu(struct ath_softc *sc,
1516 BUG_ON(list_empty(bf_head)); 1405 BUG_ON(list_empty(bf_head));
1517 1406
1518 bf = list_first_entry(bf_head, struct ath_buf, list); 1407 bf = list_first_entry(bf_head, struct ath_buf, list);
1519 bf->bf_isampdu = 1; 1408 bf->bf_state.bf_type |= BUF_AMPDU;
1520 bf->bf_seqno = txctl->seqno; /* save seqno and tidno in buffer */ 1409 bf->bf_seqno = txctl->seqno; /* save seqno and tidno in buffer */
1521 bf->bf_tidno = txctl->tidno; 1410 bf->bf_tidno = txctl->tidno;
1522 1411
@@ -1860,7 +1749,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc,
1860 if (bf->bf_nframes == 1) { 1749 if (bf->bf_nframes == 1) {
1861 ASSERT(bf->bf_lastfrm == bf_last); 1750 ASSERT(bf->bf_lastfrm == bf_last);
1862 1751
1863 bf->bf_isaggr = 0; 1752 bf->bf_state.bf_type &= ~BUF_AGGR;
1864 /* 1753 /*
1865 * clear aggr bits for every descriptor 1754 * clear aggr bits for every descriptor
1866 * XXX TODO: is there a way to optimize it? 1755 * XXX TODO: is there a way to optimize it?
@@ -1877,7 +1766,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc,
1877 /* 1766 /*
1878 * setup first desc with rate and aggr info 1767 * setup first desc with rate and aggr info
1879 */ 1768 */
1880 bf->bf_isaggr = 1; 1769 bf->bf_state.bf_type |= BUF_AGGR;
1881 ath_buf_set_rate(sc, bf); 1770 ath_buf_set_rate(sc, bf);
1882 ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al); 1771 ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
1883 1772
@@ -1925,7 +1814,7 @@ static void ath_tid_drain(struct ath_softc *sc,
1925 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list); 1814 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1926 1815
1927 /* update baw for software retried frame */ 1816 /* update baw for software retried frame */
1928 if (bf->bf_isretried) 1817 if (bf_isretried(bf))
1929 ath_tx_update_baw(sc, tid, bf->bf_seqno); 1818 ath_tx_update_baw(sc, tid, bf->bf_seqno);
1930 1819
1931 /* 1820 /*
@@ -1990,13 +1879,18 @@ static int ath_tx_start_dma(struct ath_softc *sc,
1990 struct list_head bf_head; 1879 struct list_head bf_head;
1991 struct ath_desc *ds; 1880 struct ath_desc *ds;
1992 struct ath_hal *ah = sc->sc_ah; 1881 struct ath_hal *ah = sc->sc_ah;
1993 struct ath_txq *txq = &sc->sc_txq[txctl->qnum]; 1882 struct ath_txq *txq;
1994 struct ath_tx_info_priv *tx_info_priv; 1883 struct ath_tx_info_priv *tx_info_priv;
1995 struct ath_rc_series *rcs; 1884 struct ath_rc_series *rcs;
1996 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1885 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1997 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1886 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1998 __le16 fc = hdr->frame_control; 1887 __le16 fc = hdr->frame_control;
1999 1888
1889 if (unlikely(txctl->flags & ATH9K_TXDESC_CAB))
1890 txq = sc->sc_cabq;
1891 else
1892 txq = &sc->sc_txq[txctl->qnum];
1893
2000 /* For each sglist entry, allocate an ath_buf for DMA */ 1894 /* For each sglist entry, allocate an ath_buf for DMA */
2001 INIT_LIST_HEAD(&bf_head); 1895 INIT_LIST_HEAD(&bf_head);
2002 spin_lock_bh(&sc->sc_txbuflock); 1896 spin_lock_bh(&sc->sc_txbuflock);
@@ -2014,11 +1908,21 @@ static int ath_tx_start_dma(struct ath_softc *sc,
2014 /* set up this buffer */ 1908 /* set up this buffer */
2015 ATH_TXBUF_RESET(bf); 1909 ATH_TXBUF_RESET(bf);
2016 bf->bf_frmlen = txctl->frmlen; 1910 bf->bf_frmlen = txctl->frmlen;
2017 bf->bf_isdata = ieee80211_is_data(fc); 1911
2018 bf->bf_isbar = ieee80211_is_back_req(fc); 1912 ieee80211_is_data(fc) ?
2019 bf->bf_ispspoll = ieee80211_is_pspoll(fc); 1913 (bf->bf_state.bf_type |= BUF_DATA) :
1914 (bf->bf_state.bf_type &= ~BUF_DATA);
1915 ieee80211_is_back_req(fc) ?
1916 (bf->bf_state.bf_type |= BUF_BAR) :
1917 (bf->bf_state.bf_type &= ~BUF_BAR);
1918 ieee80211_is_pspoll(fc) ?
1919 (bf->bf_state.bf_type |= BUF_PSPOLL) :
1920 (bf->bf_state.bf_type &= ~BUF_PSPOLL);
1921 (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ?
1922 (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) :
1923 (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE);
1924
2020 bf->bf_flags = txctl->flags; 1925 bf->bf_flags = txctl->flags;
2021 bf->bf_shpreamble = sc->sc_flags & ATH_PREAMBLE_SHORT;
2022 bf->bf_keytype = txctl->keytype; 1926 bf->bf_keytype = txctl->keytype;
2023 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; 1927 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
2024 rcs = tx_info_priv->rcs; 1928 rcs = tx_info_priv->rcs;
@@ -2038,8 +1942,7 @@ static int ath_tx_start_dma(struct ath_softc *sc,
2038 /* 1942 /*
2039 * Save the DMA context in the first ath_buf 1943 * Save the DMA context in the first ath_buf
2040 */ 1944 */
2041 copy_dma_mem_context(get_dma_mem_context(bf, bf_dmacontext), 1945 bf->bf_dmacontext = txctl->dmacontext;
2042 get_dma_mem_context(txctl, dmacontext));
2043 1946
2044 /* 1947 /*
2045 * Formulate first tx descriptor with tx controls. 1948 * Formulate first tx descriptor with tx controls.
@@ -2060,11 +1963,13 @@ static int ath_tx_start_dma(struct ath_softc *sc,
2060 ds); /* first descriptor */ 1963 ds); /* first descriptor */
2061 1964
2062 bf->bf_lastfrm = bf; 1965 bf->bf_lastfrm = bf;
2063 bf->bf_ht = txctl->ht; 1966 (txctl->ht) ?
1967 (bf->bf_state.bf_type |= BUF_HT) :
1968 (bf->bf_state.bf_type &= ~BUF_HT);
2064 1969
2065 spin_lock_bh(&txq->axq_lock); 1970 spin_lock_bh(&txq->axq_lock);
2066 1971
2067 if (txctl->ht && sc->sc_txaggr) { 1972 if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
2068 struct ath_atx_tid *tid = ATH_AN_2_TID(an, txctl->tidno); 1973 struct ath_atx_tid *tid = ATH_AN_2_TID(an, txctl->tidno);
2069 if (ath_aggr_query(sc, an, txctl->tidno)) { 1974 if (ath_aggr_query(sc, an, txctl->tidno)) {
2070 /* 1975 /*
@@ -2090,27 +1995,7 @@ static int ath_tx_start_dma(struct ath_softc *sc,
2090 bf->bf_tidno = txctl->tidno; 1995 bf->bf_tidno = txctl->tidno;
2091 } 1996 }
2092 1997
2093 if (is_multicast_ether_addr(hdr->addr1)) { 1998 ath_tx_txqaddbuf(sc, txq, &bf_head);
2094 struct ath_vap *avp = sc->sc_vaps[txctl->if_id];
2095
2096 /*
2097 * When servicing one or more stations in power-save
2098 * mode (or) if there is some mcast data waiting on
2099 * mcast queue (to prevent out of order delivery of
2100 * mcast,bcast packets) multicast frames must be
2101 * buffered until after the beacon. We use the private
2102 * mcast queue for that.
2103 */
2104 /* XXX? more bit in 802.11 frame header */
2105 spin_lock_bh(&avp->av_mcastq.axq_lock);
2106 if (txctl->ps || avp->av_mcastq.axq_depth)
2107 ath_tx_mcastqaddbuf(sc,
2108 &avp->av_mcastq, &bf_head);
2109 else
2110 ath_tx_txqaddbuf(sc, txq, &bf_head);
2111 spin_unlock_bh(&avp->av_mcastq.axq_lock);
2112 } else
2113 ath_tx_txqaddbuf(sc, txq, &bf_head);
2114 } 1999 }
2115 spin_unlock_bh(&txq->axq_lock); 2000 spin_unlock_bh(&txq->axq_lock);
2116 return 0; 2001 return 0;
@@ -2118,30 +2003,31 @@ static int ath_tx_start_dma(struct ath_softc *sc,
2118 2003
2119static void xmit_map_sg(struct ath_softc *sc, 2004static void xmit_map_sg(struct ath_softc *sc,
2120 struct sk_buff *skb, 2005 struct sk_buff *skb,
2121 dma_addr_t *pa,
2122 struct ath_tx_control *txctl) 2006 struct ath_tx_control *txctl)
2123{ 2007{
2124 struct ath_xmit_status tx_status; 2008 struct ath_xmit_status tx_status;
2125 struct ath_atx_tid *tid; 2009 struct ath_atx_tid *tid;
2126 struct scatterlist sg; 2010 struct scatterlist sg;
2127 2011
2128 *pa = pci_map_single(sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); 2012 txctl->dmacontext = pci_map_single(sc->pdev, skb->data,
2013 skb->len, PCI_DMA_TODEVICE);
2129 2014
2130 /* setup S/G list */ 2015 /* setup S/G list */
2131 memset(&sg, 0, sizeof(struct scatterlist)); 2016 memset(&sg, 0, sizeof(struct scatterlist));
2132 sg_dma_address(&sg) = *pa; 2017 sg_dma_address(&sg) = txctl->dmacontext;
2133 sg_dma_len(&sg) = skb->len; 2018 sg_dma_len(&sg) = skb->len;
2134 2019
2135 if (ath_tx_start_dma(sc, skb, &sg, 1, txctl) != 0) { 2020 if (ath_tx_start_dma(sc, skb, &sg, 1, txctl) != 0) {
2136 /* 2021 /*
2137 * We have to do drop frame here. 2022 * We have to do drop frame here.
2138 */ 2023 */
2139 pci_unmap_single(sc->pdev, *pa, skb->len, PCI_DMA_TODEVICE); 2024 pci_unmap_single(sc->pdev, txctl->dmacontext,
2025 skb->len, PCI_DMA_TODEVICE);
2140 2026
2141 tx_status.retries = 0; 2027 tx_status.retries = 0;
2142 tx_status.flags = ATH_TX_ERROR; 2028 tx_status.flags = ATH_TX_ERROR;
2143 2029
2144 if (txctl->ht && sc->sc_txaggr) { 2030 if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
2145 /* Reclaim the seqno. */ 2031 /* Reclaim the seqno. */
2146 tid = ATH_AN_2_TID((struct ath_node *) 2032 tid = ATH_AN_2_TID((struct ath_node *)
2147 txctl->an, txctl->tidno); 2033 txctl->an, txctl->tidno);
@@ -2162,7 +2048,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
2162 2048
2163 /* Setup tx descriptors */ 2049 /* Setup tx descriptors */
2164 error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf, 2050 error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
2165 "tx", nbufs * ATH_FRAG_PER_MSDU, ATH_TXDESC); 2051 "tx", nbufs, 1);
2166 if (error != 0) { 2052 if (error != 0) {
2167 DPRINTF(sc, ATH_DBG_FATAL, 2053 DPRINTF(sc, ATH_DBG_FATAL,
2168 "%s: failed to allocate tx descriptors: %d\n", 2054 "%s: failed to allocate tx descriptors: %d\n",
@@ -2403,6 +2289,7 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb)
2403 struct ath_tx_control txctl; 2289 struct ath_tx_control txctl;
2404 int error = 0; 2290 int error = 0;
2405 2291
2292 memset(&txctl, 0, sizeof(struct ath_tx_control));
2406 error = ath_tx_prepare(sc, skb, &txctl); 2293 error = ath_tx_prepare(sc, skb, &txctl);
2407 if (error == 0) 2294 if (error == 0)
2408 /* 2295 /*
@@ -2410,9 +2297,7 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb)
2410 * ath_tx_start_dma() will be called either synchronously 2297 * ath_tx_start_dma() will be called either synchronously
2411 * or asynchrounsly once DMA is complete. 2298 * or asynchrounsly once DMA is complete.
2412 */ 2299 */
2413 xmit_map_sg(sc, skb, 2300 xmit_map_sg(sc, skb, &txctl);
2414 get_dma_mem_context(&txctl, dmacontext),
2415 &txctl);
2416 else 2301 else
2417 ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE); 2302 ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);
2418 2303
@@ -2424,8 +2309,7 @@ int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb)
2424 2309
2425void ath_tx_tasklet(struct ath_softc *sc) 2310void ath_tx_tasklet(struct ath_softc *sc)
2426{ 2311{
2427 u64 tsf = ath9k_hw_gettsf64(sc->sc_ah); 2312 int i;
2428 int i, nacked = 0;
2429 u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); 2313 u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
2430 2314
2431 ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); 2315 ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
@@ -2435,10 +2319,8 @@ void ath_tx_tasklet(struct ath_softc *sc)
2435 */ 2319 */
2436 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 2320 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2437 if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) 2321 if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
2438 nacked += ath_tx_processq(sc, &sc->sc_txq[i]); 2322 ath_tx_processq(sc, &sc->sc_txq[i]);
2439 } 2323 }
2440 if (nacked)
2441 sc->sc_lastrx = tsf;
2442} 2324}
2443 2325
2444void ath_tx_draintxq(struct ath_softc *sc, 2326void ath_tx_draintxq(struct ath_softc *sc,
@@ -2486,14 +2368,14 @@ void ath_tx_draintxq(struct ath_softc *sc,
2486 2368
2487 spin_unlock_bh(&txq->axq_lock); 2369 spin_unlock_bh(&txq->axq_lock);
2488 2370
2489 if (bf->bf_isampdu) 2371 if (bf_isampdu(bf))
2490 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0); 2372 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0);
2491 else 2373 else
2492 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 2374 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
2493 } 2375 }
2494 2376
2495 /* flush any pending frames if aggregation is enabled */ 2377 /* flush any pending frames if aggregation is enabled */
2496 if (sc->sc_txaggr) { 2378 if (sc->sc_flags & SC_OP_TXAGGR) {
2497 if (!retry_tx) { 2379 if (!retry_tx) {
2498 spin_lock_bh(&txq->axq_lock); 2380 spin_lock_bh(&txq->axq_lock);
2499 ath_txq_drain_pending_buffers(sc, txq, 2381 ath_txq_drain_pending_buffers(sc, txq,
@@ -2509,7 +2391,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx)
2509{ 2391{
2510 /* stop beacon queue. The beacon will be freed when 2392 /* stop beacon queue. The beacon will be freed when
2511 * we go to INIT state */ 2393 * we go to INIT state */
2512 if (!sc->sc_invalid) { 2394 if (!(sc->sc_flags & SC_OP_INVALID)) {
2513 (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); 2395 (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
2514 DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__, 2396 DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__,
2515 ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq)); 2397 ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq));
@@ -2536,7 +2418,7 @@ enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
2536 struct ath_atx_tid *txtid; 2418 struct ath_atx_tid *txtid;
2537 DECLARE_MAC_BUF(mac); 2419 DECLARE_MAC_BUF(mac);
2538 2420
2539 if (!sc->sc_txaggr) 2421 if (!(sc->sc_flags & SC_OP_TXAGGR))
2540 return AGGR_NOT_REQUIRED; 2422 return AGGR_NOT_REQUIRED;
2541 2423
2542 /* ADDBA exchange must be completed before sending aggregates */ 2424 /* ADDBA exchange must be completed before sending aggregates */
@@ -2583,7 +2465,7 @@ int ath_tx_aggr_start(struct ath_softc *sc,
2583 return -1; 2465 return -1;
2584 } 2466 }
2585 2467
2586 if (sc->sc_txaggr) { 2468 if (sc->sc_flags & SC_OP_TXAGGR) {
2587 txtid = ATH_AN_2_TID(an, tid); 2469 txtid = ATH_AN_2_TID(an, tid);
2588 txtid->addba_exchangeinprogress = 1; 2470 txtid->addba_exchangeinprogress = 1;
2589 ath_tx_pause_tid(sc, txtid); 2471 ath_tx_pause_tid(sc, txtid);
@@ -2647,7 +2529,7 @@ void ath_tx_aggr_teardown(struct ath_softc *sc,
2647 spin_lock_bh(&txq->axq_lock); 2529 spin_lock_bh(&txq->axq_lock);
2648 while (!list_empty(&txtid->buf_q)) { 2530 while (!list_empty(&txtid->buf_q)) {
2649 bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); 2531 bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
2650 if (!bf->bf_isretried) { 2532 if (!bf_isretried(bf)) {
2651 /* 2533 /*
2652 * NB: it's based on the assumption that 2534 * NB: it's based on the assumption that
2653 * software retried frame will always stay 2535 * software retried frame will always stay
@@ -2743,7 +2625,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
2743 2625
2744void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) 2626void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2745{ 2627{
2746 if (sc->sc_txaggr) { 2628 if (sc->sc_flags & SC_OP_TXAGGR) {
2747 struct ath_atx_tid *tid; 2629 struct ath_atx_tid *tid;
2748 struct ath_atx_ac *ac; 2630 struct ath_atx_ac *ac;
2749 int tidno, acno; 2631 int tidno, acno;
@@ -2855,7 +2737,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc,
2855 2737
2856void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an) 2738void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an)
2857{ 2739{
2858 if (sc->sc_txaggr) { 2740 if (sc->sc_flags & SC_OP_TXAGGR) {
2859 struct ath_atx_tid *tid; 2741 struct ath_atx_tid *tid;
2860 int tidno, i; 2742 int tidno, i;
2861 2743
@@ -2869,3 +2751,57 @@ void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an)
2869 } 2751 }
2870 } 2752 }
2871} 2753}
2754
2755void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
2756{
2757 int hdrlen, padsize;
2758 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2759 struct ath_tx_control txctl;
2760
2761 /*
2762 * As a temporary workaround, assign seq# here; this will likely need
2763 * to be cleaned up to work better with Beacon transmission and virtual
2764 * BSSes.
2765 */
2766 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
2767 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2768 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
2769 sc->seq_no += 0x10;
2770 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
2771 hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
2772 }
2773
2774 /* Add the padding after the header if this is not already done */
2775 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
2776 if (hdrlen & 3) {
2777 padsize = hdrlen % 4;
2778 if (skb_headroom(skb) < padsize) {
2779 DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ padding "
2780 "failed\n", __func__);
2781 dev_kfree_skb_any(skb);
2782 return;
2783 }
2784 skb_push(skb, padsize);
2785 memmove(skb->data, skb->data + padsize, hdrlen);
2786 }
2787
2788 DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting CABQ packet, skb: %p\n",
2789 __func__,
2790 skb);
2791
2792 memset(&txctl, 0, sizeof(struct ath_tx_control));
2793 txctl.flags = ATH9K_TXDESC_CAB;
2794 if (ath_tx_prepare(sc, skb, &txctl) == 0) {
2795 /*
2796 * Start DMA mapping.
2797 * ath_tx_start_dma() will be called either synchronously
2798 * or asynchrounsly once DMA is complete.
2799 */
2800 xmit_map_sg(sc, skb, &txctl);
2801 } else {
2802 ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);
2803 DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ failed\n", __func__);
2804 dev_kfree_skb_any(skb);
2805 }
2806}
2807
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 8c52b0b9862a..fb6ffce03f0a 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,7 +1,9 @@
1b43-y += main.o 1b43-y += main.o
2b43-y += tables.o 2b43-y += tables.o
3b43-$(CONFIG_B43_NPHY) += tables_nphy.o 3b43-$(CONFIG_B43_NPHY) += tables_nphy.o
4b43-y += phy.o 4b43-y += phy_common.o
5b43-y += phy_g.o
6b43-y += phy_a.o
5b43-$(CONFIG_B43_NPHY) += nphy.o 7b43-$(CONFIG_B43_NPHY) += nphy.o
6b43-y += sysfs.o 8b43-y += sysfs.o
7b43-y += xmit.o 9b43-y += xmit.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index edcdfa366452..f9c8161671d9 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -12,7 +12,7 @@
12#include "leds.h" 12#include "leds.h"
13#include "rfkill.h" 13#include "rfkill.h"
14#include "lo.h" 14#include "lo.h"
15#include "phy.h" 15#include "phy_common.h"
16 16
17 17
18/* The unique identifier of the firmware that's officially supported by 18/* The unique identifier of the firmware that's officially supported by
@@ -173,6 +173,11 @@ enum {
173#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ 173#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */
174#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */ 174#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */
175#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ 175#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */
176/* TSSI information */
177#define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */
178#define B43_SHM_SH_TSSI_OFDM_A 0x0068 /* TSSI for last 4 OFDM frames (32bit) */
179#define B43_SHM_SH_TSSI_OFDM_G 0x0070 /* TSSI for last 4 OFDM frames (32bit) */
180#define B43_TSSI_MAX 0x7F /* Max value for one TSSI value */
176/* SHM_SHARED TX FIFO variables */ 181/* SHM_SHARED TX FIFO variables */
177#define B43_SHM_SH_SIZE01 0x0098 /* TX FIFO size for FIFO 0 (low) and 1 (high) */ 182#define B43_SHM_SH_SIZE01 0x0098 /* TX FIFO size for FIFO 0 (low) and 1 (high) */
178#define B43_SHM_SH_SIZE23 0x009A /* TX FIFO size for FIFO 2 and 3 */ 183#define B43_SHM_SH_SIZE23 0x009A /* TX FIFO size for FIFO 2 and 3 */
@@ -508,122 +513,6 @@ struct b43_iv {
508} __attribute__((__packed__)); 513} __attribute__((__packed__));
509 514
510 515
511struct b43_phy {
512 /* Band support flags. */
513 bool supports_2ghz;
514 bool supports_5ghz;
515
516 /* GMODE bit enabled? */
517 bool gmode;
518
519 /* Analog Type */
520 u8 analog;
521 /* B43_PHYTYPE_ */
522 u8 type;
523 /* PHY revision number. */
524 u8 rev;
525
526 /* Radio versioning */
527 u16 radio_manuf; /* Radio manufacturer */
528 u16 radio_ver; /* Radio version */
529 u8 radio_rev; /* Radio revision */
530
531 bool dyn_tssi_tbl; /* tssi2dbm is kmalloc()ed. */
532
533 /* ACI (adjacent channel interference) flags. */
534 bool aci_enable;
535 bool aci_wlan_automatic;
536 bool aci_hw_rssi;
537
538 /* Radio switched on/off */
539 bool radio_on;
540 struct {
541 /* Values saved when turning the radio off.
542 * They are needed when turning it on again. */
543 bool valid;
544 u16 rfover;
545 u16 rfoverval;
546 } radio_off_context;
547
548 u16 minlowsig[2];
549 u16 minlowsigpos[2];
550
551 /* TSSI to dBm table in use */
552 const s8 *tssi2dbm;
553 /* Target idle TSSI */
554 int tgt_idle_tssi;
555 /* Current idle TSSI */
556 int cur_idle_tssi;
557
558 /* LocalOscillator control values. */
559 struct b43_txpower_lo_control *lo_control;
560 /* Values from b43_calc_loopback_gain() */
561 s16 max_lb_gain; /* Maximum Loopback gain in hdB */
562 s16 trsw_rx_gain; /* TRSW RX gain in hdB */
563 s16 lna_lod_gain; /* LNA lod */
564 s16 lna_gain; /* LNA */
565 s16 pga_gain; /* PGA */
566
567 /* Desired TX power level (in dBm).
568 * This is set by the user and adjusted in b43_phy_xmitpower(). */
569 u8 power_level;
570 /* A-PHY TX Power control value. */
571 u16 txpwr_offset;
572
573 /* Current TX power level attenuation control values */
574 struct b43_bbatt bbatt;
575 struct b43_rfatt rfatt;
576 u8 tx_control; /* B43_TXCTL_XXX */
577
578 /* Hardware Power Control enabled? */
579 bool hardware_power_control;
580
581 /* Current Interference Mitigation mode */
582 int interfmode;
583 /* Stack of saved values from the Interference Mitigation code.
584 * Each value in the stack is layed out as follows:
585 * bit 0-11: offset
586 * bit 12-15: register ID
587 * bit 16-32: value
588 * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
589 */
590#define B43_INTERFSTACK_SIZE 26
591 u32 interfstack[B43_INTERFSTACK_SIZE]; //FIXME: use a data structure
592
593 /* Saved values from the NRSSI Slope calculation */
594 s16 nrssi[2];
595 s32 nrssislope;
596 /* In memory nrssi lookup table. */
597 s8 nrssi_lt[64];
598
599 /* current channel */
600 u8 channel;
601
602 u16 lofcal;
603
604 u16 initval; //FIXME rename?
605
606 /* PHY TX errors counter. */
607 atomic_t txerr_cnt;
608
609 /* The device does address auto increment for the OFDM tables.
610 * We cache the previously used address here and omit the address
611 * write on the next table access, if possible. */
612 u16 ofdmtab_addr; /* The address currently set in hardware. */
613 enum { /* The last data flow direction. */
614 B43_OFDMTAB_DIRECTION_UNKNOWN = 0,
615 B43_OFDMTAB_DIRECTION_READ,
616 B43_OFDMTAB_DIRECTION_WRITE,
617 } ofdmtab_addr_direction;
618
619#if B43_DEBUG
620 /* Manual TX-power control enabled? */
621 bool manual_txpower_control;
622 /* PHY registers locked by b43_phy_lock()? */
623 bool phy_locked;
624#endif /* B43_DEBUG */
625};
626
627/* Data structures for DMA transmission, per 80211 core. */ 516/* Data structures for DMA transmission, per 80211 core. */
628struct b43_dma { 517struct b43_dma {
629 struct b43_dmaring *tx_ring_AC_BK; /* Background */ 518 struct b43_dmaring *tx_ring_AC_BK; /* Background */
@@ -764,6 +653,11 @@ struct b43_wl {
764 struct b43_qos_params qos_params[4]; 653 struct b43_qos_params qos_params[4];
765 /* Workqueue for updating QOS parameters in hardware. */ 654 /* Workqueue for updating QOS parameters in hardware. */
766 struct work_struct qos_update_work; 655 struct work_struct qos_update_work;
656
657 /* Work for adjustment of the transmission power.
658 * This is scheduled when we determine that the actual TX output
659 * power doesn't match what we want. */
660 struct work_struct txpower_adjust_work;
767}; 661};
768 662
769/* In-memory representation of a cached microcode file. */ 663/* In-memory representation of a cached microcode file. */
@@ -908,6 +802,15 @@ static inline int b43_is_mode(struct b43_wl *wl, int type)
908 return (wl->operating && wl->if_type == type); 802 return (wl->operating && wl->if_type == type);
909} 803}
910 804
805/**
806 * b43_current_band - Returns the currently used band.
807 * Returns one of IEEE80211_BAND_2GHZ and IEEE80211_BAND_5GHZ.
808 */
809static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
810{
811 return wl->hw->conf.channel->band;
812}
813
911static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) 814static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
912{ 815{
913 return ssb_read16(dev->dev, offset); 816 return ssb_read16(dev->dev, offset);
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 29851bc1101f..06a01da80160 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -443,76 +443,6 @@ out_unlock:
443 return count; 443 return count;
444} 444}
445 445
446static ssize_t txpower_g_read_file(struct b43_wldev *dev,
447 char *buf, size_t bufsize)
448{
449 ssize_t count = 0;
450
451 if (dev->phy.type != B43_PHYTYPE_G) {
452 fappend("Device is not a G-PHY\n");
453 goto out;
454 }
455 fappend("Control: %s\n", dev->phy.manual_txpower_control ?
456 "MANUAL" : "AUTOMATIC");
457 fappend("Baseband attenuation: %u\n", dev->phy.bbatt.att);
458 fappend("Radio attenuation: %u\n", dev->phy.rfatt.att);
459 fappend("TX Mixer Gain: %s\n",
460 (dev->phy.tx_control & B43_TXCTL_TXMIX) ? "ON" : "OFF");
461 fappend("PA Gain 2dB: %s\n",
462 (dev->phy.tx_control & B43_TXCTL_PA2DB) ? "ON" : "OFF");
463 fappend("PA Gain 3dB: %s\n",
464 (dev->phy.tx_control & B43_TXCTL_PA3DB) ? "ON" : "OFF");
465 fappend("\n\n");
466 fappend("You can write to this file:\n");
467 fappend("Writing \"auto\" enables automatic txpower control.\n");
468 fappend
469 ("Writing the attenuation values as \"bbatt rfatt txmix pa2db pa3db\" "
470 "enables manual txpower control.\n");
471 fappend("Example: 5 4 0 0 1\n");
472 fappend("Enables manual control with Baseband attenuation 5, "
473 "Radio attenuation 4, No TX Mixer Gain, "
474 "No PA Gain 2dB, With PA Gain 3dB.\n");
475out:
476 return count;
477}
478
479static int txpower_g_write_file(struct b43_wldev *dev,
480 const char *buf, size_t count)
481{
482 if (dev->phy.type != B43_PHYTYPE_G)
483 return -ENODEV;
484 if ((count >= 4) && (memcmp(buf, "auto", 4) == 0)) {
485 /* Automatic control */
486 dev->phy.manual_txpower_control = 0;
487 b43_phy_xmitpower(dev);
488 } else {
489 int bbatt = 0, rfatt = 0, txmix = 0, pa2db = 0, pa3db = 0;
490 /* Manual control */
491 if (sscanf(buf, "%d %d %d %d %d", &bbatt, &rfatt,
492 &txmix, &pa2db, &pa3db) != 5)
493 return -EINVAL;
494 b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
495 dev->phy.manual_txpower_control = 1;
496 dev->phy.bbatt.att = bbatt;
497 dev->phy.rfatt.att = rfatt;
498 dev->phy.tx_control = 0;
499 if (txmix)
500 dev->phy.tx_control |= B43_TXCTL_TXMIX;
501 if (pa2db)
502 dev->phy.tx_control |= B43_TXCTL_PA2DB;
503 if (pa3db)
504 dev->phy.tx_control |= B43_TXCTL_PA3DB;
505 b43_phy_lock(dev);
506 b43_radio_lock(dev);
507 b43_set_txpower_g(dev, &dev->phy.bbatt,
508 &dev->phy.rfatt, dev->phy.tx_control);
509 b43_radio_unlock(dev);
510 b43_phy_unlock(dev);
511 }
512
513 return 0;
514}
515
516/* wl->irq_lock is locked */ 446/* wl->irq_lock is locked */
517static int restart_write_file(struct b43_wldev *dev, 447static int restart_write_file(struct b43_wldev *dev,
518 const char *buf, size_t count) 448 const char *buf, size_t count)
@@ -560,7 +490,7 @@ static ssize_t loctls_read_file(struct b43_wldev *dev,
560 err = -ENODEV; 490 err = -ENODEV;
561 goto out; 491 goto out;
562 } 492 }
563 lo = phy->lo_control; 493 lo = phy->g->lo_control;
564 fappend("-- Local Oscillator calibration data --\n\n"); 494 fappend("-- Local Oscillator calibration data --\n\n");
565 fappend("HW-power-control enabled: %d\n", 495 fappend("HW-power-control enabled: %d\n",
566 dev->phy.hardware_power_control); 496 dev->phy.hardware_power_control);
@@ -578,8 +508,8 @@ static ssize_t loctls_read_file(struct b43_wldev *dev,
578 list_for_each_entry(cal, &lo->calib_list, list) { 508 list_for_each_entry(cal, &lo->calib_list, list) {
579 bool active; 509 bool active;
580 510
581 active = (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) && 511 active = (b43_compare_bbatt(&cal->bbatt, &phy->g->bbatt) &&
582 b43_compare_rfatt(&cal->rfatt, &phy->rfatt)); 512 b43_compare_rfatt(&cal->rfatt, &phy->g->rfatt));
583 fappend("BB(%d), RF(%d,%d) -> I=%d, Q=%d " 513 fappend("BB(%d), RF(%d,%d) -> I=%d, Q=%d "
584 "(expires in %lu sec)%s\n", 514 "(expires in %lu sec)%s\n",
585 cal->bbatt.att, 515 cal->bbatt.att,
@@ -763,7 +693,6 @@ B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
763B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1); 693B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
764B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1); 694B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
765B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); 695B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
766B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0);
767B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); 696B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
768B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0); 697B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
769 698
@@ -877,7 +806,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
877 ADD_FILE(mmio32write, 0200); 806 ADD_FILE(mmio32write, 0200);
878 ADD_FILE(tsf, 0600); 807 ADD_FILE(tsf, 0600);
879 ADD_FILE(txstat, 0400); 808 ADD_FILE(txstat, 0400);
880 ADD_FILE(txpower_g, 0600);
881 ADD_FILE(restart, 0200); 809 ADD_FILE(restart, 0200);
882 ADD_FILE(loctls, 0400); 810 ADD_FILE(loctls, 0400);
883 811
@@ -907,7 +835,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
907 debugfs_remove(e->file_mmio32write.dentry); 835 debugfs_remove(e->file_mmio32write.dentry);
908 debugfs_remove(e->file_tsf.dentry); 836 debugfs_remove(e->file_tsf.dentry);
909 debugfs_remove(e->file_txstat.dentry); 837 debugfs_remove(e->file_txstat.dentry);
910 debugfs_remove(e->file_txpower_g.dentry);
911 debugfs_remove(e->file_restart.dentry); 838 debugfs_remove(e->file_restart.dentry);
912 debugfs_remove(e->file_loctls.dentry); 839 debugfs_remove(e->file_loctls.dentry);
913 840
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 9c854d6aae36..6a18a1470465 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -29,7 +29,7 @@
29 29
30#include "b43.h" 30#include "b43.h"
31#include "lo.h" 31#include "lo.h"
32#include "phy.h" 32#include "phy_g.h"
33#include "main.h" 33#include "main.h"
34 34
35#include <linux/delay.h> 35#include <linux/delay.h>
@@ -174,7 +174,8 @@ static u16 lo_txctl_register_table(struct b43_wldev *dev,
174static void lo_measure_txctl_values(struct b43_wldev *dev) 174static void lo_measure_txctl_values(struct b43_wldev *dev)
175{ 175{
176 struct b43_phy *phy = &dev->phy; 176 struct b43_phy *phy = &dev->phy;
177 struct b43_txpower_lo_control *lo = phy->lo_control; 177 struct b43_phy_g *gphy = phy->g;
178 struct b43_txpower_lo_control *lo = gphy->lo_control;
178 u16 reg, mask; 179 u16 reg, mask;
179 u16 trsw_rx, pga; 180 u16 trsw_rx, pga;
180 u16 radio_pctl_reg; 181 u16 radio_pctl_reg;
@@ -195,7 +196,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
195 int lb_gain; /* Loopback gain (in dB) */ 196 int lb_gain; /* Loopback gain (in dB) */
196 197
197 trsw_rx = 0; 198 trsw_rx = 0;
198 lb_gain = phy->max_lb_gain / 2; 199 lb_gain = gphy->max_lb_gain / 2;
199 if (lb_gain > 10) { 200 if (lb_gain > 10) {
200 radio_pctl_reg = 0; 201 radio_pctl_reg = 0;
201 pga = abs(10 - lb_gain) / 6; 202 pga = abs(10 - lb_gain) / 6;
@@ -226,7 +227,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
226 } 227 }
227 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43) 228 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
228 & 0xFFF0) | radio_pctl_reg); 229 & 0xFFF0) | radio_pctl_reg);
229 b43_phy_set_baseband_attenuation(dev, 2); 230 b43_gphy_set_baseband_attenuation(dev, 2);
230 231
231 reg = lo_txctl_register_table(dev, &mask, NULL); 232 reg = lo_txctl_register_table(dev, &mask, NULL);
232 mask = ~mask; 233 mask = ~mask;
@@ -277,7 +278,8 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
277static void lo_read_power_vector(struct b43_wldev *dev) 278static void lo_read_power_vector(struct b43_wldev *dev)
278{ 279{
279 struct b43_phy *phy = &dev->phy; 280 struct b43_phy *phy = &dev->phy;
280 struct b43_txpower_lo_control *lo = phy->lo_control; 281 struct b43_phy_g *gphy = phy->g;
282 struct b43_txpower_lo_control *lo = gphy->lo_control;
281 int i; 283 int i;
282 u64 tmp; 284 u64 tmp;
283 u64 power_vector = 0; 285 u64 power_vector = 0;
@@ -298,6 +300,7 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
298 s16 max_rx_gain, int use_trsw_rx) 300 s16 max_rx_gain, int use_trsw_rx)
299{ 301{
300 struct b43_phy *phy = &dev->phy; 302 struct b43_phy *phy = &dev->phy;
303 struct b43_phy_g *gphy = phy->g;
301 u16 tmp; 304 u16 tmp;
302 305
303 if (max_rx_gain < 0) 306 if (max_rx_gain < 0)
@@ -308,7 +311,7 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
308 int trsw_rx_gain; 311 int trsw_rx_gain;
309 312
310 if (use_trsw_rx) { 313 if (use_trsw_rx) {
311 trsw_rx_gain = phy->trsw_rx_gain / 2; 314 trsw_rx_gain = gphy->trsw_rx_gain / 2;
312 if (max_rx_gain >= trsw_rx_gain) { 315 if (max_rx_gain >= trsw_rx_gain) {
313 trsw_rx_gain = max_rx_gain - trsw_rx_gain; 316 trsw_rx_gain = max_rx_gain - trsw_rx_gain;
314 trsw_rx = 0x20; 317 trsw_rx = 0x20;
@@ -316,38 +319,38 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
316 } else 319 } else
317 trsw_rx_gain = max_rx_gain; 320 trsw_rx_gain = max_rx_gain;
318 if (trsw_rx_gain < 9) { 321 if (trsw_rx_gain < 9) {
319 phy->lna_lod_gain = 0; 322 gphy->lna_lod_gain = 0;
320 } else { 323 } else {
321 phy->lna_lod_gain = 1; 324 gphy->lna_lod_gain = 1;
322 trsw_rx_gain -= 8; 325 trsw_rx_gain -= 8;
323 } 326 }
324 trsw_rx_gain = clamp_val(trsw_rx_gain, 0, 0x2D); 327 trsw_rx_gain = clamp_val(trsw_rx_gain, 0, 0x2D);
325 phy->pga_gain = trsw_rx_gain / 3; 328 gphy->pga_gain = trsw_rx_gain / 3;
326 if (phy->pga_gain >= 5) { 329 if (gphy->pga_gain >= 5) {
327 phy->pga_gain -= 5; 330 gphy->pga_gain -= 5;
328 phy->lna_gain = 2; 331 gphy->lna_gain = 2;
329 } else 332 } else
330 phy->lna_gain = 0; 333 gphy->lna_gain = 0;
331 } else { 334 } else {
332 phy->lna_gain = 0; 335 gphy->lna_gain = 0;
333 phy->trsw_rx_gain = 0x20; 336 gphy->trsw_rx_gain = 0x20;
334 if (max_rx_gain >= 0x14) { 337 if (max_rx_gain >= 0x14) {
335 phy->lna_lod_gain = 1; 338 gphy->lna_lod_gain = 1;
336 phy->pga_gain = 2; 339 gphy->pga_gain = 2;
337 } else if (max_rx_gain >= 0x12) { 340 } else if (max_rx_gain >= 0x12) {
338 phy->lna_lod_gain = 1; 341 gphy->lna_lod_gain = 1;
339 phy->pga_gain = 1; 342 gphy->pga_gain = 1;
340 } else if (max_rx_gain >= 0xF) { 343 } else if (max_rx_gain >= 0xF) {
341 phy->lna_lod_gain = 1; 344 gphy->lna_lod_gain = 1;
342 phy->pga_gain = 0; 345 gphy->pga_gain = 0;
343 } else { 346 } else {
344 phy->lna_lod_gain = 0; 347 gphy->lna_lod_gain = 0;
345 phy->pga_gain = 0; 348 gphy->pga_gain = 0;
346 } 349 }
347 } 350 }
348 351
349 tmp = b43_radio_read16(dev, 0x7A); 352 tmp = b43_radio_read16(dev, 0x7A);
350 if (phy->lna_lod_gain == 0) 353 if (gphy->lna_lod_gain == 0)
351 tmp &= ~0x0008; 354 tmp &= ~0x0008;
352 else 355 else
353 tmp |= 0x0008; 356 tmp |= 0x0008;
@@ -392,10 +395,11 @@ static void lo_measure_setup(struct b43_wldev *dev,
392{ 395{
393 struct ssb_sprom *sprom = &dev->dev->bus->sprom; 396 struct ssb_sprom *sprom = &dev->dev->bus->sprom;
394 struct b43_phy *phy = &dev->phy; 397 struct b43_phy *phy = &dev->phy;
395 struct b43_txpower_lo_control *lo = phy->lo_control; 398 struct b43_phy_g *gphy = phy->g;
399 struct b43_txpower_lo_control *lo = gphy->lo_control;
396 u16 tmp; 400 u16 tmp;
397 401
398 if (b43_has_hardware_pctl(phy)) { 402 if (b43_has_hardware_pctl(dev)) {
399 sav->phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK); 403 sav->phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
400 sav->phy_extg_01 = b43_phy_read(dev, B43_PHY_EXTG(0x01)); 404 sav->phy_extg_01 = b43_phy_read(dev, B43_PHY_EXTG(0x01));
401 sav->phy_dacctl_hwpctl = b43_phy_read(dev, B43_PHY_DACCTL); 405 sav->phy_dacctl_hwpctl = b43_phy_read(dev, B43_PHY_DACCTL);
@@ -496,7 +500,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
496 b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x0802); 500 b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x0802);
497 if (phy->rev >= 2) 501 if (phy->rev >= 2)
498 b43_dummy_transmission(dev); 502 b43_dummy_transmission(dev);
499 b43_radio_selectchannel(dev, 6, 0); 503 b43_gphy_channel_switch(dev, 6, 0);
500 b43_radio_read16(dev, 0x51); /* dummy read */ 504 b43_radio_read16(dev, 0x51); /* dummy read */
501 if (phy->type == B43_PHYTYPE_G) 505 if (phy->type == B43_PHYTYPE_G)
502 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0); 506 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0);
@@ -520,18 +524,19 @@ static void lo_measure_restore(struct b43_wldev *dev,
520 struct lo_g_saved_values *sav) 524 struct lo_g_saved_values *sav)
521{ 525{
522 struct b43_phy *phy = &dev->phy; 526 struct b43_phy *phy = &dev->phy;
527 struct b43_phy_g *gphy = phy->g;
523 u16 tmp; 528 u16 tmp;
524 529
525 if (phy->rev >= 2) { 530 if (phy->rev >= 2) {
526 b43_phy_write(dev, B43_PHY_PGACTL, 0xE300); 531 b43_phy_write(dev, B43_PHY_PGACTL, 0xE300);
527 tmp = (phy->pga_gain << 8); 532 tmp = (gphy->pga_gain << 8);
528 b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA0); 533 b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA0);
529 udelay(5); 534 udelay(5);
530 b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA2); 535 b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA2);
531 udelay(2); 536 udelay(2);
532 b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA3); 537 b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA3);
533 } else { 538 } else {
534 tmp = (phy->pga_gain | 0xEFA0); 539 tmp = (gphy->pga_gain | 0xEFA0);
535 b43_phy_write(dev, B43_PHY_PGACTL, tmp); 540 b43_phy_write(dev, B43_PHY_PGACTL, tmp);
536 } 541 }
537 if (phy->type == B43_PHYTYPE_G) { 542 if (phy->type == B43_PHYTYPE_G) {
@@ -572,7 +577,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
572 b43_phy_write(dev, B43_PHY_CCK(0x3E), sav->phy_cck_3E); 577 b43_phy_write(dev, B43_PHY_CCK(0x3E), sav->phy_cck_3E);
573 b43_phy_write(dev, B43_PHY_CRS0, sav->phy_crs0); 578 b43_phy_write(dev, B43_PHY_CRS0, sav->phy_crs0);
574 } 579 }
575 if (b43_has_hardware_pctl(phy)) { 580 if (b43_has_hardware_pctl(dev)) {
576 tmp = (sav->phy_lo_mask & 0xBFFF); 581 tmp = (sav->phy_lo_mask & 0xBFFF);
577 b43_phy_write(dev, B43_PHY_LO_MASK, tmp); 582 b43_phy_write(dev, B43_PHY_LO_MASK, tmp);
578 b43_phy_write(dev, B43_PHY_EXTG(0x01), sav->phy_extg_01); 583 b43_phy_write(dev, B43_PHY_EXTG(0x01), sav->phy_extg_01);
@@ -580,7 +585,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
580 b43_phy_write(dev, B43_PHY_CCK(0x14), sav->phy_cck_14); 585 b43_phy_write(dev, B43_PHY_CCK(0x14), sav->phy_cck_14);
581 b43_phy_write(dev, B43_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); 586 b43_phy_write(dev, B43_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
582 } 587 }
583 b43_radio_selectchannel(dev, sav->old_channel, 1); 588 b43_gphy_channel_switch(dev, sav->old_channel, 1);
584} 589}
585 590
586struct b43_lo_g_statemachine { 591struct b43_lo_g_statemachine {
@@ -597,6 +602,7 @@ static int lo_probe_possible_loctls(struct b43_wldev *dev,
597 struct b43_lo_g_statemachine *d) 602 struct b43_lo_g_statemachine *d)
598{ 603{
599 struct b43_phy *phy = &dev->phy; 604 struct b43_phy *phy = &dev->phy;
605 struct b43_phy_g *gphy = phy->g;
600 struct b43_loctl test_loctl; 606 struct b43_loctl test_loctl;
601 struct b43_loctl orig_loctl; 607 struct b43_loctl orig_loctl;
602 struct b43_loctl prev_loctl = { 608 struct b43_loctl prev_loctl = {
@@ -646,9 +652,9 @@ static int lo_probe_possible_loctls(struct b43_wldev *dev,
646 test_loctl.q != prev_loctl.q) && 652 test_loctl.q != prev_loctl.q) &&
647 (abs(test_loctl.i) <= 16 && abs(test_loctl.q) <= 16)) { 653 (abs(test_loctl.i) <= 16 && abs(test_loctl.q) <= 16)) {
648 b43_lo_write(dev, &test_loctl); 654 b43_lo_write(dev, &test_loctl);
649 feedth = lo_measure_feedthrough(dev, phy->lna_gain, 655 feedth = lo_measure_feedthrough(dev, gphy->lna_gain,
650 phy->pga_gain, 656 gphy->pga_gain,
651 phy->trsw_rx_gain); 657 gphy->trsw_rx_gain);
652 if (feedth < d->lowest_feedth) { 658 if (feedth < d->lowest_feedth) {
653 memcpy(probe_loctl, &test_loctl, 659 memcpy(probe_loctl, &test_loctl,
654 sizeof(struct b43_loctl)); 660 sizeof(struct b43_loctl));
@@ -677,6 +683,7 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
677 int *max_rx_gain) 683 int *max_rx_gain)
678{ 684{
679 struct b43_phy *phy = &dev->phy; 685 struct b43_phy *phy = &dev->phy;
686 struct b43_phy_g *gphy = phy->g;
680 struct b43_lo_g_statemachine d; 687 struct b43_lo_g_statemachine d;
681 u16 feedth; 688 u16 feedth;
682 int found_lower; 689 int found_lower;
@@ -693,17 +700,17 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
693 max_repeat = 4; 700 max_repeat = 4;
694 do { 701 do {
695 b43_lo_write(dev, &d.min_loctl); 702 b43_lo_write(dev, &d.min_loctl);
696 feedth = lo_measure_feedthrough(dev, phy->lna_gain, 703 feedth = lo_measure_feedthrough(dev, gphy->lna_gain,
697 phy->pga_gain, 704 gphy->pga_gain,
698 phy->trsw_rx_gain); 705 gphy->trsw_rx_gain);
699 if (feedth < 0x258) { 706 if (feedth < 0x258) {
700 if (feedth >= 0x12C) 707 if (feedth >= 0x12C)
701 *max_rx_gain += 6; 708 *max_rx_gain += 6;
702 else 709 else
703 *max_rx_gain += 3; 710 *max_rx_gain += 3;
704 feedth = lo_measure_feedthrough(dev, phy->lna_gain, 711 feedth = lo_measure_feedthrough(dev, gphy->lna_gain,
705 phy->pga_gain, 712 gphy->pga_gain,
706 phy->trsw_rx_gain); 713 gphy->trsw_rx_gain);
707 } 714 }
708 d.lowest_feedth = feedth; 715 d.lowest_feedth = feedth;
709 716
@@ -752,6 +759,7 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
752 const struct b43_rfatt *rfatt) 759 const struct b43_rfatt *rfatt)
753{ 760{
754 struct b43_phy *phy = &dev->phy; 761 struct b43_phy *phy = &dev->phy;
762 struct b43_phy_g *gphy = phy->g;
755 struct b43_loctl loctl = { 763 struct b43_loctl loctl = {
756 .i = 0, 764 .i = 0,
757 .q = 0, 765 .q = 0,
@@ -782,11 +790,11 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
782 if (rfatt->with_padmix) 790 if (rfatt->with_padmix)
783 max_rx_gain -= pad_mix_gain; 791 max_rx_gain -= pad_mix_gain;
784 if (has_loopback_gain(phy)) 792 if (has_loopback_gain(phy))
785 max_rx_gain += phy->max_lb_gain; 793 max_rx_gain += gphy->max_lb_gain;
786 lo_measure_gain_values(dev, max_rx_gain, 794 lo_measure_gain_values(dev, max_rx_gain,
787 has_loopback_gain(phy)); 795 has_loopback_gain(phy));
788 796
789 b43_phy_set_baseband_attenuation(dev, bbatt->att); 797 b43_gphy_set_baseband_attenuation(dev, bbatt->att);
790 lo_probe_loctls_statemachine(dev, &loctl, &max_rx_gain); 798 lo_probe_loctls_statemachine(dev, &loctl, &max_rx_gain);
791 799
792 lo_measure_restore(dev, &saved_regs); 800 lo_measure_restore(dev, &saved_regs);
@@ -820,7 +828,7 @@ struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
820 const struct b43_bbatt *bbatt, 828 const struct b43_bbatt *bbatt,
821 const struct b43_rfatt *rfatt) 829 const struct b43_rfatt *rfatt)
822{ 830{
823 struct b43_txpower_lo_control *lo = dev->phy.lo_control; 831 struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
824 struct b43_lo_calib *c; 832 struct b43_lo_calib *c;
825 833
826 c = b43_find_lo_calib(lo, bbatt, rfatt); 834 c = b43_find_lo_calib(lo, bbatt, rfatt);
@@ -839,7 +847,8 @@ struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
839void b43_gphy_dc_lt_init(struct b43_wldev *dev, bool update_all) 847void b43_gphy_dc_lt_init(struct b43_wldev *dev, bool update_all)
840{ 848{
841 struct b43_phy *phy = &dev->phy; 849 struct b43_phy *phy = &dev->phy;
842 struct b43_txpower_lo_control *lo = phy->lo_control; 850 struct b43_phy_g *gphy = phy->g;
851 struct b43_txpower_lo_control *lo = gphy->lo_control;
843 int i; 852 int i;
844 int rf_offset, bb_offset; 853 int rf_offset, bb_offset;
845 const struct b43_rfatt *rfatt; 854 const struct b43_rfatt *rfatt;
@@ -917,14 +926,14 @@ static inline void b43_lo_fixup_rfatt(struct b43_rfatt *rf)
917 926
918void b43_lo_g_adjust(struct b43_wldev *dev) 927void b43_lo_g_adjust(struct b43_wldev *dev)
919{ 928{
920 struct b43_phy *phy = &dev->phy; 929 struct b43_phy_g *gphy = dev->phy.g;
921 struct b43_lo_calib *cal; 930 struct b43_lo_calib *cal;
922 struct b43_rfatt rf; 931 struct b43_rfatt rf;
923 932
924 memcpy(&rf, &phy->rfatt, sizeof(rf)); 933 memcpy(&rf, &gphy->rfatt, sizeof(rf));
925 b43_lo_fixup_rfatt(&rf); 934 b43_lo_fixup_rfatt(&rf);
926 935
927 cal = b43_get_calib_lo_settings(dev, &phy->bbatt, &rf); 936 cal = b43_get_calib_lo_settings(dev, &gphy->bbatt, &rf);
928 if (!cal) 937 if (!cal)
929 return; 938 return;
930 b43_lo_write(dev, &cal->ctl); 939 b43_lo_write(dev, &cal->ctl);
@@ -952,7 +961,8 @@ void b43_lo_g_adjust_to(struct b43_wldev *dev,
952void b43_lo_g_maintanance_work(struct b43_wldev *dev) 961void b43_lo_g_maintanance_work(struct b43_wldev *dev)
953{ 962{
954 struct b43_phy *phy = &dev->phy; 963 struct b43_phy *phy = &dev->phy;
955 struct b43_txpower_lo_control *lo = phy->lo_control; 964 struct b43_phy_g *gphy = phy->g;
965 struct b43_txpower_lo_control *lo = gphy->lo_control;
956 unsigned long now; 966 unsigned long now;
957 unsigned long expire; 967 unsigned long expire;
958 struct b43_lo_calib *cal, *tmp; 968 struct b43_lo_calib *cal, *tmp;
@@ -962,7 +972,7 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
962 if (!lo) 972 if (!lo)
963 return; 973 return;
964 now = jiffies; 974 now = jiffies;
965 hwpctl = b43_has_hardware_pctl(phy); 975 hwpctl = b43_has_hardware_pctl(dev);
966 976
967 if (hwpctl) { 977 if (hwpctl) {
968 /* Read the power vector and update it, if needed. */ 978 /* Read the power vector and update it, if needed. */
@@ -983,8 +993,8 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
983 if (!time_before(cal->calib_time, expire)) 993 if (!time_before(cal->calib_time, expire))
984 continue; 994 continue;
985 /* This item expired. */ 995 /* This item expired. */
986 if (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) && 996 if (b43_compare_bbatt(&cal->bbatt, &gphy->bbatt) &&
987 b43_compare_rfatt(&cal->rfatt, &phy->rfatt)) { 997 b43_compare_rfatt(&cal->rfatt, &gphy->rfatt)) {
988 B43_WARN_ON(current_item_expired); 998 B43_WARN_ON(current_item_expired);
989 current_item_expired = 1; 999 current_item_expired = 1;
990 } 1000 }
@@ -1002,7 +1012,7 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
1002 /* Recalibrate currently used LO setting. */ 1012 /* Recalibrate currently used LO setting. */
1003 if (b43_debug(dev, B43_DBG_LO)) 1013 if (b43_debug(dev, B43_DBG_LO))
1004 b43dbg(dev->wl, "LO: Recalibrating current LO setting\n"); 1014 b43dbg(dev->wl, "LO: Recalibrating current LO setting\n");
1005 cal = b43_calibrate_lo_setting(dev, &phy->bbatt, &phy->rfatt); 1015 cal = b43_calibrate_lo_setting(dev, &gphy->bbatt, &gphy->rfatt);
1006 if (cal) { 1016 if (cal) {
1007 list_add(&cal->list, &lo->calib_list); 1017 list_add(&cal->list, &lo->calib_list);
1008 b43_lo_write(dev, &cal->ctl); 1018 b43_lo_write(dev, &cal->ctl);
@@ -1013,7 +1023,7 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
1013 1023
1014void b43_lo_g_cleanup(struct b43_wldev *dev) 1024void b43_lo_g_cleanup(struct b43_wldev *dev)
1015{ 1025{
1016 struct b43_txpower_lo_control *lo = dev->phy.lo_control; 1026 struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
1017 struct b43_lo_calib *cal, *tmp; 1027 struct b43_lo_calib *cal, *tmp;
1018 1028
1019 if (!lo) 1029 if (!lo)
@@ -1027,9 +1037,7 @@ void b43_lo_g_cleanup(struct b43_wldev *dev)
1027/* LO Initialization */ 1037/* LO Initialization */
1028void b43_lo_g_init(struct b43_wldev *dev) 1038void b43_lo_g_init(struct b43_wldev *dev)
1029{ 1039{
1030 struct b43_phy *phy = &dev->phy; 1040 if (b43_has_hardware_pctl(dev)) {
1031
1032 if (b43_has_hardware_pctl(phy)) {
1033 lo_read_power_vector(dev); 1041 lo_read_power_vector(dev);
1034 b43_gphy_dc_lt_init(dev, 1); 1042 b43_gphy_dc_lt_init(dev, 1);
1035 } 1043 }
diff --git a/drivers/net/wireless/b43/lo.h b/drivers/net/wireless/b43/lo.h
index 1da321cabc12..3b27e20eff80 100644
--- a/drivers/net/wireless/b43/lo.h
+++ b/drivers/net/wireless/b43/lo.h
@@ -1,7 +1,9 @@
1#ifndef B43_LO_H_ 1#ifndef B43_LO_H_
2#define B43_LO_H_ 2#define B43_LO_H_
3 3
4#include "phy.h" 4/* G-PHY Local Oscillator */
5
6#include "phy_g.h"
5 7
6struct b43_wldev; 8struct b43_wldev;
7 9
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 7205a936ec74..63bafc2f3f0a 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -44,7 +44,8 @@
44#include "b43.h" 44#include "b43.h"
45#include "main.h" 45#include "main.h"
46#include "debugfs.h" 46#include "debugfs.h"
47#include "phy.h" 47#include "phy_common.h"
48#include "phy_g.h"
48#include "nphy.h" 49#include "nphy.h"
49#include "dma.h" 50#include "dma.h"
50#include "pio.h" 51#include "pio.h"
@@ -1174,6 +1175,8 @@ static void b43_calculate_link_quality(struct b43_wldev *dev)
1174{ 1175{
1175 /* Top half of Link Quality calculation. */ 1176 /* Top half of Link Quality calculation. */
1176 1177
1178 if (dev->phy.type != B43_PHYTYPE_G)
1179 return;
1177 if (dev->noisecalc.calculation_running) 1180 if (dev->noisecalc.calculation_running)
1178 return; 1181 return;
1179 dev->noisecalc.calculation_running = 1; 1182 dev->noisecalc.calculation_running = 1;
@@ -1184,7 +1187,7 @@ static void b43_calculate_link_quality(struct b43_wldev *dev)
1184 1187
1185static void handle_irq_noise(struct b43_wldev *dev) 1188static void handle_irq_noise(struct b43_wldev *dev)
1186{ 1189{
1187 struct b43_phy *phy = &dev->phy; 1190 struct b43_phy_g *phy = dev->phy.g;
1188 u16 tmp; 1191 u16 tmp;
1189 u8 noise[4]; 1192 u8 noise[4];
1190 u8 i, j; 1193 u8 i, j;
@@ -1192,6 +1195,9 @@ static void handle_irq_noise(struct b43_wldev *dev)
1192 1195
1193 /* Bottom half of Link Quality calculation. */ 1196 /* Bottom half of Link Quality calculation. */
1194 1197
1198 if (dev->phy.type != B43_PHYTYPE_G)
1199 return;
1200
1195 /* Possible race condition: It might be possible that the user 1201 /* Possible race condition: It might be possible that the user
1196 * changed to a different channel in the meantime since we 1202 * changed to a different channel in the meantime since we
1197 * started the calculation. We ignore that fact, since it's 1203 * started the calculation. We ignore that fact, since it's
@@ -2688,9 +2694,7 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
2688/* This is the opposite of b43_chip_init() */ 2694/* This is the opposite of b43_chip_init() */
2689static void b43_chip_exit(struct b43_wldev *dev) 2695static void b43_chip_exit(struct b43_wldev *dev)
2690{ 2696{
2691 b43_radio_turn_off(dev, 1);
2692 b43_gpio_cleanup(dev); 2697 b43_gpio_cleanup(dev);
2693 b43_lo_g_cleanup(dev);
2694 /* firmware is released later */ 2698 /* firmware is released later */
2695} 2699}
2696 2700
@@ -2700,7 +2704,7 @@ static void b43_chip_exit(struct b43_wldev *dev)
2700static int b43_chip_init(struct b43_wldev *dev) 2704static int b43_chip_init(struct b43_wldev *dev)
2701{ 2705{
2702 struct b43_phy *phy = &dev->phy; 2706 struct b43_phy *phy = &dev->phy;
2703 int err, tmp; 2707 int err;
2704 u32 value32, macctl; 2708 u32 value32, macctl;
2705 u16 value16; 2709 u16 value16;
2706 2710
@@ -2725,19 +2729,19 @@ static int b43_chip_init(struct b43_wldev *dev)
2725 err = b43_upload_initvals(dev); 2729 err = b43_upload_initvals(dev);
2726 if (err) 2730 if (err)
2727 goto err_gpio_clean; 2731 goto err_gpio_clean;
2728 b43_radio_turn_on(dev);
2729 2732
2730 b43_write16(dev, 0x03E6, 0x0000); 2733 b43_write16(dev, 0x03E6, 0x0000);
2731 err = b43_phy_init(dev); 2734 err = b43_phy_init(dev);
2732 if (err) 2735 if (err)
2733 goto err_radio_off; 2736 goto err_gpio_clean;
2734 2737
2735 /* Select initial Interference Mitigation. */ 2738 /* Disable Interference Mitigation. */
2736 tmp = phy->interfmode; 2739 if (phy->ops->interf_mitigation)
2737 phy->interfmode = B43_INTERFMODE_NONE; 2740 phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE);
2738 b43_radio_set_interference_mitigation(dev, tmp);
2739 2741
2740 b43_set_rx_antenna(dev, B43_ANTENNA_DEFAULT); 2742 /* Select the antennae */
2743 if (phy->ops->set_rx_antenna)
2744 phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT);
2741 b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); 2745 b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT);
2742 2746
2743 if (phy->type == B43_PHYTYPE_B) { 2747 if (phy->type == B43_PHYTYPE_B) {
@@ -2790,8 +2794,6 @@ static int b43_chip_init(struct b43_wldev *dev)
2790out: 2794out:
2791 return err; 2795 return err;
2792 2796
2793err_radio_off:
2794 b43_radio_turn_off(dev, 1);
2795err_gpio_clean: 2797err_gpio_clean:
2796 b43_gpio_cleanup(dev); 2798 b43_gpio_cleanup(dev);
2797 return err; 2799 return err;
@@ -2799,25 +2801,13 @@ err_gpio_clean:
2799 2801
2800static void b43_periodic_every60sec(struct b43_wldev *dev) 2802static void b43_periodic_every60sec(struct b43_wldev *dev)
2801{ 2803{
2802 struct b43_phy *phy = &dev->phy; 2804 const struct b43_phy_operations *ops = dev->phy.ops;
2803 2805
2804 if (phy->type != B43_PHYTYPE_G) 2806 if (ops->pwork_60sec)
2805 return; 2807 ops->pwork_60sec(dev);
2806 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) { 2808
2807 b43_mac_suspend(dev); 2809 /* Force check the TX power emission now. */
2808 b43_calc_nrssi_slope(dev); 2810 b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME);
2809 if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) {
2810 u8 old_chan = phy->channel;
2811
2812 /* VCO Calibration */
2813 if (old_chan >= 8)
2814 b43_radio_selectchannel(dev, 1, 0);
2815 else
2816 b43_radio_selectchannel(dev, 13, 0);
2817 b43_radio_selectchannel(dev, old_chan, 0);
2818 }
2819 b43_mac_enable(dev);
2820 }
2821} 2811}
2822 2812
2823static void b43_periodic_every30sec(struct b43_wldev *dev) 2813static void b43_periodic_every30sec(struct b43_wldev *dev)
@@ -2845,32 +2835,8 @@ static void b43_periodic_every15sec(struct b43_wldev *dev)
2845 } 2835 }
2846 } 2836 }
2847 2837
2848 if (phy->type == B43_PHYTYPE_G) { 2838 if (phy->ops->pwork_15sec)
2849 //TODO: update_aci_moving_average 2839 phy->ops->pwork_15sec(dev);
2850 if (phy->aci_enable && phy->aci_wlan_automatic) {
2851 b43_mac_suspend(dev);
2852 if (!phy->aci_enable && 1 /*TODO: not scanning? */ ) {
2853 if (0 /*TODO: bunch of conditions */ ) {
2854 b43_radio_set_interference_mitigation
2855 (dev, B43_INTERFMODE_MANUALWLAN);
2856 }
2857 } else if (1 /*TODO*/) {
2858 /*
2859 if ((aci_average > 1000) && !(b43_radio_aci_scan(dev))) {
2860 b43_radio_set_interference_mitigation(dev,
2861 B43_INTERFMODE_NONE);
2862 }
2863 */
2864 }
2865 b43_mac_enable(dev);
2866 } else if (phy->interfmode == B43_INTERFMODE_NONWLAN &&
2867 phy->rev == 1) {
2868 //TODO: implement rev1 workaround
2869 }
2870 }
2871 b43_phy_xmitpower(dev); //FIXME: unless scanning?
2872 b43_lo_g_maintanance_work(dev);
2873 //TODO for APHY (temperature?)
2874 2840
2875 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); 2841 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
2876 wmb(); 2842 wmb();
@@ -3401,7 +3367,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3401 /* Switch to the requested channel. 3367 /* Switch to the requested channel.
3402 * The firmware takes care of races with the TX handler. */ 3368 * The firmware takes care of races with the TX handler. */
3403 if (conf->channel->hw_value != phy->channel) 3369 if (conf->channel->hw_value != phy->channel)
3404 b43_radio_selectchannel(dev, conf->channel->hw_value, 0); 3370 b43_switch_channel(dev, conf->channel->hw_value);
3405 3371
3406 /* Enable/Disable ShortSlot timing. */ 3372 /* Enable/Disable ShortSlot timing. */
3407 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != 3373 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
@@ -3417,17 +3383,21 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3417 3383
3418 /* Adjust the desired TX power level. */ 3384 /* Adjust the desired TX power level. */
3419 if (conf->power_level != 0) { 3385 if (conf->power_level != 0) {
3420 if (conf->power_level != phy->power_level) { 3386 spin_lock_irqsave(&wl->irq_lock, flags);
3421 phy->power_level = conf->power_level; 3387 if (conf->power_level != phy->desired_txpower) {
3422 b43_phy_xmitpower(dev); 3388 phy->desired_txpower = conf->power_level;
3389 b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME |
3390 B43_TXPWR_IGNORE_TSSI);
3423 } 3391 }
3392 spin_unlock_irqrestore(&wl->irq_lock, flags);
3424 } 3393 }
3425 3394
3426 /* Antennas for RX and management frame TX. */ 3395 /* Antennas for RX and management frame TX. */
3427 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx); 3396 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx);
3428 b43_mgmtframe_txantenna(dev, antenna); 3397 b43_mgmtframe_txantenna(dev, antenna);
3429 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx); 3398 antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx);
3430 b43_set_rx_antenna(dev, antenna); 3399 if (phy->ops->set_rx_antenna)
3400 phy->ops->set_rx_antenna(dev, antenna);
3431 3401
3432 /* Update templates for AP/mesh mode. */ 3402 /* Update templates for AP/mesh mode. */
3433 if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) || 3403 if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) ||
@@ -3436,7 +3406,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3436 3406
3437 if (!!conf->radio_enabled != phy->radio_on) { 3407 if (!!conf->radio_enabled != phy->radio_on) {
3438 if (conf->radio_enabled) { 3408 if (conf->radio_enabled) {
3439 b43_radio_turn_on(dev); 3409 b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
3440 b43info(dev->wl, "Radio turned on by software\n"); 3410 b43info(dev->wl, "Radio turned on by software\n");
3441 if (!dev->radio_hw_enable) { 3411 if (!dev->radio_hw_enable) {
3442 b43info(dev->wl, "The hardware RF-kill button " 3412 b43info(dev->wl, "The hardware RF-kill button "
@@ -3444,7 +3414,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
3444 "Press the button to turn it on.\n"); 3414 "Press the button to turn it on.\n");
3445 } 3415 }
3446 } else { 3416 } else {
3447 b43_radio_turn_off(dev, 0); 3417 b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
3448 b43info(dev->wl, "Radio turned off by software\n"); 3418 b43info(dev->wl, "Radio turned off by software\n");
3449 } 3419 }
3450 } 3420 }
@@ -3818,48 +3788,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
3818static void setup_struct_phy_for_init(struct b43_wldev *dev, 3788static void setup_struct_phy_for_init(struct b43_wldev *dev,
3819 struct b43_phy *phy) 3789 struct b43_phy *phy)
3820{ 3790{
3821 struct b43_txpower_lo_control *lo;
3822 int i;
3823
3824 memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3825 memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3826
3827 phy->aci_enable = 0;
3828 phy->aci_wlan_automatic = 0;
3829 phy->aci_hw_rssi = 0;
3830
3831 phy->radio_off_context.valid = 0;
3832
3833 lo = phy->lo_control;
3834 if (lo) {
3835 memset(lo, 0, sizeof(*(phy->lo_control)));
3836 lo->tx_bias = 0xFF;
3837 INIT_LIST_HEAD(&lo->calib_list);
3838 }
3839 phy->max_lb_gain = 0;
3840 phy->trsw_rx_gain = 0;
3841 phy->txpwr_offset = 0;
3842
3843 /* NRSSI */
3844 phy->nrssislope = 0;
3845 for (i = 0; i < ARRAY_SIZE(phy->nrssi); i++)
3846 phy->nrssi[i] = -1000;
3847 for (i = 0; i < ARRAY_SIZE(phy->nrssi_lt); i++)
3848 phy->nrssi_lt[i] = i;
3849
3850 phy->lofcal = 0xFFFF;
3851 phy->initval = 0xFFFF;
3852
3853 phy->interfmode = B43_INTERFMODE_NONE;
3854 phy->channel = 0xFF;
3855
3856 phy->hardware_power_control = !!modparam_hwpctl; 3791 phy->hardware_power_control = !!modparam_hwpctl;
3857 3792 phy->next_txpwr_check_time = jiffies;
3858 /* PHY TX errors counter. */ 3793 /* PHY TX errors counter. */
3859 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); 3794 atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
3860
3861 /* OFDM-table address caching. */
3862 phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_UNKNOWN;
3863} 3795}
3864 3796
3865static void setup_struct_wldev_for_init(struct b43_wldev *dev) 3797static void setup_struct_wldev_for_init(struct b43_wldev *dev)
@@ -3995,7 +3927,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev)
3995/* Locking: wl->mutex */ 3927/* Locking: wl->mutex */
3996static void b43_wireless_core_exit(struct b43_wldev *dev) 3928static void b43_wireless_core_exit(struct b43_wldev *dev)
3997{ 3929{
3998 struct b43_phy *phy = &dev->phy;
3999 u32 macctl; 3930 u32 macctl;
4000 3931
4001 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED); 3932 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED);
@@ -4016,16 +3947,12 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4016 b43_dma_free(dev); 3947 b43_dma_free(dev);
4017 b43_pio_free(dev); 3948 b43_pio_free(dev);
4018 b43_chip_exit(dev); 3949 b43_chip_exit(dev);
4019 b43_radio_turn_off(dev, 1);
4020 b43_switch_analog(dev, 0); 3950 b43_switch_analog(dev, 0);
4021 if (phy->dyn_tssi_tbl)
4022 kfree(phy->tssi2dbm);
4023 kfree(phy->lo_control);
4024 phy->lo_control = NULL;
4025 if (dev->wl->current_beacon) { 3951 if (dev->wl->current_beacon) {
4026 dev_kfree_skb_any(dev->wl->current_beacon); 3952 dev_kfree_skb_any(dev->wl->current_beacon);
4027 dev->wl->current_beacon = NULL; 3953 dev->wl->current_beacon = NULL;
4028 } 3954 }
3955 b43_phy_exit(dev);
4029 3956
4030 ssb_device_disable(dev->dev, 0); 3957 ssb_device_disable(dev->dev, 0);
4031 ssb_bus_may_powerdown(dev->dev->bus); 3958 ssb_bus_may_powerdown(dev->dev->bus);
@@ -4052,29 +3979,24 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4052 b43_wireless_core_reset(dev, tmp); 3979 b43_wireless_core_reset(dev, tmp);
4053 } 3980 }
4054 3981
4055 if ((phy->type == B43_PHYTYPE_B) || (phy->type == B43_PHYTYPE_G)) {
4056 phy->lo_control =
4057 kzalloc(sizeof(*(phy->lo_control)), GFP_KERNEL);
4058 if (!phy->lo_control) {
4059 err = -ENOMEM;
4060 goto err_busdown;
4061 }
4062 }
4063 setup_struct_wldev_for_init(dev); 3982 setup_struct_wldev_for_init(dev);
4064 3983 err = b43_phy_operations_setup(dev);
4065 err = b43_phy_init_tssi2dbm_table(dev);
4066 if (err) 3984 if (err)
4067 goto err_kfree_lo_control; 3985 goto err_busdown;
4068 3986
4069 /* Enable IRQ routing to this device. */ 3987 /* Enable IRQ routing to this device. */
4070 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); 3988 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
4071 3989
4072 b43_imcfglo_timeouts_workaround(dev); 3990 b43_imcfglo_timeouts_workaround(dev);
4073 b43_bluetooth_coext_disable(dev); 3991 b43_bluetooth_coext_disable(dev);
4074 b43_phy_early_init(dev); 3992 if (phy->ops->prepare) {
3993 err = phy->ops->prepare(dev);
3994 if (err)
3995 goto err_phy_exit;
3996 }
4075 err = b43_chip_init(dev); 3997 err = b43_chip_init(dev);
4076 if (err) 3998 if (err)
4077 goto err_kfree_tssitbl; 3999 goto err_phy_exit;
4078 b43_shm_write16(dev, B43_SHM_SHARED, 4000 b43_shm_write16(dev, B43_SHM_SHARED,
4079 B43_SHM_SH_WLCOREREV, dev->dev->id.revision); 4001 B43_SHM_SH_WLCOREREV, dev->dev->id.revision);
4080 hf = b43_hf_read(dev); 4002 hf = b43_hf_read(dev);
@@ -4140,15 +4062,11 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4140out: 4062out:
4141 return err; 4063 return err;
4142 4064
4143 err_chip_exit: 4065err_chip_exit:
4144 b43_chip_exit(dev); 4066 b43_chip_exit(dev);
4145 err_kfree_tssitbl: 4067err_phy_exit:
4146 if (phy->dyn_tssi_tbl) 4068 b43_phy_exit(dev);
4147 kfree(phy->tssi2dbm); 4069err_busdown:
4148 err_kfree_lo_control:
4149 kfree(phy->lo_control);
4150 phy->lo_control = NULL;
4151 err_busdown:
4152 ssb_bus_may_powerdown(bus); 4070 ssb_bus_may_powerdown(bus);
4153 B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); 4071 B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
4154 return err; 4072 return err;
@@ -4291,6 +4209,8 @@ static void b43_op_stop(struct ieee80211_hw *hw)
4291 b43_wireless_core_stop(dev); 4209 b43_wireless_core_stop(dev);
4292 b43_wireless_core_exit(dev); 4210 b43_wireless_core_exit(dev);
4293 mutex_unlock(&wl->mutex); 4211 mutex_unlock(&wl->mutex);
4212
4213 cancel_work_sync(&(wl->txpower_adjust_work));
4294} 4214}
4295 4215
4296static int b43_op_set_retry_limit(struct ieee80211_hw *hw, 4216static int b43_op_set_retry_limit(struct ieee80211_hw *hw,
@@ -4511,7 +4431,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4511 wl->current_dev = dev; 4431 wl->current_dev = dev;
4512 INIT_WORK(&dev->restart_work, b43_chip_reset); 4432 INIT_WORK(&dev->restart_work, b43_chip_reset);
4513 4433
4514 b43_radio_turn_off(dev, 1);
4515 b43_switch_analog(dev, 0); 4434 b43_switch_analog(dev, 0);
4516 ssb_device_disable(dev->dev, 0); 4435 ssb_device_disable(dev->dev, 0);
4517 ssb_bus_may_powerdown(bus); 4436 ssb_bus_may_powerdown(bus);
@@ -4669,6 +4588,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4669 INIT_LIST_HEAD(&wl->devlist); 4588 INIT_LIST_HEAD(&wl->devlist);
4670 INIT_WORK(&wl->qos_update_work, b43_qos_update_work); 4589 INIT_WORK(&wl->qos_update_work, b43_qos_update_work);
4671 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); 4590 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
4591 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
4672 4592
4673 ssb_set_devtypedata(dev, wl); 4593 ssb_set_devtypedata(dev, wl);
4674 b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); 4594 b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/nphy.c
index 644eed993bea..4cfeab8560f6 100644
--- a/drivers/net/wireless/b43/nphy.c
+++ b/drivers/net/wireless/b43/nphy.c
@@ -34,10 +34,16 @@ void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
34{//TODO 34{//TODO
35} 35}
36 36
37void b43_nphy_xmitpower(struct b43_wldev *dev) 37static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev)
38{//TODO 38{//TODO
39} 39}
40 40
41static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
42 bool ignore_tssi)
43{//TODO
44 return B43_TXPWR_RES_DONE;
45}
46
41static void b43_chantab_radio_upload(struct b43_wldev *dev, 47static void b43_chantab_radio_upload(struct b43_wldev *dev,
42 const struct b43_nphy_channeltab_entry *e) 48 const struct b43_nphy_channeltab_entry *e)
43{ 49{
@@ -81,9 +87,8 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
81 //TODO 87 //TODO
82} 88}
83 89
84/* Tune the hardware to a new channel. Don't call this directly. 90/* Tune the hardware to a new channel. */
85 * Use b43_radio_selectchannel() */ 91static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
86int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
87{ 92{
88 const struct b43_nphy_channeltab_entry *tabent; 93 const struct b43_nphy_channeltab_entry *tabent;
89 94
@@ -162,7 +167,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
162 msleep(1); 167 msleep(1);
163 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); 168 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
164 msleep(1); 169 msleep(1);
165 b43_radio_selectchannel(dev, dev->phy.channel, 0); 170 nphy_channel_switch(dev, dev->phy.channel);
166 b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9); 171 b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9);
167 b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9); 172 b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9);
168 b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83); 173 b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
@@ -484,3 +489,136 @@ int b43_phy_initn(struct b43_wldev *dev)
484 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); 489 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
485 return 0; 490 return 0;
486} 491}
492
493static int b43_nphy_op_allocate(struct b43_wldev *dev)
494{
495 struct b43_phy_n *nphy;
496
497 nphy = kzalloc(sizeof(*nphy), GFP_KERNEL);
498 if (!nphy)
499 return -ENOMEM;
500 dev->phy.n = nphy;
501
502 //TODO init struct b43_phy_n
503
504 return 0;
505}
506
507static int b43_nphy_op_init(struct b43_wldev *dev)
508{
509 struct b43_phy_n *nphy = dev->phy.n;
510 int err;
511
512 err = b43_phy_initn(dev);
513 if (err)
514 return err;
515 nphy->initialised = 1;
516
517 return 0;
518}
519
520static void b43_nphy_op_exit(struct b43_wldev *dev)
521{
522 struct b43_phy_n *nphy = dev->phy.n;
523
524 if (nphy->initialised) {
525 //TODO
526 nphy->initialised = 0;
527 }
528 //TODO
529 kfree(nphy);
530 dev->phy.n = NULL;
531}
532
533static inline void check_phyreg(struct b43_wldev *dev, u16 offset)
534{
535#if B43_DEBUG
536 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
537 /* OFDM registers are onnly available on A/G-PHYs */
538 b43err(dev->wl, "Invalid OFDM PHY access at "
539 "0x%04X on N-PHY\n", offset);
540 dump_stack();
541 }
542 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
543 /* Ext-G registers are only available on G-PHYs */
544 b43err(dev->wl, "Invalid EXT-G PHY access at "
545 "0x%04X on N-PHY\n", offset);
546 dump_stack();
547 }
548#endif /* B43_DEBUG */
549}
550
551static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
552{
553 check_phyreg(dev, reg);
554 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
555 return b43_read16(dev, B43_MMIO_PHY_DATA);
556}
557
558static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
559{
560 check_phyreg(dev, reg);
561 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
562 b43_write16(dev, B43_MMIO_PHY_DATA, value);
563}
564
565static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
566{
567 /* Register 1 is a 32-bit register. */
568 B43_WARN_ON(reg == 1);
569 /* N-PHY needs 0x100 for read access */
570 reg |= 0x100;
571
572 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
573 return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
574}
575
576static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
577{
578 /* Register 1 is a 32-bit register. */
579 B43_WARN_ON(reg == 1);
580
581 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
582 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
583}
584
585static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
586 enum rfkill_state state)
587{//TODO
588}
589
590static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
591 unsigned int new_channel)
592{
593 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
594 if ((new_channel < 1) || (new_channel > 14))
595 return -EINVAL;
596 } else {
597 if (new_channel > 200)
598 return -EINVAL;
599 }
600
601 return nphy_channel_switch(dev, new_channel);
602}
603
604static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
605{
606 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
607 return 1;
608 return 36;
609}
610
611const struct b43_phy_operations b43_phyops_n = {
612 .allocate = b43_nphy_op_allocate,
613 .init = b43_nphy_op_init,
614 .exit = b43_nphy_op_exit,
615 .phy_read = b43_nphy_op_read,
616 .phy_write = b43_nphy_op_write,
617 .radio_read = b43_nphy_op_radio_read,
618 .radio_write = b43_nphy_op_radio_write,
619 .software_rfkill = b43_nphy_op_software_rfkill,
620 .switch_channel = b43_nphy_op_switch_channel,
621 .get_default_chan = b43_nphy_op_get_default_chan,
622 .recalc_txpower = b43_nphy_op_recalc_txpower,
623 .adjust_txpower = b43_nphy_op_adjust_txpower,
624};
diff --git a/drivers/net/wireless/b43/nphy.h b/drivers/net/wireless/b43/nphy.h
index faf46b9cbf1b..3d1f65ed2012 100644
--- a/drivers/net/wireless/b43/nphy.h
+++ b/drivers/net/wireless/b43/nphy.h
@@ -1,7 +1,7 @@
1#ifndef B43_NPHY_H_ 1#ifndef B43_NPHY_H_
2#define B43_NPHY_H_ 2#define B43_NPHY_H_
3 3
4#include "phy.h" 4#include "phy_common.h"
5 5
6 6
7/* N-PHY registers. */ 7/* N-PHY registers. */
@@ -919,54 +919,14 @@
919 919
920struct b43_wldev; 920struct b43_wldev;
921 921
922struct b43_phy_n {
923 bool initialised;
922 924
923#ifdef CONFIG_B43_NPHY 925 //TODO lots of missing stuff
924/* N-PHY support enabled */ 926};
925 927
926int b43_phy_initn(struct b43_wldev *dev);
927 928
928void b43_nphy_radio_turn_on(struct b43_wldev *dev); 929struct b43_phy_operations;
929void b43_nphy_radio_turn_off(struct b43_wldev *dev); 930extern const struct b43_phy_operations b43_phyops_n;
930 931
931int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel);
932
933void b43_nphy_xmitpower(struct b43_wldev *dev);
934void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna);
935
936
937#else /* CONFIG_B43_NPHY */
938/* N-PHY support disabled */
939
940
941static inline
942int b43_phy_initn(struct b43_wldev *dev)
943{
944 return -EOPNOTSUPP;
945}
946
947static inline
948void b43_nphy_radio_turn_on(struct b43_wldev *dev)
949{
950}
951static inline
952void b43_nphy_radio_turn_off(struct b43_wldev *dev)
953{
954}
955
956static inline
957int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
958{
959 return -ENOSYS;
960}
961
962static inline
963void b43_nphy_xmitpower(struct b43_wldev *dev)
964{
965}
966static inline
967void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
968{
969}
970
971#endif /* CONFIG_B43_NPHY */
972#endif /* B43_NPHY_H_ */ 932#endif /* B43_NPHY_H_ */
diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c
index 305d4cd6fd03..02ae450beb00 100644
--- a/drivers/net/wireless/b43/phy.c
+++ b/drivers/net/wireless/b43/phy.c
@@ -39,160 +39,6 @@
39#include "wa.h" 39#include "wa.h"
40 40
41 41
42static const s8 b43_tssi2dbm_b_table[] = {
43 0x4D, 0x4C, 0x4B, 0x4A,
44 0x4A, 0x49, 0x48, 0x47,
45 0x47, 0x46, 0x45, 0x45,
46 0x44, 0x43, 0x42, 0x42,
47 0x41, 0x40, 0x3F, 0x3E,
48 0x3D, 0x3C, 0x3B, 0x3A,
49 0x39, 0x38, 0x37, 0x36,
50 0x35, 0x34, 0x32, 0x31,
51 0x30, 0x2F, 0x2D, 0x2C,
52 0x2B, 0x29, 0x28, 0x26,
53 0x25, 0x23, 0x21, 0x1F,
54 0x1D, 0x1A, 0x17, 0x14,
55 0x10, 0x0C, 0x06, 0x00,
56 -7, -7, -7, -7,
57 -7, -7, -7, -7,
58 -7, -7, -7, -7,
59};
60
61static const s8 b43_tssi2dbm_g_table[] = {
62 77, 77, 77, 76,
63 76, 76, 75, 75,
64 74, 74, 73, 73,
65 73, 72, 72, 71,
66 71, 70, 70, 69,
67 68, 68, 67, 67,
68 66, 65, 65, 64,
69 63, 63, 62, 61,
70 60, 59, 58, 57,
71 56, 55, 54, 53,
72 52, 50, 49, 47,
73 45, 43, 40, 37,
74 33, 28, 22, 14,
75 5, -7, -20, -20,
76 -20, -20, -20, -20,
77 -20, -20, -20, -20,
78};
79
80const u8 b43_radio_channel_codes_bg[] = {
81 12, 17, 22, 27,
82 32, 37, 42, 47,
83 52, 57, 62, 67,
84 72, 84,
85};
86
87#define bitrev4(tmp) (bitrev8(tmp) >> 4)
88static void b43_phy_initg(struct b43_wldev *dev);
89
90static void generate_rfatt_list(struct b43_wldev *dev,
91 struct b43_rfatt_list *list)
92{
93 struct b43_phy *phy = &dev->phy;
94
95 /* APHY.rev < 5 || GPHY.rev < 6 */
96 static const struct b43_rfatt rfatt_0[] = {
97 {.att = 3,.with_padmix = 0,},
98 {.att = 1,.with_padmix = 0,},
99 {.att = 5,.with_padmix = 0,},
100 {.att = 7,.with_padmix = 0,},
101 {.att = 9,.with_padmix = 0,},
102 {.att = 2,.with_padmix = 0,},
103 {.att = 0,.with_padmix = 0,},
104 {.att = 4,.with_padmix = 0,},
105 {.att = 6,.with_padmix = 0,},
106 {.att = 8,.with_padmix = 0,},
107 {.att = 1,.with_padmix = 1,},
108 {.att = 2,.with_padmix = 1,},
109 {.att = 3,.with_padmix = 1,},
110 {.att = 4,.with_padmix = 1,},
111 };
112 /* Radio.rev == 8 && Radio.version == 0x2050 */
113 static const struct b43_rfatt rfatt_1[] = {
114 {.att = 2,.with_padmix = 1,},
115 {.att = 4,.with_padmix = 1,},
116 {.att = 6,.with_padmix = 1,},
117 {.att = 8,.with_padmix = 1,},
118 {.att = 10,.with_padmix = 1,},
119 {.att = 12,.with_padmix = 1,},
120 {.att = 14,.with_padmix = 1,},
121 };
122 /* Otherwise */
123 static const struct b43_rfatt rfatt_2[] = {
124 {.att = 0,.with_padmix = 1,},
125 {.att = 2,.with_padmix = 1,},
126 {.att = 4,.with_padmix = 1,},
127 {.att = 6,.with_padmix = 1,},
128 {.att = 8,.with_padmix = 1,},
129 {.att = 9,.with_padmix = 1,},
130 {.att = 9,.with_padmix = 1,},
131 };
132
133 if (!b43_has_hardware_pctl(phy)) {
134 /* Software pctl */
135 list->list = rfatt_0;
136 list->len = ARRAY_SIZE(rfatt_0);
137 list->min_val = 0;
138 list->max_val = 9;
139 return;
140 }
141 if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
142 /* Hardware pctl */
143 list->list = rfatt_1;
144 list->len = ARRAY_SIZE(rfatt_1);
145 list->min_val = 0;
146 list->max_val = 14;
147 return;
148 }
149 /* Hardware pctl */
150 list->list = rfatt_2;
151 list->len = ARRAY_SIZE(rfatt_2);
152 list->min_val = 0;
153 list->max_val = 9;
154}
155
156static void generate_bbatt_list(struct b43_wldev *dev,
157 struct b43_bbatt_list *list)
158{
159 static const struct b43_bbatt bbatt_0[] = {
160 {.att = 0,},
161 {.att = 1,},
162 {.att = 2,},
163 {.att = 3,},
164 {.att = 4,},
165 {.att = 5,},
166 {.att = 6,},
167 {.att = 7,},
168 {.att = 8,},
169 };
170
171 list->list = bbatt_0;
172 list->len = ARRAY_SIZE(bbatt_0);
173 list->min_val = 0;
174 list->max_val = 8;
175}
176
177bool b43_has_hardware_pctl(struct b43_phy *phy)
178{
179 if (!phy->hardware_power_control)
180 return 0;
181 switch (phy->type) {
182 case B43_PHYTYPE_A:
183 if (phy->rev >= 5)
184 return 1;
185 break;
186 case B43_PHYTYPE_G:
187 if (phy->rev >= 6)
188 return 1;
189 break;
190 default:
191 B43_WARN_ON(1);
192 }
193 return 0;
194}
195
196static void b43_shm_clear_tssi(struct b43_wldev *dev) 42static void b43_shm_clear_tssi(struct b43_wldev *dev)
197{ 43{
198 struct b43_phy *phy = &dev->phy; 44 struct b43_phy *phy = &dev->phy;
@@ -212,1242 +58,6 @@ static void b43_shm_clear_tssi(struct b43_wldev *dev)
212 } 58 }
213} 59}
214 60
215/* Lock the PHY registers against concurrent access from the microcode.
216 * This lock is nonrecursive. */
217void b43_phy_lock(struct b43_wldev *dev)
218{
219#if B43_DEBUG
220 B43_WARN_ON(dev->phy.phy_locked);
221 dev->phy.phy_locked = 1;
222#endif
223 B43_WARN_ON(dev->dev->id.revision < 3);
224
225 if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
226 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
227}
228
229void b43_phy_unlock(struct b43_wldev *dev)
230{
231#if B43_DEBUG
232 B43_WARN_ON(!dev->phy.phy_locked);
233 dev->phy.phy_locked = 0;
234#endif
235 B43_WARN_ON(dev->dev->id.revision < 3);
236
237 if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
238 b43_power_saving_ctl_bits(dev, 0);
239}
240
241/* Different PHYs require different register routing flags.
242 * This adjusts (and does sanity checks on) the routing flags.
243 */
244static inline u16 adjust_phyreg_for_phytype(struct b43_phy *phy,
245 u16 offset, struct b43_wldev *dev)
246{
247 if (phy->type == B43_PHYTYPE_A) {
248 /* OFDM registers are base-registers for the A-PHY. */
249 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
250 offset &= ~B43_PHYROUTE;
251 offset |= B43_PHYROUTE_BASE;
252 }
253 }
254
255#if B43_DEBUG
256 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
257 /* Ext-G registers are only available on G-PHYs */
258 if (phy->type != B43_PHYTYPE_G) {
259 b43err(dev->wl, "Invalid EXT-G PHY access at "
260 "0x%04X on PHY type %u\n", offset, phy->type);
261 dump_stack();
262 }
263 }
264 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_N_BMODE) {
265 /* N-BMODE registers are only available on N-PHYs */
266 if (phy->type != B43_PHYTYPE_N) {
267 b43err(dev->wl, "Invalid N-BMODE PHY access at "
268 "0x%04X on PHY type %u\n", offset, phy->type);
269 dump_stack();
270 }
271 }
272#endif /* B43_DEBUG */
273
274 return offset;
275}
276
277u16 b43_phy_read(struct b43_wldev * dev, u16 offset)
278{
279 struct b43_phy *phy = &dev->phy;
280
281 offset = adjust_phyreg_for_phytype(phy, offset, dev);
282 b43_write16(dev, B43_MMIO_PHY_CONTROL, offset);
283 return b43_read16(dev, B43_MMIO_PHY_DATA);
284}
285
286void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val)
287{
288 struct b43_phy *phy = &dev->phy;
289
290 offset = adjust_phyreg_for_phytype(phy, offset, dev);
291 b43_write16(dev, B43_MMIO_PHY_CONTROL, offset);
292 b43_write16(dev, B43_MMIO_PHY_DATA, val);
293}
294
295void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
296{
297 b43_phy_write(dev, offset,
298 b43_phy_read(dev, offset) & mask);
299}
300
301void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set)
302{
303 b43_phy_write(dev, offset,
304 b43_phy_read(dev, offset) | set);
305}
306
307void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
308{
309 b43_phy_write(dev, offset,
310 (b43_phy_read(dev, offset) & mask) | set);
311}
312
313/* Adjust the transmission power output (G-PHY) */
314void b43_set_txpower_g(struct b43_wldev *dev,
315 const struct b43_bbatt *bbatt,
316 const struct b43_rfatt *rfatt, u8 tx_control)
317{
318 struct b43_phy *phy = &dev->phy;
319 struct b43_txpower_lo_control *lo = phy->lo_control;
320 u16 bb, rf;
321 u16 tx_bias, tx_magn;
322
323 bb = bbatt->att;
324 rf = rfatt->att;
325 tx_bias = lo->tx_bias;
326 tx_magn = lo->tx_magn;
327 if (unlikely(tx_bias == 0xFF))
328 tx_bias = 0;
329
330 /* Save the values for later */
331 phy->tx_control = tx_control;
332 memcpy(&phy->rfatt, rfatt, sizeof(*rfatt));
333 phy->rfatt.with_padmix = !!(tx_control & B43_TXCTL_TXMIX);
334 memcpy(&phy->bbatt, bbatt, sizeof(*bbatt));
335
336 if (b43_debug(dev, B43_DBG_XMITPOWER)) {
337 b43dbg(dev->wl, "Tuning TX-power to bbatt(%u), "
338 "rfatt(%u), tx_control(0x%02X), "
339 "tx_bias(0x%02X), tx_magn(0x%02X)\n",
340 bb, rf, tx_control, tx_bias, tx_magn);
341 }
342
343 b43_phy_set_baseband_attenuation(dev, bb);
344 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_RFATT, rf);
345 if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
346 b43_radio_write16(dev, 0x43,
347 (rf & 0x000F) | (tx_control & 0x0070));
348 } else {
349 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
350 & 0xFFF0) | (rf & 0x000F));
351 b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
352 & ~0x0070) | (tx_control &
353 0x0070));
354 }
355 if (has_tx_magnification(phy)) {
356 b43_radio_write16(dev, 0x52, tx_magn | tx_bias);
357 } else {
358 b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
359 & 0xFFF0) | (tx_bias & 0x000F));
360 }
361 if (phy->type == B43_PHYTYPE_G)
362 b43_lo_g_adjust(dev);
363}
364
365static void default_baseband_attenuation(struct b43_wldev *dev,
366 struct b43_bbatt *bb)
367{
368 struct b43_phy *phy = &dev->phy;
369
370 if (phy->radio_ver == 0x2050 && phy->radio_rev < 6)
371 bb->att = 0;
372 else
373 bb->att = 2;
374}
375
376static void default_radio_attenuation(struct b43_wldev *dev,
377 struct b43_rfatt *rf)
378{
379 struct ssb_bus *bus = dev->dev->bus;
380 struct b43_phy *phy = &dev->phy;
381
382 rf->with_padmix = 0;
383
384 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
385 bus->boardinfo.type == SSB_BOARD_BCM4309G) {
386 if (bus->boardinfo.rev < 0x43) {
387 rf->att = 2;
388 return;
389 } else if (bus->boardinfo.rev < 0x51) {
390 rf->att = 3;
391 return;
392 }
393 }
394
395 if (phy->type == B43_PHYTYPE_A) {
396 rf->att = 0x60;
397 return;
398 }
399
400 switch (phy->radio_ver) {
401 case 0x2053:
402 switch (phy->radio_rev) {
403 case 1:
404 rf->att = 6;
405 return;
406 }
407 break;
408 case 0x2050:
409 switch (phy->radio_rev) {
410 case 0:
411 rf->att = 5;
412 return;
413 case 1:
414 if (phy->type == B43_PHYTYPE_G) {
415 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
416 && bus->boardinfo.type == SSB_BOARD_BCM4309G
417 && bus->boardinfo.rev >= 30)
418 rf->att = 3;
419 else if (bus->boardinfo.vendor ==
420 SSB_BOARDVENDOR_BCM
421 && bus->boardinfo.type ==
422 SSB_BOARD_BU4306)
423 rf->att = 3;
424 else
425 rf->att = 1;
426 } else {
427 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
428 && bus->boardinfo.type == SSB_BOARD_BCM4309G
429 && bus->boardinfo.rev >= 30)
430 rf->att = 7;
431 else
432 rf->att = 6;
433 }
434 return;
435 case 2:
436 if (phy->type == B43_PHYTYPE_G) {
437 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
438 && bus->boardinfo.type == SSB_BOARD_BCM4309G
439 && bus->boardinfo.rev >= 30)
440 rf->att = 3;
441 else if (bus->boardinfo.vendor ==
442 SSB_BOARDVENDOR_BCM
443 && bus->boardinfo.type ==
444 SSB_BOARD_BU4306)
445 rf->att = 5;
446 else if (bus->chip_id == 0x4320)
447 rf->att = 4;
448 else
449 rf->att = 3;
450 } else
451 rf->att = 6;
452 return;
453 case 3:
454 rf->att = 5;
455 return;
456 case 4:
457 case 5:
458 rf->att = 1;
459 return;
460 case 6:
461 case 7:
462 rf->att = 5;
463 return;
464 case 8:
465 rf->att = 0xA;
466 rf->with_padmix = 1;
467 return;
468 case 9:
469 default:
470 rf->att = 5;
471 return;
472 }
473 }
474 rf->att = 5;
475}
476
477static u16 default_tx_control(struct b43_wldev *dev)
478{
479 struct b43_phy *phy = &dev->phy;
480
481 if (phy->radio_ver != 0x2050)
482 return 0;
483 if (phy->radio_rev == 1)
484 return B43_TXCTL_PA2DB | B43_TXCTL_TXMIX;
485 if (phy->radio_rev < 6)
486 return B43_TXCTL_PA2DB;
487 if (phy->radio_rev == 8)
488 return B43_TXCTL_TXMIX;
489 return 0;
490}
491
492/* This func is called "PHY calibrate" in the specs... */
493void b43_phy_early_init(struct b43_wldev *dev)
494{
495 struct b43_phy *phy = &dev->phy;
496 struct b43_txpower_lo_control *lo = phy->lo_control;
497
498 default_baseband_attenuation(dev, &phy->bbatt);
499 default_radio_attenuation(dev, &phy->rfatt);
500 phy->tx_control = (default_tx_control(dev) << 4);
501
502 /* Commit previous writes */
503 b43_read32(dev, B43_MMIO_MACCTL);
504
505 if (phy->type == B43_PHYTYPE_B || phy->type == B43_PHYTYPE_G) {
506 generate_rfatt_list(dev, &lo->rfatt_list);
507 generate_bbatt_list(dev, &lo->bbatt_list);
508 }
509 if (phy->type == B43_PHYTYPE_G && phy->rev == 1) {
510 /* Workaround: Temporarly disable gmode through the early init
511 * phase, as the gmode stuff is not needed for phy rev 1 */
512 phy->gmode = 0;
513 b43_wireless_core_reset(dev, 0);
514 b43_phy_initg(dev);
515 phy->gmode = 1;
516 b43_wireless_core_reset(dev, B43_TMSLOW_GMODE);
517 }
518}
519
520/* GPHY_TSSI_Power_Lookup_Table_Init */
521static void b43_gphy_tssi_power_lt_init(struct b43_wldev *dev)
522{
523 struct b43_phy *phy = &dev->phy;
524 int i;
525 u16 value;
526
527 for (i = 0; i < 32; i++)
528 b43_ofdmtab_write16(dev, 0x3C20, i, phy->tssi2dbm[i]);
529 for (i = 32; i < 64; i++)
530 b43_ofdmtab_write16(dev, 0x3C00, i - 32, phy->tssi2dbm[i]);
531 for (i = 0; i < 64; i += 2) {
532 value = (u16) phy->tssi2dbm[i];
533 value |= ((u16) phy->tssi2dbm[i + 1]) << 8;
534 b43_phy_write(dev, 0x380 + (i / 2), value);
535 }
536}
537
538/* GPHY_Gain_Lookup_Table_Init */
539static void b43_gphy_gain_lt_init(struct b43_wldev *dev)
540{
541 struct b43_phy *phy = &dev->phy;
542 struct b43_txpower_lo_control *lo = phy->lo_control;
543 u16 nr_written = 0;
544 u16 tmp;
545 u8 rf, bb;
546
547 for (rf = 0; rf < lo->rfatt_list.len; rf++) {
548 for (bb = 0; bb < lo->bbatt_list.len; bb++) {
549 if (nr_written >= 0x40)
550 return;
551 tmp = lo->bbatt_list.list[bb].att;
552 tmp <<= 8;
553 if (phy->radio_rev == 8)
554 tmp |= 0x50;
555 else
556 tmp |= 0x40;
557 tmp |= lo->rfatt_list.list[rf].att;
558 b43_phy_write(dev, 0x3C0 + nr_written, tmp);
559 nr_written++;
560 }
561 }
562}
563
564static void hardware_pctl_init_aphy(struct b43_wldev *dev)
565{
566 //TODO
567}
568
569static void hardware_pctl_init_gphy(struct b43_wldev *dev)
570{
571 struct b43_phy *phy = &dev->phy;
572
573 b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)
574 | (phy->tgt_idle_tssi - phy->cur_idle_tssi));
575 b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)
576 | (phy->tgt_idle_tssi - phy->cur_idle_tssi));
577 b43_gphy_tssi_power_lt_init(dev);
578 b43_gphy_gain_lt_init(dev);
579 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);
580 b43_phy_write(dev, 0x0014, 0x0000);
581
582 B43_WARN_ON(phy->rev < 6);
583 b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
584 | 0x0800);
585 b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
586 & 0xFEFF);
587 b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
588 & 0xFFBF);
589
590 b43_gphy_dc_lt_init(dev, 1);
591}
592
593/* HardwarePowerControl init for A and G PHY */
594static void b43_hardware_pctl_init(struct b43_wldev *dev)
595{
596 struct b43_phy *phy = &dev->phy;
597
598 if (!b43_has_hardware_pctl(phy)) {
599 /* No hardware power control */
600 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_HWPCTL);
601 return;
602 }
603 /* Init the hwpctl related hardware */
604 switch (phy->type) {
605 case B43_PHYTYPE_A:
606 hardware_pctl_init_aphy(dev);
607 break;
608 case B43_PHYTYPE_G:
609 hardware_pctl_init_gphy(dev);
610 break;
611 default:
612 B43_WARN_ON(1);
613 }
614 /* Enable hardware pctl in firmware. */
615 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_HWPCTL);
616}
617
618static void b43_hardware_pctl_early_init(struct b43_wldev *dev)
619{
620 struct b43_phy *phy = &dev->phy;
621
622 if (!b43_has_hardware_pctl(phy)) {
623 b43_phy_write(dev, 0x047A, 0xC111);
624 return;
625 }
626
627 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);
628 b43_phy_write(dev, 0x002F, 0x0202);
629 b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);
630 b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);
631 if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
632 b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
633 & 0xFF0F) | 0x0010);
634 b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
635 | 0x8000);
636 b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
637 & 0xFFC0) | 0x0010);
638 b43_phy_write(dev, 0x002E, 0xC07F);
639 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
640 | 0x0400);
641 } else {
642 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
643 | 0x0200);
644 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
645 | 0x0400);
646 b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
647 & 0x7FFF);
648 b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)
649 & 0xFFFE);
650 b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
651 & 0xFFC0) | 0x0010);
652 b43_phy_write(dev, 0x002E, 0xC07F);
653 b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
654 & 0xFF0F) | 0x0010);
655 }
656}
657
658/* Intialize B/G PHY power control
659 * as described in http://bcm-specs.sipsolutions.net/InitPowerControl
660 */
661static void b43_phy_init_pctl(struct b43_wldev *dev)
662{
663 struct ssb_bus *bus = dev->dev->bus;
664 struct b43_phy *phy = &dev->phy;
665 struct b43_rfatt old_rfatt;
666 struct b43_bbatt old_bbatt;
667 u8 old_tx_control = 0;
668
669 if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
670 (bus->boardinfo.type == SSB_BOARD_BU4306))
671 return;
672
673 b43_phy_write(dev, 0x0028, 0x8018);
674
675 /* This does something with the Analog... */
676 b43_write16(dev, B43_MMIO_PHY0, b43_read16(dev, B43_MMIO_PHY0)
677 & 0xFFDF);
678
679 if (phy->type == B43_PHYTYPE_G && !phy->gmode)
680 return;
681 b43_hardware_pctl_early_init(dev);
682 if (phy->cur_idle_tssi == 0) {
683 if (phy->radio_ver == 0x2050 && phy->analog == 0) {
684 b43_radio_write16(dev, 0x0076,
685 (b43_radio_read16(dev, 0x0076)
686 & 0x00F7) | 0x0084);
687 } else {
688 struct b43_rfatt rfatt;
689 struct b43_bbatt bbatt;
690
691 memcpy(&old_rfatt, &phy->rfatt, sizeof(old_rfatt));
692 memcpy(&old_bbatt, &phy->bbatt, sizeof(old_bbatt));
693 old_tx_control = phy->tx_control;
694
695 bbatt.att = 11;
696 if (phy->radio_rev == 8) {
697 rfatt.att = 15;
698 rfatt.with_padmix = 1;
699 } else {
700 rfatt.att = 9;
701 rfatt.with_padmix = 0;
702 }
703 b43_set_txpower_g(dev, &bbatt, &rfatt, 0);
704 }
705 b43_dummy_transmission(dev);
706 phy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_ITSSI);
707 if (B43_DEBUG) {
708 /* Current-Idle-TSSI sanity check. */
709 if (abs(phy->cur_idle_tssi - phy->tgt_idle_tssi) >= 20) {
710 b43dbg(dev->wl,
711 "!WARNING! Idle-TSSI phy->cur_idle_tssi "
712 "measuring failed. (cur=%d, tgt=%d). Disabling TX power "
713 "adjustment.\n", phy->cur_idle_tssi,
714 phy->tgt_idle_tssi);
715 phy->cur_idle_tssi = 0;
716 }
717 }
718 if (phy->radio_ver == 0x2050 && phy->analog == 0) {
719 b43_radio_write16(dev, 0x0076,
720 b43_radio_read16(dev, 0x0076)
721 & 0xFF7B);
722 } else {
723 b43_set_txpower_g(dev, &old_bbatt,
724 &old_rfatt, old_tx_control);
725 }
726 }
727 b43_hardware_pctl_init(dev);
728 b43_shm_clear_tssi(dev);
729}
730
731static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable)
732{
733 int i;
734
735 if (dev->phy.rev < 3) {
736 if (enable)
737 for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
738 b43_ofdmtab_write16(dev,
739 B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8);
740 b43_ofdmtab_write16(dev,
741 B43_OFDMTAB_WRSSI, i, 0xFFF8);
742 }
743 else
744 for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
745 b43_ofdmtab_write16(dev,
746 B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]);
747 b43_ofdmtab_write16(dev,
748 B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]);
749 }
750 } else {
751 if (enable)
752 for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++)
753 b43_ofdmtab_write16(dev,
754 B43_OFDMTAB_WRSSI, i, 0x0820);
755 else
756 for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++)
757 b43_ofdmtab_write16(dev,
758 B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]);
759 }
760}
761
762static void b43_phy_ww(struct b43_wldev *dev)
763{
764 u16 b, curr_s, best_s = 0xFFFF;
765 int i;
766
767 b43_phy_write(dev, B43_PHY_CRS0,
768 b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN);
769 b43_phy_write(dev, B43_PHY_OFDM(0x1B),
770 b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000);
771 b43_phy_write(dev, B43_PHY_OFDM(0x82),
772 (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300);
773 b43_radio_write16(dev, 0x0009,
774 b43_radio_read16(dev, 0x0009) | 0x0080);
775 b43_radio_write16(dev, 0x0012,
776 (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
777 b43_wa_initgains(dev);
778 b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
779 b = b43_phy_read(dev, B43_PHY_PWRDOWN);
780 b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
781 b43_radio_write16(dev, 0x0004,
782 b43_radio_read16(dev, 0x0004) | 0x0004);
783 for (i = 0x10; i <= 0x20; i++) {
784 b43_radio_write16(dev, 0x0013, i);
785 curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
786 if (!curr_s) {
787 best_s = 0x0000;
788 break;
789 } else if (curr_s >= 0x0080)
790 curr_s = 0x0100 - curr_s;
791 if (curr_s < best_s)
792 best_s = curr_s;
793 }
794 b43_phy_write(dev, B43_PHY_PWRDOWN, b);
795 b43_radio_write16(dev, 0x0004,
796 b43_radio_read16(dev, 0x0004) & 0xFFFB);
797 b43_radio_write16(dev, 0x0013, best_s);
798 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
799 b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
800 b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00);
801 b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
802 b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
803 b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
804 b43_phy_write(dev, B43_PHY_OFDM(0xBB),
805 (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
806 b43_phy_write(dev, B43_PHY_OFDM61,
807 (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120);
808 b43_phy_write(dev, B43_PHY_OFDM(0x13),
809 (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
810 b43_phy_write(dev, B43_PHY_OFDM(0x14),
811 (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000);
812 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
813 for (i = 0; i < 6; i++)
814 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
815 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E);
816 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
817 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
818 b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
819 b43_phy_write(dev, B43_PHY_CRS0,
820 b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
821}
822
823/* Initialize APHY. This is also called for the GPHY in some cases. */
824static void b43_phy_inita(struct b43_wldev *dev)
825{
826 struct ssb_bus *bus = dev->dev->bus;
827 struct b43_phy *phy = &dev->phy;
828
829 might_sleep();
830
831 if (phy->rev >= 6) {
832 if (phy->type == B43_PHYTYPE_A)
833 b43_phy_write(dev, B43_PHY_OFDM(0x1B),
834 b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000);
835 if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
836 b43_phy_write(dev, B43_PHY_ENCORE,
837 b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010);
838 else
839 b43_phy_write(dev, B43_PHY_ENCORE,
840 b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010);
841 }
842
843 b43_wa_all(dev);
844
845 if (phy->type == B43_PHYTYPE_A) {
846 if (phy->gmode && (phy->rev < 3))
847 b43_phy_write(dev, 0x0034,
848 b43_phy_read(dev, 0x0034) | 0x0001);
849 b43_phy_rssiagc(dev, 0);
850
851 b43_phy_write(dev, B43_PHY_CRS0,
852 b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
853
854 b43_radio_init2060(dev);
855
856 if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
857 ((bus->boardinfo.type == SSB_BOARD_BU4306) ||
858 (bus->boardinfo.type == SSB_BOARD_BU4309))) {
859 ; //TODO: A PHY LO
860 }
861
862 if (phy->rev >= 3)
863 b43_phy_ww(dev);
864
865 hardware_pctl_init_aphy(dev);
866
867 //TODO: radar detection
868 }
869
870 if ((phy->type == B43_PHYTYPE_G) &&
871 (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
872 b43_phy_write(dev, B43_PHY_OFDM(0x6E),
873 (b43_phy_read(dev, B43_PHY_OFDM(0x6E))
874 & 0xE000) | 0x3CF);
875 }
876}
877
878static void b43_phy_initb5(struct b43_wldev *dev)
879{
880 struct ssb_bus *bus = dev->dev->bus;
881 struct b43_phy *phy = &dev->phy;
882 u16 offset, value;
883 u8 old_channel;
884
885 if (phy->analog == 1) {
886 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
887 | 0x0050);
888 }
889 if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
890 (bus->boardinfo.type != SSB_BOARD_BU4306)) {
891 value = 0x2120;
892 for (offset = 0x00A8; offset < 0x00C7; offset++) {
893 b43_phy_write(dev, offset, value);
894 value += 0x202;
895 }
896 }
897 b43_phy_write(dev, 0x0035, (b43_phy_read(dev, 0x0035) & 0xF0FF)
898 | 0x0700);
899 if (phy->radio_ver == 0x2050)
900 b43_phy_write(dev, 0x0038, 0x0667);
901
902 if (phy->gmode || phy->rev >= 2) {
903 if (phy->radio_ver == 0x2050) {
904 b43_radio_write16(dev, 0x007A,
905 b43_radio_read16(dev, 0x007A)
906 | 0x0020);
907 b43_radio_write16(dev, 0x0051,
908 b43_radio_read16(dev, 0x0051)
909 | 0x0004);
910 }
911 b43_write16(dev, B43_MMIO_PHY_RADIO, 0x0000);
912
913 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
914 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
915
916 b43_phy_write(dev, 0x001C, 0x186A);
917
918 b43_phy_write(dev, 0x0013,
919 (b43_phy_read(dev, 0x0013) & 0x00FF) | 0x1900);
920 b43_phy_write(dev, 0x0035,
921 (b43_phy_read(dev, 0x0035) & 0xFFC0) | 0x0064);
922 b43_phy_write(dev, 0x005D,
923 (b43_phy_read(dev, 0x005D) & 0xFF80) | 0x000A);
924 }
925
926 if (dev->bad_frames_preempt) {
927 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
928 b43_phy_read(dev,
929 B43_PHY_RADIO_BITFIELD) | (1 << 11));
930 }
931
932 if (phy->analog == 1) {
933 b43_phy_write(dev, 0x0026, 0xCE00);
934 b43_phy_write(dev, 0x0021, 0x3763);
935 b43_phy_write(dev, 0x0022, 0x1BC3);
936 b43_phy_write(dev, 0x0023, 0x06F9);
937 b43_phy_write(dev, 0x0024, 0x037E);
938 } else
939 b43_phy_write(dev, 0x0026, 0xCC00);
940 b43_phy_write(dev, 0x0030, 0x00C6);
941 b43_write16(dev, 0x03EC, 0x3F22);
942
943 if (phy->analog == 1)
944 b43_phy_write(dev, 0x0020, 0x3E1C);
945 else
946 b43_phy_write(dev, 0x0020, 0x301C);
947
948 if (phy->analog == 0)
949 b43_write16(dev, 0x03E4, 0x3000);
950
951 old_channel = phy->channel;
952 /* Force to channel 7, even if not supported. */
953 b43_radio_selectchannel(dev, 7, 0);
954
955 if (phy->radio_ver != 0x2050) {
956 b43_radio_write16(dev, 0x0075, 0x0080);
957 b43_radio_write16(dev, 0x0079, 0x0081);
958 }
959
960 b43_radio_write16(dev, 0x0050, 0x0020);
961 b43_radio_write16(dev, 0x0050, 0x0023);
962
963 if (phy->radio_ver == 0x2050) {
964 b43_radio_write16(dev, 0x0050, 0x0020);
965 b43_radio_write16(dev, 0x005A, 0x0070);
966 }
967
968 b43_radio_write16(dev, 0x005B, 0x007B);
969 b43_radio_write16(dev, 0x005C, 0x00B0);
970
971 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007);
972
973 b43_radio_selectchannel(dev, old_channel, 0);
974
975 b43_phy_write(dev, 0x0014, 0x0080);
976 b43_phy_write(dev, 0x0032, 0x00CA);
977 b43_phy_write(dev, 0x002A, 0x88A3);
978
979 b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control);
980
981 if (phy->radio_ver == 0x2050)
982 b43_radio_write16(dev, 0x005D, 0x000D);
983
984 b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004);
985}
986
987static void b43_phy_initb6(struct b43_wldev *dev)
988{
989 struct b43_phy *phy = &dev->phy;
990 u16 offset, val;
991 u8 old_channel;
992
993 b43_phy_write(dev, 0x003E, 0x817A);
994 b43_radio_write16(dev, 0x007A,
995 (b43_radio_read16(dev, 0x007A) | 0x0058));
996 if (phy->radio_rev == 4 || phy->radio_rev == 5) {
997 b43_radio_write16(dev, 0x51, 0x37);
998 b43_radio_write16(dev, 0x52, 0x70);
999 b43_radio_write16(dev, 0x53, 0xB3);
1000 b43_radio_write16(dev, 0x54, 0x9B);
1001 b43_radio_write16(dev, 0x5A, 0x88);
1002 b43_radio_write16(dev, 0x5B, 0x88);
1003 b43_radio_write16(dev, 0x5D, 0x88);
1004 b43_radio_write16(dev, 0x5E, 0x88);
1005 b43_radio_write16(dev, 0x7D, 0x88);
1006 b43_hf_write(dev, b43_hf_read(dev)
1007 | B43_HF_TSSIRPSMW);
1008 }
1009 B43_WARN_ON(phy->radio_rev == 6 || phy->radio_rev == 7); /* We had code for these revs here... */
1010 if (phy->radio_rev == 8) {
1011 b43_radio_write16(dev, 0x51, 0);
1012 b43_radio_write16(dev, 0x52, 0x40);
1013 b43_radio_write16(dev, 0x53, 0xB7);
1014 b43_radio_write16(dev, 0x54, 0x98);
1015 b43_radio_write16(dev, 0x5A, 0x88);
1016 b43_radio_write16(dev, 0x5B, 0x6B);
1017 b43_radio_write16(dev, 0x5C, 0x0F);
1018 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
1019 b43_radio_write16(dev, 0x5D, 0xFA);
1020 b43_radio_write16(dev, 0x5E, 0xD8);
1021 } else {
1022 b43_radio_write16(dev, 0x5D, 0xF5);
1023 b43_radio_write16(dev, 0x5E, 0xB8);
1024 }
1025 b43_radio_write16(dev, 0x0073, 0x0003);
1026 b43_radio_write16(dev, 0x007D, 0x00A8);
1027 b43_radio_write16(dev, 0x007C, 0x0001);
1028 b43_radio_write16(dev, 0x007E, 0x0008);
1029 }
1030 val = 0x1E1F;
1031 for (offset = 0x0088; offset < 0x0098; offset++) {
1032 b43_phy_write(dev, offset, val);
1033 val -= 0x0202;
1034 }
1035 val = 0x3E3F;
1036 for (offset = 0x0098; offset < 0x00A8; offset++) {
1037 b43_phy_write(dev, offset, val);
1038 val -= 0x0202;
1039 }
1040 val = 0x2120;
1041 for (offset = 0x00A8; offset < 0x00C8; offset++) {
1042 b43_phy_write(dev, offset, (val & 0x3F3F));
1043 val += 0x0202;
1044 }
1045 if (phy->type == B43_PHYTYPE_G) {
1046 b43_radio_write16(dev, 0x007A,
1047 b43_radio_read16(dev, 0x007A) | 0x0020);
1048 b43_radio_write16(dev, 0x0051,
1049 b43_radio_read16(dev, 0x0051) | 0x0004);
1050 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
1051 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
1052 b43_phy_write(dev, 0x5B, 0);
1053 b43_phy_write(dev, 0x5C, 0);
1054 }
1055
1056 old_channel = phy->channel;
1057 if (old_channel >= 8)
1058 b43_radio_selectchannel(dev, 1, 0);
1059 else
1060 b43_radio_selectchannel(dev, 13, 0);
1061
1062 b43_radio_write16(dev, 0x0050, 0x0020);
1063 b43_radio_write16(dev, 0x0050, 0x0023);
1064 udelay(40);
1065 if (phy->radio_rev < 6 || phy->radio_rev == 8) {
1066 b43_radio_write16(dev, 0x7C, (b43_radio_read16(dev, 0x7C)
1067 | 0x0002));
1068 b43_radio_write16(dev, 0x50, 0x20);
1069 }
1070 if (phy->radio_rev <= 2) {
1071 b43_radio_write16(dev, 0x7C, 0x20);
1072 b43_radio_write16(dev, 0x5A, 0x70);
1073 b43_radio_write16(dev, 0x5B, 0x7B);
1074 b43_radio_write16(dev, 0x5C, 0xB0);
1075 }
1076 b43_radio_write16(dev, 0x007A,
1077 (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007);
1078
1079 b43_radio_selectchannel(dev, old_channel, 0);
1080
1081 b43_phy_write(dev, 0x0014, 0x0200);
1082 if (phy->radio_rev >= 6)
1083 b43_phy_write(dev, 0x2A, 0x88C2);
1084 else
1085 b43_phy_write(dev, 0x2A, 0x8AC0);
1086 b43_phy_write(dev, 0x0038, 0x0668);
1087 b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control);
1088 if (phy->radio_rev <= 5) {
1089 b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D)
1090 & 0xFF80) | 0x0003);
1091 }
1092 if (phy->radio_rev <= 2)
1093 b43_radio_write16(dev, 0x005D, 0x000D);
1094
1095 if (phy->analog == 4) {
1096 b43_write16(dev, 0x3E4, 9);
1097 b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61)
1098 & 0x0FFF);
1099 } else {
1100 b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
1101 | 0x0004);
1102 }
1103 if (phy->type == B43_PHYTYPE_B)
1104 B43_WARN_ON(1);
1105 else if (phy->type == B43_PHYTYPE_G)
1106 b43_write16(dev, 0x03E6, 0x0);
1107}
1108
1109static void b43_calc_loopback_gain(struct b43_wldev *dev)
1110{
1111 struct b43_phy *phy = &dev->phy;
1112 u16 backup_phy[16] = { 0 };
1113 u16 backup_radio[3];
1114 u16 backup_bband;
1115 u16 i, j, loop_i_max;
1116 u16 trsw_rx;
1117 u16 loop1_outer_done, loop1_inner_done;
1118
1119 backup_phy[0] = b43_phy_read(dev, B43_PHY_CRS0);
1120 backup_phy[1] = b43_phy_read(dev, B43_PHY_CCKBBANDCFG);
1121 backup_phy[2] = b43_phy_read(dev, B43_PHY_RFOVER);
1122 backup_phy[3] = b43_phy_read(dev, B43_PHY_RFOVERVAL);
1123 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
1124 backup_phy[4] = b43_phy_read(dev, B43_PHY_ANALOGOVER);
1125 backup_phy[5] = b43_phy_read(dev, B43_PHY_ANALOGOVERVAL);
1126 }
1127 backup_phy[6] = b43_phy_read(dev, B43_PHY_CCK(0x5A));
1128 backup_phy[7] = b43_phy_read(dev, B43_PHY_CCK(0x59));
1129 backup_phy[8] = b43_phy_read(dev, B43_PHY_CCK(0x58));
1130 backup_phy[9] = b43_phy_read(dev, B43_PHY_CCK(0x0A));
1131 backup_phy[10] = b43_phy_read(dev, B43_PHY_CCK(0x03));
1132 backup_phy[11] = b43_phy_read(dev, B43_PHY_LO_MASK);
1133 backup_phy[12] = b43_phy_read(dev, B43_PHY_LO_CTL);
1134 backup_phy[13] = b43_phy_read(dev, B43_PHY_CCK(0x2B));
1135 backup_phy[14] = b43_phy_read(dev, B43_PHY_PGACTL);
1136 backup_phy[15] = b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
1137 backup_bband = phy->bbatt.att;
1138 backup_radio[0] = b43_radio_read16(dev, 0x52);
1139 backup_radio[1] = b43_radio_read16(dev, 0x43);
1140 backup_radio[2] = b43_radio_read16(dev, 0x7A);
1141
1142 b43_phy_write(dev, B43_PHY_CRS0,
1143 b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF);
1144 b43_phy_write(dev, B43_PHY_CCKBBANDCFG,
1145 b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000);
1146 b43_phy_write(dev, B43_PHY_RFOVER,
1147 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002);
1148 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1149 b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD);
1150 b43_phy_write(dev, B43_PHY_RFOVER,
1151 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001);
1152 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1153 b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE);
1154 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
1155 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1156 b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001);
1157 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1158 b43_phy_read(dev,
1159 B43_PHY_ANALOGOVERVAL) & 0xFFFE);
1160 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1161 b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002);
1162 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1163 b43_phy_read(dev,
1164 B43_PHY_ANALOGOVERVAL) & 0xFFFD);
1165 }
1166 b43_phy_write(dev, B43_PHY_RFOVER,
1167 b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C);
1168 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1169 b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C);
1170 b43_phy_write(dev, B43_PHY_RFOVER,
1171 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030);
1172 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1173 (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1174 & 0xFFCF) | 0x10);
1175
1176 b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
1177 b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
1178 b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
1179
1180 b43_phy_write(dev, B43_PHY_CCK(0x0A),
1181 b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
1182 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
1183 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1184 b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
1185 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1186 b43_phy_read(dev,
1187 B43_PHY_ANALOGOVERVAL) & 0xFFFB);
1188 }
1189 b43_phy_write(dev, B43_PHY_CCK(0x03),
1190 (b43_phy_read(dev, B43_PHY_CCK(0x03))
1191 & 0xFF9F) | 0x40);
1192
1193 if (phy->radio_rev == 8) {
1194 b43_radio_write16(dev, 0x43, 0x000F);
1195 } else {
1196 b43_radio_write16(dev, 0x52, 0);
1197 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
1198 & 0xFFF0) | 0x9);
1199 }
1200 b43_phy_set_baseband_attenuation(dev, 11);
1201
1202 if (phy->rev >= 3)
1203 b43_phy_write(dev, B43_PHY_LO_MASK, 0xC020);
1204 else
1205 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
1206 b43_phy_write(dev, B43_PHY_LO_CTL, 0);
1207
1208 b43_phy_write(dev, B43_PHY_CCK(0x2B),
1209 (b43_phy_read(dev, B43_PHY_CCK(0x2B))
1210 & 0xFFC0) | 0x01);
1211 b43_phy_write(dev, B43_PHY_CCK(0x2B),
1212 (b43_phy_read(dev, B43_PHY_CCK(0x2B))
1213 & 0xC0FF) | 0x800);
1214
1215 b43_phy_write(dev, B43_PHY_RFOVER,
1216 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100);
1217 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1218 b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
1219
1220 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
1221 if (phy->rev >= 7) {
1222 b43_phy_write(dev, B43_PHY_RFOVER,
1223 b43_phy_read(dev, B43_PHY_RFOVER)
1224 | 0x0800);
1225 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1226 b43_phy_read(dev, B43_PHY_RFOVERVAL)
1227 | 0x8000);
1228 }
1229 }
1230 b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A)
1231 & 0x00F7);
1232
1233 j = 0;
1234 loop_i_max = (phy->radio_rev == 8) ? 15 : 9;
1235 for (i = 0; i < loop_i_max; i++) {
1236 for (j = 0; j < 16; j++) {
1237 b43_radio_write16(dev, 0x43, i);
1238 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1239 (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1240 & 0xF0FF) | (j << 8));
1241 b43_phy_write(dev, B43_PHY_PGACTL,
1242 (b43_phy_read(dev, B43_PHY_PGACTL)
1243 & 0x0FFF) | 0xA000);
1244 b43_phy_write(dev, B43_PHY_PGACTL,
1245 b43_phy_read(dev, B43_PHY_PGACTL)
1246 | 0xF000);
1247 udelay(20);
1248 if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
1249 goto exit_loop1;
1250 }
1251 }
1252 exit_loop1:
1253 loop1_outer_done = i;
1254 loop1_inner_done = j;
1255 if (j >= 8) {
1256 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1257 b43_phy_read(dev, B43_PHY_RFOVERVAL)
1258 | 0x30);
1259 trsw_rx = 0x1B;
1260 for (j = j - 8; j < 16; j++) {
1261 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1262 (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1263 & 0xF0FF) | (j << 8));
1264 b43_phy_write(dev, B43_PHY_PGACTL,
1265 (b43_phy_read(dev, B43_PHY_PGACTL)
1266 & 0x0FFF) | 0xA000);
1267 b43_phy_write(dev, B43_PHY_PGACTL,
1268 b43_phy_read(dev, B43_PHY_PGACTL)
1269 | 0xF000);
1270 udelay(20);
1271 trsw_rx -= 3;
1272 if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
1273 goto exit_loop2;
1274 }
1275 } else
1276 trsw_rx = 0x18;
1277 exit_loop2:
1278
1279 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
1280 b43_phy_write(dev, B43_PHY_ANALOGOVER, backup_phy[4]);
1281 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, backup_phy[5]);
1282 }
1283 b43_phy_write(dev, B43_PHY_CCK(0x5A), backup_phy[6]);
1284 b43_phy_write(dev, B43_PHY_CCK(0x59), backup_phy[7]);
1285 b43_phy_write(dev, B43_PHY_CCK(0x58), backup_phy[8]);
1286 b43_phy_write(dev, B43_PHY_CCK(0x0A), backup_phy[9]);
1287 b43_phy_write(dev, B43_PHY_CCK(0x03), backup_phy[10]);
1288 b43_phy_write(dev, B43_PHY_LO_MASK, backup_phy[11]);
1289 b43_phy_write(dev, B43_PHY_LO_CTL, backup_phy[12]);
1290 b43_phy_write(dev, B43_PHY_CCK(0x2B), backup_phy[13]);
1291 b43_phy_write(dev, B43_PHY_PGACTL, backup_phy[14]);
1292
1293 b43_phy_set_baseband_attenuation(dev, backup_bband);
1294
1295 b43_radio_write16(dev, 0x52, backup_radio[0]);
1296 b43_radio_write16(dev, 0x43, backup_radio[1]);
1297 b43_radio_write16(dev, 0x7A, backup_radio[2]);
1298
1299 b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2] | 0x0003);
1300 udelay(10);
1301 b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2]);
1302 b43_phy_write(dev, B43_PHY_RFOVERVAL, backup_phy[3]);
1303 b43_phy_write(dev, B43_PHY_CRS0, backup_phy[0]);
1304 b43_phy_write(dev, B43_PHY_CCKBBANDCFG, backup_phy[1]);
1305
1306 phy->max_lb_gain =
1307 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
1308 phy->trsw_rx_gain = trsw_rx * 2;
1309}
1310
1311static void b43_phy_initg(struct b43_wldev *dev)
1312{
1313 struct b43_phy *phy = &dev->phy;
1314 u16 tmp;
1315
1316 if (phy->rev == 1)
1317 b43_phy_initb5(dev);
1318 else
1319 b43_phy_initb6(dev);
1320
1321 if (phy->rev >= 2 || phy->gmode)
1322 b43_phy_inita(dev);
1323
1324 if (phy->rev >= 2) {
1325 b43_phy_write(dev, B43_PHY_ANALOGOVER, 0);
1326 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, 0);
1327 }
1328 if (phy->rev == 2) {
1329 b43_phy_write(dev, B43_PHY_RFOVER, 0);
1330 b43_phy_write(dev, B43_PHY_PGACTL, 0xC0);
1331 }
1332 if (phy->rev > 5) {
1333 b43_phy_write(dev, B43_PHY_RFOVER, 0x400);
1334 b43_phy_write(dev, B43_PHY_PGACTL, 0xC0);
1335 }
1336 if (phy->gmode || phy->rev >= 2) {
1337 tmp = b43_phy_read(dev, B43_PHY_VERSION_OFDM);
1338 tmp &= B43_PHYVER_VERSION;
1339 if (tmp == 3 || tmp == 5) {
1340 b43_phy_write(dev, B43_PHY_OFDM(0xC2), 0x1816);
1341 b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006);
1342 }
1343 if (tmp == 5) {
1344 b43_phy_write(dev, B43_PHY_OFDM(0xCC),
1345 (b43_phy_read(dev, B43_PHY_OFDM(0xCC))
1346 & 0x00FF) | 0x1F00);
1347 }
1348 }
1349 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
1350 b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78);
1351 if (phy->radio_rev == 8) {
1352 b43_phy_write(dev, B43_PHY_EXTG(0x01),
1353 b43_phy_read(dev, B43_PHY_EXTG(0x01))
1354 | 0x80);
1355 b43_phy_write(dev, B43_PHY_OFDM(0x3E),
1356 b43_phy_read(dev, B43_PHY_OFDM(0x3E))
1357 | 0x4);
1358 }
1359 if (has_loopback_gain(phy))
1360 b43_calc_loopback_gain(dev);
1361
1362 if (phy->radio_rev != 8) {
1363 if (phy->initval == 0xFFFF)
1364 phy->initval = b43_radio_init2050(dev);
1365 else
1366 b43_radio_write16(dev, 0x0078, phy->initval);
1367 }
1368 b43_lo_g_init(dev);
1369 if (has_tx_magnification(phy)) {
1370 b43_radio_write16(dev, 0x52,
1371 (b43_radio_read16(dev, 0x52) & 0xFF00)
1372 | phy->lo_control->tx_bias | phy->
1373 lo_control->tx_magn);
1374 } else {
1375 b43_radio_write16(dev, 0x52,
1376 (b43_radio_read16(dev, 0x52) & 0xFFF0)
1377 | phy->lo_control->tx_bias);
1378 }
1379 if (phy->rev >= 6) {
1380 b43_phy_write(dev, B43_PHY_CCK(0x36),
1381 (b43_phy_read(dev, B43_PHY_CCK(0x36))
1382 & 0x0FFF) | (phy->lo_control->
1383 tx_bias << 12));
1384 }
1385 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
1386 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
1387 else
1388 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
1389 if (phy->rev < 2)
1390 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x101);
1391 else
1392 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x202);
1393 if (phy->gmode || phy->rev >= 2) {
1394 b43_lo_g_adjust(dev);
1395 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
1396 }
1397
1398 if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
1399 /* The specs state to update the NRSSI LT with
1400 * the value 0x7FFFFFFF here. I think that is some weird
1401 * compiler optimization in the original driver.
1402 * Essentially, what we do here is resetting all NRSSI LT
1403 * entries to -32 (see the clamp_val() in nrssi_hw_update())
1404 */
1405 b43_nrssi_hw_update(dev, 0xFFFF); //FIXME?
1406 b43_calc_nrssi_threshold(dev);
1407 } else if (phy->gmode || phy->rev >= 2) {
1408 if (phy->nrssi[0] == -1000) {
1409 B43_WARN_ON(phy->nrssi[1] != -1000);
1410 b43_calc_nrssi_slope(dev);
1411 } else
1412 b43_calc_nrssi_threshold(dev);
1413 }
1414 if (phy->radio_rev == 8)
1415 b43_phy_write(dev, B43_PHY_EXTG(0x05), 0x3230);
1416 b43_phy_init_pctl(dev);
1417 /* FIXME: The spec says in the following if, the 0 should be replaced
1418 'if OFDM may not be used in the current locale'
1419 but OFDM is legal everywhere */
1420 if ((dev->dev->bus->chip_id == 0x4306
1421 && dev->dev->bus->chip_package == 2) || 0) {
1422 b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
1423 & 0xBFFF);
1424 b43_phy_write(dev, B43_PHY_OFDM(0xC3),
1425 b43_phy_read(dev, B43_PHY_OFDM(0xC3))
1426 & 0x7FFF);
1427 }
1428}
1429
1430/* Set the baseband attenuation value on chip. */
1431void b43_phy_set_baseband_attenuation(struct b43_wldev *dev,
1432 u16 baseband_attenuation)
1433{
1434 struct b43_phy *phy = &dev->phy;
1435
1436 if (phy->analog == 0) {
1437 b43_write16(dev, B43_MMIO_PHY0, (b43_read16(dev, B43_MMIO_PHY0)
1438 & 0xFFF0) |
1439 baseband_attenuation);
1440 } else if (phy->analog > 1) {
1441 b43_phy_write(dev, B43_PHY_DACCTL,
1442 (b43_phy_read(dev, B43_PHY_DACCTL)
1443 & 0xFFC3) | (baseband_attenuation << 2));
1444 } else {
1445 b43_phy_write(dev, B43_PHY_DACCTL,
1446 (b43_phy_read(dev, B43_PHY_DACCTL)
1447 & 0xFF87) | (baseband_attenuation << 3));
1448 }
1449}
1450
1451/* http://bcm-specs.sipsolutions.net/EstimatePowerOut 61/* http://bcm-specs.sipsolutions.net/EstimatePowerOut
1452 * This function converts a TSSI value to dBm in Q5.2 62 * This function converts a TSSI value to dBm in Q5.2
1453 */ 63 */
@@ -1819,2009 +429,6 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev)
1819 return 0; 429 return 0;
1820} 430}
1821 431
1822int b43_phy_init(struct b43_wldev *dev)
1823{
1824 struct b43_phy *phy = &dev->phy;
1825 bool unsupported = 0;
1826 int err = 0;
1827
1828 switch (phy->type) {
1829 case B43_PHYTYPE_A:
1830 if (phy->rev == 2 || phy->rev == 3)
1831 b43_phy_inita(dev);
1832 else
1833 unsupported = 1;
1834 break;
1835 case B43_PHYTYPE_G:
1836 b43_phy_initg(dev);
1837 break;
1838 case B43_PHYTYPE_N:
1839 err = b43_phy_initn(dev);
1840 break;
1841 default:
1842 unsupported = 1;
1843 }
1844 if (unsupported)
1845 b43err(dev->wl, "Unknown PHYTYPE found\n");
1846
1847 return err;
1848}
1849
1850void b43_set_rx_antenna(struct b43_wldev *dev, int antenna)
1851{
1852 struct b43_phy *phy = &dev->phy;
1853 u64 hf;
1854 u16 tmp;
1855 int autodiv = 0;
1856
1857 if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
1858 autodiv = 1;
1859
1860 hf = b43_hf_read(dev);
1861 hf &= ~B43_HF_ANTDIVHELP;
1862 b43_hf_write(dev, hf);
1863
1864 switch (phy->type) {
1865 case B43_PHYTYPE_A:
1866 case B43_PHYTYPE_G:
1867 tmp = b43_phy_read(dev, B43_PHY_BBANDCFG);
1868 tmp &= ~B43_PHY_BBANDCFG_RXANT;
1869 tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
1870 << B43_PHY_BBANDCFG_RXANT_SHIFT;
1871 b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
1872
1873 if (autodiv) {
1874 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
1875 if (antenna == B43_ANTENNA_AUTO0)
1876 tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
1877 else
1878 tmp |= B43_PHY_ANTDWELL_AUTODIV1;
1879 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
1880 }
1881 if (phy->type == B43_PHYTYPE_G) {
1882 tmp = b43_phy_read(dev, B43_PHY_ANTWRSETT);
1883 if (autodiv)
1884 tmp |= B43_PHY_ANTWRSETT_ARXDIV;
1885 else
1886 tmp &= ~B43_PHY_ANTWRSETT_ARXDIV;
1887 b43_phy_write(dev, B43_PHY_ANTWRSETT, tmp);
1888 if (phy->rev >= 2) {
1889 tmp = b43_phy_read(dev, B43_PHY_OFDM61);
1890 tmp |= B43_PHY_OFDM61_10;
1891 b43_phy_write(dev, B43_PHY_OFDM61, tmp);
1892
1893 tmp =
1894 b43_phy_read(dev, B43_PHY_DIVSRCHGAINBACK);
1895 tmp = (tmp & 0xFF00) | 0x15;
1896 b43_phy_write(dev, B43_PHY_DIVSRCHGAINBACK,
1897 tmp);
1898
1899 if (phy->rev == 2) {
1900 b43_phy_write(dev, B43_PHY_ADIVRELATED,
1901 8);
1902 } else {
1903 tmp =
1904 b43_phy_read(dev,
1905 B43_PHY_ADIVRELATED);
1906 tmp = (tmp & 0xFF00) | 8;
1907 b43_phy_write(dev, B43_PHY_ADIVRELATED,
1908 tmp);
1909 }
1910 }
1911 if (phy->rev >= 6)
1912 b43_phy_write(dev, B43_PHY_OFDM9B, 0xDC);
1913 } else {
1914 if (phy->rev < 3) {
1915 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
1916 tmp = (tmp & 0xFF00) | 0x24;
1917 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
1918 } else {
1919 tmp = b43_phy_read(dev, B43_PHY_OFDM61);
1920 tmp |= 0x10;
1921 b43_phy_write(dev, B43_PHY_OFDM61, tmp);
1922 if (phy->analog == 3) {
1923 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
1924 0x1D);
1925 b43_phy_write(dev, B43_PHY_ADIVRELATED,
1926 8);
1927 } else {
1928 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
1929 0x3A);
1930 tmp =
1931 b43_phy_read(dev,
1932 B43_PHY_ADIVRELATED);
1933 tmp = (tmp & 0xFF00) | 8;
1934 b43_phy_write(dev, B43_PHY_ADIVRELATED,
1935 tmp);
1936 }
1937 }
1938 }
1939 break;
1940 case B43_PHYTYPE_B:
1941 tmp = b43_phy_read(dev, B43_PHY_CCKBBANDCFG);
1942 tmp &= ~B43_PHY_BBANDCFG_RXANT;
1943 tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
1944 << B43_PHY_BBANDCFG_RXANT_SHIFT;
1945 b43_phy_write(dev, B43_PHY_CCKBBANDCFG, tmp);
1946 break;
1947 case B43_PHYTYPE_N:
1948 b43_nphy_set_rxantenna(dev, antenna);
1949 break;
1950 default:
1951 B43_WARN_ON(1);
1952 }
1953
1954 hf |= B43_HF_ANTDIVHELP;
1955 b43_hf_write(dev, hf);
1956}
1957
1958/* Get the freq, as it has to be written to the device. */
1959static inline u16 channel2freq_bg(u8 channel)
1960{
1961 B43_WARN_ON(!(channel >= 1 && channel <= 14));
1962
1963 return b43_radio_channel_codes_bg[channel - 1];
1964}
1965
1966/* Get the freq, as it has to be written to the device. */
1967static inline u16 channel2freq_a(u8 channel)
1968{
1969 B43_WARN_ON(channel > 200);
1970
1971 return (5000 + 5 * channel);
1972}
1973
1974void b43_radio_lock(struct b43_wldev *dev)
1975{
1976 u32 macctl;
1977
1978 macctl = b43_read32(dev, B43_MMIO_MACCTL);
1979 B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK);
1980 macctl |= B43_MACCTL_RADIOLOCK;
1981 b43_write32(dev, B43_MMIO_MACCTL, macctl);
1982 /* Commit the write and wait for the device
1983 * to exit any radio register access. */
1984 b43_read32(dev, B43_MMIO_MACCTL);
1985 udelay(10);
1986}
1987
1988void b43_radio_unlock(struct b43_wldev *dev)
1989{
1990 u32 macctl;
1991
1992 /* Commit any write */
1993 b43_read16(dev, B43_MMIO_PHY_VER);
1994 /* unlock */
1995 macctl = b43_read32(dev, B43_MMIO_MACCTL);
1996 B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK));
1997 macctl &= ~B43_MACCTL_RADIOLOCK;
1998 b43_write32(dev, B43_MMIO_MACCTL, macctl);
1999}
2000
2001u16 b43_radio_read16(struct b43_wldev *dev, u16 offset)
2002{
2003 struct b43_phy *phy = &dev->phy;
2004
2005 /* Offset 1 is a 32-bit register. */
2006 B43_WARN_ON(offset == 1);
2007
2008 switch (phy->type) {
2009 case B43_PHYTYPE_A:
2010 offset |= 0x40;
2011 break;
2012 case B43_PHYTYPE_B:
2013 if (phy->radio_ver == 0x2053) {
2014 if (offset < 0x70)
2015 offset += 0x80;
2016 else if (offset < 0x80)
2017 offset += 0x70;
2018 } else if (phy->radio_ver == 0x2050) {
2019 offset |= 0x80;
2020 } else
2021 B43_WARN_ON(1);
2022 break;
2023 case B43_PHYTYPE_G:
2024 offset |= 0x80;
2025 break;
2026 case B43_PHYTYPE_N:
2027 offset |= 0x100;
2028 break;
2029 case B43_PHYTYPE_LP:
2030 /* No adjustment required. */
2031 break;
2032 default:
2033 B43_WARN_ON(1);
2034 }
2035
2036 b43_write16(dev, B43_MMIO_RADIO_CONTROL, offset);
2037 return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
2038}
2039
2040void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val)
2041{
2042 /* Offset 1 is a 32-bit register. */
2043 B43_WARN_ON(offset == 1);
2044
2045 b43_write16(dev, B43_MMIO_RADIO_CONTROL, offset);
2046 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, val);
2047}
2048
2049void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask)
2050{
2051 b43_radio_write16(dev, offset,
2052 b43_radio_read16(dev, offset) & mask);
2053}
2054
2055void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set)
2056{
2057 b43_radio_write16(dev, offset,
2058 b43_radio_read16(dev, offset) | set);
2059}
2060
2061void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
2062{
2063 b43_radio_write16(dev, offset,
2064 (b43_radio_read16(dev, offset) & mask) | set);
2065}
2066
2067static void b43_set_all_gains(struct b43_wldev *dev,
2068 s16 first, s16 second, s16 third)
2069{
2070 struct b43_phy *phy = &dev->phy;
2071 u16 i;
2072 u16 start = 0x08, end = 0x18;
2073 u16 tmp;
2074 u16 table;
2075
2076 if (phy->rev <= 1) {
2077 start = 0x10;
2078 end = 0x20;
2079 }
2080
2081 table = B43_OFDMTAB_GAINX;
2082 if (phy->rev <= 1)
2083 table = B43_OFDMTAB_GAINX_R1;
2084 for (i = 0; i < 4; i++)
2085 b43_ofdmtab_write16(dev, table, i, first);
2086
2087 for (i = start; i < end; i++)
2088 b43_ofdmtab_write16(dev, table, i, second);
2089
2090 if (third != -1) {
2091 tmp = ((u16) third << 14) | ((u16) third << 6);
2092 b43_phy_write(dev, 0x04A0,
2093 (b43_phy_read(dev, 0x04A0) & 0xBFBF) | tmp);
2094 b43_phy_write(dev, 0x04A1,
2095 (b43_phy_read(dev, 0x04A1) & 0xBFBF) | tmp);
2096 b43_phy_write(dev, 0x04A2,
2097 (b43_phy_read(dev, 0x04A2) & 0xBFBF) | tmp);
2098 }
2099 b43_dummy_transmission(dev);
2100}
2101
2102static void b43_set_original_gains(struct b43_wldev *dev)
2103{
2104 struct b43_phy *phy = &dev->phy;
2105 u16 i, tmp;
2106 u16 table;
2107 u16 start = 0x0008, end = 0x0018;
2108
2109 if (phy->rev <= 1) {
2110 start = 0x0010;
2111 end = 0x0020;
2112 }
2113
2114 table = B43_OFDMTAB_GAINX;
2115 if (phy->rev <= 1)
2116 table = B43_OFDMTAB_GAINX_R1;
2117 for (i = 0; i < 4; i++) {
2118 tmp = (i & 0xFFFC);
2119 tmp |= (i & 0x0001) << 1;
2120 tmp |= (i & 0x0002) >> 1;
2121
2122 b43_ofdmtab_write16(dev, table, i, tmp);
2123 }
2124
2125 for (i = start; i < end; i++)
2126 b43_ofdmtab_write16(dev, table, i, i - start);
2127
2128 b43_phy_write(dev, 0x04A0,
2129 (b43_phy_read(dev, 0x04A0) & 0xBFBF) | 0x4040);
2130 b43_phy_write(dev, 0x04A1,
2131 (b43_phy_read(dev, 0x04A1) & 0xBFBF) | 0x4040);
2132 b43_phy_write(dev, 0x04A2,
2133 (b43_phy_read(dev, 0x04A2) & 0xBFBF) | 0x4000);
2134 b43_dummy_transmission(dev);
2135}
2136
2137/* Synthetic PU workaround */
2138static void b43_synth_pu_workaround(struct b43_wldev *dev, u8 channel)
2139{
2140 struct b43_phy *phy = &dev->phy;
2141
2142 might_sleep();
2143
2144 if (phy->radio_ver != 0x2050 || phy->radio_rev >= 6) {
2145 /* We do not need the workaround. */
2146 return;
2147 }
2148
2149 if (channel <= 10) {
2150 b43_write16(dev, B43_MMIO_CHANNEL,
2151 channel2freq_bg(channel + 4));
2152 } else {
2153 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(1));
2154 }
2155 msleep(1);
2156 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
2157}
2158
2159u8 b43_radio_aci_detect(struct b43_wldev *dev, u8 channel)
2160{
2161 struct b43_phy *phy = &dev->phy;
2162 u8 ret = 0;
2163 u16 saved, rssi, temp;
2164 int i, j = 0;
2165
2166 saved = b43_phy_read(dev, 0x0403);
2167 b43_radio_selectchannel(dev, channel, 0);
2168 b43_phy_write(dev, 0x0403, (saved & 0xFFF8) | 5);
2169 if (phy->aci_hw_rssi)
2170 rssi = b43_phy_read(dev, 0x048A) & 0x3F;
2171 else
2172 rssi = saved & 0x3F;
2173 /* clamp temp to signed 5bit */
2174 if (rssi > 32)
2175 rssi -= 64;
2176 for (i = 0; i < 100; i++) {
2177 temp = (b43_phy_read(dev, 0x047F) >> 8) & 0x3F;
2178 if (temp > 32)
2179 temp -= 64;
2180 if (temp < rssi)
2181 j++;
2182 if (j >= 20)
2183 ret = 1;
2184 }
2185 b43_phy_write(dev, 0x0403, saved);
2186
2187 return ret;
2188}
2189
2190u8 b43_radio_aci_scan(struct b43_wldev * dev)
2191{
2192 struct b43_phy *phy = &dev->phy;
2193 u8 ret[13];
2194 unsigned int channel = phy->channel;
2195 unsigned int i, j, start, end;
2196
2197 if (!((phy->type == B43_PHYTYPE_G) && (phy->rev > 0)))
2198 return 0;
2199
2200 b43_phy_lock(dev);
2201 b43_radio_lock(dev);
2202 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
2203 b43_phy_write(dev, B43_PHY_G_CRS,
2204 b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
2205 b43_set_all_gains(dev, 3, 8, 1);
2206
2207 start = (channel - 5 > 0) ? channel - 5 : 1;
2208 end = (channel + 5 < 14) ? channel + 5 : 13;
2209
2210 for (i = start; i <= end; i++) {
2211 if (abs(channel - i) > 2)
2212 ret[i - 1] = b43_radio_aci_detect(dev, i);
2213 }
2214 b43_radio_selectchannel(dev, channel, 0);
2215 b43_phy_write(dev, 0x0802,
2216 (b43_phy_read(dev, 0x0802) & 0xFFFC) | 0x0003);
2217 b43_phy_write(dev, 0x0403, b43_phy_read(dev, 0x0403) & 0xFFF8);
2218 b43_phy_write(dev, B43_PHY_G_CRS,
2219 b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
2220 b43_set_original_gains(dev);
2221 for (i = 0; i < 13; i++) {
2222 if (!ret[i])
2223 continue;
2224 end = (i + 5 < 13) ? i + 5 : 13;
2225 for (j = i; j < end; j++)
2226 ret[j] = 1;
2227 }
2228 b43_radio_unlock(dev);
2229 b43_phy_unlock(dev);
2230
2231 return ret[channel - 1];
2232}
2233
2234/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
2235void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val)
2236{
2237 b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
2238 mmiowb();
2239 b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val);
2240}
2241
2242/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
2243s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset)
2244{
2245 u16 val;
2246
2247 b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
2248 val = b43_phy_read(dev, B43_PHY_NRSSILT_DATA);
2249
2250 return (s16) val;
2251}
2252
2253/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
2254void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val)
2255{
2256 u16 i;
2257 s16 tmp;
2258
2259 for (i = 0; i < 64; i++) {
2260 tmp = b43_nrssi_hw_read(dev, i);
2261 tmp -= val;
2262 tmp = clamp_val(tmp, -32, 31);
2263 b43_nrssi_hw_write(dev, i, tmp);
2264 }
2265}
2266
2267/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
2268void b43_nrssi_mem_update(struct b43_wldev *dev)
2269{
2270 struct b43_phy *phy = &dev->phy;
2271 s16 i, delta;
2272 s32 tmp;
2273
2274 delta = 0x1F - phy->nrssi[0];
2275 for (i = 0; i < 64; i++) {
2276 tmp = (i - delta) * phy->nrssislope;
2277 tmp /= 0x10000;
2278 tmp += 0x3A;
2279 tmp = clamp_val(tmp, 0, 0x3F);
2280 phy->nrssi_lt[i] = tmp;
2281 }
2282}
2283
2284static void b43_calc_nrssi_offset(struct b43_wldev *dev)
2285{
2286 struct b43_phy *phy = &dev->phy;
2287 u16 backup[20] = { 0 };
2288 s16 v47F;
2289 u16 i;
2290 u16 saved = 0xFFFF;
2291
2292 backup[0] = b43_phy_read(dev, 0x0001);
2293 backup[1] = b43_phy_read(dev, 0x0811);
2294 backup[2] = b43_phy_read(dev, 0x0812);
2295 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
2296 backup[3] = b43_phy_read(dev, 0x0814);
2297 backup[4] = b43_phy_read(dev, 0x0815);
2298 }
2299 backup[5] = b43_phy_read(dev, 0x005A);
2300 backup[6] = b43_phy_read(dev, 0x0059);
2301 backup[7] = b43_phy_read(dev, 0x0058);
2302 backup[8] = b43_phy_read(dev, 0x000A);
2303 backup[9] = b43_phy_read(dev, 0x0003);
2304 backup[10] = b43_radio_read16(dev, 0x007A);
2305 backup[11] = b43_radio_read16(dev, 0x0043);
2306
2307 b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) & 0x7FFF);
2308 b43_phy_write(dev, 0x0001,
2309 (b43_phy_read(dev, 0x0001) & 0x3FFF) | 0x4000);
2310 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
2311 b43_phy_write(dev, 0x0812,
2312 (b43_phy_read(dev, 0x0812) & 0xFFF3) | 0x0004);
2313 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & ~(0x1 | 0x2));
2314 if (phy->rev >= 6) {
2315 backup[12] = b43_phy_read(dev, 0x002E);
2316 backup[13] = b43_phy_read(dev, 0x002F);
2317 backup[14] = b43_phy_read(dev, 0x080F);
2318 backup[15] = b43_phy_read(dev, 0x0810);
2319 backup[16] = b43_phy_read(dev, 0x0801);
2320 backup[17] = b43_phy_read(dev, 0x0060);
2321 backup[18] = b43_phy_read(dev, 0x0014);
2322 backup[19] = b43_phy_read(dev, 0x0478);
2323
2324 b43_phy_write(dev, 0x002E, 0);
2325 b43_phy_write(dev, 0x002F, 0);
2326 b43_phy_write(dev, 0x080F, 0);
2327 b43_phy_write(dev, 0x0810, 0);
2328 b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478) | 0x0100);
2329 b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) | 0x0040);
2330 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) | 0x0040);
2331 b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014) | 0x0200);
2332 }
2333 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0070);
2334 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0080);
2335 udelay(30);
2336
2337 v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
2338 if (v47F >= 0x20)
2339 v47F -= 0x40;
2340 if (v47F == 31) {
2341 for (i = 7; i >= 4; i--) {
2342 b43_radio_write16(dev, 0x007B, i);
2343 udelay(20);
2344 v47F =
2345 (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
2346 if (v47F >= 0x20)
2347 v47F -= 0x40;
2348 if (v47F < 31 && saved == 0xFFFF)
2349 saved = i;
2350 }
2351 if (saved == 0xFFFF)
2352 saved = 4;
2353 } else {
2354 b43_radio_write16(dev, 0x007A,
2355 b43_radio_read16(dev, 0x007A) & 0x007F);
2356 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
2357 b43_phy_write(dev, 0x0814,
2358 b43_phy_read(dev, 0x0814) | 0x0001);
2359 b43_phy_write(dev, 0x0815,
2360 b43_phy_read(dev, 0x0815) & 0xFFFE);
2361 }
2362 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
2363 b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x000C);
2364 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x0030);
2365 b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x0030);
2366 b43_phy_write(dev, 0x005A, 0x0480);
2367 b43_phy_write(dev, 0x0059, 0x0810);
2368 b43_phy_write(dev, 0x0058, 0x000D);
2369 if (phy->rev == 0) {
2370 b43_phy_write(dev, 0x0003, 0x0122);
2371 } else {
2372 b43_phy_write(dev, 0x000A, b43_phy_read(dev, 0x000A)
2373 | 0x2000);
2374 }
2375 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
2376 b43_phy_write(dev, 0x0814,
2377 b43_phy_read(dev, 0x0814) | 0x0004);
2378 b43_phy_write(dev, 0x0815,
2379 b43_phy_read(dev, 0x0815) & 0xFFFB);
2380 }
2381 b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003) & 0xFF9F)
2382 | 0x0040);
2383 b43_radio_write16(dev, 0x007A,
2384 b43_radio_read16(dev, 0x007A) | 0x000F);
2385 b43_set_all_gains(dev, 3, 0, 1);
2386 b43_radio_write16(dev, 0x0043, (b43_radio_read16(dev, 0x0043)
2387 & 0x00F0) | 0x000F);
2388 udelay(30);
2389 v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
2390 if (v47F >= 0x20)
2391 v47F -= 0x40;
2392 if (v47F == -32) {
2393 for (i = 0; i < 4; i++) {
2394 b43_radio_write16(dev, 0x007B, i);
2395 udelay(20);
2396 v47F =
2397 (s16) ((b43_phy_read(dev, 0x047F) >> 8) &
2398 0x003F);
2399 if (v47F >= 0x20)
2400 v47F -= 0x40;
2401 if (v47F > -31 && saved == 0xFFFF)
2402 saved = i;
2403 }
2404 if (saved == 0xFFFF)
2405 saved = 3;
2406 } else
2407 saved = 0;
2408 }
2409 b43_radio_write16(dev, 0x007B, saved);
2410
2411 if (phy->rev >= 6) {
2412 b43_phy_write(dev, 0x002E, backup[12]);
2413 b43_phy_write(dev, 0x002F, backup[13]);
2414 b43_phy_write(dev, 0x080F, backup[14]);
2415 b43_phy_write(dev, 0x0810, backup[15]);
2416 }
2417 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
2418 b43_phy_write(dev, 0x0814, backup[3]);
2419 b43_phy_write(dev, 0x0815, backup[4]);
2420 }
2421 b43_phy_write(dev, 0x005A, backup[5]);
2422 b43_phy_write(dev, 0x0059, backup[6]);
2423 b43_phy_write(dev, 0x0058, backup[7]);
2424 b43_phy_write(dev, 0x000A, backup[8]);
2425 b43_phy_write(dev, 0x0003, backup[9]);
2426 b43_radio_write16(dev, 0x0043, backup[11]);
2427 b43_radio_write16(dev, 0x007A, backup[10]);
2428 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x1 | 0x2);
2429 b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) | 0x8000);
2430 b43_set_original_gains(dev);
2431 if (phy->rev >= 6) {
2432 b43_phy_write(dev, 0x0801, backup[16]);
2433 b43_phy_write(dev, 0x0060, backup[17]);
2434 b43_phy_write(dev, 0x0014, backup[18]);
2435 b43_phy_write(dev, 0x0478, backup[19]);
2436 }
2437 b43_phy_write(dev, 0x0001, backup[0]);
2438 b43_phy_write(dev, 0x0812, backup[2]);
2439 b43_phy_write(dev, 0x0811, backup[1]);
2440}
2441
2442void b43_calc_nrssi_slope(struct b43_wldev *dev)
2443{
2444 struct b43_phy *phy = &dev->phy;
2445 u16 backup[18] = { 0 };
2446 u16 tmp;
2447 s16 nrssi0, nrssi1;
2448
2449 switch (phy->type) {
2450 case B43_PHYTYPE_B:
2451 backup[0] = b43_radio_read16(dev, 0x007A);
2452 backup[1] = b43_radio_read16(dev, 0x0052);
2453 backup[2] = b43_radio_read16(dev, 0x0043);
2454 backup[3] = b43_phy_read(dev, 0x0030);
2455 backup[4] = b43_phy_read(dev, 0x0026);
2456 backup[5] = b43_phy_read(dev, 0x0015);
2457 backup[6] = b43_phy_read(dev, 0x002A);
2458 backup[7] = b43_phy_read(dev, 0x0020);
2459 backup[8] = b43_phy_read(dev, 0x005A);
2460 backup[9] = b43_phy_read(dev, 0x0059);
2461 backup[10] = b43_phy_read(dev, 0x0058);
2462 backup[11] = b43_read16(dev, 0x03E2);
2463 backup[12] = b43_read16(dev, 0x03E6);
2464 backup[13] = b43_read16(dev, B43_MMIO_CHANNEL_EXT);
2465
2466 tmp = b43_radio_read16(dev, 0x007A);
2467 tmp &= (phy->rev >= 5) ? 0x007F : 0x000F;
2468 b43_radio_write16(dev, 0x007A, tmp);
2469 b43_phy_write(dev, 0x0030, 0x00FF);
2470 b43_write16(dev, 0x03EC, 0x7F7F);
2471 b43_phy_write(dev, 0x0026, 0x0000);
2472 b43_phy_write(dev, 0x0015, b43_phy_read(dev, 0x0015) | 0x0020);
2473 b43_phy_write(dev, 0x002A, 0x08A3);
2474 b43_radio_write16(dev, 0x007A,
2475 b43_radio_read16(dev, 0x007A) | 0x0080);
2476
2477 nrssi0 = (s16) b43_phy_read(dev, 0x0027);
2478 b43_radio_write16(dev, 0x007A,
2479 b43_radio_read16(dev, 0x007A) & 0x007F);
2480 if (phy->rev >= 2) {
2481 b43_write16(dev, 0x03E6, 0x0040);
2482 } else if (phy->rev == 0) {
2483 b43_write16(dev, 0x03E6, 0x0122);
2484 } else {
2485 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
2486 b43_read16(dev,
2487 B43_MMIO_CHANNEL_EXT) & 0x2000);
2488 }
2489 b43_phy_write(dev, 0x0020, 0x3F3F);
2490 b43_phy_write(dev, 0x0015, 0xF330);
2491 b43_radio_write16(dev, 0x005A, 0x0060);
2492 b43_radio_write16(dev, 0x0043,
2493 b43_radio_read16(dev, 0x0043) & 0x00F0);
2494 b43_phy_write(dev, 0x005A, 0x0480);
2495 b43_phy_write(dev, 0x0059, 0x0810);
2496 b43_phy_write(dev, 0x0058, 0x000D);
2497 udelay(20);
2498
2499 nrssi1 = (s16) b43_phy_read(dev, 0x0027);
2500 b43_phy_write(dev, 0x0030, backup[3]);
2501 b43_radio_write16(dev, 0x007A, backup[0]);
2502 b43_write16(dev, 0x03E2, backup[11]);
2503 b43_phy_write(dev, 0x0026, backup[4]);
2504 b43_phy_write(dev, 0x0015, backup[5]);
2505 b43_phy_write(dev, 0x002A, backup[6]);
2506 b43_synth_pu_workaround(dev, phy->channel);
2507 if (phy->rev != 0)
2508 b43_write16(dev, 0x03F4, backup[13]);
2509
2510 b43_phy_write(dev, 0x0020, backup[7]);
2511 b43_phy_write(dev, 0x005A, backup[8]);
2512 b43_phy_write(dev, 0x0059, backup[9]);
2513 b43_phy_write(dev, 0x0058, backup[10]);
2514 b43_radio_write16(dev, 0x0052, backup[1]);
2515 b43_radio_write16(dev, 0x0043, backup[2]);
2516
2517 if (nrssi0 == nrssi1)
2518 phy->nrssislope = 0x00010000;
2519 else
2520 phy->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
2521
2522 if (nrssi0 <= -4) {
2523 phy->nrssi[0] = nrssi0;
2524 phy->nrssi[1] = nrssi1;
2525 }
2526 break;
2527 case B43_PHYTYPE_G:
2528 if (phy->radio_rev >= 9)
2529 return;
2530 if (phy->radio_rev == 8)
2531 b43_calc_nrssi_offset(dev);
2532
2533 b43_phy_write(dev, B43_PHY_G_CRS,
2534 b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
2535 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
2536 backup[7] = b43_read16(dev, 0x03E2);
2537 b43_write16(dev, 0x03E2, b43_read16(dev, 0x03E2) | 0x8000);
2538 backup[0] = b43_radio_read16(dev, 0x007A);
2539 backup[1] = b43_radio_read16(dev, 0x0052);
2540 backup[2] = b43_radio_read16(dev, 0x0043);
2541 backup[3] = b43_phy_read(dev, 0x0015);
2542 backup[4] = b43_phy_read(dev, 0x005A);
2543 backup[5] = b43_phy_read(dev, 0x0059);
2544 backup[6] = b43_phy_read(dev, 0x0058);
2545 backup[8] = b43_read16(dev, 0x03E6);
2546 backup[9] = b43_read16(dev, B43_MMIO_CHANNEL_EXT);
2547 if (phy->rev >= 3) {
2548 backup[10] = b43_phy_read(dev, 0x002E);
2549 backup[11] = b43_phy_read(dev, 0x002F);
2550 backup[12] = b43_phy_read(dev, 0x080F);
2551 backup[13] = b43_phy_read(dev, B43_PHY_G_LO_CONTROL);
2552 backup[14] = b43_phy_read(dev, 0x0801);
2553 backup[15] = b43_phy_read(dev, 0x0060);
2554 backup[16] = b43_phy_read(dev, 0x0014);
2555 backup[17] = b43_phy_read(dev, 0x0478);
2556 b43_phy_write(dev, 0x002E, 0);
2557 b43_phy_write(dev, B43_PHY_G_LO_CONTROL, 0);
2558 switch (phy->rev) {
2559 case 4:
2560 case 6:
2561 case 7:
2562 b43_phy_write(dev, 0x0478,
2563 b43_phy_read(dev, 0x0478)
2564 | 0x0100);
2565 b43_phy_write(dev, 0x0801,
2566 b43_phy_read(dev, 0x0801)
2567 | 0x0040);
2568 break;
2569 case 3:
2570 case 5:
2571 b43_phy_write(dev, 0x0801,
2572 b43_phy_read(dev, 0x0801)
2573 & 0xFFBF);
2574 break;
2575 }
2576 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060)
2577 | 0x0040);
2578 b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014)
2579 | 0x0200);
2580 }
2581 b43_radio_write16(dev, 0x007A,
2582 b43_radio_read16(dev, 0x007A) | 0x0070);
2583 b43_set_all_gains(dev, 0, 8, 0);
2584 b43_radio_write16(dev, 0x007A,
2585 b43_radio_read16(dev, 0x007A) & 0x00F7);
2586 if (phy->rev >= 2) {
2587 b43_phy_write(dev, 0x0811,
2588 (b43_phy_read(dev, 0x0811) & 0xFFCF) |
2589 0x0030);
2590 b43_phy_write(dev, 0x0812,
2591 (b43_phy_read(dev, 0x0812) & 0xFFCF) |
2592 0x0010);
2593 }
2594 b43_radio_write16(dev, 0x007A,
2595 b43_radio_read16(dev, 0x007A) | 0x0080);
2596 udelay(20);
2597
2598 nrssi0 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
2599 if (nrssi0 >= 0x0020)
2600 nrssi0 -= 0x0040;
2601
2602 b43_radio_write16(dev, 0x007A,
2603 b43_radio_read16(dev, 0x007A) & 0x007F);
2604 if (phy->rev >= 2) {
2605 b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003)
2606 & 0xFF9F) | 0x0040);
2607 }
2608
2609 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
2610 b43_read16(dev, B43_MMIO_CHANNEL_EXT)
2611 | 0x2000);
2612 b43_radio_write16(dev, 0x007A,
2613 b43_radio_read16(dev, 0x007A) | 0x000F);
2614 b43_phy_write(dev, 0x0015, 0xF330);
2615 if (phy->rev >= 2) {
2616 b43_phy_write(dev, 0x0812,
2617 (b43_phy_read(dev, 0x0812) & 0xFFCF) |
2618 0x0020);
2619 b43_phy_write(dev, 0x0811,
2620 (b43_phy_read(dev, 0x0811) & 0xFFCF) |
2621 0x0020);
2622 }
2623
2624 b43_set_all_gains(dev, 3, 0, 1);
2625 if (phy->radio_rev == 8) {
2626 b43_radio_write16(dev, 0x0043, 0x001F);
2627 } else {
2628 tmp = b43_radio_read16(dev, 0x0052) & 0xFF0F;
2629 b43_radio_write16(dev, 0x0052, tmp | 0x0060);
2630 tmp = b43_radio_read16(dev, 0x0043) & 0xFFF0;
2631 b43_radio_write16(dev, 0x0043, tmp | 0x0009);
2632 }
2633 b43_phy_write(dev, 0x005A, 0x0480);
2634 b43_phy_write(dev, 0x0059, 0x0810);
2635 b43_phy_write(dev, 0x0058, 0x000D);
2636 udelay(20);
2637 nrssi1 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
2638 if (nrssi1 >= 0x0020)
2639 nrssi1 -= 0x0040;
2640 if (nrssi0 == nrssi1)
2641 phy->nrssislope = 0x00010000;
2642 else
2643 phy->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
2644 if (nrssi0 >= -4) {
2645 phy->nrssi[0] = nrssi1;
2646 phy->nrssi[1] = nrssi0;
2647 }
2648 if (phy->rev >= 3) {
2649 b43_phy_write(dev, 0x002E, backup[10]);
2650 b43_phy_write(dev, 0x002F, backup[11]);
2651 b43_phy_write(dev, 0x080F, backup[12]);
2652 b43_phy_write(dev, B43_PHY_G_LO_CONTROL, backup[13]);
2653 }
2654 if (phy->rev >= 2) {
2655 b43_phy_write(dev, 0x0812,
2656 b43_phy_read(dev, 0x0812) & 0xFFCF);
2657 b43_phy_write(dev, 0x0811,
2658 b43_phy_read(dev, 0x0811) & 0xFFCF);
2659 }
2660
2661 b43_radio_write16(dev, 0x007A, backup[0]);
2662 b43_radio_write16(dev, 0x0052, backup[1]);
2663 b43_radio_write16(dev, 0x0043, backup[2]);
2664 b43_write16(dev, 0x03E2, backup[7]);
2665 b43_write16(dev, 0x03E6, backup[8]);
2666 b43_write16(dev, B43_MMIO_CHANNEL_EXT, backup[9]);
2667 b43_phy_write(dev, 0x0015, backup[3]);
2668 b43_phy_write(dev, 0x005A, backup[4]);
2669 b43_phy_write(dev, 0x0059, backup[5]);
2670 b43_phy_write(dev, 0x0058, backup[6]);
2671 b43_synth_pu_workaround(dev, phy->channel);
2672 b43_phy_write(dev, 0x0802,
2673 b43_phy_read(dev, 0x0802) | (0x0001 | 0x0002));
2674 b43_set_original_gains(dev);
2675 b43_phy_write(dev, B43_PHY_G_CRS,
2676 b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
2677 if (phy->rev >= 3) {
2678 b43_phy_write(dev, 0x0801, backup[14]);
2679 b43_phy_write(dev, 0x0060, backup[15]);
2680 b43_phy_write(dev, 0x0014, backup[16]);
2681 b43_phy_write(dev, 0x0478, backup[17]);
2682 }
2683 b43_nrssi_mem_update(dev);
2684 b43_calc_nrssi_threshold(dev);
2685 break;
2686 default:
2687 B43_WARN_ON(1);
2688 }
2689}
2690
2691void b43_calc_nrssi_threshold(struct b43_wldev *dev)
2692{
2693 struct b43_phy *phy = &dev->phy;
2694 s32 threshold;
2695 s32 a, b;
2696 s16 tmp16;
2697 u16 tmp_u16;
2698
2699 switch (phy->type) {
2700 case B43_PHYTYPE_B:{
2701 if (phy->radio_ver != 0x2050)
2702 return;
2703 if (!
2704 (dev->dev->bus->sprom.
2705 boardflags_lo & B43_BFL_RSSI))
2706 return;
2707
2708 if (phy->radio_rev >= 6) {
2709 threshold =
2710 (phy->nrssi[1] - phy->nrssi[0]) * 32;
2711 threshold += 20 * (phy->nrssi[0] + 1);
2712 threshold /= 40;
2713 } else
2714 threshold = phy->nrssi[1] - 5;
2715
2716 threshold = clamp_val(threshold, 0, 0x3E);
2717 b43_phy_read(dev, 0x0020); /* dummy read */
2718 b43_phy_write(dev, 0x0020,
2719 (((u16) threshold) << 8) | 0x001C);
2720
2721 if (phy->radio_rev >= 6) {
2722 b43_phy_write(dev, 0x0087, 0x0E0D);
2723 b43_phy_write(dev, 0x0086, 0x0C0B);
2724 b43_phy_write(dev, 0x0085, 0x0A09);
2725 b43_phy_write(dev, 0x0084, 0x0808);
2726 b43_phy_write(dev, 0x0083, 0x0808);
2727 b43_phy_write(dev, 0x0082, 0x0604);
2728 b43_phy_write(dev, 0x0081, 0x0302);
2729 b43_phy_write(dev, 0x0080, 0x0100);
2730 }
2731 break;
2732 }
2733 case B43_PHYTYPE_G:
2734 if (!phy->gmode ||
2735 !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
2736 tmp16 = b43_nrssi_hw_read(dev, 0x20);
2737 if (tmp16 >= 0x20)
2738 tmp16 -= 0x40;
2739 if (tmp16 < 3) {
2740 b43_phy_write(dev, 0x048A,
2741 (b43_phy_read(dev, 0x048A)
2742 & 0xF000) | 0x09EB);
2743 } else {
2744 b43_phy_write(dev, 0x048A,
2745 (b43_phy_read(dev, 0x048A)
2746 & 0xF000) | 0x0AED);
2747 }
2748 } else {
2749 if (phy->interfmode == B43_INTERFMODE_NONWLAN) {
2750 a = 0xE;
2751 b = 0xA;
2752 } else if (!phy->aci_wlan_automatic && phy->aci_enable) {
2753 a = 0x13;
2754 b = 0x12;
2755 } else {
2756 a = 0xE;
2757 b = 0x11;
2758 }
2759
2760 a = a * (phy->nrssi[1] - phy->nrssi[0]);
2761 a += (phy->nrssi[0] << 6);
2762 if (a < 32)
2763 a += 31;
2764 else
2765 a += 32;
2766 a = a >> 6;
2767 a = clamp_val(a, -31, 31);
2768
2769 b = b * (phy->nrssi[1] - phy->nrssi[0]);
2770 b += (phy->nrssi[0] << 6);
2771 if (b < 32)
2772 b += 31;
2773 else
2774 b += 32;
2775 b = b >> 6;
2776 b = clamp_val(b, -31, 31);
2777
2778 tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000;
2779 tmp_u16 |= ((u32) b & 0x0000003F);
2780 tmp_u16 |= (((u32) a & 0x0000003F) << 6);
2781 b43_phy_write(dev, 0x048A, tmp_u16);
2782 }
2783 break;
2784 default:
2785 B43_WARN_ON(1);
2786 }
2787}
2788
2789/* Stack implementation to save/restore values from the
2790 * interference mitigation code.
2791 * It is save to restore values in random order.
2792 */
2793static void _stack_save(u32 * _stackptr, size_t * stackidx,
2794 u8 id, u16 offset, u16 value)
2795{
2796 u32 *stackptr = &(_stackptr[*stackidx]);
2797
2798 B43_WARN_ON(offset & 0xF000);
2799 B43_WARN_ON(id & 0xF0);
2800 *stackptr = offset;
2801 *stackptr |= ((u32) id) << 12;
2802 *stackptr |= ((u32) value) << 16;
2803 (*stackidx)++;
2804 B43_WARN_ON(*stackidx >= B43_INTERFSTACK_SIZE);
2805}
2806
2807static u16 _stack_restore(u32 * stackptr, u8 id, u16 offset)
2808{
2809 size_t i;
2810
2811 B43_WARN_ON(offset & 0xF000);
2812 B43_WARN_ON(id & 0xF0);
2813 for (i = 0; i < B43_INTERFSTACK_SIZE; i++, stackptr++) {
2814 if ((*stackptr & 0x00000FFF) != offset)
2815 continue;
2816 if (((*stackptr & 0x0000F000) >> 12) != id)
2817 continue;
2818 return ((*stackptr & 0xFFFF0000) >> 16);
2819 }
2820 B43_WARN_ON(1);
2821
2822 return 0;
2823}
2824
2825#define phy_stacksave(offset) \
2826 do { \
2827 _stack_save(stack, &stackidx, 0x1, (offset), \
2828 b43_phy_read(dev, (offset))); \
2829 } while (0)
2830#define phy_stackrestore(offset) \
2831 do { \
2832 b43_phy_write(dev, (offset), \
2833 _stack_restore(stack, 0x1, \
2834 (offset))); \
2835 } while (0)
2836#define radio_stacksave(offset) \
2837 do { \
2838 _stack_save(stack, &stackidx, 0x2, (offset), \
2839 b43_radio_read16(dev, (offset))); \
2840 } while (0)
2841#define radio_stackrestore(offset) \
2842 do { \
2843 b43_radio_write16(dev, (offset), \
2844 _stack_restore(stack, 0x2, \
2845 (offset))); \
2846 } while (0)
2847#define ofdmtab_stacksave(table, offset) \
2848 do { \
2849 _stack_save(stack, &stackidx, 0x3, (offset)|(table), \
2850 b43_ofdmtab_read16(dev, (table), (offset))); \
2851 } while (0)
2852#define ofdmtab_stackrestore(table, offset) \
2853 do { \
2854 b43_ofdmtab_write16(dev, (table), (offset), \
2855 _stack_restore(stack, 0x3, \
2856 (offset)|(table))); \
2857 } while (0)
2858
2859static void
2860b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
2861{
2862 struct b43_phy *phy = &dev->phy;
2863 u16 tmp, flipped;
2864 size_t stackidx = 0;
2865 u32 *stack = phy->interfstack;
2866
2867 switch (mode) {
2868 case B43_INTERFMODE_NONWLAN:
2869 if (phy->rev != 1) {
2870 b43_phy_write(dev, 0x042B,
2871 b43_phy_read(dev, 0x042B) | 0x0800);
2872 b43_phy_write(dev, B43_PHY_G_CRS,
2873 b43_phy_read(dev,
2874 B43_PHY_G_CRS) & ~0x4000);
2875 break;
2876 }
2877 radio_stacksave(0x0078);
2878 tmp = (b43_radio_read16(dev, 0x0078) & 0x001E);
2879 B43_WARN_ON(tmp > 15);
2880 flipped = bitrev4(tmp);
2881 if (flipped < 10 && flipped >= 8)
2882 flipped = 7;
2883 else if (flipped >= 10)
2884 flipped -= 3;
2885 flipped = (bitrev4(flipped) << 1) | 0x0020;
2886 b43_radio_write16(dev, 0x0078, flipped);
2887
2888 b43_calc_nrssi_threshold(dev);
2889
2890 phy_stacksave(0x0406);
2891 b43_phy_write(dev, 0x0406, 0x7E28);
2892
2893 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x0800);
2894 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
2895 b43_phy_read(dev,
2896 B43_PHY_RADIO_BITFIELD) | 0x1000);
2897
2898 phy_stacksave(0x04A0);
2899 b43_phy_write(dev, 0x04A0,
2900 (b43_phy_read(dev, 0x04A0) & 0xC0C0) | 0x0008);
2901 phy_stacksave(0x04A1);
2902 b43_phy_write(dev, 0x04A1,
2903 (b43_phy_read(dev, 0x04A1) & 0xC0C0) | 0x0605);
2904 phy_stacksave(0x04A2);
2905 b43_phy_write(dev, 0x04A2,
2906 (b43_phy_read(dev, 0x04A2) & 0xC0C0) | 0x0204);
2907 phy_stacksave(0x04A8);
2908 b43_phy_write(dev, 0x04A8,
2909 (b43_phy_read(dev, 0x04A8) & 0xC0C0) | 0x0803);
2910 phy_stacksave(0x04AB);
2911 b43_phy_write(dev, 0x04AB,
2912 (b43_phy_read(dev, 0x04AB) & 0xC0C0) | 0x0605);
2913
2914 phy_stacksave(0x04A7);
2915 b43_phy_write(dev, 0x04A7, 0x0002);
2916 phy_stacksave(0x04A3);
2917 b43_phy_write(dev, 0x04A3, 0x287A);
2918 phy_stacksave(0x04A9);
2919 b43_phy_write(dev, 0x04A9, 0x2027);
2920 phy_stacksave(0x0493);
2921 b43_phy_write(dev, 0x0493, 0x32F5);
2922 phy_stacksave(0x04AA);
2923 b43_phy_write(dev, 0x04AA, 0x2027);
2924 phy_stacksave(0x04AC);
2925 b43_phy_write(dev, 0x04AC, 0x32F5);
2926 break;
2927 case B43_INTERFMODE_MANUALWLAN:
2928 if (b43_phy_read(dev, 0x0033) & 0x0800)
2929 break;
2930
2931 phy->aci_enable = 1;
2932
2933 phy_stacksave(B43_PHY_RADIO_BITFIELD);
2934 phy_stacksave(B43_PHY_G_CRS);
2935 if (phy->rev < 2) {
2936 phy_stacksave(0x0406);
2937 } else {
2938 phy_stacksave(0x04C0);
2939 phy_stacksave(0x04C1);
2940 }
2941 phy_stacksave(0x0033);
2942 phy_stacksave(0x04A7);
2943 phy_stacksave(0x04A3);
2944 phy_stacksave(0x04A9);
2945 phy_stacksave(0x04AA);
2946 phy_stacksave(0x04AC);
2947 phy_stacksave(0x0493);
2948 phy_stacksave(0x04A1);
2949 phy_stacksave(0x04A0);
2950 phy_stacksave(0x04A2);
2951 phy_stacksave(0x048A);
2952 phy_stacksave(0x04A8);
2953 phy_stacksave(0x04AB);
2954 if (phy->rev == 2) {
2955 phy_stacksave(0x04AD);
2956 phy_stacksave(0x04AE);
2957 } else if (phy->rev >= 3) {
2958 phy_stacksave(0x04AD);
2959 phy_stacksave(0x0415);
2960 phy_stacksave(0x0416);
2961 phy_stacksave(0x0417);
2962 ofdmtab_stacksave(0x1A00, 0x2);
2963 ofdmtab_stacksave(0x1A00, 0x3);
2964 }
2965 phy_stacksave(0x042B);
2966 phy_stacksave(0x048C);
2967
2968 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
2969 b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
2970 & ~0x1000);
2971 b43_phy_write(dev, B43_PHY_G_CRS,
2972 (b43_phy_read(dev, B43_PHY_G_CRS)
2973 & 0xFFFC) | 0x0002);
2974
2975 b43_phy_write(dev, 0x0033, 0x0800);
2976 b43_phy_write(dev, 0x04A3, 0x2027);
2977 b43_phy_write(dev, 0x04A9, 0x1CA8);
2978 b43_phy_write(dev, 0x0493, 0x287A);
2979 b43_phy_write(dev, 0x04AA, 0x1CA8);
2980 b43_phy_write(dev, 0x04AC, 0x287A);
2981
2982 b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
2983 & 0xFFC0) | 0x001A);
2984 b43_phy_write(dev, 0x04A7, 0x000D);
2985
2986 if (phy->rev < 2) {
2987 b43_phy_write(dev, 0x0406, 0xFF0D);
2988 } else if (phy->rev == 2) {
2989 b43_phy_write(dev, 0x04C0, 0xFFFF);
2990 b43_phy_write(dev, 0x04C1, 0x00A9);
2991 } else {
2992 b43_phy_write(dev, 0x04C0, 0x00C1);
2993 b43_phy_write(dev, 0x04C1, 0x0059);
2994 }
2995
2996 b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
2997 & 0xC0FF) | 0x1800);
2998 b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
2999 & 0xFFC0) | 0x0015);
3000 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
3001 & 0xCFFF) | 0x1000);
3002 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
3003 & 0xF0FF) | 0x0A00);
3004 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
3005 & 0xCFFF) | 0x1000);
3006 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
3007 & 0xF0FF) | 0x0800);
3008 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
3009 & 0xFFCF) | 0x0010);
3010 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
3011 & 0xFFF0) | 0x0005);
3012 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
3013 & 0xFFCF) | 0x0010);
3014 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
3015 & 0xFFF0) | 0x0006);
3016 b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
3017 & 0xF0FF) | 0x0800);
3018 b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
3019 & 0xF0FF) | 0x0500);
3020 b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
3021 & 0xFFF0) | 0x000B);
3022
3023 if (phy->rev >= 3) {
3024 b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
3025 & ~0x8000);
3026 b43_phy_write(dev, 0x0415, (b43_phy_read(dev, 0x0415)
3027 & 0x8000) | 0x36D8);
3028 b43_phy_write(dev, 0x0416, (b43_phy_read(dev, 0x0416)
3029 & 0x8000) | 0x36D8);
3030 b43_phy_write(dev, 0x0417, (b43_phy_read(dev, 0x0417)
3031 & 0xFE00) | 0x016D);
3032 } else {
3033 b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
3034 | 0x1000);
3035 b43_phy_write(dev, 0x048A, (b43_phy_read(dev, 0x048A)
3036 & 0x9FFF) | 0x2000);
3037 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ACIW);
3038 }
3039 if (phy->rev >= 2) {
3040 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B)
3041 | 0x0800);
3042 }
3043 b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
3044 & 0xF0FF) | 0x0200);
3045 if (phy->rev == 2) {
3046 b43_phy_write(dev, 0x04AE, (b43_phy_read(dev, 0x04AE)
3047 & 0xFF00) | 0x007F);
3048 b43_phy_write(dev, 0x04AD, (b43_phy_read(dev, 0x04AD)
3049 & 0x00FF) | 0x1300);
3050 } else if (phy->rev >= 6) {
3051 b43_ofdmtab_write16(dev, 0x1A00, 0x3, 0x007F);
3052 b43_ofdmtab_write16(dev, 0x1A00, 0x2, 0x007F);
3053 b43_phy_write(dev, 0x04AD, b43_phy_read(dev, 0x04AD)
3054 & 0x00FF);
3055 }
3056 b43_calc_nrssi_slope(dev);
3057 break;
3058 default:
3059 B43_WARN_ON(1);
3060 }
3061}
3062
3063static void
3064b43_radio_interference_mitigation_disable(struct b43_wldev *dev, int mode)
3065{
3066 struct b43_phy *phy = &dev->phy;
3067 u32 *stack = phy->interfstack;
3068
3069 switch (mode) {
3070 case B43_INTERFMODE_NONWLAN:
3071 if (phy->rev != 1) {
3072 b43_phy_write(dev, 0x042B,
3073 b43_phy_read(dev, 0x042B) & ~0x0800);
3074 b43_phy_write(dev, B43_PHY_G_CRS,
3075 b43_phy_read(dev,
3076 B43_PHY_G_CRS) | 0x4000);
3077 break;
3078 }
3079 radio_stackrestore(0x0078);
3080 b43_calc_nrssi_threshold(dev);
3081 phy_stackrestore(0x0406);
3082 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) & ~0x0800);
3083 if (!dev->bad_frames_preempt) {
3084 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
3085 b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
3086 & ~(1 << 11));
3087 }
3088 b43_phy_write(dev, B43_PHY_G_CRS,
3089 b43_phy_read(dev, B43_PHY_G_CRS) | 0x4000);
3090 phy_stackrestore(0x04A0);
3091 phy_stackrestore(0x04A1);
3092 phy_stackrestore(0x04A2);
3093 phy_stackrestore(0x04A8);
3094 phy_stackrestore(0x04AB);
3095 phy_stackrestore(0x04A7);
3096 phy_stackrestore(0x04A3);
3097 phy_stackrestore(0x04A9);
3098 phy_stackrestore(0x0493);
3099 phy_stackrestore(0x04AA);
3100 phy_stackrestore(0x04AC);
3101 break;
3102 case B43_INTERFMODE_MANUALWLAN:
3103 if (!(b43_phy_read(dev, 0x0033) & 0x0800))
3104 break;
3105
3106 phy->aci_enable = 0;
3107
3108 phy_stackrestore(B43_PHY_RADIO_BITFIELD);
3109 phy_stackrestore(B43_PHY_G_CRS);
3110 phy_stackrestore(0x0033);
3111 phy_stackrestore(0x04A3);
3112 phy_stackrestore(0x04A9);
3113 phy_stackrestore(0x0493);
3114 phy_stackrestore(0x04AA);
3115 phy_stackrestore(0x04AC);
3116 phy_stackrestore(0x04A0);
3117 phy_stackrestore(0x04A7);
3118 if (phy->rev >= 2) {
3119 phy_stackrestore(0x04C0);
3120 phy_stackrestore(0x04C1);
3121 } else
3122 phy_stackrestore(0x0406);
3123 phy_stackrestore(0x04A1);
3124 phy_stackrestore(0x04AB);
3125 phy_stackrestore(0x04A8);
3126 if (phy->rev == 2) {
3127 phy_stackrestore(0x04AD);
3128 phy_stackrestore(0x04AE);
3129 } else if (phy->rev >= 3) {
3130 phy_stackrestore(0x04AD);
3131 phy_stackrestore(0x0415);
3132 phy_stackrestore(0x0416);
3133 phy_stackrestore(0x0417);
3134 ofdmtab_stackrestore(0x1A00, 0x2);
3135 ofdmtab_stackrestore(0x1A00, 0x3);
3136 }
3137 phy_stackrestore(0x04A2);
3138 phy_stackrestore(0x048A);
3139 phy_stackrestore(0x042B);
3140 phy_stackrestore(0x048C);
3141 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACIW);
3142 b43_calc_nrssi_slope(dev);
3143 break;
3144 default:
3145 B43_WARN_ON(1);
3146 }
3147}
3148
3149#undef phy_stacksave
3150#undef phy_stackrestore
3151#undef radio_stacksave
3152#undef radio_stackrestore
3153#undef ofdmtab_stacksave
3154#undef ofdmtab_stackrestore
3155
3156int b43_radio_set_interference_mitigation(struct b43_wldev *dev, int mode)
3157{
3158 struct b43_phy *phy = &dev->phy;
3159 int currentmode;
3160
3161 if ((phy->type != B43_PHYTYPE_G) || (phy->rev == 0) || (!phy->gmode))
3162 return -ENODEV;
3163
3164 phy->aci_wlan_automatic = 0;
3165 switch (mode) {
3166 case B43_INTERFMODE_AUTOWLAN:
3167 phy->aci_wlan_automatic = 1;
3168 if (phy->aci_enable)
3169 mode = B43_INTERFMODE_MANUALWLAN;
3170 else
3171 mode = B43_INTERFMODE_NONE;
3172 break;
3173 case B43_INTERFMODE_NONE:
3174 case B43_INTERFMODE_NONWLAN:
3175 case B43_INTERFMODE_MANUALWLAN:
3176 break;
3177 default:
3178 return -EINVAL;
3179 }
3180
3181 currentmode = phy->interfmode;
3182 if (currentmode == mode)
3183 return 0;
3184 if (currentmode != B43_INTERFMODE_NONE)
3185 b43_radio_interference_mitigation_disable(dev, currentmode);
3186
3187 if (mode == B43_INTERFMODE_NONE) {
3188 phy->aci_enable = 0;
3189 phy->aci_hw_rssi = 0;
3190 } else
3191 b43_radio_interference_mitigation_enable(dev, mode);
3192 phy->interfmode = mode;
3193
3194 return 0;
3195}
3196
3197static u16 b43_radio_core_calibration_value(struct b43_wldev *dev)
3198{
3199 u16 reg, index, ret;
3200
3201 static const u8 rcc_table[] = {
3202 0x02, 0x03, 0x01, 0x0F,
3203 0x06, 0x07, 0x05, 0x0F,
3204 0x0A, 0x0B, 0x09, 0x0F,
3205 0x0E, 0x0F, 0x0D, 0x0F,
3206 };
3207
3208 reg = b43_radio_read16(dev, 0x60);
3209 index = (reg & 0x001E) >> 1;
3210 ret = rcc_table[index] << 1;
3211 ret |= (reg & 0x0001);
3212 ret |= 0x0020;
3213
3214 return ret;
3215}
3216
3217#define LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
3218static u16 radio2050_rfover_val(struct b43_wldev *dev,
3219 u16 phy_register, unsigned int lpd)
3220{
3221 struct b43_phy *phy = &dev->phy;
3222 struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
3223
3224 if (!phy->gmode)
3225 return 0;
3226
3227 if (has_loopback_gain(phy)) {
3228 int max_lb_gain = phy->max_lb_gain;
3229 u16 extlna;
3230 u16 i;
3231
3232 if (phy->radio_rev == 8)
3233 max_lb_gain += 0x3E;
3234 else
3235 max_lb_gain += 0x26;
3236 if (max_lb_gain >= 0x46) {
3237 extlna = 0x3000;
3238 max_lb_gain -= 0x46;
3239 } else if (max_lb_gain >= 0x3A) {
3240 extlna = 0x1000;
3241 max_lb_gain -= 0x3A;
3242 } else if (max_lb_gain >= 0x2E) {
3243 extlna = 0x2000;
3244 max_lb_gain -= 0x2E;
3245 } else {
3246 extlna = 0;
3247 max_lb_gain -= 0x10;
3248 }
3249
3250 for (i = 0; i < 16; i++) {
3251 max_lb_gain -= (i * 6);
3252 if (max_lb_gain < 6)
3253 break;
3254 }
3255
3256 if ((phy->rev < 7) ||
3257 !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
3258 if (phy_register == B43_PHY_RFOVER) {
3259 return 0x1B3;
3260 } else if (phy_register == B43_PHY_RFOVERVAL) {
3261 extlna |= (i << 8);
3262 switch (lpd) {
3263 case LPD(0, 1, 1):
3264 return 0x0F92;
3265 case LPD(0, 0, 1):
3266 case LPD(1, 0, 1):
3267 return (0x0092 | extlna);
3268 case LPD(1, 0, 0):
3269 return (0x0093 | extlna);
3270 }
3271 B43_WARN_ON(1);
3272 }
3273 B43_WARN_ON(1);
3274 } else {
3275 if (phy_register == B43_PHY_RFOVER) {
3276 return 0x9B3;
3277 } else if (phy_register == B43_PHY_RFOVERVAL) {
3278 if (extlna)
3279 extlna |= 0x8000;
3280 extlna |= (i << 8);
3281 switch (lpd) {
3282 case LPD(0, 1, 1):
3283 return 0x8F92;
3284 case LPD(0, 0, 1):
3285 return (0x8092 | extlna);
3286 case LPD(1, 0, 1):
3287 return (0x2092 | extlna);
3288 case LPD(1, 0, 0):
3289 return (0x2093 | extlna);
3290 }
3291 B43_WARN_ON(1);
3292 }
3293 B43_WARN_ON(1);
3294 }
3295 } else {
3296 if ((phy->rev < 7) ||
3297 !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
3298 if (phy_register == B43_PHY_RFOVER) {
3299 return 0x1B3;
3300 } else if (phy_register == B43_PHY_RFOVERVAL) {
3301 switch (lpd) {
3302 case LPD(0, 1, 1):
3303 return 0x0FB2;
3304 case LPD(0, 0, 1):
3305 return 0x00B2;
3306 case LPD(1, 0, 1):
3307 return 0x30B2;
3308 case LPD(1, 0, 0):
3309 return 0x30B3;
3310 }
3311 B43_WARN_ON(1);
3312 }
3313 B43_WARN_ON(1);
3314 } else {
3315 if (phy_register == B43_PHY_RFOVER) {
3316 return 0x9B3;
3317 } else if (phy_register == B43_PHY_RFOVERVAL) {
3318 switch (lpd) {
3319 case LPD(0, 1, 1):
3320 return 0x8FB2;
3321 case LPD(0, 0, 1):
3322 return 0x80B2;
3323 case LPD(1, 0, 1):
3324 return 0x20B2;
3325 case LPD(1, 0, 0):
3326 return 0x20B3;
3327 }
3328 B43_WARN_ON(1);
3329 }
3330 B43_WARN_ON(1);
3331 }
3332 }
3333 return 0;
3334}
3335
3336struct init2050_saved_values {
3337 /* Core registers */
3338 u16 reg_3EC;
3339 u16 reg_3E6;
3340 u16 reg_3F4;
3341 /* Radio registers */
3342 u16 radio_43;
3343 u16 radio_51;
3344 u16 radio_52;
3345 /* PHY registers */
3346 u16 phy_pgactl;
3347 u16 phy_cck_5A;
3348 u16 phy_cck_59;
3349 u16 phy_cck_58;
3350 u16 phy_cck_30;
3351 u16 phy_rfover;
3352 u16 phy_rfoverval;
3353 u16 phy_analogover;
3354 u16 phy_analogoverval;
3355 u16 phy_crs0;
3356 u16 phy_classctl;
3357 u16 phy_lo_mask;
3358 u16 phy_lo_ctl;
3359 u16 phy_syncctl;
3360};
3361
3362u16 b43_radio_init2050(struct b43_wldev *dev)
3363{
3364 struct b43_phy *phy = &dev->phy;
3365 struct init2050_saved_values sav;
3366 u16 rcc;
3367 u16 radio78;
3368 u16 ret;
3369 u16 i, j;
3370 u32 tmp1 = 0, tmp2 = 0;
3371
3372 memset(&sav, 0, sizeof(sav)); /* get rid of "may be used uninitialized..." */
3373
3374 sav.radio_43 = b43_radio_read16(dev, 0x43);
3375 sav.radio_51 = b43_radio_read16(dev, 0x51);
3376 sav.radio_52 = b43_radio_read16(dev, 0x52);
3377 sav.phy_pgactl = b43_phy_read(dev, B43_PHY_PGACTL);
3378 sav.phy_cck_5A = b43_phy_read(dev, B43_PHY_CCK(0x5A));
3379 sav.phy_cck_59 = b43_phy_read(dev, B43_PHY_CCK(0x59));
3380 sav.phy_cck_58 = b43_phy_read(dev, B43_PHY_CCK(0x58));
3381
3382 if (phy->type == B43_PHYTYPE_B) {
3383 sav.phy_cck_30 = b43_phy_read(dev, B43_PHY_CCK(0x30));
3384 sav.reg_3EC = b43_read16(dev, 0x3EC);
3385
3386 b43_phy_write(dev, B43_PHY_CCK(0x30), 0xFF);
3387 b43_write16(dev, 0x3EC, 0x3F3F);
3388 } else if (phy->gmode || phy->rev >= 2) {
3389 sav.phy_rfover = b43_phy_read(dev, B43_PHY_RFOVER);
3390 sav.phy_rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
3391 sav.phy_analogover = b43_phy_read(dev, B43_PHY_ANALOGOVER);
3392 sav.phy_analogoverval =
3393 b43_phy_read(dev, B43_PHY_ANALOGOVERVAL);
3394 sav.phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
3395 sav.phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
3396
3397 b43_phy_write(dev, B43_PHY_ANALOGOVER,
3398 b43_phy_read(dev, B43_PHY_ANALOGOVER)
3399 | 0x0003);
3400 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
3401 b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
3402 & 0xFFFC);
3403 b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
3404 & 0x7FFF);
3405 b43_phy_write(dev, B43_PHY_CLASSCTL,
3406 b43_phy_read(dev, B43_PHY_CLASSCTL)
3407 & 0xFFFC);
3408 if (has_loopback_gain(phy)) {
3409 sav.phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
3410 sav.phy_lo_ctl = b43_phy_read(dev, B43_PHY_LO_CTL);
3411
3412 if (phy->rev >= 3)
3413 b43_phy_write(dev, B43_PHY_LO_MASK, 0xC020);
3414 else
3415 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
3416 b43_phy_write(dev, B43_PHY_LO_CTL, 0);
3417 }
3418
3419 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3420 radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
3421 LPD(0, 1, 1)));
3422 b43_phy_write(dev, B43_PHY_RFOVER,
3423 radio2050_rfover_val(dev, B43_PHY_RFOVER, 0));
3424 }
3425 b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000);
3426
3427 sav.phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
3428 b43_phy_write(dev, B43_PHY_SYNCCTL, b43_phy_read(dev, B43_PHY_SYNCCTL)
3429 & 0xFF7F);
3430 sav.reg_3E6 = b43_read16(dev, 0x3E6);
3431 sav.reg_3F4 = b43_read16(dev, 0x3F4);
3432
3433 if (phy->analog == 0) {
3434 b43_write16(dev, 0x03E6, 0x0122);
3435 } else {
3436 if (phy->analog >= 2) {
3437 b43_phy_write(dev, B43_PHY_CCK(0x03),
3438 (b43_phy_read(dev, B43_PHY_CCK(0x03))
3439 & 0xFFBF) | 0x40);
3440 }
3441 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
3442 (b43_read16(dev, B43_MMIO_CHANNEL_EXT) | 0x2000));
3443 }
3444
3445 rcc = b43_radio_core_calibration_value(dev);
3446
3447 if (phy->type == B43_PHYTYPE_B)
3448 b43_radio_write16(dev, 0x78, 0x26);
3449 if (phy->gmode || phy->rev >= 2) {
3450 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3451 radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
3452 LPD(0, 1, 1)));
3453 }
3454 b43_phy_write(dev, B43_PHY_PGACTL, 0xBFAF);
3455 b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x1403);
3456 if (phy->gmode || phy->rev >= 2) {
3457 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3458 radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
3459 LPD(0, 0, 1)));
3460 }
3461 b43_phy_write(dev, B43_PHY_PGACTL, 0xBFA0);
3462 b43_radio_write16(dev, 0x51, b43_radio_read16(dev, 0x51)
3463 | 0x0004);
3464 if (phy->radio_rev == 8) {
3465 b43_radio_write16(dev, 0x43, 0x1F);
3466 } else {
3467 b43_radio_write16(dev, 0x52, 0);
3468 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
3469 & 0xFFF0) | 0x0009);
3470 }
3471 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
3472
3473 for (i = 0; i < 16; i++) {
3474 b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0480);
3475 b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
3476 b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
3477 if (phy->gmode || phy->rev >= 2) {
3478 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3479 radio2050_rfover_val(dev,
3480 B43_PHY_RFOVERVAL,
3481 LPD(1, 0, 1)));
3482 }
3483 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
3484 udelay(10);
3485 if (phy->gmode || phy->rev >= 2) {
3486 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3487 radio2050_rfover_val(dev,
3488 B43_PHY_RFOVERVAL,
3489 LPD(1, 0, 1)));
3490 }
3491 b43_phy_write(dev, B43_PHY_PGACTL, 0xEFB0);
3492 udelay(10);
3493 if (phy->gmode || phy->rev >= 2) {
3494 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3495 radio2050_rfover_val(dev,
3496 B43_PHY_RFOVERVAL,
3497 LPD(1, 0, 0)));
3498 }
3499 b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
3500 udelay(20);
3501 tmp1 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
3502 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
3503 if (phy->gmode || phy->rev >= 2) {
3504 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3505 radio2050_rfover_val(dev,
3506 B43_PHY_RFOVERVAL,
3507 LPD(1, 0, 1)));
3508 }
3509 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
3510 }
3511 udelay(10);
3512
3513 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
3514 tmp1++;
3515 tmp1 >>= 9;
3516
3517 for (i = 0; i < 16; i++) {
3518 radio78 = (bitrev4(i) << 1) | 0x0020;
3519 b43_radio_write16(dev, 0x78, radio78);
3520 udelay(10);
3521 for (j = 0; j < 16; j++) {
3522 b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0D80);
3523 b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
3524 b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
3525 if (phy->gmode || phy->rev >= 2) {
3526 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3527 radio2050_rfover_val(dev,
3528 B43_PHY_RFOVERVAL,
3529 LPD(1, 0,
3530 1)));
3531 }
3532 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
3533 udelay(10);
3534 if (phy->gmode || phy->rev >= 2) {
3535 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3536 radio2050_rfover_val(dev,
3537 B43_PHY_RFOVERVAL,
3538 LPD(1, 0,
3539 1)));
3540 }
3541 b43_phy_write(dev, B43_PHY_PGACTL, 0xEFB0);
3542 udelay(10);
3543 if (phy->gmode || phy->rev >= 2) {
3544 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3545 radio2050_rfover_val(dev,
3546 B43_PHY_RFOVERVAL,
3547 LPD(1, 0,
3548 0)));
3549 }
3550 b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
3551 udelay(10);
3552 tmp2 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
3553 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
3554 if (phy->gmode || phy->rev >= 2) {
3555 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3556 radio2050_rfover_val(dev,
3557 B43_PHY_RFOVERVAL,
3558 LPD(1, 0,
3559 1)));
3560 }
3561 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
3562 }
3563 tmp2++;
3564 tmp2 >>= 8;
3565 if (tmp1 < tmp2)
3566 break;
3567 }
3568
3569 /* Restore the registers */
3570 b43_phy_write(dev, B43_PHY_PGACTL, sav.phy_pgactl);
3571 b43_radio_write16(dev, 0x51, sav.radio_51);
3572 b43_radio_write16(dev, 0x52, sav.radio_52);
3573 b43_radio_write16(dev, 0x43, sav.radio_43);
3574 b43_phy_write(dev, B43_PHY_CCK(0x5A), sav.phy_cck_5A);
3575 b43_phy_write(dev, B43_PHY_CCK(0x59), sav.phy_cck_59);
3576 b43_phy_write(dev, B43_PHY_CCK(0x58), sav.phy_cck_58);
3577 b43_write16(dev, 0x3E6, sav.reg_3E6);
3578 if (phy->analog != 0)
3579 b43_write16(dev, 0x3F4, sav.reg_3F4);
3580 b43_phy_write(dev, B43_PHY_SYNCCTL, sav.phy_syncctl);
3581 b43_synth_pu_workaround(dev, phy->channel);
3582 if (phy->type == B43_PHYTYPE_B) {
3583 b43_phy_write(dev, B43_PHY_CCK(0x30), sav.phy_cck_30);
3584 b43_write16(dev, 0x3EC, sav.reg_3EC);
3585 } else if (phy->gmode) {
3586 b43_write16(dev, B43_MMIO_PHY_RADIO,
3587 b43_read16(dev, B43_MMIO_PHY_RADIO)
3588 & 0x7FFF);
3589 b43_phy_write(dev, B43_PHY_RFOVER, sav.phy_rfover);
3590 b43_phy_write(dev, B43_PHY_RFOVERVAL, sav.phy_rfoverval);
3591 b43_phy_write(dev, B43_PHY_ANALOGOVER, sav.phy_analogover);
3592 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
3593 sav.phy_analogoverval);
3594 b43_phy_write(dev, B43_PHY_CRS0, sav.phy_crs0);
3595 b43_phy_write(dev, B43_PHY_CLASSCTL, sav.phy_classctl);
3596 if (has_loopback_gain(phy)) {
3597 b43_phy_write(dev, B43_PHY_LO_MASK, sav.phy_lo_mask);
3598 b43_phy_write(dev, B43_PHY_LO_CTL, sav.phy_lo_ctl);
3599 }
3600 }
3601 if (i > 15)
3602 ret = radio78;
3603 else
3604 ret = rcc;
3605
3606 return ret;
3607}
3608
3609void b43_radio_init2060(struct b43_wldev *dev)
3610{
3611 int err;
3612
3613 b43_radio_write16(dev, 0x0004, 0x00C0);
3614 b43_radio_write16(dev, 0x0005, 0x0008);
3615 b43_radio_write16(dev, 0x0009, 0x0040);
3616 b43_radio_write16(dev, 0x0005, 0x00AA);
3617 b43_radio_write16(dev, 0x0032, 0x008F);
3618 b43_radio_write16(dev, 0x0006, 0x008F);
3619 b43_radio_write16(dev, 0x0034, 0x008F);
3620 b43_radio_write16(dev, 0x002C, 0x0007);
3621 b43_radio_write16(dev, 0x0082, 0x0080);
3622 b43_radio_write16(dev, 0x0080, 0x0000);
3623 b43_radio_write16(dev, 0x003F, 0x00DA);
3624 b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
3625 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0010);
3626 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
3627 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
3628 msleep(1); /* delay 400usec */
3629
3630 b43_radio_write16(dev, 0x0081,
3631 (b43_radio_read16(dev, 0x0081) & ~0x0020) | 0x0010);
3632 msleep(1); /* delay 400usec */
3633
3634 b43_radio_write16(dev, 0x0005,
3635 (b43_radio_read16(dev, 0x0005) & ~0x0008) | 0x0008);
3636 b43_radio_write16(dev, 0x0085, b43_radio_read16(dev, 0x0085) & ~0x0010);
3637 b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
3638 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0040);
3639 b43_radio_write16(dev, 0x0081,
3640 (b43_radio_read16(dev, 0x0081) & ~0x0040) | 0x0040);
3641 b43_radio_write16(dev, 0x0005,
3642 (b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
3643 b43_phy_write(dev, 0x0063, 0xDDC6);
3644 b43_phy_write(dev, 0x0069, 0x07BE);
3645 b43_phy_write(dev, 0x006A, 0x0000);
3646
3647 err = b43_radio_selectchannel(dev, B43_DEFAULT_CHANNEL_A, 0);
3648 B43_WARN_ON(err);
3649
3650 msleep(1);
3651}
3652
3653static inline u16 freq_r3A_value(u16 frequency)
3654{
3655 u16 value;
3656
3657 if (frequency < 5091)
3658 value = 0x0040;
3659 else if (frequency < 5321)
3660 value = 0x0000;
3661 else if (frequency < 5806)
3662 value = 0x0080;
3663 else
3664 value = 0x0040;
3665
3666 return value;
3667}
3668
3669void b43_radio_set_tx_iq(struct b43_wldev *dev)
3670{
3671 static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
3672 static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
3673 u16 tmp = b43_radio_read16(dev, 0x001E);
3674 int i, j;
3675
3676 for (i = 0; i < 5; i++) {
3677 for (j = 0; j < 5; j++) {
3678 if (tmp == (data_high[i] << 4 | data_low[j])) {
3679 b43_phy_write(dev, 0x0069,
3680 (i - j) << 8 | 0x00C0);
3681 return;
3682 }
3683 }
3684 }
3685}
3686
3687int b43_radio_selectchannel(struct b43_wldev *dev,
3688 u8 channel, int synthetic_pu_workaround)
3689{
3690 struct b43_phy *phy = &dev->phy;
3691 u16 r8, tmp;
3692 u16 freq;
3693 u16 channelcookie, savedcookie;
3694 int err = 0;
3695
3696 if (channel == 0xFF) {
3697 switch (phy->type) {
3698 case B43_PHYTYPE_A:
3699 channel = B43_DEFAULT_CHANNEL_A;
3700 break;
3701 case B43_PHYTYPE_B:
3702 case B43_PHYTYPE_G:
3703 channel = B43_DEFAULT_CHANNEL_BG;
3704 break;
3705 case B43_PHYTYPE_N:
3706 //FIXME check if we are on 2.4GHz or 5GHz and set a default channel.
3707 channel = 1;
3708 break;
3709 default:
3710 B43_WARN_ON(1);
3711 }
3712 }
3713
3714 /* First we set the channel radio code to prevent the
3715 * firmware from sending ghost packets.
3716 */
3717 channelcookie = channel;
3718 if (0 /*FIXME on 5Ghz */)
3719 channelcookie |= 0x100;
3720 //FIXME set 40Mhz flag if required
3721 savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
3722 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
3723
3724 switch (phy->type) {
3725 case B43_PHYTYPE_A:
3726 if (channel > 200) {
3727 err = -EINVAL;
3728 goto out;
3729 }
3730 freq = channel2freq_a(channel);
3731
3732 r8 = b43_radio_read16(dev, 0x0008);
3733 b43_write16(dev, 0x03F0, freq);
3734 b43_radio_write16(dev, 0x0008, r8);
3735
3736 //TODO: write max channel TX power? to Radio 0x2D
3737 tmp = b43_radio_read16(dev, 0x002E);
3738 tmp &= 0x0080;
3739 //TODO: OR tmp with the Power out estimation for this channel?
3740 b43_radio_write16(dev, 0x002E, tmp);
3741
3742 if (freq >= 4920 && freq <= 5500) {
3743 /*
3744 * r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F;
3745 * = (freq * 0.025862069
3746 */
3747 r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */
3748 }
3749 b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
3750 b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
3751 b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
3752 b43_radio_write16(dev, 0x0022, (b43_radio_read16(dev, 0x0022)
3753 & 0x000F) | (r8 << 4));
3754 b43_radio_write16(dev, 0x002A, (r8 << 4));
3755 b43_radio_write16(dev, 0x002B, (r8 << 4));
3756 b43_radio_write16(dev, 0x0008, (b43_radio_read16(dev, 0x0008)
3757 & 0x00F0) | (r8 << 4));
3758 b43_radio_write16(dev, 0x0029, (b43_radio_read16(dev, 0x0029)
3759 & 0xFF0F) | 0x00B0);
3760 b43_radio_write16(dev, 0x0035, 0x00AA);
3761 b43_radio_write16(dev, 0x0036, 0x0085);
3762 b43_radio_write16(dev, 0x003A, (b43_radio_read16(dev, 0x003A)
3763 & 0xFF20) |
3764 freq_r3A_value(freq));
3765 b43_radio_write16(dev, 0x003D,
3766 b43_radio_read16(dev, 0x003D) & 0x00FF);
3767 b43_radio_write16(dev, 0x0081, (b43_radio_read16(dev, 0x0081)
3768 & 0xFF7F) | 0x0080);
3769 b43_radio_write16(dev, 0x0035,
3770 b43_radio_read16(dev, 0x0035) & 0xFFEF);
3771 b43_radio_write16(dev, 0x0035, (b43_radio_read16(dev, 0x0035)
3772 & 0xFFEF) | 0x0010);
3773 b43_radio_set_tx_iq(dev);
3774 //TODO: TSSI2dbm workaround
3775 b43_phy_xmitpower(dev); //FIXME correct?
3776 break;
3777 case B43_PHYTYPE_G:
3778 if ((channel < 1) || (channel > 14)) {
3779 err = -EINVAL;
3780 goto out;
3781 }
3782
3783 if (synthetic_pu_workaround)
3784 b43_synth_pu_workaround(dev, channel);
3785
3786 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
3787
3788 if (channel == 14) {
3789 if (dev->dev->bus->sprom.country_code ==
3790 SSB_SPROM1CCODE_JAPAN)
3791 b43_hf_write(dev,
3792 b43_hf_read(dev) & ~B43_HF_ACPR);
3793 else
3794 b43_hf_write(dev,
3795 b43_hf_read(dev) | B43_HF_ACPR);
3796 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
3797 b43_read16(dev, B43_MMIO_CHANNEL_EXT)
3798 | (1 << 11));
3799 } else {
3800 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
3801 b43_read16(dev, B43_MMIO_CHANNEL_EXT)
3802 & 0xF7BF);
3803 }
3804 break;
3805 case B43_PHYTYPE_N:
3806 err = b43_nphy_selectchannel(dev, channel);
3807 if (err)
3808 goto out;
3809 break;
3810 default:
3811 B43_WARN_ON(1);
3812 }
3813
3814 phy->channel = channel;
3815 /* Wait for the radio to tune to the channel and stabilize. */
3816 msleep(8);
3817out:
3818 if (err) {
3819 b43_shm_write16(dev, B43_SHM_SHARED,
3820 B43_SHM_SH_CHAN, savedcookie);
3821 }
3822 return err;
3823}
3824
3825void b43_radio_turn_on(struct b43_wldev *dev) 432void b43_radio_turn_on(struct b43_wldev *dev)
3826{ 433{
3827 struct b43_phy *phy = &dev->phy; 434 struct b43_phy *phy = &dev->phy;
@@ -3843,21 +450,7 @@ void b43_radio_turn_on(struct b43_wldev *dev)
3843 break; 450 break;
3844 case B43_PHYTYPE_B: 451 case B43_PHYTYPE_B:
3845 case B43_PHYTYPE_G: 452 case B43_PHYTYPE_G:
3846 b43_phy_write(dev, 0x0015, 0x8000); 453 //XXX
3847 b43_phy_write(dev, 0x0015, 0xCC00);
3848 b43_phy_write(dev, 0x0015, (phy->gmode ? 0x00C0 : 0x0000));
3849 if (phy->radio_off_context.valid) {
3850 /* Restore the RFover values. */
3851 b43_phy_write(dev, B43_PHY_RFOVER,
3852 phy->radio_off_context.rfover);
3853 b43_phy_write(dev, B43_PHY_RFOVERVAL,
3854 phy->radio_off_context.rfoverval);
3855 phy->radio_off_context.valid = 0;
3856 }
3857 channel = phy->channel;
3858 err = b43_radio_selectchannel(dev, B43_DEFAULT_CHANNEL_BG, 1);
3859 err |= b43_radio_selectchannel(dev, channel, 0);
3860 B43_WARN_ON(err);
3861 break; 454 break;
3862 case B43_PHYTYPE_N: 455 case B43_PHYTYPE_N:
3863 b43_nphy_radio_turn_on(dev); 456 b43_nphy_radio_turn_on(dev);
@@ -3886,17 +479,7 @@ void b43_radio_turn_off(struct b43_wldev *dev, bool force)
3886 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008); 479 b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
3887 break; 480 break;
3888 case B43_PHYTYPE_G: { 481 case B43_PHYTYPE_G: {
3889 u16 rfover, rfoverval; 482 //XXX
3890
3891 rfover = b43_phy_read(dev, B43_PHY_RFOVER);
3892 rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
3893 if (!force) {
3894 phy->radio_off_context.rfover = rfover;
3895 phy->radio_off_context.rfoverval = rfoverval;
3896 phy->radio_off_context.valid = 1;
3897 }
3898 b43_phy_write(dev, B43_PHY_RFOVER, rfover | 0x008C);
3899 b43_phy_write(dev, B43_PHY_RFOVERVAL, rfoverval & 0xFF73);
3900 break; 483 break;
3901 } 484 }
3902 default: 485 default:
diff --git a/drivers/net/wireless/b43/phy.h b/drivers/net/wireless/b43/phy.h
deleted file mode 100644
index 4aab10903529..000000000000
--- a/drivers/net/wireless/b43/phy.h
+++ /dev/null
@@ -1,340 +0,0 @@
1#ifndef B43_PHY_H_
2#define B43_PHY_H_
3
4#include <linux/types.h>
5
6struct b43_wldev;
7struct b43_phy;
8
9/*** PHY Registers ***/
10
11/* Routing */
12#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
13#define B43_PHYROUTE_BASE 0x0000 /* Base registers */
14#define B43_PHYROUTE_OFDM_GPHY 0x0400 /* OFDM register routing for G-PHYs */
15#define B43_PHYROUTE_EXT_GPHY 0x0800 /* Extended G-PHY registers */
16#define B43_PHYROUTE_N_BMODE 0x0C00 /* N-PHY BMODE registers */
17
18/* CCK (B-PHY) registers. */
19#define B43_PHY_CCK(reg) ((reg) | B43_PHYROUTE_BASE)
20/* N-PHY registers. */
21#define B43_PHY_N(reg) ((reg) | B43_PHYROUTE_BASE)
22/* N-PHY BMODE registers. */
23#define B43_PHY_N_BMODE(reg) ((reg) | B43_PHYROUTE_N_BMODE)
24/* OFDM (A-PHY) registers. */
25#define B43_PHY_OFDM(reg) ((reg) | B43_PHYROUTE_OFDM_GPHY)
26/* Extended G-PHY registers. */
27#define B43_PHY_EXTG(reg) ((reg) | B43_PHYROUTE_EXT_GPHY)
28
29/* OFDM (A) PHY Registers */
30#define B43_PHY_VERSION_OFDM B43_PHY_OFDM(0x00) /* Versioning register for A-PHY */
31#define B43_PHY_BBANDCFG B43_PHY_OFDM(0x01) /* Baseband config */
32#define B43_PHY_BBANDCFG_RXANT 0x180 /* RX Antenna selection */
33#define B43_PHY_BBANDCFG_RXANT_SHIFT 7
34#define B43_PHY_PWRDOWN B43_PHY_OFDM(0x03) /* Powerdown */
35#define B43_PHY_CRSTHRES1_R1 B43_PHY_OFDM(0x06) /* CRS Threshold 1 (phy.rev 1 only) */
36#define B43_PHY_LNAHPFCTL B43_PHY_OFDM(0x1C) /* LNA/HPF control */
37#define B43_PHY_LPFGAINCTL B43_PHY_OFDM(0x20) /* LPF Gain control */
38#define B43_PHY_ADIVRELATED B43_PHY_OFDM(0x27) /* FIXME rename */
39#define B43_PHY_CRS0 B43_PHY_OFDM(0x29)
40#define B43_PHY_CRS0_EN 0x4000
41#define B43_PHY_PEAK_COUNT B43_PHY_OFDM(0x30)
42#define B43_PHY_ANTDWELL B43_PHY_OFDM(0x2B) /* Antenna dwell */
43#define B43_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX diversity start antenna */
44#define B43_PHY_ENCORE B43_PHY_OFDM(0x49) /* "Encore" (RangeMax / BroadRange) */
45#define B43_PHY_ENCORE_EN 0x0200 /* Encore enable */
46#define B43_PHY_LMS B43_PHY_OFDM(0x55)
47#define B43_PHY_OFDM61 B43_PHY_OFDM(0x61) /* FIXME rename */
48#define B43_PHY_OFDM61_10 0x0010 /* FIXME rename */
49#define B43_PHY_IQBAL B43_PHY_OFDM(0x69) /* I/Q balance */
50#define B43_PHY_BBTXDC_BIAS B43_PHY_OFDM(0x6B) /* Baseband TX DC bias */
51#define B43_PHY_OTABLECTL B43_PHY_OFDM(0x72) /* OFDM table control (see below) */
52#define B43_PHY_OTABLEOFF 0x03FF /* OFDM table offset (see below) */
53#define B43_PHY_OTABLENR 0xFC00 /* OFDM table number (see below) */
54#define B43_PHY_OTABLENR_SHIFT 10
55#define B43_PHY_OTABLEI B43_PHY_OFDM(0x73) /* OFDM table data I */
56#define B43_PHY_OTABLEQ B43_PHY_OFDM(0x74) /* OFDM table data Q */
57#define B43_PHY_HPWR_TSSICTL B43_PHY_OFDM(0x78) /* Hardware power TSSI control */
58#define B43_PHY_ADCCTL B43_PHY_OFDM(0x7A) /* ADC control */
59#define B43_PHY_IDLE_TSSI B43_PHY_OFDM(0x7B)
60#define B43_PHY_A_TEMP_SENSE B43_PHY_OFDM(0x7C) /* A PHY temperature sense */
61#define B43_PHY_NRSSITHRES B43_PHY_OFDM(0x8A) /* NRSSI threshold */
62#define B43_PHY_ANTWRSETT B43_PHY_OFDM(0x8C) /* Antenna WR settle */
63#define B43_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX diversity enabled */
64#define B43_PHY_CLIPPWRDOWNT B43_PHY_OFDM(0x93) /* Clip powerdown threshold */
65#define B43_PHY_OFDM9B B43_PHY_OFDM(0x9B) /* FIXME rename */
66#define B43_PHY_N1P1GAIN B43_PHY_OFDM(0xA0)
67#define B43_PHY_P1P2GAIN B43_PHY_OFDM(0xA1)
68#define B43_PHY_N1N2GAIN B43_PHY_OFDM(0xA2)
69#define B43_PHY_CLIPTHRES B43_PHY_OFDM(0xA3)
70#define B43_PHY_CLIPN1P2THRES B43_PHY_OFDM(0xA4)
71#define B43_PHY_CCKSHIFTBITS_WA B43_PHY_OFDM(0xA5) /* CCK shiftbits workaround, FIXME rename */
72#define B43_PHY_CCKSHIFTBITS B43_PHY_OFDM(0xA7) /* FIXME rename */
73#define B43_PHY_DIVSRCHIDX B43_PHY_OFDM(0xA8) /* Divider search gain/index */
74#define B43_PHY_CLIPP2THRES B43_PHY_OFDM(0xA9)
75#define B43_PHY_CLIPP3THRES B43_PHY_OFDM(0xAA)
76#define B43_PHY_DIVP1P2GAIN B43_PHY_OFDM(0xAB)
77#define B43_PHY_DIVSRCHGAINBACK B43_PHY_OFDM(0xAD) /* Divider search gain back */
78#define B43_PHY_DIVSRCHGAINCHNG B43_PHY_OFDM(0xAE) /* Divider search gain change */
79#define B43_PHY_CRSTHRES1 B43_PHY_OFDM(0xC0) /* CRS Threshold 1 (phy.rev >= 2 only) */
80#define B43_PHY_CRSTHRES2 B43_PHY_OFDM(0xC1) /* CRS Threshold 2 (phy.rev >= 2 only) */
81#define B43_PHY_TSSIP_LTBASE B43_PHY_OFDM(0x380) /* TSSI power lookup table base */
82#define B43_PHY_DC_LTBASE B43_PHY_OFDM(0x3A0) /* DC lookup table base */
83#define B43_PHY_GAIN_LTBASE B43_PHY_OFDM(0x3C0) /* Gain lookup table base */
84
85/* CCK (B) PHY Registers */
86#define B43_PHY_VERSION_CCK B43_PHY_CCK(0x00) /* Versioning register for B-PHY */
87#define B43_PHY_CCKBBANDCFG B43_PHY_CCK(0x01) /* Contains antenna 0/1 control bit */
88#define B43_PHY_PGACTL B43_PHY_CCK(0x15) /* PGA control */
89#define B43_PHY_PGACTL_LPF 0x1000 /* Low pass filter (?) */
90#define B43_PHY_PGACTL_LOWBANDW 0x0040 /* Low bandwidth flag */
91#define B43_PHY_PGACTL_UNKNOWN 0xEFA0
92#define B43_PHY_FBCTL1 B43_PHY_CCK(0x18) /* Frequency bandwidth control 1 */
93#define B43_PHY_ITSSI B43_PHY_CCK(0x29) /* Idle TSSI */
94#define B43_PHY_LO_LEAKAGE B43_PHY_CCK(0x2D) /* Measured LO leakage */
95#define B43_PHY_ENERGY B43_PHY_CCK(0x33) /* Energy */
96#define B43_PHY_SYNCCTL B43_PHY_CCK(0x35)
97#define B43_PHY_FBCTL2 B43_PHY_CCK(0x38) /* Frequency bandwidth control 2 */
98#define B43_PHY_DACCTL B43_PHY_CCK(0x60) /* DAC control */
99#define B43_PHY_RCCALOVER B43_PHY_CCK(0x78) /* RC calibration override */
100
101/* Extended G-PHY Registers */
102#define B43_PHY_CLASSCTL B43_PHY_EXTG(0x02) /* Classify control */
103#define B43_PHY_GTABCTL B43_PHY_EXTG(0x03) /* G-PHY table control (see below) */
104#define B43_PHY_GTABOFF 0x03FF /* G-PHY table offset (see below) */
105#define B43_PHY_GTABNR 0xFC00 /* G-PHY table number (see below) */
106#define B43_PHY_GTABNR_SHIFT 10
107#define B43_PHY_GTABDATA B43_PHY_EXTG(0x04) /* G-PHY table data */
108#define B43_PHY_LO_MASK B43_PHY_EXTG(0x0F) /* Local Oscillator control mask */
109#define B43_PHY_LO_CTL B43_PHY_EXTG(0x10) /* Local Oscillator control */
110#define B43_PHY_RFOVER B43_PHY_EXTG(0x11) /* RF override */
111#define B43_PHY_RFOVERVAL B43_PHY_EXTG(0x12) /* RF override value */
112#define B43_PHY_RFOVERVAL_EXTLNA 0x8000
113#define B43_PHY_RFOVERVAL_LNA 0x7000
114#define B43_PHY_RFOVERVAL_LNA_SHIFT 12
115#define B43_PHY_RFOVERVAL_PGA 0x0F00
116#define B43_PHY_RFOVERVAL_PGA_SHIFT 8
117#define B43_PHY_RFOVERVAL_UNK 0x0010 /* Unknown, always set. */
118#define B43_PHY_RFOVERVAL_TRSWRX 0x00E0
119#define B43_PHY_RFOVERVAL_BW 0x0003 /* Bandwidth flags */
120#define B43_PHY_RFOVERVAL_BW_LPF 0x0001 /* Low Pass Filter */
121#define B43_PHY_RFOVERVAL_BW_LBW 0x0002 /* Low Bandwidth (when set), high when unset */
122#define B43_PHY_ANALOGOVER B43_PHY_EXTG(0x14) /* Analog override */
123#define B43_PHY_ANALOGOVERVAL B43_PHY_EXTG(0x15) /* Analog override value */
124
125/*** OFDM table numbers ***/
126#define B43_OFDMTAB(number, offset) (((number) << B43_PHY_OTABLENR_SHIFT) | (offset))
127#define B43_OFDMTAB_AGC1 B43_OFDMTAB(0x00, 0)
128#define B43_OFDMTAB_GAIN0 B43_OFDMTAB(0x00, 0)
129#define B43_OFDMTAB_GAINX B43_OFDMTAB(0x01, 0) //TODO rename
130#define B43_OFDMTAB_GAIN1 B43_OFDMTAB(0x01, 4)
131#define B43_OFDMTAB_AGC3 B43_OFDMTAB(0x02, 0)
132#define B43_OFDMTAB_GAIN2 B43_OFDMTAB(0x02, 3)
133#define B43_OFDMTAB_LNAHPFGAIN1 B43_OFDMTAB(0x03, 0)
134#define B43_OFDMTAB_WRSSI B43_OFDMTAB(0x04, 0)
135#define B43_OFDMTAB_LNAHPFGAIN2 B43_OFDMTAB(0x04, 0)
136#define B43_OFDMTAB_NOISESCALE B43_OFDMTAB(0x05, 0)
137#define B43_OFDMTAB_AGC2 B43_OFDMTAB(0x06, 0)
138#define B43_OFDMTAB_ROTOR B43_OFDMTAB(0x08, 0)
139#define B43_OFDMTAB_ADVRETARD B43_OFDMTAB(0x09, 0)
140#define B43_OFDMTAB_DAC B43_OFDMTAB(0x0C, 0)
141#define B43_OFDMTAB_DC B43_OFDMTAB(0x0E, 7)
142#define B43_OFDMTAB_PWRDYN2 B43_OFDMTAB(0x0E, 12)
143#define B43_OFDMTAB_LNAGAIN B43_OFDMTAB(0x0E, 13)
144#define B43_OFDMTAB_UNKNOWN_0F B43_OFDMTAB(0x0F, 0) //TODO rename
145#define B43_OFDMTAB_UNKNOWN_APHY B43_OFDMTAB(0x0F, 7) //TODO rename
146#define B43_OFDMTAB_LPFGAIN B43_OFDMTAB(0x0F, 12)
147#define B43_OFDMTAB_RSSI B43_OFDMTAB(0x10, 0)
148#define B43_OFDMTAB_UNKNOWN_11 B43_OFDMTAB(0x11, 4) //TODO rename
149#define B43_OFDMTAB_AGC1_R1 B43_OFDMTAB(0x13, 0)
150#define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO remove!
151#define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 0)
152#define B43_OFDMTAB_AGC3_R1 B43_OFDMTAB(0x15, 0)
153#define B43_OFDMTAB_WRSSI_R1 B43_OFDMTAB(0x15, 4)
154#define B43_OFDMTAB_TSSI B43_OFDMTAB(0x15, 0)
155#define B43_OFDMTAB_DACRFPABB B43_OFDMTAB(0x16, 0)
156#define B43_OFDMTAB_DACOFF B43_OFDMTAB(0x17, 0)
157#define B43_OFDMTAB_DCBIAS B43_OFDMTAB(0x18, 0)
158
159u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset);
160void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table,
161 u16 offset, u16 value);
162u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset);
163void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
164 u16 offset, u32 value);
165
166/*** G-PHY table numbers */
167#define B43_GTAB(number, offset) (((number) << B43_PHY_GTABNR_SHIFT) | (offset))
168#define B43_GTAB_NRSSI B43_GTAB(0x00, 0)
169#define B43_GTAB_TRFEMW B43_GTAB(0x0C, 0x120)
170#define B43_GTAB_ORIGTR B43_GTAB(0x2E, 0x298)
171
172u16 b43_gtab_read(struct b43_wldev *dev, u16 table, u16 offset); //TODO implement
173void b43_gtab_write(struct b43_wldev *dev, u16 table, u16 offset, u16 value); //TODO implement
174
175#define B43_DEFAULT_CHANNEL_A 36
176#define B43_DEFAULT_CHANNEL_BG 6
177
178enum {
179 B43_ANTENNA0, /* Antenna 0 */
180 B43_ANTENNA1, /* Antenna 0 */
181 B43_ANTENNA_AUTO1, /* Automatic, starting with antenna 1 */
182 B43_ANTENNA_AUTO0, /* Automatic, starting with antenna 0 */
183 B43_ANTENNA2,
184 B43_ANTENNA3 = 8,
185
186 B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
187 B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO,
188};
189
190enum {
191 B43_INTERFMODE_NONE,
192 B43_INTERFMODE_NONWLAN,
193 B43_INTERFMODE_MANUALWLAN,
194 B43_INTERFMODE_AUTOWLAN,
195};
196
197/* Masks for the different PHY versioning registers. */
198#define B43_PHYVER_ANALOG 0xF000
199#define B43_PHYVER_ANALOG_SHIFT 12
200#define B43_PHYVER_TYPE 0x0F00
201#define B43_PHYVER_TYPE_SHIFT 8
202#define B43_PHYVER_VERSION 0x00FF
203
204void b43_phy_lock(struct b43_wldev *dev);
205void b43_phy_unlock(struct b43_wldev *dev);
206
207
208/* Read a value from a PHY register */
209u16 b43_phy_read(struct b43_wldev *dev, u16 offset);
210/* Write a value to a PHY register */
211void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val);
212/* Mask a PHY register with a mask */
213void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
214/* OR a PHY register with a bitmap */
215void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set);
216/* Mask and OR a PHY register with a mask and bitmap */
217void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
218
219
220int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev);
221
222void b43_phy_early_init(struct b43_wldev *dev);
223int b43_phy_init(struct b43_wldev *dev);
224
225void b43_set_rx_antenna(struct b43_wldev *dev, int antenna);
226
227void b43_phy_xmitpower(struct b43_wldev *dev);
228
229/* Returns the boolean whether the board has HardwarePowerControl */
230bool b43_has_hardware_pctl(struct b43_phy *phy);
231/* Returns the boolean whether "TX Magnification" is enabled. */
232#define has_tx_magnification(phy) \
233 (((phy)->rev >= 2) && \
234 ((phy)->radio_ver == 0x2050) && \
235 ((phy)->radio_rev == 8))
236/* Card uses the loopback gain stuff */
237#define has_loopback_gain(phy) \
238 (((phy)->rev > 1) || ((phy)->gmode))
239
240/* Radio Attenuation (RF Attenuation) */
241struct b43_rfatt {
242 u8 att; /* Attenuation value */
243 bool with_padmix; /* Flag, PAD Mixer enabled. */
244};
245struct b43_rfatt_list {
246 /* Attenuation values list */
247 const struct b43_rfatt *list;
248 u8 len;
249 /* Minimum/Maximum attenuation values */
250 u8 min_val;
251 u8 max_val;
252};
253
254/* Returns true, if the values are the same. */
255static inline bool b43_compare_rfatt(const struct b43_rfatt *a,
256 const struct b43_rfatt *b)
257{
258 return ((a->att == b->att) &&
259 (a->with_padmix == b->with_padmix));
260}
261
262/* Baseband Attenuation */
263struct b43_bbatt {
264 u8 att; /* Attenuation value */
265};
266struct b43_bbatt_list {
267 /* Attenuation values list */
268 const struct b43_bbatt *list;
269 u8 len;
270 /* Minimum/Maximum attenuation values */
271 u8 min_val;
272 u8 max_val;
273};
274
275/* Returns true, if the values are the same. */
276static inline bool b43_compare_bbatt(const struct b43_bbatt *a,
277 const struct b43_bbatt *b)
278{
279 return (a->att == b->att);
280}
281
282/* tx_control bits. */
283#define B43_TXCTL_PA3DB 0x40 /* PA Gain 3dB */
284#define B43_TXCTL_PA2DB 0x20 /* PA Gain 2dB */
285#define B43_TXCTL_TXMIX 0x10 /* TX Mixer Gain */
286
287/* Write BasebandAttenuation value to the device. */
288void b43_phy_set_baseband_attenuation(struct b43_wldev *dev,
289 u16 baseband_attenuation);
290
291extern const u8 b43_radio_channel_codes_bg[];
292
293void b43_radio_lock(struct b43_wldev *dev);
294void b43_radio_unlock(struct b43_wldev *dev);
295
296
297/* Read a value from a 16bit radio register */
298u16 b43_radio_read16(struct b43_wldev *dev, u16 offset);
299/* Write a value to a 16bit radio register */
300void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val);
301/* Mask a 16bit radio register with a mask */
302void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask);
303/* OR a 16bit radio register with a bitmap */
304void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
305/* Mask and OR a PHY register with a mask and bitmap */
306void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
307
308
309u16 b43_radio_init2050(struct b43_wldev *dev);
310void b43_radio_init2060(struct b43_wldev *dev);
311
312void b43_radio_turn_on(struct b43_wldev *dev);
313void b43_radio_turn_off(struct b43_wldev *dev, bool force);
314
315int b43_radio_selectchannel(struct b43_wldev *dev, u8 channel,
316 int synthetic_pu_workaround);
317
318u8 b43_radio_aci_detect(struct b43_wldev *dev, u8 channel);
319u8 b43_radio_aci_scan(struct b43_wldev *dev);
320
321int b43_radio_set_interference_mitigation(struct b43_wldev *dev, int mode);
322
323void b43_calc_nrssi_slope(struct b43_wldev *dev);
324void b43_calc_nrssi_threshold(struct b43_wldev *dev);
325s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset);
326void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val);
327void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val);
328void b43_nrssi_mem_update(struct b43_wldev *dev);
329
330void b43_radio_set_tx_iq(struct b43_wldev *dev);
331u16 b43_radio_calibrationvalue(struct b43_wldev *dev);
332
333void b43_put_attenuation_into_ranges(struct b43_wldev *dev,
334 int *_bbatt, int *_rfatt);
335
336void b43_set_txpower_g(struct b43_wldev *dev,
337 const struct b43_bbatt *bbatt,
338 const struct b43_rfatt *rfatt, u8 tx_control);
339
340#endif /* B43_PHY_H_ */
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
new file mode 100644
index 000000000000..4d7d59e30960
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -0,0 +1,543 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11a PHY driver
5
6 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
7 Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
8 Copyright (c) 2005-2008 Michael Buesch <mb@bu3sch.de>
9 Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
10 Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; see the file COPYING. If not, write to
24 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
25 Boston, MA 02110-1301, USA.
26
27*/
28
29#include "b43.h"
30#include "phy_a.h"
31#include "phy_common.h"
32#include "wa.h"
33#include "tables.h"
34#include "main.h"
35
36
37/* Get the freq, as it has to be written to the device. */
38static inline u16 channel2freq_a(u8 channel)
39{
40 B43_WARN_ON(channel > 200);
41
42 return (5000 + 5 * channel);
43}
44
45static inline u16 freq_r3A_value(u16 frequency)
46{
47 u16 value;
48
49 if (frequency < 5091)
50 value = 0x0040;
51 else if (frequency < 5321)
52 value = 0x0000;
53 else if (frequency < 5806)
54 value = 0x0080;
55 else
56 value = 0x0040;
57
58 return value;
59}
60
61void b43_radio_set_tx_iq(struct b43_wldev *dev)
62{
63 static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
64 static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
65 u16 tmp = b43_radio_read16(dev, 0x001E);
66 int i, j;
67
68 for (i = 0; i < 5; i++) {
69 for (j = 0; j < 5; j++) {
70 if (tmp == (data_high[i] << 4 | data_low[j])) {
71 b43_phy_write(dev, 0x0069,
72 (i - j) << 8 | 0x00C0);
73 return;
74 }
75 }
76 }
77}
78
79static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
80{
81 u16 freq, r8, tmp;
82
83 freq = channel2freq_a(channel);
84
85 r8 = b43_radio_read16(dev, 0x0008);
86 b43_write16(dev, 0x03F0, freq);
87 b43_radio_write16(dev, 0x0008, r8);
88
89 //TODO: write max channel TX power? to Radio 0x2D
90 tmp = b43_radio_read16(dev, 0x002E);
91 tmp &= 0x0080;
92 //TODO: OR tmp with the Power out estimation for this channel?
93 b43_radio_write16(dev, 0x002E, tmp);
94
95 if (freq >= 4920 && freq <= 5500) {
96 /*
97 * r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F;
98 * = (freq * 0.025862069
99 */
100 r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */
101 }
102 b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
103 b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
104 b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
105 b43_radio_write16(dev, 0x0022, (b43_radio_read16(dev, 0x0022)
106 & 0x000F) | (r8 << 4));
107 b43_radio_write16(dev, 0x002A, (r8 << 4));
108 b43_radio_write16(dev, 0x002B, (r8 << 4));
109 b43_radio_write16(dev, 0x0008, (b43_radio_read16(dev, 0x0008)
110 & 0x00F0) | (r8 << 4));
111 b43_radio_write16(dev, 0x0029, (b43_radio_read16(dev, 0x0029)
112 & 0xFF0F) | 0x00B0);
113 b43_radio_write16(dev, 0x0035, 0x00AA);
114 b43_radio_write16(dev, 0x0036, 0x0085);
115 b43_radio_write16(dev, 0x003A, (b43_radio_read16(dev, 0x003A)
116 & 0xFF20) |
117 freq_r3A_value(freq));
118 b43_radio_write16(dev, 0x003D,
119 b43_radio_read16(dev, 0x003D) & 0x00FF);
120 b43_radio_write16(dev, 0x0081, (b43_radio_read16(dev, 0x0081)
121 & 0xFF7F) | 0x0080);
122 b43_radio_write16(dev, 0x0035,
123 b43_radio_read16(dev, 0x0035) & 0xFFEF);
124 b43_radio_write16(dev, 0x0035, (b43_radio_read16(dev, 0x0035)
125 & 0xFFEF) | 0x0010);
126 b43_radio_set_tx_iq(dev);
127 //TODO: TSSI2dbm workaround
128//FIXME b43_phy_xmitpower(dev);
129}
130
131void b43_radio_init2060(struct b43_wldev *dev)
132{
133 b43_radio_write16(dev, 0x0004, 0x00C0);
134 b43_radio_write16(dev, 0x0005, 0x0008);
135 b43_radio_write16(dev, 0x0009, 0x0040);
136 b43_radio_write16(dev, 0x0005, 0x00AA);
137 b43_radio_write16(dev, 0x0032, 0x008F);
138 b43_radio_write16(dev, 0x0006, 0x008F);
139 b43_radio_write16(dev, 0x0034, 0x008F);
140 b43_radio_write16(dev, 0x002C, 0x0007);
141 b43_radio_write16(dev, 0x0082, 0x0080);
142 b43_radio_write16(dev, 0x0080, 0x0000);
143 b43_radio_write16(dev, 0x003F, 0x00DA);
144 b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
145 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0010);
146 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
147 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
148 msleep(1); /* delay 400usec */
149
150 b43_radio_write16(dev, 0x0081,
151 (b43_radio_read16(dev, 0x0081) & ~0x0020) | 0x0010);
152 msleep(1); /* delay 400usec */
153
154 b43_radio_write16(dev, 0x0005,
155 (b43_radio_read16(dev, 0x0005) & ~0x0008) | 0x0008);
156 b43_radio_write16(dev, 0x0085, b43_radio_read16(dev, 0x0085) & ~0x0010);
157 b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
158 b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0040);
159 b43_radio_write16(dev, 0x0081,
160 (b43_radio_read16(dev, 0x0081) & ~0x0040) | 0x0040);
161 b43_radio_write16(dev, 0x0005,
162 (b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
163 b43_phy_write(dev, 0x0063, 0xDDC6);
164 b43_phy_write(dev, 0x0069, 0x07BE);
165 b43_phy_write(dev, 0x006A, 0x0000);
166
167 aphy_channel_switch(dev, dev->phy.ops->get_default_chan(dev));
168
169 msleep(1);
170}
171
172static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable)
173{
174 int i;
175
176 if (dev->phy.rev < 3) {
177 if (enable)
178 for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
179 b43_ofdmtab_write16(dev,
180 B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8);
181 b43_ofdmtab_write16(dev,
182 B43_OFDMTAB_WRSSI, i, 0xFFF8);
183 }
184 else
185 for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
186 b43_ofdmtab_write16(dev,
187 B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]);
188 b43_ofdmtab_write16(dev,
189 B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]);
190 }
191 } else {
192 if (enable)
193 for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++)
194 b43_ofdmtab_write16(dev,
195 B43_OFDMTAB_WRSSI, i, 0x0820);
196 else
197 for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++)
198 b43_ofdmtab_write16(dev,
199 B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]);
200 }
201}
202
203static void b43_phy_ww(struct b43_wldev *dev)
204{
205 u16 b, curr_s, best_s = 0xFFFF;
206 int i;
207
208 b43_phy_write(dev, B43_PHY_CRS0,
209 b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN);
210 b43_phy_write(dev, B43_PHY_OFDM(0x1B),
211 b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000);
212 b43_phy_write(dev, B43_PHY_OFDM(0x82),
213 (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300);
214 b43_radio_write16(dev, 0x0009,
215 b43_radio_read16(dev, 0x0009) | 0x0080);
216 b43_radio_write16(dev, 0x0012,
217 (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
218 b43_wa_initgains(dev);
219 b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
220 b = b43_phy_read(dev, B43_PHY_PWRDOWN);
221 b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
222 b43_radio_write16(dev, 0x0004,
223 b43_radio_read16(dev, 0x0004) | 0x0004);
224 for (i = 0x10; i <= 0x20; i++) {
225 b43_radio_write16(dev, 0x0013, i);
226 curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
227 if (!curr_s) {
228 best_s = 0x0000;
229 break;
230 } else if (curr_s >= 0x0080)
231 curr_s = 0x0100 - curr_s;
232 if (curr_s < best_s)
233 best_s = curr_s;
234 }
235 b43_phy_write(dev, B43_PHY_PWRDOWN, b);
236 b43_radio_write16(dev, 0x0004,
237 b43_radio_read16(dev, 0x0004) & 0xFFFB);
238 b43_radio_write16(dev, 0x0013, best_s);
239 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
240 b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
241 b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00);
242 b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
243 b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
244 b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
245 b43_phy_write(dev, B43_PHY_OFDM(0xBB),
246 (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
247 b43_phy_write(dev, B43_PHY_OFDM61,
248 (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120);
249 b43_phy_write(dev, B43_PHY_OFDM(0x13),
250 (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
251 b43_phy_write(dev, B43_PHY_OFDM(0x14),
252 (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000);
253 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
254 for (i = 0; i < 6; i++)
255 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
256 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E);
257 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
258 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
259 b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
260 b43_phy_write(dev, B43_PHY_CRS0,
261 b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
262}
263
264static void hardware_pctl_init_aphy(struct b43_wldev *dev)
265{
266 //TODO
267}
268
269void b43_phy_inita(struct b43_wldev *dev)
270{
271 struct ssb_bus *bus = dev->dev->bus;
272 struct b43_phy *phy = &dev->phy;
273
274 /* This lowlevel A-PHY init is also called from G-PHY init.
275 * So we must not access phy->a, if called from G-PHY code.
276 */
277 B43_WARN_ON((phy->type != B43_PHYTYPE_A) &&
278 (phy->type != B43_PHYTYPE_G));
279
280 might_sleep();
281
282 if (phy->rev >= 6) {
283 if (phy->type == B43_PHYTYPE_A)
284 b43_phy_write(dev, B43_PHY_OFDM(0x1B),
285 b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000);
286 if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
287 b43_phy_write(dev, B43_PHY_ENCORE,
288 b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010);
289 else
290 b43_phy_write(dev, B43_PHY_ENCORE,
291 b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010);
292 }
293
294 b43_wa_all(dev);
295
296 if (phy->type == B43_PHYTYPE_A) {
297 if (phy->gmode && (phy->rev < 3))
298 b43_phy_write(dev, 0x0034,
299 b43_phy_read(dev, 0x0034) | 0x0001);
300 b43_phy_rssiagc(dev, 0);
301
302 b43_phy_write(dev, B43_PHY_CRS0,
303 b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
304
305 b43_radio_init2060(dev);
306
307 if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
308 ((bus->boardinfo.type == SSB_BOARD_BU4306) ||
309 (bus->boardinfo.type == SSB_BOARD_BU4309))) {
310 ; //TODO: A PHY LO
311 }
312
313 if (phy->rev >= 3)
314 b43_phy_ww(dev);
315
316 hardware_pctl_init_aphy(dev);
317
318 //TODO: radar detection
319 }
320
321 if ((phy->type == B43_PHYTYPE_G) &&
322 (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
323 b43_phy_write(dev, B43_PHY_OFDM(0x6E),
324 (b43_phy_read(dev, B43_PHY_OFDM(0x6E))
325 & 0xE000) | 0x3CF);
326 }
327}
328
329static int b43_aphy_op_allocate(struct b43_wldev *dev)
330{
331 struct b43_phy_a *aphy;
332
333 aphy = kzalloc(sizeof(*aphy), GFP_KERNEL);
334 if (!aphy)
335 return -ENOMEM;
336 dev->phy.a = aphy;
337
338 //TODO init struct b43_phy_a
339
340 return 0;
341}
342
343static int b43_aphy_op_init(struct b43_wldev *dev)
344{
345 struct b43_phy_a *aphy = dev->phy.a;
346
347 b43_phy_inita(dev);
348 aphy->initialised = 1;
349
350 return 0;
351}
352
353static void b43_aphy_op_exit(struct b43_wldev *dev)
354{
355 struct b43_phy_a *aphy = dev->phy.a;
356
357 if (aphy->initialised) {
358 //TODO
359 aphy->initialised = 0;
360 }
361 //TODO
362 kfree(aphy);
363 dev->phy.a = NULL;
364}
365
366static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
367{
368 /* OFDM registers are base-registers for the A-PHY. */
369 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
370 offset &= ~B43_PHYROUTE;
371 offset |= B43_PHYROUTE_BASE;
372 }
373
374#if B43_DEBUG
375 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
376 /* Ext-G registers are only available on G-PHYs */
377 b43err(dev->wl, "Invalid EXT-G PHY access at "
378 "0x%04X on A-PHY\n", offset);
379 dump_stack();
380 }
381 if ((offset & B43_PHYROUTE) == B43_PHYROUTE_N_BMODE) {
382 /* N-BMODE registers are only available on N-PHYs */
383 b43err(dev->wl, "Invalid N-BMODE PHY access at "
384 "0x%04X on A-PHY\n", offset);
385 dump_stack();
386 }
387#endif /* B43_DEBUG */
388
389 return offset;
390}
391
392static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
393{
394 reg = adjust_phyreg(dev, reg);
395 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
396 return b43_read16(dev, B43_MMIO_PHY_DATA);
397}
398
399static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
400{
401 reg = adjust_phyreg(dev, reg);
402 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
403 b43_write16(dev, B43_MMIO_PHY_DATA, value);
404}
405
406static u16 b43_aphy_op_radio_read(struct b43_wldev *dev, u16 reg)
407{
408 /* Register 1 is a 32-bit register. */
409 B43_WARN_ON(reg == 1);
410 /* A-PHY needs 0x40 for read access */
411 reg |= 0x40;
412
413 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
414 return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
415}
416
417static void b43_aphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
418{
419 /* Register 1 is a 32-bit register. */
420 B43_WARN_ON(reg == 1);
421
422 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
423 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
424}
425
426static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
427{
428 return (dev->phy.rev >= 5);
429}
430
431static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
432 enum rfkill_state state)
433{//TODO
434}
435
436static int b43_aphy_op_switch_channel(struct b43_wldev *dev,
437 unsigned int new_channel)
438{
439 if (new_channel > 200)
440 return -EINVAL;
441 aphy_channel_switch(dev, new_channel);
442
443 return 0;
444}
445
446static unsigned int b43_aphy_op_get_default_chan(struct b43_wldev *dev)
447{
448 return 36; /* Default to channel 36 */
449}
450
451static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
452{//TODO
453 struct b43_phy *phy = &dev->phy;
454 u64 hf;
455 u16 tmp;
456 int autodiv = 0;
457
458 if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
459 autodiv = 1;
460
461 hf = b43_hf_read(dev);
462 hf &= ~B43_HF_ANTDIVHELP;
463 b43_hf_write(dev, hf);
464
465 tmp = b43_phy_read(dev, B43_PHY_BBANDCFG);
466 tmp &= ~B43_PHY_BBANDCFG_RXANT;
467 tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
468 << B43_PHY_BBANDCFG_RXANT_SHIFT;
469 b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
470
471 if (autodiv) {
472 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
473 if (antenna == B43_ANTENNA_AUTO0)
474 tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
475 else
476 tmp |= B43_PHY_ANTDWELL_AUTODIV1;
477 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
478 }
479 if (phy->rev < 3) {
480 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
481 tmp = (tmp & 0xFF00) | 0x24;
482 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
483 } else {
484 tmp = b43_phy_read(dev, B43_PHY_OFDM61);
485 tmp |= 0x10;
486 b43_phy_write(dev, B43_PHY_OFDM61, tmp);
487 if (phy->analog == 3) {
488 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
489 0x1D);
490 b43_phy_write(dev, B43_PHY_ADIVRELATED,
491 8);
492 } else {
493 b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
494 0x3A);
495 tmp =
496 b43_phy_read(dev,
497 B43_PHY_ADIVRELATED);
498 tmp = (tmp & 0xFF00) | 8;
499 b43_phy_write(dev, B43_PHY_ADIVRELATED,
500 tmp);
501 }
502 }
503
504 hf |= B43_HF_ANTDIVHELP;
505 b43_hf_write(dev, hf);
506}
507
508static void b43_aphy_op_adjust_txpower(struct b43_wldev *dev)
509{//TODO
510}
511
512static enum b43_txpwr_result b43_aphy_op_recalc_txpower(struct b43_wldev *dev,
513 bool ignore_tssi)
514{//TODO
515 return B43_TXPWR_RES_DONE;
516}
517
518static void b43_aphy_op_pwork_15sec(struct b43_wldev *dev)
519{//TODO
520}
521
522static void b43_aphy_op_pwork_60sec(struct b43_wldev *dev)
523{//TODO
524}
525
526const struct b43_phy_operations b43_phyops_a = {
527 .allocate = b43_aphy_op_allocate,
528 .init = b43_aphy_op_init,
529 .exit = b43_aphy_op_exit,
530 .phy_read = b43_aphy_op_read,
531 .phy_write = b43_aphy_op_write,
532 .radio_read = b43_aphy_op_radio_read,
533 .radio_write = b43_aphy_op_radio_write,
534 .supports_hwpctl = b43_aphy_op_supports_hwpctl,
535 .software_rfkill = b43_aphy_op_software_rfkill,
536 .switch_channel = b43_aphy_op_switch_channel,
537 .get_default_chan = b43_aphy_op_get_default_chan,
538 .set_rx_antenna = b43_aphy_op_set_rx_antenna,
539 .recalc_txpower = b43_aphy_op_recalc_txpower,
540 .adjust_txpower = b43_aphy_op_adjust_txpower,
541 .pwork_15sec = b43_aphy_op_pwork_15sec,
542 .pwork_60sec = b43_aphy_op_pwork_60sec,
543};
diff --git a/drivers/net/wireless/b43/phy_a.h b/drivers/net/wireless/b43/phy_a.h
new file mode 100644
index 000000000000..e8640f7312bf
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_a.h
@@ -0,0 +1,124 @@
1#ifndef LINUX_B43_PHY_A_H_
2#define LINUX_B43_PHY_A_H_
3
4#include "phy_common.h"
5
6
7/* OFDM (A) PHY Registers */
8#define B43_PHY_VERSION_OFDM B43_PHY_OFDM(0x00) /* Versioning register for A-PHY */
9#define B43_PHY_BBANDCFG B43_PHY_OFDM(0x01) /* Baseband config */
10#define B43_PHY_BBANDCFG_RXANT 0x180 /* RX Antenna selection */
11#define B43_PHY_BBANDCFG_RXANT_SHIFT 7
12#define B43_PHY_PWRDOWN B43_PHY_OFDM(0x03) /* Powerdown */
13#define B43_PHY_CRSTHRES1_R1 B43_PHY_OFDM(0x06) /* CRS Threshold 1 (phy.rev 1 only) */
14#define B43_PHY_LNAHPFCTL B43_PHY_OFDM(0x1C) /* LNA/HPF control */
15#define B43_PHY_LPFGAINCTL B43_PHY_OFDM(0x20) /* LPF Gain control */
16#define B43_PHY_ADIVRELATED B43_PHY_OFDM(0x27) /* FIXME rename */
17#define B43_PHY_CRS0 B43_PHY_OFDM(0x29)
18#define B43_PHY_CRS0_EN 0x4000
19#define B43_PHY_PEAK_COUNT B43_PHY_OFDM(0x30)
20#define B43_PHY_ANTDWELL B43_PHY_OFDM(0x2B) /* Antenna dwell */
21#define B43_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX diversity start antenna */
22#define B43_PHY_ENCORE B43_PHY_OFDM(0x49) /* "Encore" (RangeMax / BroadRange) */
23#define B43_PHY_ENCORE_EN 0x0200 /* Encore enable */
24#define B43_PHY_LMS B43_PHY_OFDM(0x55)
25#define B43_PHY_OFDM61 B43_PHY_OFDM(0x61) /* FIXME rename */
26#define B43_PHY_OFDM61_10 0x0010 /* FIXME rename */
27#define B43_PHY_IQBAL B43_PHY_OFDM(0x69) /* I/Q balance */
28#define B43_PHY_BBTXDC_BIAS B43_PHY_OFDM(0x6B) /* Baseband TX DC bias */
29#define B43_PHY_OTABLECTL B43_PHY_OFDM(0x72) /* OFDM table control (see below) */
30#define B43_PHY_OTABLEOFF 0x03FF /* OFDM table offset (see below) */
31#define B43_PHY_OTABLENR 0xFC00 /* OFDM table number (see below) */
32#define B43_PHY_OTABLENR_SHIFT 10
33#define B43_PHY_OTABLEI B43_PHY_OFDM(0x73) /* OFDM table data I */
34#define B43_PHY_OTABLEQ B43_PHY_OFDM(0x74) /* OFDM table data Q */
35#define B43_PHY_HPWR_TSSICTL B43_PHY_OFDM(0x78) /* Hardware power TSSI control */
36#define B43_PHY_ADCCTL B43_PHY_OFDM(0x7A) /* ADC control */
37#define B43_PHY_IDLE_TSSI B43_PHY_OFDM(0x7B)
38#define B43_PHY_A_TEMP_SENSE B43_PHY_OFDM(0x7C) /* A PHY temperature sense */
39#define B43_PHY_NRSSITHRES B43_PHY_OFDM(0x8A) /* NRSSI threshold */
40#define B43_PHY_ANTWRSETT B43_PHY_OFDM(0x8C) /* Antenna WR settle */
41#define B43_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX diversity enabled */
42#define B43_PHY_CLIPPWRDOWNT B43_PHY_OFDM(0x93) /* Clip powerdown threshold */
43#define B43_PHY_OFDM9B B43_PHY_OFDM(0x9B) /* FIXME rename */
44#define B43_PHY_N1P1GAIN B43_PHY_OFDM(0xA0)
45#define B43_PHY_P1P2GAIN B43_PHY_OFDM(0xA1)
46#define B43_PHY_N1N2GAIN B43_PHY_OFDM(0xA2)
47#define B43_PHY_CLIPTHRES B43_PHY_OFDM(0xA3)
48#define B43_PHY_CLIPN1P2THRES B43_PHY_OFDM(0xA4)
49#define B43_PHY_CCKSHIFTBITS_WA B43_PHY_OFDM(0xA5) /* CCK shiftbits workaround, FIXME rename */
50#define B43_PHY_CCKSHIFTBITS B43_PHY_OFDM(0xA7) /* FIXME rename */
51#define B43_PHY_DIVSRCHIDX B43_PHY_OFDM(0xA8) /* Divider search gain/index */
52#define B43_PHY_CLIPP2THRES B43_PHY_OFDM(0xA9)
53#define B43_PHY_CLIPP3THRES B43_PHY_OFDM(0xAA)
54#define B43_PHY_DIVP1P2GAIN B43_PHY_OFDM(0xAB)
55#define B43_PHY_DIVSRCHGAINBACK B43_PHY_OFDM(0xAD) /* Divider search gain back */
56#define B43_PHY_DIVSRCHGAINCHNG B43_PHY_OFDM(0xAE) /* Divider search gain change */
57#define B43_PHY_CRSTHRES1 B43_PHY_OFDM(0xC0) /* CRS Threshold 1 (phy.rev >= 2 only) */
58#define B43_PHY_CRSTHRES2 B43_PHY_OFDM(0xC1) /* CRS Threshold 2 (phy.rev >= 2 only) */
59#define B43_PHY_TSSIP_LTBASE B43_PHY_OFDM(0x380) /* TSSI power lookup table base */
60#define B43_PHY_DC_LTBASE B43_PHY_OFDM(0x3A0) /* DC lookup table base */
61#define B43_PHY_GAIN_LTBASE B43_PHY_OFDM(0x3C0) /* Gain lookup table base */
62
63/*** OFDM table numbers ***/
64#define B43_OFDMTAB(number, offset) (((number) << B43_PHY_OTABLENR_SHIFT) | (offset))
65#define B43_OFDMTAB_AGC1 B43_OFDMTAB(0x00, 0)
66#define B43_OFDMTAB_GAIN0 B43_OFDMTAB(0x00, 0)
67#define B43_OFDMTAB_GAINX B43_OFDMTAB(0x01, 0) //TODO rename
68#define B43_OFDMTAB_GAIN1 B43_OFDMTAB(0x01, 4)
69#define B43_OFDMTAB_AGC3 B43_OFDMTAB(0x02, 0)
70#define B43_OFDMTAB_GAIN2 B43_OFDMTAB(0x02, 3)
71#define B43_OFDMTAB_LNAHPFGAIN1 B43_OFDMTAB(0x03, 0)
72#define B43_OFDMTAB_WRSSI B43_OFDMTAB(0x04, 0)
73#define B43_OFDMTAB_LNAHPFGAIN2 B43_OFDMTAB(0x04, 0)
74#define B43_OFDMTAB_NOISESCALE B43_OFDMTAB(0x05, 0)
75#define B43_OFDMTAB_AGC2 B43_OFDMTAB(0x06, 0)
76#define B43_OFDMTAB_ROTOR B43_OFDMTAB(0x08, 0)
77#define B43_OFDMTAB_ADVRETARD B43_OFDMTAB(0x09, 0)
78#define B43_OFDMTAB_DAC B43_OFDMTAB(0x0C, 0)
79#define B43_OFDMTAB_DC B43_OFDMTAB(0x0E, 7)
80#define B43_OFDMTAB_PWRDYN2 B43_OFDMTAB(0x0E, 12)
81#define B43_OFDMTAB_LNAGAIN B43_OFDMTAB(0x0E, 13)
82#define B43_OFDMTAB_UNKNOWN_0F B43_OFDMTAB(0x0F, 0) //TODO rename
83#define B43_OFDMTAB_UNKNOWN_APHY B43_OFDMTAB(0x0F, 7) //TODO rename
84#define B43_OFDMTAB_LPFGAIN B43_OFDMTAB(0x0F, 12)
85#define B43_OFDMTAB_RSSI B43_OFDMTAB(0x10, 0)
86#define B43_OFDMTAB_UNKNOWN_11 B43_OFDMTAB(0x11, 4) //TODO rename
87#define B43_OFDMTAB_AGC1_R1 B43_OFDMTAB(0x13, 0)
88#define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO remove!
89#define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 0)
90#define B43_OFDMTAB_AGC3_R1 B43_OFDMTAB(0x15, 0)
91#define B43_OFDMTAB_WRSSI_R1 B43_OFDMTAB(0x15, 4)
92#define B43_OFDMTAB_TSSI B43_OFDMTAB(0x15, 0)
93#define B43_OFDMTAB_DACRFPABB B43_OFDMTAB(0x16, 0)
94#define B43_OFDMTAB_DACOFF B43_OFDMTAB(0x17, 0)
95#define B43_OFDMTAB_DCBIAS B43_OFDMTAB(0x18, 0)
96
97u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset);
98void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table,
99 u16 offset, u16 value);
100u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset);
101void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
102 u16 offset, u32 value);
103
104
105struct b43_phy_a {
106 bool initialised;
107
108 /* A-PHY TX Power control value. */
109 u16 txpwr_offset;
110
111 //TODO lots of missing stuff
112};
113
114/**
115 * b43_phy_inita - Lowlevel A-PHY init routine.
116 * This is _only_ used by the G-PHY code.
117 */
118void b43_phy_inita(struct b43_wldev *dev);
119
120
121struct b43_phy_operations;
122extern const struct b43_phy_operations b43_phyops_a;
123
124#endif /* LINUX_B43_PHY_A_H_ */
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
new file mode 100644
index 000000000000..5a550a7af2e9
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -0,0 +1,367 @@
1/*
2
3 Broadcom B43 wireless driver
4 Common PHY routines
5
6 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
7 Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
8 Copyright (c) 2005-2008 Michael Buesch <mb@bu3sch.de>
9 Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
10 Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; see the file COPYING. If not, write to
24 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
25 Boston, MA 02110-1301, USA.
26
27*/
28
29#include "phy_common.h"
30#include "phy_g.h"
31#include "phy_a.h"
32#include "nphy.h"
33#include "b43.h"
34#include "main.h"
35
36
37int b43_phy_operations_setup(struct b43_wldev *dev)
38{
39 struct b43_phy *phy = &(dev->phy);
40 int err;
41
42 phy->ops = NULL;
43
44 switch (phy->type) {
45 case B43_PHYTYPE_A:
46 phy->ops = &b43_phyops_a;
47 break;
48 case B43_PHYTYPE_G:
49 phy->ops = &b43_phyops_g;
50 break;
51 case B43_PHYTYPE_N:
52#ifdef CONFIG_B43_NPHY
53 phy->ops = &b43_phyops_n;
54#endif
55 break;
56 case B43_PHYTYPE_LP:
57 /* FIXME: Not yet */
58 break;
59 }
60 if (B43_WARN_ON(!phy->ops))
61 return -ENODEV;
62
63 err = phy->ops->allocate(dev);
64 if (err)
65 phy->ops = NULL;
66
67 return err;
68}
69
70int b43_phy_init(struct b43_wldev *dev)
71{
72 struct b43_phy *phy = &dev->phy;
73 const struct b43_phy_operations *ops = phy->ops;
74 int err;
75
76 phy->channel = ops->get_default_chan(dev);
77
78 ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
79 err = ops->init(dev);
80 if (err) {
81 b43err(dev->wl, "PHY init failed\n");
82 goto err_block_rf;
83 }
84 /* Make sure to switch hardware and firmware (SHM) to
85 * the default channel. */
86 err = b43_switch_channel(dev, ops->get_default_chan(dev));
87 if (err) {
88 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
89 goto err_phy_exit;
90 }
91
92 return 0;
93
94err_phy_exit:
95 if (ops->exit)
96 ops->exit(dev);
97err_block_rf:
98 ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
99
100 return err;
101}
102
103void b43_phy_exit(struct b43_wldev *dev)
104{
105 const struct b43_phy_operations *ops = dev->phy.ops;
106
107 ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
108 if (ops->exit)
109 ops->exit(dev);
110}
111
112bool b43_has_hardware_pctl(struct b43_wldev *dev)
113{
114 if (!dev->phy.hardware_power_control)
115 return 0;
116 if (!dev->phy.ops->supports_hwpctl)
117 return 0;
118 return dev->phy.ops->supports_hwpctl(dev);
119}
120
121void b43_radio_lock(struct b43_wldev *dev)
122{
123 u32 macctl;
124
125 macctl = b43_read32(dev, B43_MMIO_MACCTL);
126 B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK);
127 macctl |= B43_MACCTL_RADIOLOCK;
128 b43_write32(dev, B43_MMIO_MACCTL, macctl);
129 /* Commit the write and wait for the device
130 * to exit any radio register access. */
131 b43_read32(dev, B43_MMIO_MACCTL);
132 udelay(10);
133}
134
135void b43_radio_unlock(struct b43_wldev *dev)
136{
137 u32 macctl;
138
139 /* Commit any write */
140 b43_read16(dev, B43_MMIO_PHY_VER);
141 /* unlock */
142 macctl = b43_read32(dev, B43_MMIO_MACCTL);
143 B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK));
144 macctl &= ~B43_MACCTL_RADIOLOCK;
145 b43_write32(dev, B43_MMIO_MACCTL, macctl);
146}
147
148void b43_phy_lock(struct b43_wldev *dev)
149{
150#if B43_DEBUG
151 B43_WARN_ON(dev->phy.phy_locked);
152 dev->phy.phy_locked = 1;
153#endif
154 B43_WARN_ON(dev->dev->id.revision < 3);
155
156 if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
157 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
158}
159
160void b43_phy_unlock(struct b43_wldev *dev)
161{
162#if B43_DEBUG
163 B43_WARN_ON(!dev->phy.phy_locked);
164 dev->phy.phy_locked = 0;
165#endif
166 B43_WARN_ON(dev->dev->id.revision < 3);
167
168 if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
169 b43_power_saving_ctl_bits(dev, 0);
170}
171
172u16 b43_radio_read(struct b43_wldev *dev, u16 reg)
173{
174 return dev->phy.ops->radio_read(dev, reg);
175}
176
177void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
178{
179 dev->phy.ops->radio_write(dev, reg, value);
180}
181
182void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask)
183{
184 b43_radio_write16(dev, offset,
185 b43_radio_read16(dev, offset) & mask);
186}
187
188void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set)
189{
190 b43_radio_write16(dev, offset,
191 b43_radio_read16(dev, offset) | set);
192}
193
194void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
195{
196 b43_radio_write16(dev, offset,
197 (b43_radio_read16(dev, offset) & mask) | set);
198}
199
200u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
201{
202 return dev->phy.ops->phy_read(dev, reg);
203}
204
205void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
206{
207 dev->phy.ops->phy_write(dev, reg, value);
208}
209
210void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
211{
212 b43_phy_write(dev, offset,
213 b43_phy_read(dev, offset) & mask);
214}
215
216void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set)
217{
218 b43_phy_write(dev, offset,
219 b43_phy_read(dev, offset) | set);
220}
221
222void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
223{
224 b43_phy_write(dev, offset,
225 (b43_phy_read(dev, offset) & mask) | set);
226}
227
228int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
229{
230 struct b43_phy *phy = &(dev->phy);
231 u16 channelcookie, savedcookie;
232 int err;
233
234 if (new_channel == B43_DEFAULT_CHANNEL)
235 new_channel = phy->ops->get_default_chan(dev);
236
237 /* First we set the channel radio code to prevent the
238 * firmware from sending ghost packets.
239 */
240 channelcookie = new_channel;
241 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
242 channelcookie |= 0x100;
243 //FIXME set 40Mhz flag if required
244 savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
245 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
246
247 /* Now try to switch the PHY hardware channel. */
248 err = phy->ops->switch_channel(dev, new_channel);
249 if (err)
250 goto err_restore_cookie;
251
252 dev->phy.channel = new_channel;
253 /* Wait for the radio to tune to the channel and stabilize. */
254 msleep(8);
255
256 return 0;
257
258err_restore_cookie:
259 b43_shm_write16(dev, B43_SHM_SHARED,
260 B43_SHM_SH_CHAN, savedcookie);
261
262 return err;
263}
264
265void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state)
266{
267 struct b43_phy *phy = &dev->phy;
268
269 if (state == RFKILL_STATE_HARD_BLOCKED) {
270 /* We cannot hardware-block the device */
271 state = RFKILL_STATE_SOFT_BLOCKED;
272 }
273
274 phy->ops->software_rfkill(dev, state);
275 phy->radio_on = (state == RFKILL_STATE_UNBLOCKED);
276}
277
278/**
279 * b43_phy_txpower_adjust_work - TX power workqueue.
280 *
281 * Workqueue for updating the TX power parameters in hardware.
282 */
283void b43_phy_txpower_adjust_work(struct work_struct *work)
284{
285 struct b43_wl *wl = container_of(work, struct b43_wl,
286 txpower_adjust_work);
287 struct b43_wldev *dev;
288
289 mutex_lock(&wl->mutex);
290 dev = wl->current_dev;
291
292 if (likely(dev && (b43_status(dev) >= B43_STAT_STARTED)))
293 dev->phy.ops->adjust_txpower(dev);
294
295 mutex_unlock(&wl->mutex);
296}
297
298/* Called with wl->irq_lock locked */
299void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
300{
301 struct b43_phy *phy = &dev->phy;
302 unsigned long now = jiffies;
303 enum b43_txpwr_result result;
304
305 if (!(flags & B43_TXPWR_IGNORE_TIME)) {
306 /* Check if it's time for a TXpower check. */
307 if (time_before(now, phy->next_txpwr_check_time))
308 return; /* Not yet */
309 }
310 /* The next check will be needed in two seconds, or later. */
311 phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2));
312
313 if ((dev->dev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
314 (dev->dev->bus->boardinfo.type == SSB_BOARD_BU4306))
315 return; /* No software txpower adjustment needed */
316
317 result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI));
318 if (result == B43_TXPWR_RES_DONE)
319 return; /* We are done. */
320 B43_WARN_ON(result != B43_TXPWR_RES_NEED_ADJUST);
321 B43_WARN_ON(phy->ops->adjust_txpower == NULL);
322
323 /* We must adjust the transmission power in hardware.
324 * Schedule b43_phy_txpower_adjust_work(). */
325 queue_work(dev->wl->hw->workqueue, &dev->wl->txpower_adjust_work);
326}
327
328int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset)
329{
330 const bool is_ofdm = (shm_offset != B43_SHM_SH_TSSI_CCK);
331 unsigned int a, b, c, d;
332 unsigned int average;
333 u32 tmp;
334
335 tmp = b43_shm_read32(dev, B43_SHM_SHARED, shm_offset);
336 a = tmp & 0xFF;
337 b = (tmp >> 8) & 0xFF;
338 c = (tmp >> 16) & 0xFF;
339 d = (tmp >> 24) & 0xFF;
340 if (a == 0 || a == B43_TSSI_MAX ||
341 b == 0 || b == B43_TSSI_MAX ||
342 c == 0 || c == B43_TSSI_MAX ||
343 d == 0 || d == B43_TSSI_MAX)
344 return -ENOENT;
345 /* The values are OK. Clear them. */
346 tmp = B43_TSSI_MAX | (B43_TSSI_MAX << 8) |
347 (B43_TSSI_MAX << 16) | (B43_TSSI_MAX << 24);
348 b43_shm_write32(dev, B43_SHM_SHARED, shm_offset, tmp);
349
350 if (is_ofdm) {
351 a = (a + 32) & 0x3F;
352 b = (b + 32) & 0x3F;
353 c = (c + 32) & 0x3F;
354 d = (d + 32) & 0x3F;
355 }
356
357 /* Get the average of the values with 0.5 added to each value. */
358 average = (a + b + c + d + 2) / 4;
359 if (is_ofdm) {
360 /* Adjust for CCK-boost */
361 if (b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO)
362 & B43_HF_CCKBOOST)
363 average = (average >= 13) ? (average - 13) : 0;
364 }
365
366 return average;
367}
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
new file mode 100644
index 000000000000..f8db9f40df5d
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -0,0 +1,381 @@
1#ifndef LINUX_B43_PHY_COMMON_H_
2#define LINUX_B43_PHY_COMMON_H_
3
4#include <linux/rfkill.h>
5
6struct b43_wldev;
7
8
9/* PHY register routing bits */
10#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
11#define B43_PHYROUTE_BASE 0x0000 /* Base registers */
12#define B43_PHYROUTE_OFDM_GPHY 0x0400 /* OFDM register routing for G-PHYs */
13#define B43_PHYROUTE_EXT_GPHY 0x0800 /* Extended G-PHY registers */
14#define B43_PHYROUTE_N_BMODE 0x0C00 /* N-PHY BMODE registers */
15
16/* CCK (B-PHY) registers. */
17#define B43_PHY_CCK(reg) ((reg) | B43_PHYROUTE_BASE)
18/* N-PHY registers. */
19#define B43_PHY_N(reg) ((reg) | B43_PHYROUTE_BASE)
20/* N-PHY BMODE registers. */
21#define B43_PHY_N_BMODE(reg) ((reg) | B43_PHYROUTE_N_BMODE)
22/* OFDM (A-PHY) registers. */
23#define B43_PHY_OFDM(reg) ((reg) | B43_PHYROUTE_OFDM_GPHY)
24/* Extended G-PHY registers. */
25#define B43_PHY_EXTG(reg) ((reg) | B43_PHYROUTE_EXT_GPHY)
26
27
28/* Masks for the PHY versioning registers. */
29#define B43_PHYVER_ANALOG 0xF000
30#define B43_PHYVER_ANALOG_SHIFT 12
31#define B43_PHYVER_TYPE 0x0F00
32#define B43_PHYVER_TYPE_SHIFT 8
33#define B43_PHYVER_VERSION 0x00FF
34
35/**
36 * enum b43_interference_mitigation - Interference Mitigation mode
37 *
38 * @B43_INTERFMODE_NONE: Disabled
39 * @B43_INTERFMODE_NONWLAN: Non-WLAN Interference Mitigation
40 * @B43_INTERFMODE_MANUALWLAN: WLAN Interference Mitigation
41 * @B43_INTERFMODE_AUTOWLAN: Automatic WLAN Interference Mitigation
42 */
43enum b43_interference_mitigation {
44 B43_INTERFMODE_NONE,
45 B43_INTERFMODE_NONWLAN,
46 B43_INTERFMODE_MANUALWLAN,
47 B43_INTERFMODE_AUTOWLAN,
48};
49
50/* Antenna identifiers */
51enum {
52 B43_ANTENNA0, /* Antenna 0 */
53 B43_ANTENNA1, /* Antenna 0 */
54 B43_ANTENNA_AUTO1, /* Automatic, starting with antenna 1 */
55 B43_ANTENNA_AUTO0, /* Automatic, starting with antenna 0 */
56 B43_ANTENNA2,
57 B43_ANTENNA3 = 8,
58
59 B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
60 B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO,
61};
62
63/**
64 * enum b43_txpwr_result - Return value for the recalc_txpower PHY op.
65 *
66 * @B43_TXPWR_RES_NEED_ADJUST: Values changed. Hardware adjustment is needed.
67 * @B43_TXPWR_RES_DONE: No more work to do. Everything is done.
68 */
69enum b43_txpwr_result {
70 B43_TXPWR_RES_NEED_ADJUST,
71 B43_TXPWR_RES_DONE,
72};
73
74/**
75 * struct b43_phy_operations - Function pointers for PHY ops.
76 *
77 * @prepare: Prepare the PHY. This is called before @init.
78 * Can be NULL, if not required.
79 * @init: Initialize the PHY.
80 * Must not be NULL.
81 * @exit: Shutdown the PHY and free all data structures.
82 * Can be NULL, if not required.
83 *
84 * @phy_read: Read from a PHY register.
85 * Must not be NULL.
86 * @phy_write: Write to a PHY register.
87 * Must not be NULL.
88 * @radio_read: Read from a Radio register.
89 * Must not be NULL.
90 * @radio_write: Write to a Radio register.
91 * Must not be NULL.
92 *
93 * @supports_hwpctl: Returns a boolean whether Hardware Power Control
94 * is supported or not.
95 * If NULL, hwpctl is assumed to be never supported.
96 * @software_rfkill: Turn the radio ON or OFF.
97 * Possible state values are
98 * RFKILL_STATE_SOFT_BLOCKED or
99 * RFKILL_STATE_UNBLOCKED
100 * Must not be NULL.
101 * @switch_channel: Switch the radio to another channel.
102 * Must not be NULL.
103 * @get_default_chan: Just returns the default channel number.
104 * Must not be NULL.
105 * @set_rx_antenna: Set the antenna used for RX.
106 * Can be NULL, if not supported.
107 * @interf_mitigation: Switch the Interference Mitigation mode.
108 * Can be NULL, if not supported.
109 *
110 * @recalc_txpower: Recalculate the transmission power parameters.
111 * This callback has to recalculate the TX power settings,
112 * but does not need to write them to the hardware, yet.
113 * Returns enum b43_txpwr_result to indicate whether the hardware
114 * needs to be adjusted.
115 * If B43_TXPWR_NEED_ADJUST is returned, @adjust_txpower
116 * will be called later.
117 * If the parameter "ignore_tssi" is true, the TSSI values should
118 * be ignored and a recalculation of the power settings should be
119 * done even if the TSSI values did not change.
120 * This callback is called with wl->irq_lock held and must not sleep.
121 * Must not be NULL.
122 * @adjust_txpower: Write the previously calculated TX power settings
123 * (from @recalc_txpower) to the hardware.
124 * This function may sleep.
125 * Can be NULL, if (and ONLY if) @recalc_txpower _always_
126 * returns B43_TXPWR_RES_DONE.
127 *
128 * @pwork_15sec: Periodic work. Called every 15 seconds.
129 * Can be NULL, if not required.
130 * @pwork_60sec: Periodic work. Called every 60 seconds.
131 * Can be NULL, if not required.
132 */
133struct b43_phy_operations {
134 /* Initialisation */
135 int (*allocate)(struct b43_wldev *dev);
136 int (*prepare)(struct b43_wldev *dev);
137 int (*init)(struct b43_wldev *dev);
138 void (*exit)(struct b43_wldev *dev);
139
140 /* Register access */
141 u16 (*phy_read)(struct b43_wldev *dev, u16 reg);
142 void (*phy_write)(struct b43_wldev *dev, u16 reg, u16 value);
143 u16 (*radio_read)(struct b43_wldev *dev, u16 reg);
144 void (*radio_write)(struct b43_wldev *dev, u16 reg, u16 value);
145
146 /* Radio */
147 bool (*supports_hwpctl)(struct b43_wldev *dev);
148 void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state);
149 int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
150 unsigned int (*get_default_chan)(struct b43_wldev *dev);
151 void (*set_rx_antenna)(struct b43_wldev *dev, int antenna);
152 int (*interf_mitigation)(struct b43_wldev *dev,
153 enum b43_interference_mitigation new_mode);
154
155 /* Transmission power adjustment */
156 enum b43_txpwr_result (*recalc_txpower)(struct b43_wldev *dev,
157 bool ignore_tssi);
158 void (*adjust_txpower)(struct b43_wldev *dev);
159
160 /* Misc */
161 void (*pwork_15sec)(struct b43_wldev *dev);
162 void (*pwork_60sec)(struct b43_wldev *dev);
163};
164
165struct b43_phy_a;
166struct b43_phy_g;
167struct b43_phy_n;
168
169struct b43_phy {
170 /* Hardware operation callbacks. */
171 const struct b43_phy_operations *ops;
172
173 /* Most hardware context information is stored in the standard-
174 * specific data structures pointed to by the pointers below.
175 * Only one of them is valid (the currently enabled PHY). */
176#ifdef CONFIG_B43_DEBUG
177 /* No union for debug build to force NULL derefs in buggy code. */
178 struct {
179#else
180 union {
181#endif
182 /* A-PHY specific information */
183 struct b43_phy_a *a;
184 /* G-PHY specific information */
185 struct b43_phy_g *g;
186 /* N-PHY specific information */
187 struct b43_phy_n *n;
188 };
189
190 /* Band support flags. */
191 bool supports_2ghz;
192 bool supports_5ghz;
193
194 /* GMODE bit enabled? */
195 bool gmode;
196
197 /* Analog Type */
198 u8 analog;
199 /* B43_PHYTYPE_ */
200 u8 type;
201 /* PHY revision number. */
202 u8 rev;
203
204 /* Radio versioning */
205 u16 radio_manuf; /* Radio manufacturer */
206 u16 radio_ver; /* Radio version */
207 u8 radio_rev; /* Radio revision */
208
209 /* Software state of the radio */
210 bool radio_on;
211
212 /* Desired TX power level (in dBm).
213 * This is set by the user and adjusted in b43_phy_xmitpower(). */
214 int desired_txpower;
215
216 /* Hardware Power Control enabled? */
217 bool hardware_power_control;
218
219 /* The time (in absolute jiffies) when the next TX power output
220 * check is needed. */
221 unsigned long next_txpwr_check_time;
222
223 /* current channel */
224 unsigned int channel;
225
226 /* PHY TX errors counter. */
227 atomic_t txerr_cnt;
228
229#ifdef CONFIG_B43_DEBUG
230 /* PHY registers locked by b43_phy_lock()? */
231 bool phy_locked;
232#endif /* B43_DEBUG */
233};
234
235
236/**
237 * b43_phy_operations_setup - Initialize the PHY operations datastructure
238 * based on the current PHY type.
239 */
240int b43_phy_operations_setup(struct b43_wldev *dev);
241
242/**
243 * b43_phy_init - Initialise the PHY
244 */
245int b43_phy_init(struct b43_wldev *dev);
246
247/**
248 * b43_phy_exit - Cleanup PHY
249 */
250void b43_phy_exit(struct b43_wldev *dev);
251
252/**
253 * b43_has_hardware_pctl - Hardware Power Control supported?
254 * Returns a boolean, whether hardware power control is supported.
255 */
256bool b43_has_hardware_pctl(struct b43_wldev *dev);
257
258/**
259 * b43_phy_read - 16bit PHY register read access
260 */
261u16 b43_phy_read(struct b43_wldev *dev, u16 reg);
262
263/**
264 * b43_phy_write - 16bit PHY register write access
265 */
266void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value);
267
268/**
269 * b43_phy_mask - Mask a PHY register with a mask
270 */
271void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
272
273/**
274 * b43_phy_set - OR a PHY register with a bitmap
275 */
276void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set);
277
278/**
279 * b43_phy_maskset - Mask and OR a PHY register with a mask and bitmap
280 */
281void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
282
283/**
284 * b43_radio_read - 16bit Radio register read access
285 */
286u16 b43_radio_read(struct b43_wldev *dev, u16 reg);
287#define b43_radio_read16 b43_radio_read /* DEPRECATED */
288
289/**
290 * b43_radio_write - 16bit Radio register write access
291 */
292void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value);
293#define b43_radio_write16 b43_radio_write /* DEPRECATED */
294
295/**
296 * b43_radio_mask - Mask a 16bit radio register with a mask
297 */
298void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask);
299
300/**
301 * b43_radio_set - OR a 16bit radio register with a bitmap
302 */
303void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
304
305/**
306 * b43_radio_maskset - Mask and OR a radio register with a mask and bitmap
307 */
308void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
309
310/**
311 * b43_radio_lock - Lock firmware radio register access
312 */
313void b43_radio_lock(struct b43_wldev *dev);
314
315/**
316 * b43_radio_unlock - Unlock firmware radio register access
317 */
318void b43_radio_unlock(struct b43_wldev *dev);
319
320/**
321 * b43_phy_lock - Lock firmware PHY register access
322 */
323void b43_phy_lock(struct b43_wldev *dev);
324
325/**
326 * b43_phy_unlock - Unlock firmware PHY register access
327 */
328void b43_phy_unlock(struct b43_wldev *dev);
329
330/**
331 * b43_switch_channel - Switch to another channel
332 */
333int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
334/**
335 * B43_DEFAULT_CHANNEL - Switch to the default channel.
336 */
337#define B43_DEFAULT_CHANNEL UINT_MAX
338
339/**
340 * b43_software_rfkill - Turn the radio ON or OFF in software.
341 */
342void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state);
343
344/**
345 * b43_phy_txpower_check - Check TX power output.
346 *
347 * Compare the current TX power output to the desired power emission
348 * and schedule an adjustment in case it mismatches.
349 * Requires wl->irq_lock locked.
350 *
351 * @flags: OR'ed enum b43_phy_txpower_check_flags flags.
352 * See the docs below.
353 */
354void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags);
355/**
356 * enum b43_phy_txpower_check_flags - Flags for b43_phy_txpower_check()
357 *
358 * @B43_TXPWR_IGNORE_TIME: Ignore the schedule time and force-redo
359 * the check now.
360 * @B43_TXPWR_IGNORE_TSSI: Redo the recalculation, even if the average
361 * TSSI did not change.
362 */
363enum b43_phy_txpower_check_flags {
364 B43_TXPWR_IGNORE_TIME = (1 << 0),
365 B43_TXPWR_IGNORE_TSSI = (1 << 1),
366};
367
368struct work_struct;
369void b43_phy_txpower_adjust_work(struct work_struct *work);
370
371/**
372 * b43_phy_shm_tssi_read - Read the average of the last 4 TSSI from SHM.
373 *
374 * @shm_offset: The SHM address to read the values from.
375 *
376 * Returns the average of the 4 TSSI values, or a negative error code.
377 */
378int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
379
380
381#endif /* LINUX_B43_PHY_COMMON_H_ */
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
new file mode 100644
index 000000000000..fce84896d34c
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -0,0 +1,3251 @@
1/*
2
3 Broadcom B43 wireless driver
4 IEEE 802.11g PHY driver
5
6 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
7 Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
8 Copyright (c) 2005-2008 Michael Buesch <mb@bu3sch.de>
9 Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
10 Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; see the file COPYING. If not, write to
24 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
25 Boston, MA 02110-1301, USA.
26
27*/
28
29#include "b43.h"
30#include "phy_g.h"
31#include "phy_common.h"
32#include "lo.h"
33#include "main.h"
34
35#include <linux/bitrev.h>
36
37
38static const s8 b43_tssi2dbm_g_table[] = {
39 77, 77, 77, 76,
40 76, 76, 75, 75,
41 74, 74, 73, 73,
42 73, 72, 72, 71,
43 71, 70, 70, 69,
44 68, 68, 67, 67,
45 66, 65, 65, 64,
46 63, 63, 62, 61,
47 60, 59, 58, 57,
48 56, 55, 54, 53,
49 52, 50, 49, 47,
50 45, 43, 40, 37,
51 33, 28, 22, 14,
52 5, -7, -20, -20,
53 -20, -20, -20, -20,
54 -20, -20, -20, -20,
55};
56
57const u8 b43_radio_channel_codes_bg[] = {
58 12, 17, 22, 27,
59 32, 37, 42, 47,
60 52, 57, 62, 67,
61 72, 84,
62};
63
64
65static void b43_calc_nrssi_threshold(struct b43_wldev *dev);
66
67
68#define bitrev4(tmp) (bitrev8(tmp) >> 4)
69
70
71/* Get the freq, as it has to be written to the device. */
72static inline u16 channel2freq_bg(u8 channel)
73{
74 B43_WARN_ON(!(channel >= 1 && channel <= 14));
75
76 return b43_radio_channel_codes_bg[channel - 1];
77}
78
79static void generate_rfatt_list(struct b43_wldev *dev,
80 struct b43_rfatt_list *list)
81{
82 struct b43_phy *phy = &dev->phy;
83
84 /* APHY.rev < 5 || GPHY.rev < 6 */
85 static const struct b43_rfatt rfatt_0[] = {
86 {.att = 3,.with_padmix = 0,},
87 {.att = 1,.with_padmix = 0,},
88 {.att = 5,.with_padmix = 0,},
89 {.att = 7,.with_padmix = 0,},
90 {.att = 9,.with_padmix = 0,},
91 {.att = 2,.with_padmix = 0,},
92 {.att = 0,.with_padmix = 0,},
93 {.att = 4,.with_padmix = 0,},
94 {.att = 6,.with_padmix = 0,},
95 {.att = 8,.with_padmix = 0,},
96 {.att = 1,.with_padmix = 1,},
97 {.att = 2,.with_padmix = 1,},
98 {.att = 3,.with_padmix = 1,},
99 {.att = 4,.with_padmix = 1,},
100 };
101 /* Radio.rev == 8 && Radio.version == 0x2050 */
102 static const struct b43_rfatt rfatt_1[] = {
103 {.att = 2,.with_padmix = 1,},
104 {.att = 4,.with_padmix = 1,},
105 {.att = 6,.with_padmix = 1,},
106 {.att = 8,.with_padmix = 1,},
107 {.att = 10,.with_padmix = 1,},
108 {.att = 12,.with_padmix = 1,},
109 {.att = 14,.with_padmix = 1,},
110 };
111 /* Otherwise */
112 static const struct b43_rfatt rfatt_2[] = {
113 {.att = 0,.with_padmix = 1,},
114 {.att = 2,.with_padmix = 1,},
115 {.att = 4,.with_padmix = 1,},
116 {.att = 6,.with_padmix = 1,},
117 {.att = 8,.with_padmix = 1,},
118 {.att = 9,.with_padmix = 1,},
119 {.att = 9,.with_padmix = 1,},
120 };
121
122 if (!b43_has_hardware_pctl(dev)) {
123 /* Software pctl */
124 list->list = rfatt_0;
125 list->len = ARRAY_SIZE(rfatt_0);
126 list->min_val = 0;
127 list->max_val = 9;
128 return;
129 }
130 if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
131 /* Hardware pctl */
132 list->list = rfatt_1;
133 list->len = ARRAY_SIZE(rfatt_1);
134 list->min_val = 0;
135 list->max_val = 14;
136 return;
137 }
138 /* Hardware pctl */
139 list->list = rfatt_2;
140 list->len = ARRAY_SIZE(rfatt_2);
141 list->min_val = 0;
142 list->max_val = 9;
143}
144
145static void generate_bbatt_list(struct b43_wldev *dev,
146 struct b43_bbatt_list *list)
147{
148 static const struct b43_bbatt bbatt_0[] = {
149 {.att = 0,},
150 {.att = 1,},
151 {.att = 2,},
152 {.att = 3,},
153 {.att = 4,},
154 {.att = 5,},
155 {.att = 6,},
156 {.att = 7,},
157 {.att = 8,},
158 };
159
160 list->list = bbatt_0;
161 list->len = ARRAY_SIZE(bbatt_0);
162 list->min_val = 0;
163 list->max_val = 8;
164}
165
166static void b43_shm_clear_tssi(struct b43_wldev *dev)
167{
168 b43_shm_write16(dev, B43_SHM_SHARED, 0x0058, 0x7F7F);
169 b43_shm_write16(dev, B43_SHM_SHARED, 0x005a, 0x7F7F);
170 b43_shm_write16(dev, B43_SHM_SHARED, 0x0070, 0x7F7F);
171 b43_shm_write16(dev, B43_SHM_SHARED, 0x0072, 0x7F7F);
172}
173
174/* Synthetic PU workaround */
175static void b43_synth_pu_workaround(struct b43_wldev *dev, u8 channel)
176{
177 struct b43_phy *phy = &dev->phy;
178
179 might_sleep();
180
181 if (phy->radio_ver != 0x2050 || phy->radio_rev >= 6) {
182 /* We do not need the workaround. */
183 return;
184 }
185
186 if (channel <= 10) {
187 b43_write16(dev, B43_MMIO_CHANNEL,
188 channel2freq_bg(channel + 4));
189 } else {
190 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(1));
191 }
192 msleep(1);
193 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
194}
195
196/* Set the baseband attenuation value on chip. */
197void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
198 u16 baseband_attenuation)
199{
200 struct b43_phy *phy = &dev->phy;
201
202 if (phy->analog == 0) {
203 b43_write16(dev, B43_MMIO_PHY0, (b43_read16(dev, B43_MMIO_PHY0)
204 & 0xFFF0) |
205 baseband_attenuation);
206 } else if (phy->analog > 1) {
207 b43_phy_write(dev, B43_PHY_DACCTL,
208 (b43_phy_read(dev, B43_PHY_DACCTL)
209 & 0xFFC3) | (baseband_attenuation << 2));
210 } else {
211 b43_phy_write(dev, B43_PHY_DACCTL,
212 (b43_phy_read(dev, B43_PHY_DACCTL)
213 & 0xFF87) | (baseband_attenuation << 3));
214 }
215}
216
217/* Adjust the transmission power output (G-PHY) */
218void b43_set_txpower_g(struct b43_wldev *dev,
219 const struct b43_bbatt *bbatt,
220 const struct b43_rfatt *rfatt, u8 tx_control)
221{
222 struct b43_phy *phy = &dev->phy;
223 struct b43_phy_g *gphy = phy->g;
224 struct b43_txpower_lo_control *lo = gphy->lo_control;
225 u16 bb, rf;
226 u16 tx_bias, tx_magn;
227
228 bb = bbatt->att;
229 rf = rfatt->att;
230 tx_bias = lo->tx_bias;
231 tx_magn = lo->tx_magn;
232 if (unlikely(tx_bias == 0xFF))
233 tx_bias = 0;
234
235 /* Save the values for later */
236 gphy->tx_control = tx_control;
237 memcpy(&gphy->rfatt, rfatt, sizeof(*rfatt));
238 gphy->rfatt.with_padmix = !!(tx_control & B43_TXCTL_TXMIX);
239 memcpy(&gphy->bbatt, bbatt, sizeof(*bbatt));
240
241 if (b43_debug(dev, B43_DBG_XMITPOWER)) {
242 b43dbg(dev->wl, "Tuning TX-power to bbatt(%u), "
243 "rfatt(%u), tx_control(0x%02X), "
244 "tx_bias(0x%02X), tx_magn(0x%02X)\n",
245 bb, rf, tx_control, tx_bias, tx_magn);
246 }
247
248 b43_gphy_set_baseband_attenuation(dev, bb);
249 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_RFATT, rf);
250 if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
251 b43_radio_write16(dev, 0x43,
252 (rf & 0x000F) | (tx_control & 0x0070));
253 } else {
254 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
255 & 0xFFF0) | (rf & 0x000F));
256 b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
257 & ~0x0070) | (tx_control &
258 0x0070));
259 }
260 if (has_tx_magnification(phy)) {
261 b43_radio_write16(dev, 0x52, tx_magn | tx_bias);
262 } else {
263 b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
264 & 0xFFF0) | (tx_bias & 0x000F));
265 }
266 b43_lo_g_adjust(dev);
267}
268
269/* GPHY_TSSI_Power_Lookup_Table_Init */
270static void b43_gphy_tssi_power_lt_init(struct b43_wldev *dev)
271{
272 struct b43_phy_g *gphy = dev->phy.g;
273 int i;
274 u16 value;
275
276 for (i = 0; i < 32; i++)
277 b43_ofdmtab_write16(dev, 0x3C20, i, gphy->tssi2dbm[i]);
278 for (i = 32; i < 64; i++)
279 b43_ofdmtab_write16(dev, 0x3C00, i - 32, gphy->tssi2dbm[i]);
280 for (i = 0; i < 64; i += 2) {
281 value = (u16) gphy->tssi2dbm[i];
282 value |= ((u16) gphy->tssi2dbm[i + 1]) << 8;
283 b43_phy_write(dev, 0x380 + (i / 2), value);
284 }
285}
286
287/* GPHY_Gain_Lookup_Table_Init */
288static void b43_gphy_gain_lt_init(struct b43_wldev *dev)
289{
290 struct b43_phy *phy = &dev->phy;
291 struct b43_phy_g *gphy = phy->g;
292 struct b43_txpower_lo_control *lo = gphy->lo_control;
293 u16 nr_written = 0;
294 u16 tmp;
295 u8 rf, bb;
296
297 for (rf = 0; rf < lo->rfatt_list.len; rf++) {
298 for (bb = 0; bb < lo->bbatt_list.len; bb++) {
299 if (nr_written >= 0x40)
300 return;
301 tmp = lo->bbatt_list.list[bb].att;
302 tmp <<= 8;
303 if (phy->radio_rev == 8)
304 tmp |= 0x50;
305 else
306 tmp |= 0x40;
307 tmp |= lo->rfatt_list.list[rf].att;
308 b43_phy_write(dev, 0x3C0 + nr_written, tmp);
309 nr_written++;
310 }
311 }
312}
313
314static void b43_set_all_gains(struct b43_wldev *dev,
315 s16 first, s16 second, s16 third)
316{
317 struct b43_phy *phy = &dev->phy;
318 u16 i;
319 u16 start = 0x08, end = 0x18;
320 u16 tmp;
321 u16 table;
322
323 if (phy->rev <= 1) {
324 start = 0x10;
325 end = 0x20;
326 }
327
328 table = B43_OFDMTAB_GAINX;
329 if (phy->rev <= 1)
330 table = B43_OFDMTAB_GAINX_R1;
331 for (i = 0; i < 4; i++)
332 b43_ofdmtab_write16(dev, table, i, first);
333
334 for (i = start; i < end; i++)
335 b43_ofdmtab_write16(dev, table, i, second);
336
337 if (third != -1) {
338 tmp = ((u16) third << 14) | ((u16) third << 6);
339 b43_phy_write(dev, 0x04A0,
340 (b43_phy_read(dev, 0x04A0) & 0xBFBF) | tmp);
341 b43_phy_write(dev, 0x04A1,
342 (b43_phy_read(dev, 0x04A1) & 0xBFBF) | tmp);
343 b43_phy_write(dev, 0x04A2,
344 (b43_phy_read(dev, 0x04A2) & 0xBFBF) | tmp);
345 }
346 b43_dummy_transmission(dev);
347}
348
349static void b43_set_original_gains(struct b43_wldev *dev)
350{
351 struct b43_phy *phy = &dev->phy;
352 u16 i, tmp;
353 u16 table;
354 u16 start = 0x0008, end = 0x0018;
355
356 if (phy->rev <= 1) {
357 start = 0x0010;
358 end = 0x0020;
359 }
360
361 table = B43_OFDMTAB_GAINX;
362 if (phy->rev <= 1)
363 table = B43_OFDMTAB_GAINX_R1;
364 for (i = 0; i < 4; i++) {
365 tmp = (i & 0xFFFC);
366 tmp |= (i & 0x0001) << 1;
367 tmp |= (i & 0x0002) >> 1;
368
369 b43_ofdmtab_write16(dev, table, i, tmp);
370 }
371
372 for (i = start; i < end; i++)
373 b43_ofdmtab_write16(dev, table, i, i - start);
374
375 b43_phy_write(dev, 0x04A0,
376 (b43_phy_read(dev, 0x04A0) & 0xBFBF) | 0x4040);
377 b43_phy_write(dev, 0x04A1,
378 (b43_phy_read(dev, 0x04A1) & 0xBFBF) | 0x4040);
379 b43_phy_write(dev, 0x04A2,
380 (b43_phy_read(dev, 0x04A2) & 0xBFBF) | 0x4000);
381 b43_dummy_transmission(dev);
382}
383
384/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
385void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val)
386{
387 b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
388 mmiowb();
389 b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val);
390}
391
392/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
393s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset)
394{
395 u16 val;
396
397 b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
398 val = b43_phy_read(dev, B43_PHY_NRSSILT_DATA);
399
400 return (s16) val;
401}
402
403/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
404void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val)
405{
406 u16 i;
407 s16 tmp;
408
409 for (i = 0; i < 64; i++) {
410 tmp = b43_nrssi_hw_read(dev, i);
411 tmp -= val;
412 tmp = clamp_val(tmp, -32, 31);
413 b43_nrssi_hw_write(dev, i, tmp);
414 }
415}
416
417/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
418void b43_nrssi_mem_update(struct b43_wldev *dev)
419{
420 struct b43_phy_g *gphy = dev->phy.g;
421 s16 i, delta;
422 s32 tmp;
423
424 delta = 0x1F - gphy->nrssi[0];
425 for (i = 0; i < 64; i++) {
426 tmp = (i - delta) * gphy->nrssislope;
427 tmp /= 0x10000;
428 tmp += 0x3A;
429 tmp = clamp_val(tmp, 0, 0x3F);
430 gphy->nrssi_lt[i] = tmp;
431 }
432}
433
434static void b43_calc_nrssi_offset(struct b43_wldev *dev)
435{
436 struct b43_phy *phy = &dev->phy;
437 u16 backup[20] = { 0 };
438 s16 v47F;
439 u16 i;
440 u16 saved = 0xFFFF;
441
442 backup[0] = b43_phy_read(dev, 0x0001);
443 backup[1] = b43_phy_read(dev, 0x0811);
444 backup[2] = b43_phy_read(dev, 0x0812);
445 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
446 backup[3] = b43_phy_read(dev, 0x0814);
447 backup[4] = b43_phy_read(dev, 0x0815);
448 }
449 backup[5] = b43_phy_read(dev, 0x005A);
450 backup[6] = b43_phy_read(dev, 0x0059);
451 backup[7] = b43_phy_read(dev, 0x0058);
452 backup[8] = b43_phy_read(dev, 0x000A);
453 backup[9] = b43_phy_read(dev, 0x0003);
454 backup[10] = b43_radio_read16(dev, 0x007A);
455 backup[11] = b43_radio_read16(dev, 0x0043);
456
457 b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) & 0x7FFF);
458 b43_phy_write(dev, 0x0001,
459 (b43_phy_read(dev, 0x0001) & 0x3FFF) | 0x4000);
460 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
461 b43_phy_write(dev, 0x0812,
462 (b43_phy_read(dev, 0x0812) & 0xFFF3) | 0x0004);
463 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & ~(0x1 | 0x2));
464 if (phy->rev >= 6) {
465 backup[12] = b43_phy_read(dev, 0x002E);
466 backup[13] = b43_phy_read(dev, 0x002F);
467 backup[14] = b43_phy_read(dev, 0x080F);
468 backup[15] = b43_phy_read(dev, 0x0810);
469 backup[16] = b43_phy_read(dev, 0x0801);
470 backup[17] = b43_phy_read(dev, 0x0060);
471 backup[18] = b43_phy_read(dev, 0x0014);
472 backup[19] = b43_phy_read(dev, 0x0478);
473
474 b43_phy_write(dev, 0x002E, 0);
475 b43_phy_write(dev, 0x002F, 0);
476 b43_phy_write(dev, 0x080F, 0);
477 b43_phy_write(dev, 0x0810, 0);
478 b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478) | 0x0100);
479 b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) | 0x0040);
480 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) | 0x0040);
481 b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014) | 0x0200);
482 }
483 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0070);
484 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0080);
485 udelay(30);
486
487 v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
488 if (v47F >= 0x20)
489 v47F -= 0x40;
490 if (v47F == 31) {
491 for (i = 7; i >= 4; i--) {
492 b43_radio_write16(dev, 0x007B, i);
493 udelay(20);
494 v47F =
495 (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
496 if (v47F >= 0x20)
497 v47F -= 0x40;
498 if (v47F < 31 && saved == 0xFFFF)
499 saved = i;
500 }
501 if (saved == 0xFFFF)
502 saved = 4;
503 } else {
504 b43_radio_write16(dev, 0x007A,
505 b43_radio_read16(dev, 0x007A) & 0x007F);
506 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
507 b43_phy_write(dev, 0x0814,
508 b43_phy_read(dev, 0x0814) | 0x0001);
509 b43_phy_write(dev, 0x0815,
510 b43_phy_read(dev, 0x0815) & 0xFFFE);
511 }
512 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
513 b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x000C);
514 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x0030);
515 b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x0030);
516 b43_phy_write(dev, 0x005A, 0x0480);
517 b43_phy_write(dev, 0x0059, 0x0810);
518 b43_phy_write(dev, 0x0058, 0x000D);
519 if (phy->rev == 0) {
520 b43_phy_write(dev, 0x0003, 0x0122);
521 } else {
522 b43_phy_write(dev, 0x000A, b43_phy_read(dev, 0x000A)
523 | 0x2000);
524 }
525 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
526 b43_phy_write(dev, 0x0814,
527 b43_phy_read(dev, 0x0814) | 0x0004);
528 b43_phy_write(dev, 0x0815,
529 b43_phy_read(dev, 0x0815) & 0xFFFB);
530 }
531 b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003) & 0xFF9F)
532 | 0x0040);
533 b43_radio_write16(dev, 0x007A,
534 b43_radio_read16(dev, 0x007A) | 0x000F);
535 b43_set_all_gains(dev, 3, 0, 1);
536 b43_radio_write16(dev, 0x0043, (b43_radio_read16(dev, 0x0043)
537 & 0x00F0) | 0x000F);
538 udelay(30);
539 v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
540 if (v47F >= 0x20)
541 v47F -= 0x40;
542 if (v47F == -32) {
543 for (i = 0; i < 4; i++) {
544 b43_radio_write16(dev, 0x007B, i);
545 udelay(20);
546 v47F =
547 (s16) ((b43_phy_read(dev, 0x047F) >> 8) &
548 0x003F);
549 if (v47F >= 0x20)
550 v47F -= 0x40;
551 if (v47F > -31 && saved == 0xFFFF)
552 saved = i;
553 }
554 if (saved == 0xFFFF)
555 saved = 3;
556 } else
557 saved = 0;
558 }
559 b43_radio_write16(dev, 0x007B, saved);
560
561 if (phy->rev >= 6) {
562 b43_phy_write(dev, 0x002E, backup[12]);
563 b43_phy_write(dev, 0x002F, backup[13]);
564 b43_phy_write(dev, 0x080F, backup[14]);
565 b43_phy_write(dev, 0x0810, backup[15]);
566 }
567 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
568 b43_phy_write(dev, 0x0814, backup[3]);
569 b43_phy_write(dev, 0x0815, backup[4]);
570 }
571 b43_phy_write(dev, 0x005A, backup[5]);
572 b43_phy_write(dev, 0x0059, backup[6]);
573 b43_phy_write(dev, 0x0058, backup[7]);
574 b43_phy_write(dev, 0x000A, backup[8]);
575 b43_phy_write(dev, 0x0003, backup[9]);
576 b43_radio_write16(dev, 0x0043, backup[11]);
577 b43_radio_write16(dev, 0x007A, backup[10]);
578 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x1 | 0x2);
579 b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) | 0x8000);
580 b43_set_original_gains(dev);
581 if (phy->rev >= 6) {
582 b43_phy_write(dev, 0x0801, backup[16]);
583 b43_phy_write(dev, 0x0060, backup[17]);
584 b43_phy_write(dev, 0x0014, backup[18]);
585 b43_phy_write(dev, 0x0478, backup[19]);
586 }
587 b43_phy_write(dev, 0x0001, backup[0]);
588 b43_phy_write(dev, 0x0812, backup[2]);
589 b43_phy_write(dev, 0x0811, backup[1]);
590}
591
592void b43_calc_nrssi_slope(struct b43_wldev *dev)
593{
594 struct b43_phy *phy = &dev->phy;
595 struct b43_phy_g *gphy = phy->g;
596 u16 backup[18] = { 0 };
597 u16 tmp;
598 s16 nrssi0, nrssi1;
599
600 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
601
602 if (phy->radio_rev >= 9)
603 return;
604 if (phy->radio_rev == 8)
605 b43_calc_nrssi_offset(dev);
606
607 b43_phy_write(dev, B43_PHY_G_CRS,
608 b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
609 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
610 backup[7] = b43_read16(dev, 0x03E2);
611 b43_write16(dev, 0x03E2, b43_read16(dev, 0x03E2) | 0x8000);
612 backup[0] = b43_radio_read16(dev, 0x007A);
613 backup[1] = b43_radio_read16(dev, 0x0052);
614 backup[2] = b43_radio_read16(dev, 0x0043);
615 backup[3] = b43_phy_read(dev, 0x0015);
616 backup[4] = b43_phy_read(dev, 0x005A);
617 backup[5] = b43_phy_read(dev, 0x0059);
618 backup[6] = b43_phy_read(dev, 0x0058);
619 backup[8] = b43_read16(dev, 0x03E6);
620 backup[9] = b43_read16(dev, B43_MMIO_CHANNEL_EXT);
621 if (phy->rev >= 3) {
622 backup[10] = b43_phy_read(dev, 0x002E);
623 backup[11] = b43_phy_read(dev, 0x002F);
624 backup[12] = b43_phy_read(dev, 0x080F);
625 backup[13] = b43_phy_read(dev, B43_PHY_G_LO_CONTROL);
626 backup[14] = b43_phy_read(dev, 0x0801);
627 backup[15] = b43_phy_read(dev, 0x0060);
628 backup[16] = b43_phy_read(dev, 0x0014);
629 backup[17] = b43_phy_read(dev, 0x0478);
630 b43_phy_write(dev, 0x002E, 0);
631 b43_phy_write(dev, B43_PHY_G_LO_CONTROL, 0);
632 switch (phy->rev) {
633 case 4:
634 case 6:
635 case 7:
636 b43_phy_write(dev, 0x0478,
637 b43_phy_read(dev, 0x0478)
638 | 0x0100);
639 b43_phy_write(dev, 0x0801,
640 b43_phy_read(dev, 0x0801)
641 | 0x0040);
642 break;
643 case 3:
644 case 5:
645 b43_phy_write(dev, 0x0801,
646 b43_phy_read(dev, 0x0801)
647 & 0xFFBF);
648 break;
649 }
650 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060)
651 | 0x0040);
652 b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014)
653 | 0x0200);
654 }
655 b43_radio_write16(dev, 0x007A,
656 b43_radio_read16(dev, 0x007A) | 0x0070);
657 b43_set_all_gains(dev, 0, 8, 0);
658 b43_radio_write16(dev, 0x007A,
659 b43_radio_read16(dev, 0x007A) & 0x00F7);
660 if (phy->rev >= 2) {
661 b43_phy_write(dev, 0x0811,
662 (b43_phy_read(dev, 0x0811) & 0xFFCF) |
663 0x0030);
664 b43_phy_write(dev, 0x0812,
665 (b43_phy_read(dev, 0x0812) & 0xFFCF) |
666 0x0010);
667 }
668 b43_radio_write16(dev, 0x007A,
669 b43_radio_read16(dev, 0x007A) | 0x0080);
670 udelay(20);
671
672 nrssi0 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
673 if (nrssi0 >= 0x0020)
674 nrssi0 -= 0x0040;
675
676 b43_radio_write16(dev, 0x007A,
677 b43_radio_read16(dev, 0x007A) & 0x007F);
678 if (phy->rev >= 2) {
679 b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003)
680 & 0xFF9F) | 0x0040);
681 }
682
683 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
684 b43_read16(dev, B43_MMIO_CHANNEL_EXT)
685 | 0x2000);
686 b43_radio_write16(dev, 0x007A,
687 b43_radio_read16(dev, 0x007A) | 0x000F);
688 b43_phy_write(dev, 0x0015, 0xF330);
689 if (phy->rev >= 2) {
690 b43_phy_write(dev, 0x0812,
691 (b43_phy_read(dev, 0x0812) & 0xFFCF) |
692 0x0020);
693 b43_phy_write(dev, 0x0811,
694 (b43_phy_read(dev, 0x0811) & 0xFFCF) |
695 0x0020);
696 }
697
698 b43_set_all_gains(dev, 3, 0, 1);
699 if (phy->radio_rev == 8) {
700 b43_radio_write16(dev, 0x0043, 0x001F);
701 } else {
702 tmp = b43_radio_read16(dev, 0x0052) & 0xFF0F;
703 b43_radio_write16(dev, 0x0052, tmp | 0x0060);
704 tmp = b43_radio_read16(dev, 0x0043) & 0xFFF0;
705 b43_radio_write16(dev, 0x0043, tmp | 0x0009);
706 }
707 b43_phy_write(dev, 0x005A, 0x0480);
708 b43_phy_write(dev, 0x0059, 0x0810);
709 b43_phy_write(dev, 0x0058, 0x000D);
710 udelay(20);
711 nrssi1 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
712 if (nrssi1 >= 0x0020)
713 nrssi1 -= 0x0040;
714 if (nrssi0 == nrssi1)
715 gphy->nrssislope = 0x00010000;
716 else
717 gphy->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
718 if (nrssi0 >= -4) {
719 gphy->nrssi[0] = nrssi1;
720 gphy->nrssi[1] = nrssi0;
721 }
722 if (phy->rev >= 3) {
723 b43_phy_write(dev, 0x002E, backup[10]);
724 b43_phy_write(dev, 0x002F, backup[11]);
725 b43_phy_write(dev, 0x080F, backup[12]);
726 b43_phy_write(dev, B43_PHY_G_LO_CONTROL, backup[13]);
727 }
728 if (phy->rev >= 2) {
729 b43_phy_write(dev, 0x0812,
730 b43_phy_read(dev, 0x0812) & 0xFFCF);
731 b43_phy_write(dev, 0x0811,
732 b43_phy_read(dev, 0x0811) & 0xFFCF);
733 }
734
735 b43_radio_write16(dev, 0x007A, backup[0]);
736 b43_radio_write16(dev, 0x0052, backup[1]);
737 b43_radio_write16(dev, 0x0043, backup[2]);
738 b43_write16(dev, 0x03E2, backup[7]);
739 b43_write16(dev, 0x03E6, backup[8]);
740 b43_write16(dev, B43_MMIO_CHANNEL_EXT, backup[9]);
741 b43_phy_write(dev, 0x0015, backup[3]);
742 b43_phy_write(dev, 0x005A, backup[4]);
743 b43_phy_write(dev, 0x0059, backup[5]);
744 b43_phy_write(dev, 0x0058, backup[6]);
745 b43_synth_pu_workaround(dev, phy->channel);
746 b43_phy_write(dev, 0x0802,
747 b43_phy_read(dev, 0x0802) | (0x0001 | 0x0002));
748 b43_set_original_gains(dev);
749 b43_phy_write(dev, B43_PHY_G_CRS,
750 b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
751 if (phy->rev >= 3) {
752 b43_phy_write(dev, 0x0801, backup[14]);
753 b43_phy_write(dev, 0x0060, backup[15]);
754 b43_phy_write(dev, 0x0014, backup[16]);
755 b43_phy_write(dev, 0x0478, backup[17]);
756 }
757 b43_nrssi_mem_update(dev);
758 b43_calc_nrssi_threshold(dev);
759}
760
761static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
762{
763 struct b43_phy *phy = &dev->phy;
764 struct b43_phy_g *gphy = phy->g;
765 s32 a, b;
766 s16 tmp16;
767 u16 tmp_u16;
768
769 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
770
771 if (!phy->gmode ||
772 !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
773 tmp16 = b43_nrssi_hw_read(dev, 0x20);
774 if (tmp16 >= 0x20)
775 tmp16 -= 0x40;
776 if (tmp16 < 3) {
777 b43_phy_write(dev, 0x048A,
778 (b43_phy_read(dev, 0x048A)
779 & 0xF000) | 0x09EB);
780 } else {
781 b43_phy_write(dev, 0x048A,
782 (b43_phy_read(dev, 0x048A)
783 & 0xF000) | 0x0AED);
784 }
785 } else {
786 if (gphy->interfmode == B43_INTERFMODE_NONWLAN) {
787 a = 0xE;
788 b = 0xA;
789 } else if (!gphy->aci_wlan_automatic && gphy->aci_enable) {
790 a = 0x13;
791 b = 0x12;
792 } else {
793 a = 0xE;
794 b = 0x11;
795 }
796
797 a = a * (gphy->nrssi[1] - gphy->nrssi[0]);
798 a += (gphy->nrssi[0] << 6);
799 if (a < 32)
800 a += 31;
801 else
802 a += 32;
803 a = a >> 6;
804 a = clamp_val(a, -31, 31);
805
806 b = b * (gphy->nrssi[1] - gphy->nrssi[0]);
807 b += (gphy->nrssi[0] << 6);
808 if (b < 32)
809 b += 31;
810 else
811 b += 32;
812 b = b >> 6;
813 b = clamp_val(b, -31, 31);
814
815 tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000;
816 tmp_u16 |= ((u32) b & 0x0000003F);
817 tmp_u16 |= (((u32) a & 0x0000003F) << 6);
818 b43_phy_write(dev, 0x048A, tmp_u16);
819 }
820}
821
822/* Stack implementation to save/restore values from the
823 * interference mitigation code.
824 * It is save to restore values in random order.
825 */
826static void _stack_save(u32 * _stackptr, size_t * stackidx,
827 u8 id, u16 offset, u16 value)
828{
829 u32 *stackptr = &(_stackptr[*stackidx]);
830
831 B43_WARN_ON(offset & 0xF000);
832 B43_WARN_ON(id & 0xF0);
833 *stackptr = offset;
834 *stackptr |= ((u32) id) << 12;
835 *stackptr |= ((u32) value) << 16;
836 (*stackidx)++;
837 B43_WARN_ON(*stackidx >= B43_INTERFSTACK_SIZE);
838}
839
840static u16 _stack_restore(u32 * stackptr, u8 id, u16 offset)
841{
842 size_t i;
843
844 B43_WARN_ON(offset & 0xF000);
845 B43_WARN_ON(id & 0xF0);
846 for (i = 0; i < B43_INTERFSTACK_SIZE; i++, stackptr++) {
847 if ((*stackptr & 0x00000FFF) != offset)
848 continue;
849 if (((*stackptr & 0x0000F000) >> 12) != id)
850 continue;
851 return ((*stackptr & 0xFFFF0000) >> 16);
852 }
853 B43_WARN_ON(1);
854
855 return 0;
856}
857
858#define phy_stacksave(offset) \
859 do { \
860 _stack_save(stack, &stackidx, 0x1, (offset), \
861 b43_phy_read(dev, (offset))); \
862 } while (0)
863#define phy_stackrestore(offset) \
864 do { \
865 b43_phy_write(dev, (offset), \
866 _stack_restore(stack, 0x1, \
867 (offset))); \
868 } while (0)
869#define radio_stacksave(offset) \
870 do { \
871 _stack_save(stack, &stackidx, 0x2, (offset), \
872 b43_radio_read16(dev, (offset))); \
873 } while (0)
874#define radio_stackrestore(offset) \
875 do { \
876 b43_radio_write16(dev, (offset), \
877 _stack_restore(stack, 0x2, \
878 (offset))); \
879 } while (0)
880#define ofdmtab_stacksave(table, offset) \
881 do { \
882 _stack_save(stack, &stackidx, 0x3, (offset)|(table), \
883 b43_ofdmtab_read16(dev, (table), (offset))); \
884 } while (0)
885#define ofdmtab_stackrestore(table, offset) \
886 do { \
887 b43_ofdmtab_write16(dev, (table), (offset), \
888 _stack_restore(stack, 0x3, \
889 (offset)|(table))); \
890 } while (0)
891
892static void
893b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
894{
895 struct b43_phy *phy = &dev->phy;
896 struct b43_phy_g *gphy = phy->g;
897 u16 tmp, flipped;
898 size_t stackidx = 0;
899 u32 *stack = gphy->interfstack;
900
901 switch (mode) {
902 case B43_INTERFMODE_NONWLAN:
903 if (phy->rev != 1) {
904 b43_phy_write(dev, 0x042B,
905 b43_phy_read(dev, 0x042B) | 0x0800);
906 b43_phy_write(dev, B43_PHY_G_CRS,
907 b43_phy_read(dev,
908 B43_PHY_G_CRS) & ~0x4000);
909 break;
910 }
911 radio_stacksave(0x0078);
912 tmp = (b43_radio_read16(dev, 0x0078) & 0x001E);
913 B43_WARN_ON(tmp > 15);
914 flipped = bitrev4(tmp);
915 if (flipped < 10 && flipped >= 8)
916 flipped = 7;
917 else if (flipped >= 10)
918 flipped -= 3;
919 flipped = (bitrev4(flipped) << 1) | 0x0020;
920 b43_radio_write16(dev, 0x0078, flipped);
921
922 b43_calc_nrssi_threshold(dev);
923
924 phy_stacksave(0x0406);
925 b43_phy_write(dev, 0x0406, 0x7E28);
926
927 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x0800);
928 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
929 b43_phy_read(dev,
930 B43_PHY_RADIO_BITFIELD) | 0x1000);
931
932 phy_stacksave(0x04A0);
933 b43_phy_write(dev, 0x04A0,
934 (b43_phy_read(dev, 0x04A0) & 0xC0C0) | 0x0008);
935 phy_stacksave(0x04A1);
936 b43_phy_write(dev, 0x04A1,
937 (b43_phy_read(dev, 0x04A1) & 0xC0C0) | 0x0605);
938 phy_stacksave(0x04A2);
939 b43_phy_write(dev, 0x04A2,
940 (b43_phy_read(dev, 0x04A2) & 0xC0C0) | 0x0204);
941 phy_stacksave(0x04A8);
942 b43_phy_write(dev, 0x04A8,
943 (b43_phy_read(dev, 0x04A8) & 0xC0C0) | 0x0803);
944 phy_stacksave(0x04AB);
945 b43_phy_write(dev, 0x04AB,
946 (b43_phy_read(dev, 0x04AB) & 0xC0C0) | 0x0605);
947
948 phy_stacksave(0x04A7);
949 b43_phy_write(dev, 0x04A7, 0x0002);
950 phy_stacksave(0x04A3);
951 b43_phy_write(dev, 0x04A3, 0x287A);
952 phy_stacksave(0x04A9);
953 b43_phy_write(dev, 0x04A9, 0x2027);
954 phy_stacksave(0x0493);
955 b43_phy_write(dev, 0x0493, 0x32F5);
956 phy_stacksave(0x04AA);
957 b43_phy_write(dev, 0x04AA, 0x2027);
958 phy_stacksave(0x04AC);
959 b43_phy_write(dev, 0x04AC, 0x32F5);
960 break;
961 case B43_INTERFMODE_MANUALWLAN:
962 if (b43_phy_read(dev, 0x0033) & 0x0800)
963 break;
964
965 gphy->aci_enable = 1;
966
967 phy_stacksave(B43_PHY_RADIO_BITFIELD);
968 phy_stacksave(B43_PHY_G_CRS);
969 if (phy->rev < 2) {
970 phy_stacksave(0x0406);
971 } else {
972 phy_stacksave(0x04C0);
973 phy_stacksave(0x04C1);
974 }
975 phy_stacksave(0x0033);
976 phy_stacksave(0x04A7);
977 phy_stacksave(0x04A3);
978 phy_stacksave(0x04A9);
979 phy_stacksave(0x04AA);
980 phy_stacksave(0x04AC);
981 phy_stacksave(0x0493);
982 phy_stacksave(0x04A1);
983 phy_stacksave(0x04A0);
984 phy_stacksave(0x04A2);
985 phy_stacksave(0x048A);
986 phy_stacksave(0x04A8);
987 phy_stacksave(0x04AB);
988 if (phy->rev == 2) {
989 phy_stacksave(0x04AD);
990 phy_stacksave(0x04AE);
991 } else if (phy->rev >= 3) {
992 phy_stacksave(0x04AD);
993 phy_stacksave(0x0415);
994 phy_stacksave(0x0416);
995 phy_stacksave(0x0417);
996 ofdmtab_stacksave(0x1A00, 0x2);
997 ofdmtab_stacksave(0x1A00, 0x3);
998 }
999 phy_stacksave(0x042B);
1000 phy_stacksave(0x048C);
1001
1002 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
1003 b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
1004 & ~0x1000);
1005 b43_phy_write(dev, B43_PHY_G_CRS,
1006 (b43_phy_read(dev, B43_PHY_G_CRS)
1007 & 0xFFFC) | 0x0002);
1008
1009 b43_phy_write(dev, 0x0033, 0x0800);
1010 b43_phy_write(dev, 0x04A3, 0x2027);
1011 b43_phy_write(dev, 0x04A9, 0x1CA8);
1012 b43_phy_write(dev, 0x0493, 0x287A);
1013 b43_phy_write(dev, 0x04AA, 0x1CA8);
1014 b43_phy_write(dev, 0x04AC, 0x287A);
1015
1016 b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
1017 & 0xFFC0) | 0x001A);
1018 b43_phy_write(dev, 0x04A7, 0x000D);
1019
1020 if (phy->rev < 2) {
1021 b43_phy_write(dev, 0x0406, 0xFF0D);
1022 } else if (phy->rev == 2) {
1023 b43_phy_write(dev, 0x04C0, 0xFFFF);
1024 b43_phy_write(dev, 0x04C1, 0x00A9);
1025 } else {
1026 b43_phy_write(dev, 0x04C0, 0x00C1);
1027 b43_phy_write(dev, 0x04C1, 0x0059);
1028 }
1029
1030 b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
1031 & 0xC0FF) | 0x1800);
1032 b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
1033 & 0xFFC0) | 0x0015);
1034 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1035 & 0xCFFF) | 0x1000);
1036 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1037 & 0xF0FF) | 0x0A00);
1038 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1039 & 0xCFFF) | 0x1000);
1040 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1041 & 0xF0FF) | 0x0800);
1042 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1043 & 0xFFCF) | 0x0010);
1044 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1045 & 0xFFF0) | 0x0005);
1046 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1047 & 0xFFCF) | 0x0010);
1048 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1049 & 0xFFF0) | 0x0006);
1050 b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
1051 & 0xF0FF) | 0x0800);
1052 b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
1053 & 0xF0FF) | 0x0500);
1054 b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
1055 & 0xFFF0) | 0x000B);
1056
1057 if (phy->rev >= 3) {
1058 b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
1059 & ~0x8000);
1060 b43_phy_write(dev, 0x0415, (b43_phy_read(dev, 0x0415)
1061 & 0x8000) | 0x36D8);
1062 b43_phy_write(dev, 0x0416, (b43_phy_read(dev, 0x0416)
1063 & 0x8000) | 0x36D8);
1064 b43_phy_write(dev, 0x0417, (b43_phy_read(dev, 0x0417)
1065 & 0xFE00) | 0x016D);
1066 } else {
1067 b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
1068 | 0x1000);
1069 b43_phy_write(dev, 0x048A, (b43_phy_read(dev, 0x048A)
1070 & 0x9FFF) | 0x2000);
1071 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ACIW);
1072 }
1073 if (phy->rev >= 2) {
1074 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B)
1075 | 0x0800);
1076 }
1077 b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
1078 & 0xF0FF) | 0x0200);
1079 if (phy->rev == 2) {
1080 b43_phy_write(dev, 0x04AE, (b43_phy_read(dev, 0x04AE)
1081 & 0xFF00) | 0x007F);
1082 b43_phy_write(dev, 0x04AD, (b43_phy_read(dev, 0x04AD)
1083 & 0x00FF) | 0x1300);
1084 } else if (phy->rev >= 6) {
1085 b43_ofdmtab_write16(dev, 0x1A00, 0x3, 0x007F);
1086 b43_ofdmtab_write16(dev, 0x1A00, 0x2, 0x007F);
1087 b43_phy_write(dev, 0x04AD, b43_phy_read(dev, 0x04AD)
1088 & 0x00FF);
1089 }
1090 b43_calc_nrssi_slope(dev);
1091 break;
1092 default:
1093 B43_WARN_ON(1);
1094 }
1095}
1096
1097static void
1098b43_radio_interference_mitigation_disable(struct b43_wldev *dev, int mode)
1099{
1100 struct b43_phy *phy = &dev->phy;
1101 struct b43_phy_g *gphy = phy->g;
1102 u32 *stack = gphy->interfstack;
1103
1104 switch (mode) {
1105 case B43_INTERFMODE_NONWLAN:
1106 if (phy->rev != 1) {
1107 b43_phy_write(dev, 0x042B,
1108 b43_phy_read(dev, 0x042B) & ~0x0800);
1109 b43_phy_write(dev, B43_PHY_G_CRS,
1110 b43_phy_read(dev,
1111 B43_PHY_G_CRS) | 0x4000);
1112 break;
1113 }
1114 radio_stackrestore(0x0078);
1115 b43_calc_nrssi_threshold(dev);
1116 phy_stackrestore(0x0406);
1117 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) & ~0x0800);
1118 if (!dev->bad_frames_preempt) {
1119 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
1120 b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
1121 & ~(1 << 11));
1122 }
1123 b43_phy_write(dev, B43_PHY_G_CRS,
1124 b43_phy_read(dev, B43_PHY_G_CRS) | 0x4000);
1125 phy_stackrestore(0x04A0);
1126 phy_stackrestore(0x04A1);
1127 phy_stackrestore(0x04A2);
1128 phy_stackrestore(0x04A8);
1129 phy_stackrestore(0x04AB);
1130 phy_stackrestore(0x04A7);
1131 phy_stackrestore(0x04A3);
1132 phy_stackrestore(0x04A9);
1133 phy_stackrestore(0x0493);
1134 phy_stackrestore(0x04AA);
1135 phy_stackrestore(0x04AC);
1136 break;
1137 case B43_INTERFMODE_MANUALWLAN:
1138 if (!(b43_phy_read(dev, 0x0033) & 0x0800))
1139 break;
1140
1141 gphy->aci_enable = 0;
1142
1143 phy_stackrestore(B43_PHY_RADIO_BITFIELD);
1144 phy_stackrestore(B43_PHY_G_CRS);
1145 phy_stackrestore(0x0033);
1146 phy_stackrestore(0x04A3);
1147 phy_stackrestore(0x04A9);
1148 phy_stackrestore(0x0493);
1149 phy_stackrestore(0x04AA);
1150 phy_stackrestore(0x04AC);
1151 phy_stackrestore(0x04A0);
1152 phy_stackrestore(0x04A7);
1153 if (phy->rev >= 2) {
1154 phy_stackrestore(0x04C0);
1155 phy_stackrestore(0x04C1);
1156 } else
1157 phy_stackrestore(0x0406);
1158 phy_stackrestore(0x04A1);
1159 phy_stackrestore(0x04AB);
1160 phy_stackrestore(0x04A8);
1161 if (phy->rev == 2) {
1162 phy_stackrestore(0x04AD);
1163 phy_stackrestore(0x04AE);
1164 } else if (phy->rev >= 3) {
1165 phy_stackrestore(0x04AD);
1166 phy_stackrestore(0x0415);
1167 phy_stackrestore(0x0416);
1168 phy_stackrestore(0x0417);
1169 ofdmtab_stackrestore(0x1A00, 0x2);
1170 ofdmtab_stackrestore(0x1A00, 0x3);
1171 }
1172 phy_stackrestore(0x04A2);
1173 phy_stackrestore(0x048A);
1174 phy_stackrestore(0x042B);
1175 phy_stackrestore(0x048C);
1176 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACIW);
1177 b43_calc_nrssi_slope(dev);
1178 break;
1179 default:
1180 B43_WARN_ON(1);
1181 }
1182}
1183
1184#undef phy_stacksave
1185#undef phy_stackrestore
1186#undef radio_stacksave
1187#undef radio_stackrestore
1188#undef ofdmtab_stacksave
1189#undef ofdmtab_stackrestore
1190
1191static u16 b43_radio_core_calibration_value(struct b43_wldev *dev)
1192{
1193 u16 reg, index, ret;
1194
1195 static const u8 rcc_table[] = {
1196 0x02, 0x03, 0x01, 0x0F,
1197 0x06, 0x07, 0x05, 0x0F,
1198 0x0A, 0x0B, 0x09, 0x0F,
1199 0x0E, 0x0F, 0x0D, 0x0F,
1200 };
1201
1202 reg = b43_radio_read16(dev, 0x60);
1203 index = (reg & 0x001E) >> 1;
1204 ret = rcc_table[index] << 1;
1205 ret |= (reg & 0x0001);
1206 ret |= 0x0020;
1207
1208 return ret;
1209}
1210
1211#define LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
1212static u16 radio2050_rfover_val(struct b43_wldev *dev,
1213 u16 phy_register, unsigned int lpd)
1214{
1215 struct b43_phy *phy = &dev->phy;
1216 struct b43_phy_g *gphy = phy->g;
1217 struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
1218
1219 if (!phy->gmode)
1220 return 0;
1221
1222 if (has_loopback_gain(phy)) {
1223 int max_lb_gain = gphy->max_lb_gain;
1224 u16 extlna;
1225 u16 i;
1226
1227 if (phy->radio_rev == 8)
1228 max_lb_gain += 0x3E;
1229 else
1230 max_lb_gain += 0x26;
1231 if (max_lb_gain >= 0x46) {
1232 extlna = 0x3000;
1233 max_lb_gain -= 0x46;
1234 } else if (max_lb_gain >= 0x3A) {
1235 extlna = 0x1000;
1236 max_lb_gain -= 0x3A;
1237 } else if (max_lb_gain >= 0x2E) {
1238 extlna = 0x2000;
1239 max_lb_gain -= 0x2E;
1240 } else {
1241 extlna = 0;
1242 max_lb_gain -= 0x10;
1243 }
1244
1245 for (i = 0; i < 16; i++) {
1246 max_lb_gain -= (i * 6);
1247 if (max_lb_gain < 6)
1248 break;
1249 }
1250
1251 if ((phy->rev < 7) ||
1252 !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
1253 if (phy_register == B43_PHY_RFOVER) {
1254 return 0x1B3;
1255 } else if (phy_register == B43_PHY_RFOVERVAL) {
1256 extlna |= (i << 8);
1257 switch (lpd) {
1258 case LPD(0, 1, 1):
1259 return 0x0F92;
1260 case LPD(0, 0, 1):
1261 case LPD(1, 0, 1):
1262 return (0x0092 | extlna);
1263 case LPD(1, 0, 0):
1264 return (0x0093 | extlna);
1265 }
1266 B43_WARN_ON(1);
1267 }
1268 B43_WARN_ON(1);
1269 } else {
1270 if (phy_register == B43_PHY_RFOVER) {
1271 return 0x9B3;
1272 } else if (phy_register == B43_PHY_RFOVERVAL) {
1273 if (extlna)
1274 extlna |= 0x8000;
1275 extlna |= (i << 8);
1276 switch (lpd) {
1277 case LPD(0, 1, 1):
1278 return 0x8F92;
1279 case LPD(0, 0, 1):
1280 return (0x8092 | extlna);
1281 case LPD(1, 0, 1):
1282 return (0x2092 | extlna);
1283 case LPD(1, 0, 0):
1284 return (0x2093 | extlna);
1285 }
1286 B43_WARN_ON(1);
1287 }
1288 B43_WARN_ON(1);
1289 }
1290 } else {
1291 if ((phy->rev < 7) ||
1292 !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
1293 if (phy_register == B43_PHY_RFOVER) {
1294 return 0x1B3;
1295 } else if (phy_register == B43_PHY_RFOVERVAL) {
1296 switch (lpd) {
1297 case LPD(0, 1, 1):
1298 return 0x0FB2;
1299 case LPD(0, 0, 1):
1300 return 0x00B2;
1301 case LPD(1, 0, 1):
1302 return 0x30B2;
1303 case LPD(1, 0, 0):
1304 return 0x30B3;
1305 }
1306 B43_WARN_ON(1);
1307 }
1308 B43_WARN_ON(1);
1309 } else {
1310 if (phy_register == B43_PHY_RFOVER) {
1311 return 0x9B3;
1312 } else if (phy_register == B43_PHY_RFOVERVAL) {
1313 switch (lpd) {
1314 case LPD(0, 1, 1):
1315 return 0x8FB2;
1316 case LPD(0, 0, 1):
1317 return 0x80B2;
1318 case LPD(1, 0, 1):
1319 return 0x20B2;
1320 case LPD(1, 0, 0):
1321 return 0x20B3;
1322 }
1323 B43_WARN_ON(1);
1324 }
1325 B43_WARN_ON(1);
1326 }
1327 }
1328 return 0;
1329}
1330
1331struct init2050_saved_values {
1332 /* Core registers */
1333 u16 reg_3EC;
1334 u16 reg_3E6;
1335 u16 reg_3F4;
1336 /* Radio registers */
1337 u16 radio_43;
1338 u16 radio_51;
1339 u16 radio_52;
1340 /* PHY registers */
1341 u16 phy_pgactl;
1342 u16 phy_cck_5A;
1343 u16 phy_cck_59;
1344 u16 phy_cck_58;
1345 u16 phy_cck_30;
1346 u16 phy_rfover;
1347 u16 phy_rfoverval;
1348 u16 phy_analogover;
1349 u16 phy_analogoverval;
1350 u16 phy_crs0;
1351 u16 phy_classctl;
1352 u16 phy_lo_mask;
1353 u16 phy_lo_ctl;
1354 u16 phy_syncctl;
1355};
1356
1357u16 b43_radio_init2050(struct b43_wldev *dev)
1358{
1359 struct b43_phy *phy = &dev->phy;
1360 struct init2050_saved_values sav;
1361 u16 rcc;
1362 u16 radio78;
1363 u16 ret;
1364 u16 i, j;
1365 u32 tmp1 = 0, tmp2 = 0;
1366
1367 memset(&sav, 0, sizeof(sav)); /* get rid of "may be used uninitialized..." */
1368
1369 sav.radio_43 = b43_radio_read16(dev, 0x43);
1370 sav.radio_51 = b43_radio_read16(dev, 0x51);
1371 sav.radio_52 = b43_radio_read16(dev, 0x52);
1372 sav.phy_pgactl = b43_phy_read(dev, B43_PHY_PGACTL);
1373 sav.phy_cck_5A = b43_phy_read(dev, B43_PHY_CCK(0x5A));
1374 sav.phy_cck_59 = b43_phy_read(dev, B43_PHY_CCK(0x59));
1375 sav.phy_cck_58 = b43_phy_read(dev, B43_PHY_CCK(0x58));
1376
1377 if (phy->type == B43_PHYTYPE_B) {
1378 sav.phy_cck_30 = b43_phy_read(dev, B43_PHY_CCK(0x30));
1379 sav.reg_3EC = b43_read16(dev, 0x3EC);
1380
1381 b43_phy_write(dev, B43_PHY_CCK(0x30), 0xFF);
1382 b43_write16(dev, 0x3EC, 0x3F3F);
1383 } else if (phy->gmode || phy->rev >= 2) {
1384 sav.phy_rfover = b43_phy_read(dev, B43_PHY_RFOVER);
1385 sav.phy_rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
1386 sav.phy_analogover = b43_phy_read(dev, B43_PHY_ANALOGOVER);
1387 sav.phy_analogoverval =
1388 b43_phy_read(dev, B43_PHY_ANALOGOVERVAL);
1389 sav.phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
1390 sav.phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
1391
1392 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1393 b43_phy_read(dev, B43_PHY_ANALOGOVER)
1394 | 0x0003);
1395 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1396 b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
1397 & 0xFFFC);
1398 b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
1399 & 0x7FFF);
1400 b43_phy_write(dev, B43_PHY_CLASSCTL,
1401 b43_phy_read(dev, B43_PHY_CLASSCTL)
1402 & 0xFFFC);
1403 if (has_loopback_gain(phy)) {
1404 sav.phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
1405 sav.phy_lo_ctl = b43_phy_read(dev, B43_PHY_LO_CTL);
1406
1407 if (phy->rev >= 3)
1408 b43_phy_write(dev, B43_PHY_LO_MASK, 0xC020);
1409 else
1410 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
1411 b43_phy_write(dev, B43_PHY_LO_CTL, 0);
1412 }
1413
1414 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1415 radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
1416 LPD(0, 1, 1)));
1417 b43_phy_write(dev, B43_PHY_RFOVER,
1418 radio2050_rfover_val(dev, B43_PHY_RFOVER, 0));
1419 }
1420 b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000);
1421
1422 sav.phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
1423 b43_phy_write(dev, B43_PHY_SYNCCTL, b43_phy_read(dev, B43_PHY_SYNCCTL)
1424 & 0xFF7F);
1425 sav.reg_3E6 = b43_read16(dev, 0x3E6);
1426 sav.reg_3F4 = b43_read16(dev, 0x3F4);
1427
1428 if (phy->analog == 0) {
1429 b43_write16(dev, 0x03E6, 0x0122);
1430 } else {
1431 if (phy->analog >= 2) {
1432 b43_phy_write(dev, B43_PHY_CCK(0x03),
1433 (b43_phy_read(dev, B43_PHY_CCK(0x03))
1434 & 0xFFBF) | 0x40);
1435 }
1436 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
1437 (b43_read16(dev, B43_MMIO_CHANNEL_EXT) | 0x2000));
1438 }
1439
1440 rcc = b43_radio_core_calibration_value(dev);
1441
1442 if (phy->type == B43_PHYTYPE_B)
1443 b43_radio_write16(dev, 0x78, 0x26);
1444 if (phy->gmode || phy->rev >= 2) {
1445 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1446 radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
1447 LPD(0, 1, 1)));
1448 }
1449 b43_phy_write(dev, B43_PHY_PGACTL, 0xBFAF);
1450 b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x1403);
1451 if (phy->gmode || phy->rev >= 2) {
1452 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1453 radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
1454 LPD(0, 0, 1)));
1455 }
1456 b43_phy_write(dev, B43_PHY_PGACTL, 0xBFA0);
1457 b43_radio_write16(dev, 0x51, b43_radio_read16(dev, 0x51)
1458 | 0x0004);
1459 if (phy->radio_rev == 8) {
1460 b43_radio_write16(dev, 0x43, 0x1F);
1461 } else {
1462 b43_radio_write16(dev, 0x52, 0);
1463 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
1464 & 0xFFF0) | 0x0009);
1465 }
1466 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1467
1468 for (i = 0; i < 16; i++) {
1469 b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0480);
1470 b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
1471 b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
1472 if (phy->gmode || phy->rev >= 2) {
1473 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1474 radio2050_rfover_val(dev,
1475 B43_PHY_RFOVERVAL,
1476 LPD(1, 0, 1)));
1477 }
1478 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1479 udelay(10);
1480 if (phy->gmode || phy->rev >= 2) {
1481 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1482 radio2050_rfover_val(dev,
1483 B43_PHY_RFOVERVAL,
1484 LPD(1, 0, 1)));
1485 }
1486 b43_phy_write(dev, B43_PHY_PGACTL, 0xEFB0);
1487 udelay(10);
1488 if (phy->gmode || phy->rev >= 2) {
1489 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1490 radio2050_rfover_val(dev,
1491 B43_PHY_RFOVERVAL,
1492 LPD(1, 0, 0)));
1493 }
1494 b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
1495 udelay(20);
1496 tmp1 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
1497 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1498 if (phy->gmode || phy->rev >= 2) {
1499 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1500 radio2050_rfover_val(dev,
1501 B43_PHY_RFOVERVAL,
1502 LPD(1, 0, 1)));
1503 }
1504 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1505 }
1506 udelay(10);
1507
1508 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1509 tmp1++;
1510 tmp1 >>= 9;
1511
1512 for (i = 0; i < 16; i++) {
1513 radio78 = (bitrev4(i) << 1) | 0x0020;
1514 b43_radio_write16(dev, 0x78, radio78);
1515 udelay(10);
1516 for (j = 0; j < 16; j++) {
1517 b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0D80);
1518 b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
1519 b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
1520 if (phy->gmode || phy->rev >= 2) {
1521 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1522 radio2050_rfover_val(dev,
1523 B43_PHY_RFOVERVAL,
1524 LPD(1, 0,
1525 1)));
1526 }
1527 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1528 udelay(10);
1529 if (phy->gmode || phy->rev >= 2) {
1530 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1531 radio2050_rfover_val(dev,
1532 B43_PHY_RFOVERVAL,
1533 LPD(1, 0,
1534 1)));
1535 }
1536 b43_phy_write(dev, B43_PHY_PGACTL, 0xEFB0);
1537 udelay(10);
1538 if (phy->gmode || phy->rev >= 2) {
1539 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1540 radio2050_rfover_val(dev,
1541 B43_PHY_RFOVERVAL,
1542 LPD(1, 0,
1543 0)));
1544 }
1545 b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
1546 udelay(10);
1547 tmp2 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
1548 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1549 if (phy->gmode || phy->rev >= 2) {
1550 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1551 radio2050_rfover_val(dev,
1552 B43_PHY_RFOVERVAL,
1553 LPD(1, 0,
1554 1)));
1555 }
1556 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1557 }
1558 tmp2++;
1559 tmp2 >>= 8;
1560 if (tmp1 < tmp2)
1561 break;
1562 }
1563
1564 /* Restore the registers */
1565 b43_phy_write(dev, B43_PHY_PGACTL, sav.phy_pgactl);
1566 b43_radio_write16(dev, 0x51, sav.radio_51);
1567 b43_radio_write16(dev, 0x52, sav.radio_52);
1568 b43_radio_write16(dev, 0x43, sav.radio_43);
1569 b43_phy_write(dev, B43_PHY_CCK(0x5A), sav.phy_cck_5A);
1570 b43_phy_write(dev, B43_PHY_CCK(0x59), sav.phy_cck_59);
1571 b43_phy_write(dev, B43_PHY_CCK(0x58), sav.phy_cck_58);
1572 b43_write16(dev, 0x3E6, sav.reg_3E6);
1573 if (phy->analog != 0)
1574 b43_write16(dev, 0x3F4, sav.reg_3F4);
1575 b43_phy_write(dev, B43_PHY_SYNCCTL, sav.phy_syncctl);
1576 b43_synth_pu_workaround(dev, phy->channel);
1577 if (phy->type == B43_PHYTYPE_B) {
1578 b43_phy_write(dev, B43_PHY_CCK(0x30), sav.phy_cck_30);
1579 b43_write16(dev, 0x3EC, sav.reg_3EC);
1580 } else if (phy->gmode) {
1581 b43_write16(dev, B43_MMIO_PHY_RADIO,
1582 b43_read16(dev, B43_MMIO_PHY_RADIO)
1583 & 0x7FFF);
1584 b43_phy_write(dev, B43_PHY_RFOVER, sav.phy_rfover);
1585 b43_phy_write(dev, B43_PHY_RFOVERVAL, sav.phy_rfoverval);
1586 b43_phy_write(dev, B43_PHY_ANALOGOVER, sav.phy_analogover);
1587 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1588 sav.phy_analogoverval);
1589 b43_phy_write(dev, B43_PHY_CRS0, sav.phy_crs0);
1590 b43_phy_write(dev, B43_PHY_CLASSCTL, sav.phy_classctl);
1591 if (has_loopback_gain(phy)) {
1592 b43_phy_write(dev, B43_PHY_LO_MASK, sav.phy_lo_mask);
1593 b43_phy_write(dev, B43_PHY_LO_CTL, sav.phy_lo_ctl);
1594 }
1595 }
1596 if (i > 15)
1597 ret = radio78;
1598 else
1599 ret = rcc;
1600
1601 return ret;
1602}
1603
1604static void b43_phy_initb5(struct b43_wldev *dev)
1605{
1606 struct ssb_bus *bus = dev->dev->bus;
1607 struct b43_phy *phy = &dev->phy;
1608 struct b43_phy_g *gphy = phy->g;
1609 u16 offset, value;
1610 u8 old_channel;
1611
1612 if (phy->analog == 1) {
1613 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
1614 | 0x0050);
1615 }
1616 if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
1617 (bus->boardinfo.type != SSB_BOARD_BU4306)) {
1618 value = 0x2120;
1619 for (offset = 0x00A8; offset < 0x00C7; offset++) {
1620 b43_phy_write(dev, offset, value);
1621 value += 0x202;
1622 }
1623 }
1624 b43_phy_write(dev, 0x0035, (b43_phy_read(dev, 0x0035) & 0xF0FF)
1625 | 0x0700);
1626 if (phy->radio_ver == 0x2050)
1627 b43_phy_write(dev, 0x0038, 0x0667);
1628
1629 if (phy->gmode || phy->rev >= 2) {
1630 if (phy->radio_ver == 0x2050) {
1631 b43_radio_write16(dev, 0x007A,
1632 b43_radio_read16(dev, 0x007A)
1633 | 0x0020);
1634 b43_radio_write16(dev, 0x0051,
1635 b43_radio_read16(dev, 0x0051)
1636 | 0x0004);
1637 }
1638 b43_write16(dev, B43_MMIO_PHY_RADIO, 0x0000);
1639
1640 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
1641 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
1642
1643 b43_phy_write(dev, 0x001C, 0x186A);
1644
1645 b43_phy_write(dev, 0x0013,
1646 (b43_phy_read(dev, 0x0013) & 0x00FF) | 0x1900);
1647 b43_phy_write(dev, 0x0035,
1648 (b43_phy_read(dev, 0x0035) & 0xFFC0) | 0x0064);
1649 b43_phy_write(dev, 0x005D,
1650 (b43_phy_read(dev, 0x005D) & 0xFF80) | 0x000A);
1651 }
1652
1653 if (dev->bad_frames_preempt) {
1654 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
1655 b43_phy_read(dev,
1656 B43_PHY_RADIO_BITFIELD) | (1 << 11));
1657 }
1658
1659 if (phy->analog == 1) {
1660 b43_phy_write(dev, 0x0026, 0xCE00);
1661 b43_phy_write(dev, 0x0021, 0x3763);
1662 b43_phy_write(dev, 0x0022, 0x1BC3);
1663 b43_phy_write(dev, 0x0023, 0x06F9);
1664 b43_phy_write(dev, 0x0024, 0x037E);
1665 } else
1666 b43_phy_write(dev, 0x0026, 0xCC00);
1667 b43_phy_write(dev, 0x0030, 0x00C6);
1668 b43_write16(dev, 0x03EC, 0x3F22);
1669
1670 if (phy->analog == 1)
1671 b43_phy_write(dev, 0x0020, 0x3E1C);
1672 else
1673 b43_phy_write(dev, 0x0020, 0x301C);
1674
1675 if (phy->analog == 0)
1676 b43_write16(dev, 0x03E4, 0x3000);
1677
1678 old_channel = phy->channel;
1679 /* Force to channel 7, even if not supported. */
1680 b43_gphy_channel_switch(dev, 7, 0);
1681
1682 if (phy->radio_ver != 0x2050) {
1683 b43_radio_write16(dev, 0x0075, 0x0080);
1684 b43_radio_write16(dev, 0x0079, 0x0081);
1685 }
1686
1687 b43_radio_write16(dev, 0x0050, 0x0020);
1688 b43_radio_write16(dev, 0x0050, 0x0023);
1689
1690 if (phy->radio_ver == 0x2050) {
1691 b43_radio_write16(dev, 0x0050, 0x0020);
1692 b43_radio_write16(dev, 0x005A, 0x0070);
1693 }
1694
1695 b43_radio_write16(dev, 0x005B, 0x007B);
1696 b43_radio_write16(dev, 0x005C, 0x00B0);
1697
1698 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007);
1699
1700 b43_gphy_channel_switch(dev, old_channel, 0);
1701
1702 b43_phy_write(dev, 0x0014, 0x0080);
1703 b43_phy_write(dev, 0x0032, 0x00CA);
1704 b43_phy_write(dev, 0x002A, 0x88A3);
1705
1706 b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
1707
1708 if (phy->radio_ver == 0x2050)
1709 b43_radio_write16(dev, 0x005D, 0x000D);
1710
1711 b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004);
1712}
1713
1714static void b43_phy_initb6(struct b43_wldev *dev)
1715{
1716 struct b43_phy *phy = &dev->phy;
1717 struct b43_phy_g *gphy = phy->g;
1718 u16 offset, val;
1719 u8 old_channel;
1720
1721 b43_phy_write(dev, 0x003E, 0x817A);
1722 b43_radio_write16(dev, 0x007A,
1723 (b43_radio_read16(dev, 0x007A) | 0x0058));
1724 if (phy->radio_rev == 4 || phy->radio_rev == 5) {
1725 b43_radio_write16(dev, 0x51, 0x37);
1726 b43_radio_write16(dev, 0x52, 0x70);
1727 b43_radio_write16(dev, 0x53, 0xB3);
1728 b43_radio_write16(dev, 0x54, 0x9B);
1729 b43_radio_write16(dev, 0x5A, 0x88);
1730 b43_radio_write16(dev, 0x5B, 0x88);
1731 b43_radio_write16(dev, 0x5D, 0x88);
1732 b43_radio_write16(dev, 0x5E, 0x88);
1733 b43_radio_write16(dev, 0x7D, 0x88);
1734 b43_hf_write(dev, b43_hf_read(dev)
1735 | B43_HF_TSSIRPSMW);
1736 }
1737 B43_WARN_ON(phy->radio_rev == 6 || phy->radio_rev == 7); /* We had code for these revs here... */
1738 if (phy->radio_rev == 8) {
1739 b43_radio_write16(dev, 0x51, 0);
1740 b43_radio_write16(dev, 0x52, 0x40);
1741 b43_radio_write16(dev, 0x53, 0xB7);
1742 b43_radio_write16(dev, 0x54, 0x98);
1743 b43_radio_write16(dev, 0x5A, 0x88);
1744 b43_radio_write16(dev, 0x5B, 0x6B);
1745 b43_radio_write16(dev, 0x5C, 0x0F);
1746 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
1747 b43_radio_write16(dev, 0x5D, 0xFA);
1748 b43_radio_write16(dev, 0x5E, 0xD8);
1749 } else {
1750 b43_radio_write16(dev, 0x5D, 0xF5);
1751 b43_radio_write16(dev, 0x5E, 0xB8);
1752 }
1753 b43_radio_write16(dev, 0x0073, 0x0003);
1754 b43_radio_write16(dev, 0x007D, 0x00A8);
1755 b43_radio_write16(dev, 0x007C, 0x0001);
1756 b43_radio_write16(dev, 0x007E, 0x0008);
1757 }
1758 val = 0x1E1F;
1759 for (offset = 0x0088; offset < 0x0098; offset++) {
1760 b43_phy_write(dev, offset, val);
1761 val -= 0x0202;
1762 }
1763 val = 0x3E3F;
1764 for (offset = 0x0098; offset < 0x00A8; offset++) {
1765 b43_phy_write(dev, offset, val);
1766 val -= 0x0202;
1767 }
1768 val = 0x2120;
1769 for (offset = 0x00A8; offset < 0x00C8; offset++) {
1770 b43_phy_write(dev, offset, (val & 0x3F3F));
1771 val += 0x0202;
1772 }
1773 if (phy->type == B43_PHYTYPE_G) {
1774 b43_radio_write16(dev, 0x007A,
1775 b43_radio_read16(dev, 0x007A) | 0x0020);
1776 b43_radio_write16(dev, 0x0051,
1777 b43_radio_read16(dev, 0x0051) | 0x0004);
1778 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
1779 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
1780 b43_phy_write(dev, 0x5B, 0);
1781 b43_phy_write(dev, 0x5C, 0);
1782 }
1783
1784 old_channel = phy->channel;
1785 if (old_channel >= 8)
1786 b43_gphy_channel_switch(dev, 1, 0);
1787 else
1788 b43_gphy_channel_switch(dev, 13, 0);
1789
1790 b43_radio_write16(dev, 0x0050, 0x0020);
1791 b43_radio_write16(dev, 0x0050, 0x0023);
1792 udelay(40);
1793 if (phy->radio_rev < 6 || phy->radio_rev == 8) {
1794 b43_radio_write16(dev, 0x7C, (b43_radio_read16(dev, 0x7C)
1795 | 0x0002));
1796 b43_radio_write16(dev, 0x50, 0x20);
1797 }
1798 if (phy->radio_rev <= 2) {
1799 b43_radio_write16(dev, 0x7C, 0x20);
1800 b43_radio_write16(dev, 0x5A, 0x70);
1801 b43_radio_write16(dev, 0x5B, 0x7B);
1802 b43_radio_write16(dev, 0x5C, 0xB0);
1803 }
1804 b43_radio_write16(dev, 0x007A,
1805 (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007);
1806
1807 b43_gphy_channel_switch(dev, old_channel, 0);
1808
1809 b43_phy_write(dev, 0x0014, 0x0200);
1810 if (phy->radio_rev >= 6)
1811 b43_phy_write(dev, 0x2A, 0x88C2);
1812 else
1813 b43_phy_write(dev, 0x2A, 0x8AC0);
1814 b43_phy_write(dev, 0x0038, 0x0668);
1815 b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
1816 if (phy->radio_rev <= 5) {
1817 b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D)
1818 & 0xFF80) | 0x0003);
1819 }
1820 if (phy->radio_rev <= 2)
1821 b43_radio_write16(dev, 0x005D, 0x000D);
1822
1823 if (phy->analog == 4) {
1824 b43_write16(dev, 0x3E4, 9);
1825 b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61)
1826 & 0x0FFF);
1827 } else {
1828 b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
1829 | 0x0004);
1830 }
1831 if (phy->type == B43_PHYTYPE_B)
1832 B43_WARN_ON(1);
1833 else if (phy->type == B43_PHYTYPE_G)
1834 b43_write16(dev, 0x03E6, 0x0);
1835}
1836
1837static void b43_calc_loopback_gain(struct b43_wldev *dev)
1838{
1839 struct b43_phy *phy = &dev->phy;
1840 struct b43_phy_g *gphy = phy->g;
1841 u16 backup_phy[16] = { 0 };
1842 u16 backup_radio[3];
1843 u16 backup_bband;
1844 u16 i, j, loop_i_max;
1845 u16 trsw_rx;
1846 u16 loop1_outer_done, loop1_inner_done;
1847
1848 backup_phy[0] = b43_phy_read(dev, B43_PHY_CRS0);
1849 backup_phy[1] = b43_phy_read(dev, B43_PHY_CCKBBANDCFG);
1850 backup_phy[2] = b43_phy_read(dev, B43_PHY_RFOVER);
1851 backup_phy[3] = b43_phy_read(dev, B43_PHY_RFOVERVAL);
1852 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
1853 backup_phy[4] = b43_phy_read(dev, B43_PHY_ANALOGOVER);
1854 backup_phy[5] = b43_phy_read(dev, B43_PHY_ANALOGOVERVAL);
1855 }
1856 backup_phy[6] = b43_phy_read(dev, B43_PHY_CCK(0x5A));
1857 backup_phy[7] = b43_phy_read(dev, B43_PHY_CCK(0x59));
1858 backup_phy[8] = b43_phy_read(dev, B43_PHY_CCK(0x58));
1859 backup_phy[9] = b43_phy_read(dev, B43_PHY_CCK(0x0A));
1860 backup_phy[10] = b43_phy_read(dev, B43_PHY_CCK(0x03));
1861 backup_phy[11] = b43_phy_read(dev, B43_PHY_LO_MASK);
1862 backup_phy[12] = b43_phy_read(dev, B43_PHY_LO_CTL);
1863 backup_phy[13] = b43_phy_read(dev, B43_PHY_CCK(0x2B));
1864 backup_phy[14] = b43_phy_read(dev, B43_PHY_PGACTL);
1865 backup_phy[15] = b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
1866 backup_bband = gphy->bbatt.att;
1867 backup_radio[0] = b43_radio_read16(dev, 0x52);
1868 backup_radio[1] = b43_radio_read16(dev, 0x43);
1869 backup_radio[2] = b43_radio_read16(dev, 0x7A);
1870
1871 b43_phy_write(dev, B43_PHY_CRS0,
1872 b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF);
1873 b43_phy_write(dev, B43_PHY_CCKBBANDCFG,
1874 b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000);
1875 b43_phy_write(dev, B43_PHY_RFOVER,
1876 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002);
1877 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1878 b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD);
1879 b43_phy_write(dev, B43_PHY_RFOVER,
1880 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001);
1881 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1882 b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE);
1883 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
1884 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1885 b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001);
1886 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1887 b43_phy_read(dev,
1888 B43_PHY_ANALOGOVERVAL) & 0xFFFE);
1889 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1890 b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002);
1891 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1892 b43_phy_read(dev,
1893 B43_PHY_ANALOGOVERVAL) & 0xFFFD);
1894 }
1895 b43_phy_write(dev, B43_PHY_RFOVER,
1896 b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C);
1897 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1898 b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C);
1899 b43_phy_write(dev, B43_PHY_RFOVER,
1900 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030);
1901 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1902 (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1903 & 0xFFCF) | 0x10);
1904
1905 b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
1906 b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
1907 b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
1908
1909 b43_phy_write(dev, B43_PHY_CCK(0x0A),
1910 b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
1911 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
1912 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1913 b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
1914 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1915 b43_phy_read(dev,
1916 B43_PHY_ANALOGOVERVAL) & 0xFFFB);
1917 }
1918 b43_phy_write(dev, B43_PHY_CCK(0x03),
1919 (b43_phy_read(dev, B43_PHY_CCK(0x03))
1920 & 0xFF9F) | 0x40);
1921
1922 if (phy->radio_rev == 8) {
1923 b43_radio_write16(dev, 0x43, 0x000F);
1924 } else {
1925 b43_radio_write16(dev, 0x52, 0);
1926 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
1927 & 0xFFF0) | 0x9);
1928 }
1929 b43_gphy_set_baseband_attenuation(dev, 11);
1930
1931 if (phy->rev >= 3)
1932 b43_phy_write(dev, B43_PHY_LO_MASK, 0xC020);
1933 else
1934 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
1935 b43_phy_write(dev, B43_PHY_LO_CTL, 0);
1936
1937 b43_phy_write(dev, B43_PHY_CCK(0x2B),
1938 (b43_phy_read(dev, B43_PHY_CCK(0x2B))
1939 & 0xFFC0) | 0x01);
1940 b43_phy_write(dev, B43_PHY_CCK(0x2B),
1941 (b43_phy_read(dev, B43_PHY_CCK(0x2B))
1942 & 0xC0FF) | 0x800);
1943
1944 b43_phy_write(dev, B43_PHY_RFOVER,
1945 b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100);
1946 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1947 b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
1948
1949 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
1950 if (phy->rev >= 7) {
1951 b43_phy_write(dev, B43_PHY_RFOVER,
1952 b43_phy_read(dev, B43_PHY_RFOVER)
1953 | 0x0800);
1954 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1955 b43_phy_read(dev, B43_PHY_RFOVERVAL)
1956 | 0x8000);
1957 }
1958 }
1959 b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A)
1960 & 0x00F7);
1961
1962 j = 0;
1963 loop_i_max = (phy->radio_rev == 8) ? 15 : 9;
1964 for (i = 0; i < loop_i_max; i++) {
1965 for (j = 0; j < 16; j++) {
1966 b43_radio_write16(dev, 0x43, i);
1967 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1968 (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1969 & 0xF0FF) | (j << 8));
1970 b43_phy_write(dev, B43_PHY_PGACTL,
1971 (b43_phy_read(dev, B43_PHY_PGACTL)
1972 & 0x0FFF) | 0xA000);
1973 b43_phy_write(dev, B43_PHY_PGACTL,
1974 b43_phy_read(dev, B43_PHY_PGACTL)
1975 | 0xF000);
1976 udelay(20);
1977 if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
1978 goto exit_loop1;
1979 }
1980 }
1981 exit_loop1:
1982 loop1_outer_done = i;
1983 loop1_inner_done = j;
1984 if (j >= 8) {
1985 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1986 b43_phy_read(dev, B43_PHY_RFOVERVAL)
1987 | 0x30);
1988 trsw_rx = 0x1B;
1989 for (j = j - 8; j < 16; j++) {
1990 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1991 (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1992 & 0xF0FF) | (j << 8));
1993 b43_phy_write(dev, B43_PHY_PGACTL,
1994 (b43_phy_read(dev, B43_PHY_PGACTL)
1995 & 0x0FFF) | 0xA000);
1996 b43_phy_write(dev, B43_PHY_PGACTL,
1997 b43_phy_read(dev, B43_PHY_PGACTL)
1998 | 0xF000);
1999 udelay(20);
2000 trsw_rx -= 3;
2001 if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
2002 goto exit_loop2;
2003 }
2004 } else
2005 trsw_rx = 0x18;
2006 exit_loop2:
2007
2008 if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
2009 b43_phy_write(dev, B43_PHY_ANALOGOVER, backup_phy[4]);
2010 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, backup_phy[5]);
2011 }
2012 b43_phy_write(dev, B43_PHY_CCK(0x5A), backup_phy[6]);
2013 b43_phy_write(dev, B43_PHY_CCK(0x59), backup_phy[7]);
2014 b43_phy_write(dev, B43_PHY_CCK(0x58), backup_phy[8]);
2015 b43_phy_write(dev, B43_PHY_CCK(0x0A), backup_phy[9]);
2016 b43_phy_write(dev, B43_PHY_CCK(0x03), backup_phy[10]);
2017 b43_phy_write(dev, B43_PHY_LO_MASK, backup_phy[11]);
2018 b43_phy_write(dev, B43_PHY_LO_CTL, backup_phy[12]);
2019 b43_phy_write(dev, B43_PHY_CCK(0x2B), backup_phy[13]);
2020 b43_phy_write(dev, B43_PHY_PGACTL, backup_phy[14]);
2021
2022 b43_gphy_set_baseband_attenuation(dev, backup_bband);
2023
2024 b43_radio_write16(dev, 0x52, backup_radio[0]);
2025 b43_radio_write16(dev, 0x43, backup_radio[1]);
2026 b43_radio_write16(dev, 0x7A, backup_radio[2]);
2027
2028 b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2] | 0x0003);
2029 udelay(10);
2030 b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2]);
2031 b43_phy_write(dev, B43_PHY_RFOVERVAL, backup_phy[3]);
2032 b43_phy_write(dev, B43_PHY_CRS0, backup_phy[0]);
2033 b43_phy_write(dev, B43_PHY_CCKBBANDCFG, backup_phy[1]);
2034
2035 gphy->max_lb_gain =
2036 ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
2037 gphy->trsw_rx_gain = trsw_rx * 2;
2038}
2039
2040static void b43_hardware_pctl_early_init(struct b43_wldev *dev)
2041{
2042 struct b43_phy *phy = &dev->phy;
2043
2044 if (!b43_has_hardware_pctl(dev)) {
2045 b43_phy_write(dev, 0x047A, 0xC111);
2046 return;
2047 }
2048
2049 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);
2050 b43_phy_write(dev, 0x002F, 0x0202);
2051 b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);
2052 b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);
2053 if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
2054 b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
2055 & 0xFF0F) | 0x0010);
2056 b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
2057 | 0x8000);
2058 b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
2059 & 0xFFC0) | 0x0010);
2060 b43_phy_write(dev, 0x002E, 0xC07F);
2061 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
2062 | 0x0400);
2063 } else {
2064 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
2065 | 0x0200);
2066 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
2067 | 0x0400);
2068 b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
2069 & 0x7FFF);
2070 b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)
2071 & 0xFFFE);
2072 b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
2073 & 0xFFC0) | 0x0010);
2074 b43_phy_write(dev, 0x002E, 0xC07F);
2075 b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
2076 & 0xFF0F) | 0x0010);
2077 }
2078}
2079
2080/* Hardware power control for G-PHY */
2081static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
2082{
2083 struct b43_phy *phy = &dev->phy;
2084 struct b43_phy_g *gphy = phy->g;
2085
2086 if (!b43_has_hardware_pctl(dev)) {
2087 /* No hardware power control */
2088 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_HWPCTL);
2089 return;
2090 }
2091
2092 b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)
2093 | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
2094 b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)
2095 | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
2096 b43_gphy_tssi_power_lt_init(dev);
2097 b43_gphy_gain_lt_init(dev);
2098 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);
2099 b43_phy_write(dev, 0x0014, 0x0000);
2100
2101 B43_WARN_ON(phy->rev < 6);
2102 b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
2103 | 0x0800);
2104 b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
2105 & 0xFEFF);
2106 b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
2107 & 0xFFBF);
2108
2109 b43_gphy_dc_lt_init(dev, 1);
2110
2111 /* Enable hardware pctl in firmware. */
2112 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_HWPCTL);
2113}
2114
2115/* Intialize B/G PHY power control */
2116static void b43_phy_init_pctl(struct b43_wldev *dev)
2117{
2118 struct ssb_bus *bus = dev->dev->bus;
2119 struct b43_phy *phy = &dev->phy;
2120 struct b43_phy_g *gphy = phy->g;
2121 struct b43_rfatt old_rfatt;
2122 struct b43_bbatt old_bbatt;
2123 u8 old_tx_control = 0;
2124
2125 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
2126
2127 if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
2128 (bus->boardinfo.type == SSB_BOARD_BU4306))
2129 return;
2130
2131 b43_phy_write(dev, 0x0028, 0x8018);
2132
2133 /* This does something with the Analog... */
2134 b43_write16(dev, B43_MMIO_PHY0, b43_read16(dev, B43_MMIO_PHY0)
2135 & 0xFFDF);
2136
2137 if (!phy->gmode)
2138 return;
2139 b43_hardware_pctl_early_init(dev);
2140 if (gphy->cur_idle_tssi == 0) {
2141 if (phy->radio_ver == 0x2050 && phy->analog == 0) {
2142 b43_radio_write16(dev, 0x0076,
2143 (b43_radio_read16(dev, 0x0076)
2144 & 0x00F7) | 0x0084);
2145 } else {
2146 struct b43_rfatt rfatt;
2147 struct b43_bbatt bbatt;
2148
2149 memcpy(&old_rfatt, &gphy->rfatt, sizeof(old_rfatt));
2150 memcpy(&old_bbatt, &gphy->bbatt, sizeof(old_bbatt));
2151 old_tx_control = gphy->tx_control;
2152
2153 bbatt.att = 11;
2154 if (phy->radio_rev == 8) {
2155 rfatt.att = 15;
2156 rfatt.with_padmix = 1;
2157 } else {
2158 rfatt.att = 9;
2159 rfatt.with_padmix = 0;
2160 }
2161 b43_set_txpower_g(dev, &bbatt, &rfatt, 0);
2162 }
2163 b43_dummy_transmission(dev);
2164 gphy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_ITSSI);
2165 if (B43_DEBUG) {
2166 /* Current-Idle-TSSI sanity check. */
2167 if (abs(gphy->cur_idle_tssi - gphy->tgt_idle_tssi) >= 20) {
2168 b43dbg(dev->wl,
2169 "!WARNING! Idle-TSSI phy->cur_idle_tssi "
2170 "measuring failed. (cur=%d, tgt=%d). Disabling TX power "
2171 "adjustment.\n", gphy->cur_idle_tssi,
2172 gphy->tgt_idle_tssi);
2173 gphy->cur_idle_tssi = 0;
2174 }
2175 }
2176 if (phy->radio_ver == 0x2050 && phy->analog == 0) {
2177 b43_radio_write16(dev, 0x0076,
2178 b43_radio_read16(dev, 0x0076)
2179 & 0xFF7B);
2180 } else {
2181 b43_set_txpower_g(dev, &old_bbatt,
2182 &old_rfatt, old_tx_control);
2183 }
2184 }
2185 b43_hardware_pctl_init_gphy(dev);
2186 b43_shm_clear_tssi(dev);
2187}
2188
2189static void b43_phy_initg(struct b43_wldev *dev)
2190{
2191 struct b43_phy *phy = &dev->phy;
2192 struct b43_phy_g *gphy = phy->g;
2193 u16 tmp;
2194
2195 if (phy->rev == 1)
2196 b43_phy_initb5(dev);
2197 else
2198 b43_phy_initb6(dev);
2199
2200 if (phy->rev >= 2 || phy->gmode)
2201 b43_phy_inita(dev);
2202
2203 if (phy->rev >= 2) {
2204 b43_phy_write(dev, B43_PHY_ANALOGOVER, 0);
2205 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, 0);
2206 }
2207 if (phy->rev == 2) {
2208 b43_phy_write(dev, B43_PHY_RFOVER, 0);
2209 b43_phy_write(dev, B43_PHY_PGACTL, 0xC0);
2210 }
2211 if (phy->rev > 5) {
2212 b43_phy_write(dev, B43_PHY_RFOVER, 0x400);
2213 b43_phy_write(dev, B43_PHY_PGACTL, 0xC0);
2214 }
2215 if (phy->gmode || phy->rev >= 2) {
2216 tmp = b43_phy_read(dev, B43_PHY_VERSION_OFDM);
2217 tmp &= B43_PHYVER_VERSION;
2218 if (tmp == 3 || tmp == 5) {
2219 b43_phy_write(dev, B43_PHY_OFDM(0xC2), 0x1816);
2220 b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006);
2221 }
2222 if (tmp == 5) {
2223 b43_phy_write(dev, B43_PHY_OFDM(0xCC),
2224 (b43_phy_read(dev, B43_PHY_OFDM(0xCC))
2225 & 0x00FF) | 0x1F00);
2226 }
2227 }
2228 if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
2229 b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78);
2230 if (phy->radio_rev == 8) {
2231 b43_phy_write(dev, B43_PHY_EXTG(0x01),
2232 b43_phy_read(dev, B43_PHY_EXTG(0x01))
2233 | 0x80);
2234 b43_phy_write(dev, B43_PHY_OFDM(0x3E),
2235 b43_phy_read(dev, B43_PHY_OFDM(0x3E))
2236 | 0x4);
2237 }
2238 if (has_loopback_gain(phy))
2239 b43_calc_loopback_gain(dev);
2240
2241 if (phy->radio_rev != 8) {
2242 if (gphy->initval == 0xFFFF)
2243 gphy->initval = b43_radio_init2050(dev);
2244 else
2245 b43_radio_write16(dev, 0x0078, gphy->initval);
2246 }
2247 b43_lo_g_init(dev);
2248 if (has_tx_magnification(phy)) {
2249 b43_radio_write16(dev, 0x52,
2250 (b43_radio_read16(dev, 0x52) & 0xFF00)
2251 | gphy->lo_control->tx_bias | gphy->
2252 lo_control->tx_magn);
2253 } else {
2254 b43_radio_write16(dev, 0x52,
2255 (b43_radio_read16(dev, 0x52) & 0xFFF0)
2256 | gphy->lo_control->tx_bias);
2257 }
2258 if (phy->rev >= 6) {
2259 b43_phy_write(dev, B43_PHY_CCK(0x36),
2260 (b43_phy_read(dev, B43_PHY_CCK(0x36))
2261 & 0x0FFF) | (gphy->lo_control->
2262 tx_bias << 12));
2263 }
2264 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
2265 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
2266 else
2267 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
2268 if (phy->rev < 2)
2269 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x101);
2270 else
2271 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x202);
2272 if (phy->gmode || phy->rev >= 2) {
2273 b43_lo_g_adjust(dev);
2274 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
2275 }
2276
2277 if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
2278 /* The specs state to update the NRSSI LT with
2279 * the value 0x7FFFFFFF here. I think that is some weird
2280 * compiler optimization in the original driver.
2281 * Essentially, what we do here is resetting all NRSSI LT
2282 * entries to -32 (see the clamp_val() in nrssi_hw_update())
2283 */
2284 b43_nrssi_hw_update(dev, 0xFFFF); //FIXME?
2285 b43_calc_nrssi_threshold(dev);
2286 } else if (phy->gmode || phy->rev >= 2) {
2287 if (gphy->nrssi[0] == -1000) {
2288 B43_WARN_ON(gphy->nrssi[1] != -1000);
2289 b43_calc_nrssi_slope(dev);
2290 } else
2291 b43_calc_nrssi_threshold(dev);
2292 }
2293 if (phy->radio_rev == 8)
2294 b43_phy_write(dev, B43_PHY_EXTG(0x05), 0x3230);
2295 b43_phy_init_pctl(dev);
2296 /* FIXME: The spec says in the following if, the 0 should be replaced
2297 'if OFDM may not be used in the current locale'
2298 but OFDM is legal everywhere */
2299 if ((dev->dev->bus->chip_id == 0x4306
2300 && dev->dev->bus->chip_package == 2) || 0) {
2301 b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
2302 & 0xBFFF);
2303 b43_phy_write(dev, B43_PHY_OFDM(0xC3),
2304 b43_phy_read(dev, B43_PHY_OFDM(0xC3))
2305 & 0x7FFF);
2306 }
2307}
2308
2309void b43_gphy_channel_switch(struct b43_wldev *dev,
2310 unsigned int channel,
2311 bool synthetic_pu_workaround)
2312{
2313 if (synthetic_pu_workaround)
2314 b43_synth_pu_workaround(dev, channel);
2315
2316 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
2317
2318 if (channel == 14) {
2319 if (dev->dev->bus->sprom.country_code ==
2320 SSB_SPROM1CCODE_JAPAN)
2321 b43_hf_write(dev,
2322 b43_hf_read(dev) & ~B43_HF_ACPR);
2323 else
2324 b43_hf_write(dev,
2325 b43_hf_read(dev) | B43_HF_ACPR);
2326 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
2327 b43_read16(dev, B43_MMIO_CHANNEL_EXT)
2328 | (1 << 11));
2329 } else {
2330 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
2331 b43_read16(dev, B43_MMIO_CHANNEL_EXT)
2332 & 0xF7BF);
2333 }
2334}
2335
2336static void default_baseband_attenuation(struct b43_wldev *dev,
2337 struct b43_bbatt *bb)
2338{
2339 struct b43_phy *phy = &dev->phy;
2340
2341 if (phy->radio_ver == 0x2050 && phy->radio_rev < 6)
2342 bb->att = 0;
2343 else
2344 bb->att = 2;
2345}
2346
2347static void default_radio_attenuation(struct b43_wldev *dev,
2348 struct b43_rfatt *rf)
2349{
2350 struct ssb_bus *bus = dev->dev->bus;
2351 struct b43_phy *phy = &dev->phy;
2352
2353 rf->with_padmix = 0;
2354
2355 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
2356 bus->boardinfo.type == SSB_BOARD_BCM4309G) {
2357 if (bus->boardinfo.rev < 0x43) {
2358 rf->att = 2;
2359 return;
2360 } else if (bus->boardinfo.rev < 0x51) {
2361 rf->att = 3;
2362 return;
2363 }
2364 }
2365
2366 if (phy->type == B43_PHYTYPE_A) {
2367 rf->att = 0x60;
2368 return;
2369 }
2370
2371 switch (phy->radio_ver) {
2372 case 0x2053:
2373 switch (phy->radio_rev) {
2374 case 1:
2375 rf->att = 6;
2376 return;
2377 }
2378 break;
2379 case 0x2050:
2380 switch (phy->radio_rev) {
2381 case 0:
2382 rf->att = 5;
2383 return;
2384 case 1:
2385 if (phy->type == B43_PHYTYPE_G) {
2386 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
2387 && bus->boardinfo.type == SSB_BOARD_BCM4309G
2388 && bus->boardinfo.rev >= 30)
2389 rf->att = 3;
2390 else if (bus->boardinfo.vendor ==
2391 SSB_BOARDVENDOR_BCM
2392 && bus->boardinfo.type ==
2393 SSB_BOARD_BU4306)
2394 rf->att = 3;
2395 else
2396 rf->att = 1;
2397 } else {
2398 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
2399 && bus->boardinfo.type == SSB_BOARD_BCM4309G
2400 && bus->boardinfo.rev >= 30)
2401 rf->att = 7;
2402 else
2403 rf->att = 6;
2404 }
2405 return;
2406 case 2:
2407 if (phy->type == B43_PHYTYPE_G) {
2408 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
2409 && bus->boardinfo.type == SSB_BOARD_BCM4309G
2410 && bus->boardinfo.rev >= 30)
2411 rf->att = 3;
2412 else if (bus->boardinfo.vendor ==
2413 SSB_BOARDVENDOR_BCM
2414 && bus->boardinfo.type ==
2415 SSB_BOARD_BU4306)
2416 rf->att = 5;
2417 else if (bus->chip_id == 0x4320)
2418 rf->att = 4;
2419 else
2420 rf->att = 3;
2421 } else
2422 rf->att = 6;
2423 return;
2424 case 3:
2425 rf->att = 5;
2426 return;
2427 case 4:
2428 case 5:
2429 rf->att = 1;
2430 return;
2431 case 6:
2432 case 7:
2433 rf->att = 5;
2434 return;
2435 case 8:
2436 rf->att = 0xA;
2437 rf->with_padmix = 1;
2438 return;
2439 case 9:
2440 default:
2441 rf->att = 5;
2442 return;
2443 }
2444 }
2445 rf->att = 5;
2446}
2447
2448static u16 default_tx_control(struct b43_wldev *dev)
2449{
2450 struct b43_phy *phy = &dev->phy;
2451
2452 if (phy->radio_ver != 0x2050)
2453 return 0;
2454 if (phy->radio_rev == 1)
2455 return B43_TXCTL_PA2DB | B43_TXCTL_TXMIX;
2456 if (phy->radio_rev < 6)
2457 return B43_TXCTL_PA2DB;
2458 if (phy->radio_rev == 8)
2459 return B43_TXCTL_TXMIX;
2460 return 0;
2461}
2462
2463static u8 b43_gphy_aci_detect(struct b43_wldev *dev, u8 channel)
2464{
2465 struct b43_phy *phy = &dev->phy;
2466 struct b43_phy_g *gphy = phy->g;
2467 u8 ret = 0;
2468 u16 saved, rssi, temp;
2469 int i, j = 0;
2470
2471 saved = b43_phy_read(dev, 0x0403);
2472 b43_switch_channel(dev, channel);
2473 b43_phy_write(dev, 0x0403, (saved & 0xFFF8) | 5);
2474 if (gphy->aci_hw_rssi)
2475 rssi = b43_phy_read(dev, 0x048A) & 0x3F;
2476 else
2477 rssi = saved & 0x3F;
2478 /* clamp temp to signed 5bit */
2479 if (rssi > 32)
2480 rssi -= 64;
2481 for (i = 0; i < 100; i++) {
2482 temp = (b43_phy_read(dev, 0x047F) >> 8) & 0x3F;
2483 if (temp > 32)
2484 temp -= 64;
2485 if (temp < rssi)
2486 j++;
2487 if (j >= 20)
2488 ret = 1;
2489 }
2490 b43_phy_write(dev, 0x0403, saved);
2491
2492 return ret;
2493}
2494
2495static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
2496{
2497 struct b43_phy *phy = &dev->phy;
2498 u8 ret[13];
2499 unsigned int channel = phy->channel;
2500 unsigned int i, j, start, end;
2501
2502 if (!((phy->type == B43_PHYTYPE_G) && (phy->rev > 0)))
2503 return 0;
2504
2505 b43_phy_lock(dev);
2506 b43_radio_lock(dev);
2507 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
2508 b43_phy_write(dev, B43_PHY_G_CRS,
2509 b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
2510 b43_set_all_gains(dev, 3, 8, 1);
2511
2512 start = (channel - 5 > 0) ? channel - 5 : 1;
2513 end = (channel + 5 < 14) ? channel + 5 : 13;
2514
2515 for (i = start; i <= end; i++) {
2516 if (abs(channel - i) > 2)
2517 ret[i - 1] = b43_gphy_aci_detect(dev, i);
2518 }
2519 b43_switch_channel(dev, channel);
2520 b43_phy_write(dev, 0x0802,
2521 (b43_phy_read(dev, 0x0802) & 0xFFFC) | 0x0003);
2522 b43_phy_write(dev, 0x0403, b43_phy_read(dev, 0x0403) & 0xFFF8);
2523 b43_phy_write(dev, B43_PHY_G_CRS,
2524 b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
2525 b43_set_original_gains(dev);
2526 for (i = 0; i < 13; i++) {
2527 if (!ret[i])
2528 continue;
2529 end = (i + 5 < 13) ? i + 5 : 13;
2530 for (j = i; j < end; j++)
2531 ret[j] = 1;
2532 }
2533 b43_radio_unlock(dev);
2534 b43_phy_unlock(dev);
2535
2536 return ret[channel - 1];
2537}
2538
2539static s32 b43_tssi2dbm_ad(s32 num, s32 den)
2540{
2541 if (num < 0)
2542 return num / den;
2543 else
2544 return (num + den / 2) / den;
2545}
2546
2547static s8 b43_tssi2dbm_entry(s8 entry[], u8 index,
2548 s16 pab0, s16 pab1, s16 pab2)
2549{
2550 s32 m1, m2, f = 256, q, delta;
2551 s8 i = 0;
2552
2553 m1 = b43_tssi2dbm_ad(16 * pab0 + index * pab1, 32);
2554 m2 = max(b43_tssi2dbm_ad(32768 + index * pab2, 256), 1);
2555 do {
2556 if (i > 15)
2557 return -EINVAL;
2558 q = b43_tssi2dbm_ad(f * 4096 -
2559 b43_tssi2dbm_ad(m2 * f, 16) * f, 2048);
2560 delta = abs(q - f);
2561 f = q;
2562 i++;
2563 } while (delta >= 2);
2564 entry[index] = clamp_val(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128);
2565 return 0;
2566}
2567
2568u8 * b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
2569 s16 pab0, s16 pab1, s16 pab2)
2570{
2571 unsigned int i;
2572 u8 *tab;
2573 int err;
2574
2575 tab = kmalloc(64, GFP_KERNEL);
2576 if (!tab) {
2577 b43err(dev->wl, "Could not allocate memory "
2578 "for tssi2dbm table\n");
2579 return NULL;
2580 }
2581 for (i = 0; i < 64; i++) {
2582 err = b43_tssi2dbm_entry(tab, i, pab0, pab1, pab2);
2583 if (err) {
2584 b43err(dev->wl, "Could not generate "
2585 "tssi2dBm table\n");
2586 kfree(tab);
2587 return NULL;
2588 }
2589 }
2590
2591 return tab;
2592}
2593
2594/* Initialise the TSSI->dBm lookup table */
2595static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
2596{
2597 struct b43_phy *phy = &dev->phy;
2598 struct b43_phy_g *gphy = phy->g;
2599 s16 pab0, pab1, pab2;
2600
2601 pab0 = (s16) (dev->dev->bus->sprom.pa0b0);
2602 pab1 = (s16) (dev->dev->bus->sprom.pa0b1);
2603 pab2 = (s16) (dev->dev->bus->sprom.pa0b2);
2604
2605 B43_WARN_ON((dev->dev->bus->chip_id == 0x4301) &&
2606 (phy->radio_ver != 0x2050)); /* Not supported anymore */
2607
2608 gphy->dyn_tssi_tbl = 0;
2609
2610 if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
2611 pab0 != -1 && pab1 != -1 && pab2 != -1) {
2612 /* The pabX values are set in SPROM. Use them. */
2613 if ((s8) dev->dev->bus->sprom.itssi_bg != 0 &&
2614 (s8) dev->dev->bus->sprom.itssi_bg != -1) {
2615 gphy->tgt_idle_tssi =
2616 (s8) (dev->dev->bus->sprom.itssi_bg);
2617 } else
2618 gphy->tgt_idle_tssi = 62;
2619 gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
2620 pab1, pab2);
2621 if (!gphy->tssi2dbm)
2622 return -ENOMEM;
2623 gphy->dyn_tssi_tbl = 1;
2624 } else {
2625 /* pabX values not set in SPROM. */
2626 gphy->tgt_idle_tssi = 52;
2627 gphy->tssi2dbm = b43_tssi2dbm_g_table;
2628 }
2629
2630 return 0;
2631}
2632
2633static int b43_gphy_op_allocate(struct b43_wldev *dev)
2634{
2635 struct b43_phy_g *gphy;
2636 struct b43_txpower_lo_control *lo;
2637 int err, i;
2638
2639 gphy = kzalloc(sizeof(*gphy), GFP_KERNEL);
2640 if (!gphy) {
2641 err = -ENOMEM;
2642 goto error;
2643 }
2644 dev->phy.g = gphy;
2645
2646 memset(gphy->minlowsig, 0xFF, sizeof(gphy->minlowsig));
2647
2648 /* NRSSI */
2649 for (i = 0; i < ARRAY_SIZE(gphy->nrssi); i++)
2650 gphy->nrssi[i] = -1000;
2651 for (i = 0; i < ARRAY_SIZE(gphy->nrssi_lt); i++)
2652 gphy->nrssi_lt[i] = i;
2653
2654 gphy->lofcal = 0xFFFF;
2655 gphy->initval = 0xFFFF;
2656
2657 gphy->interfmode = B43_INTERFMODE_NONE;
2658
2659 /* OFDM-table address caching. */
2660 gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_UNKNOWN;
2661
2662 gphy->average_tssi = 0xFF;
2663
2664 lo = kzalloc(sizeof(*lo), GFP_KERNEL);
2665 if (!lo) {
2666 err = -ENOMEM;
2667 goto err_free_gphy;
2668 }
2669 gphy->lo_control = lo;
2670
2671 lo->tx_bias = 0xFF;
2672 INIT_LIST_HEAD(&lo->calib_list);
2673
2674 err = b43_gphy_init_tssi2dbm_table(dev);
2675 if (err)
2676 goto err_free_lo;
2677
2678 return 0;
2679
2680err_free_lo:
2681 kfree(lo);
2682err_free_gphy:
2683 kfree(gphy);
2684error:
2685 return err;
2686}
2687
2688static int b43_gphy_op_prepare(struct b43_wldev *dev)
2689{
2690 struct b43_phy *phy = &dev->phy;
2691 struct b43_phy_g *gphy = phy->g;
2692 struct b43_txpower_lo_control *lo = gphy->lo_control;
2693
2694 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
2695
2696 default_baseband_attenuation(dev, &gphy->bbatt);
2697 default_radio_attenuation(dev, &gphy->rfatt);
2698 gphy->tx_control = (default_tx_control(dev) << 4);
2699 generate_rfatt_list(dev, &lo->rfatt_list);
2700 generate_bbatt_list(dev, &lo->bbatt_list);
2701
2702 /* Commit previous writes */
2703 b43_read32(dev, B43_MMIO_MACCTL);
2704
2705 if (phy->rev == 1) {
2706 /* Workaround: Temporarly disable gmode through the early init
2707 * phase, as the gmode stuff is not needed for phy rev 1 */
2708 phy->gmode = 0;
2709 b43_wireless_core_reset(dev, 0);
2710 b43_phy_initg(dev);
2711 phy->gmode = 1;
2712 b43_wireless_core_reset(dev, B43_TMSLOW_GMODE);
2713 }
2714
2715 return 0;
2716}
2717
2718static int b43_gphy_op_init(struct b43_wldev *dev)
2719{
2720 struct b43_phy_g *gphy = dev->phy.g;
2721
2722 b43_phy_initg(dev);
2723 gphy->initialised = 1;
2724
2725 return 0;
2726}
2727
2728static void b43_gphy_op_exit(struct b43_wldev *dev)
2729{
2730 struct b43_phy_g *gphy = dev->phy.g;
2731
2732 if (gphy->initialised) {
2733 //TODO
2734 gphy->initialised = 0;
2735 }
2736 b43_lo_g_cleanup(dev);
2737 kfree(gphy->lo_control);
2738 if (gphy->dyn_tssi_tbl)
2739 kfree(gphy->tssi2dbm);
2740 kfree(gphy);
2741 dev->phy.g = NULL;
2742}
2743
2744static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
2745{
2746 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
2747 return b43_read16(dev, B43_MMIO_PHY_DATA);
2748}
2749
2750static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
2751{
2752 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
2753 b43_write16(dev, B43_MMIO_PHY_DATA, value);
2754}
2755
2756static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
2757{
2758 /* Register 1 is a 32-bit register. */
2759 B43_WARN_ON(reg == 1);
2760 /* G-PHY needs 0x80 for read access. */
2761 reg |= 0x80;
2762
2763 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
2764 return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
2765}
2766
2767static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
2768{
2769 /* Register 1 is a 32-bit register. */
2770 B43_WARN_ON(reg == 1);
2771
2772 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
2773 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
2774}
2775
2776static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev)
2777{
2778 return (dev->phy.rev >= 6);
2779}
2780
2781static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
2782 enum rfkill_state state)
2783{
2784 struct b43_phy *phy = &dev->phy;
2785 struct b43_phy_g *gphy = phy->g;
2786 unsigned int channel;
2787
2788 might_sleep();
2789
2790 if (state == RFKILL_STATE_UNBLOCKED) {
2791 /* Turn radio ON */
2792 if (phy->radio_on)
2793 return;
2794
2795 b43_phy_write(dev, 0x0015, 0x8000);
2796 b43_phy_write(dev, 0x0015, 0xCC00);
2797 b43_phy_write(dev, 0x0015, (phy->gmode ? 0x00C0 : 0x0000));
2798 if (gphy->radio_off_context.valid) {
2799 /* Restore the RFover values. */
2800 b43_phy_write(dev, B43_PHY_RFOVER,
2801 gphy->radio_off_context.rfover);
2802 b43_phy_write(dev, B43_PHY_RFOVERVAL,
2803 gphy->radio_off_context.rfoverval);
2804 gphy->radio_off_context.valid = 0;
2805 }
2806 channel = phy->channel;
2807 b43_gphy_channel_switch(dev, 6, 1);
2808 b43_gphy_channel_switch(dev, channel, 0);
2809 } else {
2810 /* Turn radio OFF */
2811 u16 rfover, rfoverval;
2812
2813 rfover = b43_phy_read(dev, B43_PHY_RFOVER);
2814 rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
2815 gphy->radio_off_context.rfover = rfover;
2816 gphy->radio_off_context.rfoverval = rfoverval;
2817 gphy->radio_off_context.valid = 1;
2818 b43_phy_write(dev, B43_PHY_RFOVER, rfover | 0x008C);
2819 b43_phy_write(dev, B43_PHY_RFOVERVAL, rfoverval & 0xFF73);
2820 }
2821}
2822
2823static int b43_gphy_op_switch_channel(struct b43_wldev *dev,
2824 unsigned int new_channel)
2825{
2826 if ((new_channel < 1) || (new_channel > 14))
2827 return -EINVAL;
2828 b43_gphy_channel_switch(dev, new_channel, 0);
2829
2830 return 0;
2831}
2832
2833static unsigned int b43_gphy_op_get_default_chan(struct b43_wldev *dev)
2834{
2835 return 1; /* Default to channel 1 */
2836}
2837
2838static void b43_gphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
2839{
2840 struct b43_phy *phy = &dev->phy;
2841 u64 hf;
2842 u16 tmp;
2843 int autodiv = 0;
2844
2845 if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
2846 autodiv = 1;
2847
2848 hf = b43_hf_read(dev);
2849 hf &= ~B43_HF_ANTDIVHELP;
2850 b43_hf_write(dev, hf);
2851
2852 tmp = b43_phy_read(dev, B43_PHY_BBANDCFG);
2853 tmp &= ~B43_PHY_BBANDCFG_RXANT;
2854 tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
2855 << B43_PHY_BBANDCFG_RXANT_SHIFT;
2856 b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
2857
2858 if (autodiv) {
2859 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
2860 if (antenna == B43_ANTENNA_AUTO0)
2861 tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
2862 else
2863 tmp |= B43_PHY_ANTDWELL_AUTODIV1;
2864 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
2865 }
2866 tmp = b43_phy_read(dev, B43_PHY_ANTWRSETT);
2867 if (autodiv)
2868 tmp |= B43_PHY_ANTWRSETT_ARXDIV;
2869 else
2870 tmp &= ~B43_PHY_ANTWRSETT_ARXDIV;
2871 b43_phy_write(dev, B43_PHY_ANTWRSETT, tmp);
2872 if (phy->rev >= 2) {
2873 tmp = b43_phy_read(dev, B43_PHY_OFDM61);
2874 tmp |= B43_PHY_OFDM61_10;
2875 b43_phy_write(dev, B43_PHY_OFDM61, tmp);
2876
2877 tmp =
2878 b43_phy_read(dev, B43_PHY_DIVSRCHGAINBACK);
2879 tmp = (tmp & 0xFF00) | 0x15;
2880 b43_phy_write(dev, B43_PHY_DIVSRCHGAINBACK,
2881 tmp);
2882
2883 if (phy->rev == 2) {
2884 b43_phy_write(dev, B43_PHY_ADIVRELATED,
2885 8);
2886 } else {
2887 tmp =
2888 b43_phy_read(dev,
2889 B43_PHY_ADIVRELATED);
2890 tmp = (tmp & 0xFF00) | 8;
2891 b43_phy_write(dev, B43_PHY_ADIVRELATED,
2892 tmp);
2893 }
2894 }
2895 if (phy->rev >= 6)
2896 b43_phy_write(dev, B43_PHY_OFDM9B, 0xDC);
2897
2898 hf |= B43_HF_ANTDIVHELP;
2899 b43_hf_write(dev, hf);
2900}
2901
2902static int b43_gphy_op_interf_mitigation(struct b43_wldev *dev,
2903 enum b43_interference_mitigation mode)
2904{
2905 struct b43_phy *phy = &dev->phy;
2906 struct b43_phy_g *gphy = phy->g;
2907 int currentmode;
2908
2909 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
2910 if ((phy->rev == 0) || (!phy->gmode))
2911 return -ENODEV;
2912
2913 gphy->aci_wlan_automatic = 0;
2914 switch (mode) {
2915 case B43_INTERFMODE_AUTOWLAN:
2916 gphy->aci_wlan_automatic = 1;
2917 if (gphy->aci_enable)
2918 mode = B43_INTERFMODE_MANUALWLAN;
2919 else
2920 mode = B43_INTERFMODE_NONE;
2921 break;
2922 case B43_INTERFMODE_NONE:
2923 case B43_INTERFMODE_NONWLAN:
2924 case B43_INTERFMODE_MANUALWLAN:
2925 break;
2926 default:
2927 return -EINVAL;
2928 }
2929
2930 currentmode = gphy->interfmode;
2931 if (currentmode == mode)
2932 return 0;
2933 if (currentmode != B43_INTERFMODE_NONE)
2934 b43_radio_interference_mitigation_disable(dev, currentmode);
2935
2936 if (mode == B43_INTERFMODE_NONE) {
2937 gphy->aci_enable = 0;
2938 gphy->aci_hw_rssi = 0;
2939 } else
2940 b43_radio_interference_mitigation_enable(dev, mode);
2941 gphy->interfmode = mode;
2942
2943 return 0;
2944}
2945
2946/* http://bcm-specs.sipsolutions.net/EstimatePowerOut
2947 * This function converts a TSSI value to dBm in Q5.2
2948 */
2949static s8 b43_gphy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
2950{
2951 struct b43_phy_g *gphy = dev->phy.g;
2952 s8 dbm;
2953 s32 tmp;
2954
2955 tmp = (gphy->tgt_idle_tssi - gphy->cur_idle_tssi + tssi);
2956 tmp = clamp_val(tmp, 0x00, 0x3F);
2957 dbm = gphy->tssi2dbm[tmp];
2958
2959 return dbm;
2960}
2961
2962static void b43_put_attenuation_into_ranges(struct b43_wldev *dev,
2963 int *_bbatt, int *_rfatt)
2964{
2965 int rfatt = *_rfatt;
2966 int bbatt = *_bbatt;
2967 struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
2968
2969 /* Get baseband and radio attenuation values into their permitted ranges.
2970 * Radio attenuation affects power level 4 times as much as baseband. */
2971
2972 /* Range constants */
2973 const int rf_min = lo->rfatt_list.min_val;
2974 const int rf_max = lo->rfatt_list.max_val;
2975 const int bb_min = lo->bbatt_list.min_val;
2976 const int bb_max = lo->bbatt_list.max_val;
2977
2978 while (1) {
2979 if (rfatt > rf_max && bbatt > bb_max - 4)
2980 break; /* Can not get it into ranges */
2981 if (rfatt < rf_min && bbatt < bb_min + 4)
2982 break; /* Can not get it into ranges */
2983 if (bbatt > bb_max && rfatt > rf_max - 1)
2984 break; /* Can not get it into ranges */
2985 if (bbatt < bb_min && rfatt < rf_min + 1)
2986 break; /* Can not get it into ranges */
2987
2988 if (bbatt > bb_max) {
2989 bbatt -= 4;
2990 rfatt += 1;
2991 continue;
2992 }
2993 if (bbatt < bb_min) {
2994 bbatt += 4;
2995 rfatt -= 1;
2996 continue;
2997 }
2998 if (rfatt > rf_max) {
2999 rfatt -= 1;
3000 bbatt += 4;
3001 continue;
3002 }
3003 if (rfatt < rf_min) {
3004 rfatt += 1;
3005 bbatt -= 4;
3006 continue;
3007 }
3008 break;
3009 }
3010
3011 *_rfatt = clamp_val(rfatt, rf_min, rf_max);
3012 *_bbatt = clamp_val(bbatt, bb_min, bb_max);
3013}
3014
3015static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
3016{
3017 struct b43_phy *phy = &dev->phy;
3018 struct b43_phy_g *gphy = phy->g;
3019 int rfatt, bbatt;
3020 u8 tx_control;
3021
3022 spin_lock_irq(&dev->wl->irq_lock);
3023
3024 /* Calculate the new attenuation values. */
3025 bbatt = gphy->bbatt.att;
3026 bbatt += gphy->bbatt_delta;
3027 rfatt = gphy->rfatt.att;
3028 rfatt += gphy->rfatt_delta;
3029
3030 b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
3031 tx_control = gphy->tx_control;
3032 if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) {
3033 if (rfatt <= 1) {
3034 if (tx_control == 0) {
3035 tx_control =
3036 B43_TXCTL_PA2DB |
3037 B43_TXCTL_TXMIX;
3038 rfatt += 2;
3039 bbatt += 2;
3040 } else if (dev->dev->bus->sprom.
3041 boardflags_lo &
3042 B43_BFL_PACTRL) {
3043 bbatt += 4 * (rfatt - 2);
3044 rfatt = 2;
3045 }
3046 } else if (rfatt > 4 && tx_control) {
3047 tx_control = 0;
3048 if (bbatt < 3) {
3049 rfatt -= 3;
3050 bbatt += 2;
3051 } else {
3052 rfatt -= 2;
3053 bbatt -= 2;
3054 }
3055 }
3056 }
3057 /* Save the control values */
3058 gphy->tx_control = tx_control;
3059 b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
3060 gphy->rfatt.att = rfatt;
3061 gphy->bbatt.att = bbatt;
3062
3063 /* We drop the lock early, so we can sleep during hardware
3064 * adjustment. Possible races with op_recalc_txpower are harmless,
3065 * as we will be called once again in case we raced. */
3066 spin_unlock_irq(&dev->wl->irq_lock);
3067
3068 if (b43_debug(dev, B43_DBG_XMITPOWER))
3069 b43dbg(dev->wl, "Adjusting TX power\n");
3070
3071 /* Adjust the hardware */
3072 b43_phy_lock(dev);
3073 b43_radio_lock(dev);
3074 b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt,
3075 gphy->tx_control);
3076 b43_radio_unlock(dev);
3077 b43_phy_unlock(dev);
3078}
3079
3080static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
3081 bool ignore_tssi)
3082{
3083 struct b43_phy *phy = &dev->phy;
3084 struct b43_phy_g *gphy = phy->g;
3085 unsigned int average_tssi;
3086 int cck_result, ofdm_result;
3087 int estimated_pwr, desired_pwr, pwr_adjust;
3088 int rfatt_delta, bbatt_delta;
3089 unsigned int max_pwr;
3090
3091 /* First get the average TSSI */
3092 cck_result = b43_phy_shm_tssi_read(dev, B43_SHM_SH_TSSI_CCK);
3093 ofdm_result = b43_phy_shm_tssi_read(dev, B43_SHM_SH_TSSI_OFDM_G);
3094 if ((cck_result < 0) && (ofdm_result < 0)) {
3095 /* No TSSI information available */
3096 if (!ignore_tssi)
3097 goto no_adjustment_needed;
3098 cck_result = 0;
3099 ofdm_result = 0;
3100 }
3101 if (cck_result < 0)
3102 average_tssi = ofdm_result;
3103 else if (ofdm_result < 0)
3104 average_tssi = cck_result;
3105 else
3106 average_tssi = (cck_result + ofdm_result) / 2;
3107 /* Merge the average with the stored value. */
3108 if (likely(gphy->average_tssi != 0xFF))
3109 average_tssi = (average_tssi + gphy->average_tssi) / 2;
3110 gphy->average_tssi = average_tssi;
3111 B43_WARN_ON(average_tssi >= B43_TSSI_MAX);
3112
3113 /* Estimate the TX power emission based on the TSSI */
3114 estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi);
3115
3116 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
3117 max_pwr = dev->dev->bus->sprom.maxpwr_bg;
3118 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
3119 max_pwr -= 3; /* minus 0.75 */
3120 if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) {
3121 b43warn(dev->wl,
3122 "Invalid max-TX-power value in SPROM.\n");
3123 max_pwr = INT_TO_Q52(20); /* fake it */
3124 dev->dev->bus->sprom.maxpwr_bg = max_pwr;
3125 }
3126
3127 /* Get desired power (in Q5.2) */
3128 if (phy->desired_txpower < 0)
3129 desired_pwr = INT_TO_Q52(0);
3130 else
3131 desired_pwr = INT_TO_Q52(phy->desired_txpower);
3132 /* And limit it. max_pwr already is Q5.2 */
3133 desired_pwr = clamp_val(desired_pwr, 0, max_pwr);
3134 if (b43_debug(dev, B43_DBG_XMITPOWER)) {
3135 b43dbg(dev->wl,
3136 "[TX power] current = " Q52_FMT
3137 " dBm, desired = " Q52_FMT
3138 " dBm, max = " Q52_FMT "\n",
3139 Q52_ARG(estimated_pwr),
3140 Q52_ARG(desired_pwr),
3141 Q52_ARG(max_pwr));
3142 }
3143
3144 /* Calculate the adjustment delta. */
3145 pwr_adjust = desired_pwr - estimated_pwr;
3146 if (pwr_adjust == 0)
3147 goto no_adjustment_needed;
3148
3149 /* RF attenuation delta. */
3150 rfatt_delta = ((pwr_adjust + 7) / 8);
3151 /* Lower attenuation => Bigger power output. Negate it. */
3152 rfatt_delta = -rfatt_delta;
3153
3154 /* Baseband attenuation delta. */
3155 bbatt_delta = pwr_adjust / 2;
3156 /* Lower attenuation => Bigger power output. Negate it. */
3157 bbatt_delta = -bbatt_delta;
3158 /* RF att affects power level 4 times as much as
3159 * Baseband attennuation. Subtract it. */
3160 bbatt_delta -= 4 * rfatt_delta;
3161
3162 if (b43_debug(dev, B43_DBG_XMITPOWER)) {
3163 int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust;
3164 b43dbg(dev->wl,
3165 "[TX power deltas] %s" Q52_FMT " dBm => "
3166 "bbatt-delta = %d, rfatt-delta = %d\n",
3167 (pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm),
3168 bbatt_delta, rfatt_delta);
3169 }
3170 /* So do we finally need to adjust something in hardware? */
3171 if ((rfatt_delta == 0) && (bbatt_delta == 0))
3172 goto no_adjustment_needed;
3173
3174 /* Save the deltas for later when we adjust the power. */
3175 gphy->bbatt_delta = bbatt_delta;
3176 gphy->rfatt_delta = rfatt_delta;
3177
3178 /* We need to adjust the TX power on the device. */
3179 return B43_TXPWR_RES_NEED_ADJUST;
3180
3181no_adjustment_needed:
3182 return B43_TXPWR_RES_DONE;
3183}
3184
3185static void b43_gphy_op_pwork_15sec(struct b43_wldev *dev)
3186{
3187 struct b43_phy *phy = &dev->phy;
3188 struct b43_phy_g *gphy = phy->g;
3189
3190 //TODO: update_aci_moving_average
3191 if (gphy->aci_enable && gphy->aci_wlan_automatic) {
3192 b43_mac_suspend(dev);
3193 if (!gphy->aci_enable && 1 /*TODO: not scanning? */ ) {
3194 if (0 /*TODO: bunch of conditions */ ) {
3195 phy->ops->interf_mitigation(dev,
3196 B43_INTERFMODE_MANUALWLAN);
3197 }
3198 } else if (0 /*TODO*/) {
3199 if (/*(aci_average > 1000) &&*/ !b43_gphy_aci_scan(dev))
3200 phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE);
3201 }
3202 b43_mac_enable(dev);
3203 } else if (gphy->interfmode == B43_INTERFMODE_NONWLAN &&
3204 phy->rev == 1) {
3205 //TODO: implement rev1 workaround
3206 }
3207 b43_lo_g_maintanance_work(dev);
3208}
3209
3210static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev)
3211{
3212 struct b43_phy *phy = &dev->phy;
3213
3214 if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI))
3215 return;
3216
3217 b43_mac_suspend(dev);
3218 b43_calc_nrssi_slope(dev);
3219 if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) {
3220 u8 old_chan = phy->channel;
3221
3222 /* VCO Calibration */
3223 if (old_chan >= 8)
3224 b43_switch_channel(dev, 1);
3225 else
3226 b43_switch_channel(dev, 13);
3227 b43_switch_channel(dev, old_chan);
3228 }
3229 b43_mac_enable(dev);
3230}
3231
3232const struct b43_phy_operations b43_phyops_g = {
3233 .allocate = b43_gphy_op_allocate,
3234 .prepare = b43_gphy_op_prepare,
3235 .init = b43_gphy_op_init,
3236 .exit = b43_gphy_op_exit,
3237 .phy_read = b43_gphy_op_read,
3238 .phy_write = b43_gphy_op_write,
3239 .radio_read = b43_gphy_op_radio_read,
3240 .radio_write = b43_gphy_op_radio_write,
3241 .supports_hwpctl = b43_gphy_op_supports_hwpctl,
3242 .software_rfkill = b43_gphy_op_software_rfkill,
3243 .switch_channel = b43_gphy_op_switch_channel,
3244 .get_default_chan = b43_gphy_op_get_default_chan,
3245 .set_rx_antenna = b43_gphy_op_set_rx_antenna,
3246 .interf_mitigation = b43_gphy_op_interf_mitigation,
3247 .recalc_txpower = b43_gphy_op_recalc_txpower,
3248 .adjust_txpower = b43_gphy_op_adjust_txpower,
3249 .pwork_15sec = b43_gphy_op_pwork_15sec,
3250 .pwork_60sec = b43_gphy_op_pwork_60sec,
3251};
diff --git a/drivers/net/wireless/b43/phy_g.h b/drivers/net/wireless/b43/phy_g.h
new file mode 100644
index 000000000000..7f95edea1c63
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_g.h
@@ -0,0 +1,209 @@
1#ifndef LINUX_B43_PHY_G_H_
2#define LINUX_B43_PHY_G_H_
3
4/* OFDM PHY registers are defined in the A-PHY header. */
5#include "phy_a.h"
6
7/* CCK (B) PHY Registers */
8#define B43_PHY_VERSION_CCK B43_PHY_CCK(0x00) /* Versioning register for B-PHY */
9#define B43_PHY_CCKBBANDCFG B43_PHY_CCK(0x01) /* Contains antenna 0/1 control bit */
10#define B43_PHY_PGACTL B43_PHY_CCK(0x15) /* PGA control */
11#define B43_PHY_PGACTL_LPF 0x1000 /* Low pass filter (?) */
12#define B43_PHY_PGACTL_LOWBANDW 0x0040 /* Low bandwidth flag */
13#define B43_PHY_PGACTL_UNKNOWN 0xEFA0
14#define B43_PHY_FBCTL1 B43_PHY_CCK(0x18) /* Frequency bandwidth control 1 */
15#define B43_PHY_ITSSI B43_PHY_CCK(0x29) /* Idle TSSI */
16#define B43_PHY_LO_LEAKAGE B43_PHY_CCK(0x2D) /* Measured LO leakage */
17#define B43_PHY_ENERGY B43_PHY_CCK(0x33) /* Energy */
18#define B43_PHY_SYNCCTL B43_PHY_CCK(0x35)
19#define B43_PHY_FBCTL2 B43_PHY_CCK(0x38) /* Frequency bandwidth control 2 */
20#define B43_PHY_DACCTL B43_PHY_CCK(0x60) /* DAC control */
21#define B43_PHY_RCCALOVER B43_PHY_CCK(0x78) /* RC calibration override */
22
23/* Extended G-PHY Registers */
24#define B43_PHY_CLASSCTL B43_PHY_EXTG(0x02) /* Classify control */
25#define B43_PHY_GTABCTL B43_PHY_EXTG(0x03) /* G-PHY table control (see below) */
26#define B43_PHY_GTABOFF 0x03FF /* G-PHY table offset (see below) */
27#define B43_PHY_GTABNR 0xFC00 /* G-PHY table number (see below) */
28#define B43_PHY_GTABNR_SHIFT 10
29#define B43_PHY_GTABDATA B43_PHY_EXTG(0x04) /* G-PHY table data */
30#define B43_PHY_LO_MASK B43_PHY_EXTG(0x0F) /* Local Oscillator control mask */
31#define B43_PHY_LO_CTL B43_PHY_EXTG(0x10) /* Local Oscillator control */
32#define B43_PHY_RFOVER B43_PHY_EXTG(0x11) /* RF override */
33#define B43_PHY_RFOVERVAL B43_PHY_EXTG(0x12) /* RF override value */
34#define B43_PHY_RFOVERVAL_EXTLNA 0x8000
35#define B43_PHY_RFOVERVAL_LNA 0x7000
36#define B43_PHY_RFOVERVAL_LNA_SHIFT 12
37#define B43_PHY_RFOVERVAL_PGA 0x0F00
38#define B43_PHY_RFOVERVAL_PGA_SHIFT 8
39#define B43_PHY_RFOVERVAL_UNK 0x0010 /* Unknown, always set. */
40#define B43_PHY_RFOVERVAL_TRSWRX 0x00E0
41#define B43_PHY_RFOVERVAL_BW 0x0003 /* Bandwidth flags */
42#define B43_PHY_RFOVERVAL_BW_LPF 0x0001 /* Low Pass Filter */
43#define B43_PHY_RFOVERVAL_BW_LBW 0x0002 /* Low Bandwidth (when set), high when unset */
44#define B43_PHY_ANALOGOVER B43_PHY_EXTG(0x14) /* Analog override */
45#define B43_PHY_ANALOGOVERVAL B43_PHY_EXTG(0x15) /* Analog override value */
46
47
48/*** G-PHY table numbers */
49#define B43_GTAB(number, offset) (((number) << B43_PHY_GTABNR_SHIFT) | (offset))
50#define B43_GTAB_NRSSI B43_GTAB(0x00, 0)
51#define B43_GTAB_TRFEMW B43_GTAB(0x0C, 0x120)
52#define B43_GTAB_ORIGTR B43_GTAB(0x2E, 0x298)
53
54u16 b43_gtab_read(struct b43_wldev *dev, u16 table, u16 offset);
55void b43_gtab_write(struct b43_wldev *dev, u16 table, u16 offset, u16 value);
56
57
58/* Returns the boolean whether "TX Magnification" is enabled. */
59#define has_tx_magnification(phy) \
60 (((phy)->rev >= 2) && \
61 ((phy)->radio_ver == 0x2050) && \
62 ((phy)->radio_rev == 8))
63/* Card uses the loopback gain stuff */
64#define has_loopback_gain(phy) \
65 (((phy)->rev > 1) || ((phy)->gmode))
66
67/* Radio Attenuation (RF Attenuation) */
68struct b43_rfatt {
69 u8 att; /* Attenuation value */
70 bool with_padmix; /* Flag, PAD Mixer enabled. */
71};
72struct b43_rfatt_list {
73 /* Attenuation values list */
74 const struct b43_rfatt *list;
75 u8 len;
76 /* Minimum/Maximum attenuation values */
77 u8 min_val;
78 u8 max_val;
79};
80
81/* Returns true, if the values are the same. */
82static inline bool b43_compare_rfatt(const struct b43_rfatt *a,
83 const struct b43_rfatt *b)
84{
85 return ((a->att == b->att) &&
86 (a->with_padmix == b->with_padmix));
87}
88
89/* Baseband Attenuation */
90struct b43_bbatt {
91 u8 att; /* Attenuation value */
92};
93struct b43_bbatt_list {
94 /* Attenuation values list */
95 const struct b43_bbatt *list;
96 u8 len;
97 /* Minimum/Maximum attenuation values */
98 u8 min_val;
99 u8 max_val;
100};
101
102/* Returns true, if the values are the same. */
103static inline bool b43_compare_bbatt(const struct b43_bbatt *a,
104 const struct b43_bbatt *b)
105{
106 return (a->att == b->att);
107}
108
109/* tx_control bits. */
110#define B43_TXCTL_PA3DB 0x40 /* PA Gain 3dB */
111#define B43_TXCTL_PA2DB 0x20 /* PA Gain 2dB */
112#define B43_TXCTL_TXMIX 0x10 /* TX Mixer Gain */
113
114struct b43_txpower_lo_control;
115
116struct b43_phy_g {
117 bool initialised;
118
119 /* ACI (adjacent channel interference) flags. */
120 bool aci_enable;
121 bool aci_wlan_automatic;
122 bool aci_hw_rssi;
123
124 /* Radio switched on/off */
125 bool radio_on;
126 struct {
127 /* Values saved when turning the radio off.
128 * They are needed when turning it on again. */
129 bool valid;
130 u16 rfover;
131 u16 rfoverval;
132 } radio_off_context;
133
134 u16 minlowsig[2];
135 u16 minlowsigpos[2];
136
137 /* Pointer to the table used to convert a
138 * TSSI value to dBm-Q5.2 */
139 const s8 *tssi2dbm;
140 /* tssi2dbm is kmalloc()ed. Only used for free()ing. */
141 bool dyn_tssi_tbl;
142 /* Target idle TSSI */
143 int tgt_idle_tssi;
144 /* Current idle TSSI */
145 int cur_idle_tssi;
146 /* The current average TSSI.
147 * Needs irq_lock, as it's updated in the IRQ path. */
148 u8 average_tssi;
149 /* Current TX power level attenuation control values */
150 struct b43_bbatt bbatt;
151 struct b43_rfatt rfatt;
152 u8 tx_control; /* B43_TXCTL_XXX */
153 /* The calculated attenuation deltas that are used later
154 * when adjusting the actual power output. */
155 int bbatt_delta;
156 int rfatt_delta;
157
158 /* LocalOscillator control values. */
159 struct b43_txpower_lo_control *lo_control;
160 /* Values from b43_calc_loopback_gain() */
161 s16 max_lb_gain; /* Maximum Loopback gain in hdB */
162 s16 trsw_rx_gain; /* TRSW RX gain in hdB */
163 s16 lna_lod_gain; /* LNA lod */
164 s16 lna_gain; /* LNA */
165 s16 pga_gain; /* PGA */
166
167 /* Current Interference Mitigation mode */
168 int interfmode;
169 /* Stack of saved values from the Interference Mitigation code.
170 * Each value in the stack is layed out as follows:
171 * bit 0-11: offset
172 * bit 12-15: register ID
173 * bit 16-32: value
174 * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
175 */
176#define B43_INTERFSTACK_SIZE 26
177 u32 interfstack[B43_INTERFSTACK_SIZE]; //FIXME: use a data structure
178
179 /* Saved values from the NRSSI Slope calculation */
180 s16 nrssi[2];
181 s32 nrssislope;
182 /* In memory nrssi lookup table. */
183 s8 nrssi_lt[64];
184
185 u16 lofcal;
186
187 u16 initval; //FIXME rename?
188
189 /* The device does address auto increment for the OFDM tables.
190 * We cache the previously used address here and omit the address
191 * write on the next table access, if possible. */
192 u16 ofdmtab_addr; /* The address currently set in hardware. */
193 enum { /* The last data flow direction. */
194 B43_OFDMTAB_DIRECTION_UNKNOWN = 0,
195 B43_OFDMTAB_DIRECTION_READ,
196 B43_OFDMTAB_DIRECTION_WRITE,
197 } ofdmtab_addr_direction;
198};
199
200void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
201 u16 baseband_attenuation);
202void b43_gphy_channel_switch(struct b43_wldev *dev,
203 unsigned int channel,
204 bool synthetic_pu_workaround);
205
206struct b43_phy_operations;
207extern const struct b43_phy_operations b43_phyops_g;
208
209#endif /* LINUX_B43_PHY_G_H_ */
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index fec5645944a4..7b9e99adb8c3 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -24,6 +24,7 @@
24 24
25#include "rfkill.h" 25#include "rfkill.h"
26#include "b43.h" 26#include "b43.h"
27#include "phy_common.h"
27 28
28#include <linux/kmod.h> 29#include <linux/kmod.h>
29 30
@@ -114,11 +115,11 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
114 goto out_unlock; 115 goto out_unlock;
115 } 116 }
116 if (!dev->phy.radio_on) 117 if (!dev->phy.radio_on)
117 b43_radio_turn_on(dev); 118 b43_software_rfkill(dev, state);
118 break; 119 break;
119 case RFKILL_STATE_SOFT_BLOCKED: 120 case RFKILL_STATE_SOFT_BLOCKED:
120 if (dev->phy.radio_on) 121 if (dev->phy.radio_on)
121 b43_radio_turn_off(dev, 0); 122 b43_software_rfkill(dev, state);
122 break; 123 break;
123 default: 124 default:
124 b43warn(wl, "Received unexpected rfkill state %d.\n", state); 125 b43warn(wl, "Received unexpected rfkill state %d.\n", state);
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c
index 275095b8cbe7..5adaa3692d75 100644
--- a/drivers/net/wireless/b43/sysfs.c
+++ b/drivers/net/wireless/b43/sysfs.c
@@ -29,7 +29,7 @@
29#include "b43.h" 29#include "b43.h"
30#include "sysfs.h" 30#include "sysfs.h"
31#include "main.h" 31#include "main.h"
32#include "phy.h" 32#include "phy_common.h"
33 33
34#define GENERIC_FILESIZE 64 34#define GENERIC_FILESIZE 64
35 35
@@ -59,7 +59,12 @@ static ssize_t b43_attr_interfmode_show(struct device *dev,
59 59
60 mutex_lock(&wldev->wl->mutex); 60 mutex_lock(&wldev->wl->mutex);
61 61
62 switch (wldev->phy.interfmode) { 62 if (wldev->phy.type != B43_PHYTYPE_G) {
63 mutex_unlock(&wldev->wl->mutex);
64 return -ENOSYS;
65 }
66
67 switch (wldev->phy.g->interfmode) {
63 case B43_INTERFMODE_NONE: 68 case B43_INTERFMODE_NONE:
64 count = 69 count =
65 snprintf(buf, PAGE_SIZE, 70 snprintf(buf, PAGE_SIZE,
@@ -117,11 +122,15 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
117 mutex_lock(&wldev->wl->mutex); 122 mutex_lock(&wldev->wl->mutex);
118 spin_lock_irqsave(&wldev->wl->irq_lock, flags); 123 spin_lock_irqsave(&wldev->wl->irq_lock, flags);
119 124
120 err = b43_radio_set_interference_mitigation(wldev, mode); 125 if (wldev->phy.ops->interf_mitigation) {
121 if (err) { 126 err = wldev->phy.ops->interf_mitigation(wldev, mode);
122 b43err(wldev->wl, "Interference Mitigation not " 127 if (err) {
123 "supported by device\n"); 128 b43err(wldev->wl, "Interference Mitigation not "
124 } 129 "supported by device\n");
130 }
131 } else
132 err = -ENOSYS;
133
125 mmiowb(); 134 mmiowb();
126 spin_unlock_irqrestore(&wldev->wl->irq_lock, flags); 135 spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
127 mutex_unlock(&wldev->wl->mutex); 136 mutex_unlock(&wldev->wl->mutex);
diff --git a/drivers/net/wireless/b43/tables.c b/drivers/net/wireless/b43/tables.c
index 3f5ea06bf13c..1ef9a6463ec6 100644
--- a/drivers/net/wireless/b43/tables.c
+++ b/drivers/net/wireless/b43/tables.c
@@ -27,7 +27,8 @@
27 27
28#include "b43.h" 28#include "b43.h"
29#include "tables.h" 29#include "tables.h"
30#include "phy.h" 30#include "phy_g.h"
31
31 32
32const u32 b43_tab_rotor[] = { 33const u32 b43_tab_rotor[] = {
33 0xFEB93FFD, 0xFEC63FFD, /* 0 */ 34 0xFEB93FFD, 0xFEC63FFD, /* 0 */
@@ -377,17 +378,17 @@ static inline void assert_sizes(void)
377 378
378u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset) 379u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset)
379{ 380{
380 struct b43_phy *phy = &dev->phy; 381 struct b43_phy_g *gphy = dev->phy.g;
381 u16 addr; 382 u16 addr;
382 383
383 addr = table + offset; 384 addr = table + offset;
384 if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) || 385 if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
385 (addr - 1 != phy->ofdmtab_addr)) { 386 (addr - 1 != gphy->ofdmtab_addr)) {
386 /* The hardware has a different address in memory. Update it. */ 387 /* The hardware has a different address in memory. Update it. */
387 b43_phy_write(dev, B43_PHY_OTABLECTL, addr); 388 b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
388 phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ; 389 gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
389 } 390 }
390 phy->ofdmtab_addr = addr; 391 gphy->ofdmtab_addr = addr;
391 392
392 return b43_phy_read(dev, B43_PHY_OTABLEI); 393 return b43_phy_read(dev, B43_PHY_OTABLEI);
393 394
@@ -398,34 +399,34 @@ u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset)
398void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table, 399void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table,
399 u16 offset, u16 value) 400 u16 offset, u16 value)
400{ 401{
401 struct b43_phy *phy = &dev->phy; 402 struct b43_phy_g *gphy = dev->phy.g;
402 u16 addr; 403 u16 addr;
403 404
404 addr = table + offset; 405 addr = table + offset;
405 if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) || 406 if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
406 (addr - 1 != phy->ofdmtab_addr)) { 407 (addr - 1 != gphy->ofdmtab_addr)) {
407 /* The hardware has a different address in memory. Update it. */ 408 /* The hardware has a different address in memory. Update it. */
408 b43_phy_write(dev, B43_PHY_OTABLECTL, addr); 409 b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
409 phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE; 410 gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
410 } 411 }
411 phy->ofdmtab_addr = addr; 412 gphy->ofdmtab_addr = addr;
412 b43_phy_write(dev, B43_PHY_OTABLEI, value); 413 b43_phy_write(dev, B43_PHY_OTABLEI, value);
413} 414}
414 415
415u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) 416u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset)
416{ 417{
417 struct b43_phy *phy = &dev->phy; 418 struct b43_phy_g *gphy = dev->phy.g;
418 u32 ret; 419 u32 ret;
419 u16 addr; 420 u16 addr;
420 421
421 addr = table + offset; 422 addr = table + offset;
422 if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) || 423 if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
423 (addr - 1 != phy->ofdmtab_addr)) { 424 (addr - 1 != gphy->ofdmtab_addr)) {
424 /* The hardware has a different address in memory. Update it. */ 425 /* The hardware has a different address in memory. Update it. */
425 b43_phy_write(dev, B43_PHY_OTABLECTL, addr); 426 b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
426 phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ; 427 gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
427 } 428 }
428 phy->ofdmtab_addr = addr; 429 gphy->ofdmtab_addr = addr;
429 ret = b43_phy_read(dev, B43_PHY_OTABLEQ); 430 ret = b43_phy_read(dev, B43_PHY_OTABLEQ);
430 ret <<= 16; 431 ret <<= 16;
431 ret |= b43_phy_read(dev, B43_PHY_OTABLEI); 432 ret |= b43_phy_read(dev, B43_PHY_OTABLEI);
@@ -436,17 +437,17 @@ u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset)
436void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table, 437void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
437 u16 offset, u32 value) 438 u16 offset, u32 value)
438{ 439{
439 struct b43_phy *phy = &dev->phy; 440 struct b43_phy_g *gphy = dev->phy.g;
440 u16 addr; 441 u16 addr;
441 442
442 addr = table + offset; 443 addr = table + offset;
443 if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) || 444 if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
444 (addr - 1 != phy->ofdmtab_addr)) { 445 (addr - 1 != gphy->ofdmtab_addr)) {
445 /* The hardware has a different address in memory. Update it. */ 446 /* The hardware has a different address in memory. Update it. */
446 b43_phy_write(dev, B43_PHY_OTABLECTL, addr); 447 b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
447 phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE; 448 gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
448 } 449 }
449 phy->ofdmtab_addr = addr; 450 gphy->ofdmtab_addr = addr;
450 451
451 b43_phy_write(dev, B43_PHY_OTABLEI, value); 452 b43_phy_write(dev, B43_PHY_OTABLEI, value);
452 b43_phy_write(dev, B43_PHY_OTABLEQ, (value >> 16)); 453 b43_phy_write(dev, B43_PHY_OTABLEQ, (value >> 16));
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 2aa57551786a..1de2c2e2e14c 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -24,7 +24,7 @@
24 24
25#include "b43.h" 25#include "b43.h"
26#include "tables_nphy.h" 26#include "tables_nphy.h"
27#include "phy.h" 27#include "phy_common.h"
28#include "nphy.h" 28#include "nphy.h"
29 29
30 30
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index daa94211f838..0c0fb15abb9f 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -27,7 +27,7 @@
27#include "b43.h" 27#include "b43.h"
28#include "main.h" 28#include "main.h"
29#include "tables.h" 29#include "tables.h"
30#include "phy.h" 30#include "phy_common.h"
31#include "wa.h" 31#include "wa.h"
32 32
33static void b43_wa_papd(struct b43_wldev *dev) 33static void b43_wa_papd(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 9dda8169f7cc..5e0b71c3ad02 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -28,7 +28,7 @@
28*/ 28*/
29 29
30#include "xmit.h" 30#include "xmit.h"
31#include "phy.h" 31#include "phy_common.h"
32#include "dma.h" 32#include "dma.h"
33#include "pio.h" 33#include "pio.h"
34 34
@@ -431,6 +431,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
431 int adjust_2053, int adjust_2050) 431 int adjust_2053, int adjust_2050)
432{ 432{
433 struct b43_phy *phy = &dev->phy; 433 struct b43_phy *phy = &dev->phy;
434 struct b43_phy_g *gphy = phy->g;
434 s32 tmp; 435 s32 tmp;
435 436
436 switch (phy->radio_ver) { 437 switch (phy->radio_ver) {
@@ -450,7 +451,8 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
450 boardflags_lo & B43_BFL_RSSI) { 451 boardflags_lo & B43_BFL_RSSI) {
451 if (in_rssi > 63) 452 if (in_rssi > 63)
452 in_rssi = 63; 453 in_rssi = 63;
453 tmp = phy->nrssi_lt[in_rssi]; 454 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
455 tmp = gphy->nrssi_lt[in_rssi];
454 tmp = 31 - tmp; 456 tmp = 31 - tmp;
455 tmp *= -131; 457 tmp *= -131;
456 tmp /= 128; 458 tmp /= 128;
@@ -678,6 +680,8 @@ void b43_handle_txstatus(struct b43_wldev *dev,
678 b43_pio_handle_txstatus(dev, status); 680 b43_pio_handle_txstatus(dev, status);
679 else 681 else
680 b43_dma_handle_txstatus(dev, status); 682 b43_dma_handle_txstatus(dev, status);
683
684 b43_phy_txpower_check(dev, 0);
681} 685}
682 686
683/* Fill out the mac80211 TXstatus report based on the b43-specific 687/* Fill out the mac80211 TXstatus report based on the b43-specific
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 2541c81932f0..1cb77db5c292 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -34,7 +34,6 @@
34#include <linux/moduleparam.h> 34#include <linux/moduleparam.h>
35#include <linux/if_arp.h> 35#include <linux/if_arp.h>
36#include <linux/etherdevice.h> 36#include <linux/etherdevice.h>
37#include <linux/version.h>
38#include <linux/firmware.h> 37#include <linux/firmware.h>
39#include <linux/wireless.h> 38#include <linux/wireless.h>
40#include <linux/workqueue.h> 39#include <linux/workqueue.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index d3336966b6b5..705c65bed9fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -27,7 +27,6 @@
27 27
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/version.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/pci.h> 31#include <linux/pci.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index cb11c4a4d691..4eee1b163cd2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -27,7 +27,6 @@
27 27
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/version.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/pci.h> 31#include <linux/pci.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index e5e5846e9f25..5d642298f04c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -27,7 +27,6 @@
27 *****************************************************************************/ 27 *****************************************************************************/
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/version.h>
31#include <linux/init.h> 30#include <linux/init.h>
32 31
33#include <net/mac80211.h> 32#include <net/mac80211.h>
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index a267d6e65f03..4ddf44b2758b 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -8,6 +8,7 @@
8#include "scan.h" 8#include "scan.h"
9#include "cmd.h" 9#include "cmd.h"
10 10
11static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp);
11 12
12static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = 13static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
13 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 14 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@@ -20,12 +21,88 @@ static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
20#define CAPINFO_MASK (~(0xda00)) 21#define CAPINFO_MASK (~(0xda00))
21 22
22 23
24/**
25 * @brief This function finds common rates between rates and card rates.
26 *
27 * It will fill common rates in rates as output if found.
28 *
29 * NOTE: Setting the MSB of the basic rates need to be taken
30 * care, either before or after calling this function
31 *
32 * @param priv A pointer to struct lbs_private structure
33 * @param rates the buffer which keeps input and output
34 * @param rates_size the size of rate1 buffer; new size of buffer on return
35 *
36 * @return 0 on success, or -1 on error
37 */
38static int get_common_rates(struct lbs_private *priv,
39 u8 *rates,
40 u16 *rates_size)
41{
42 u8 *card_rates = lbs_bg_rates;
43 size_t num_card_rates = sizeof(lbs_bg_rates);
44 int ret = 0, i, j;
45 u8 tmp[30];
46 size_t tmp_size = 0;
47
48 /* For each rate in card_rates that exists in rate1, copy to tmp */
49 for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
50 for (j = 0; rates[j] && (j < *rates_size); j++) {
51 if (rates[j] == card_rates[i])
52 tmp[tmp_size++] = card_rates[i];
53 }
54 }
55
56 lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size);
57 lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates);
58 lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
59 lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
60
61 if (!priv->enablehwauto) {
62 for (i = 0; i < tmp_size; i++) {
63 if (tmp[i] == priv->cur_rate)
64 goto done;
65 }
66 lbs_pr_alert("Previously set fixed data rate %#x isn't "
67 "compatible with the network.\n", priv->cur_rate);
68 ret = -1;
69 goto done;
70 }
71 ret = 0;
72
73done:
74 memset(rates, 0, *rates_size);
75 *rates_size = min_t(int, tmp_size, *rates_size);
76 memcpy(rates, tmp, *rates_size);
77 return ret;
78}
79
80
81/**
82 * @brief Sets the MSB on basic rates as the firmware requires
83 *
84 * Scan through an array and set the MSB for basic data rates.
85 *
86 * @param rates buffer of data rates
87 * @param len size of buffer
88 */
89static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
90{
91 int i;
92
93 for (i = 0; i < len; i++) {
94 if (rates[i] == 0x02 || rates[i] == 0x04 ||
95 rates[i] == 0x0b || rates[i] == 0x16)
96 rates[i] |= 0x80;
97 }
98}
99
23 100
24/** 101/**
25 * @brief Associate to a specific BSS discovered in a scan 102 * @brief Associate to a specific BSS discovered in a scan
26 * 103 *
27 * @param priv A pointer to struct lbs_private structure 104 * @param priv A pointer to struct lbs_private structure
28 * @param pbssdesc Pointer to the BSS descriptor to associate with. 105 * @param assoc_req The association request describing the BSS to associate with
29 * 106 *
30 * @return 0-success, otherwise fail 107 * @return 0-success, otherwise fail
31 */ 108 */
@@ -33,29 +110,29 @@ static int lbs_associate(struct lbs_private *priv,
33 struct assoc_request *assoc_req) 110 struct assoc_request *assoc_req)
34{ 111{
35 int ret; 112 int ret;
113 u8 preamble = RADIO_PREAMBLE_LONG;
36 114
37 lbs_deb_enter(LBS_DEB_ASSOC); 115 lbs_deb_enter(LBS_DEB_ASSOC);
38 116
39 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, 117 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
40 0, CMD_OPTION_WAITFORRSP, 118 0, CMD_OPTION_WAITFORRSP,
41 0, assoc_req->bss.bssid); 119 0, assoc_req->bss.bssid);
42
43 if (ret) 120 if (ret)
44 goto done; 121 goto out;
45 122
46 /* set preamble to firmware */ 123 /* Use short preamble only when both the BSS and firmware support it */
47 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 124 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
48 (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) 125 (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
49 priv->preamble = CMD_TYPE_SHORT_PREAMBLE; 126 preamble = RADIO_PREAMBLE_SHORT;
50 else
51 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
52 127
53 lbs_set_radio_control(priv); 128 ret = lbs_set_radio(priv, preamble, 1);
129 if (ret)
130 goto out;
54 131
55 ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, 132 ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
56 0, CMD_OPTION_WAITFORRSP, 0, assoc_req); 133 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
57 134
58done: 135out:
59 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 136 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
60 return ret; 137 return ret;
61} 138}
@@ -64,17 +141,22 @@ done:
64 * @brief Join an adhoc network found in a previous scan 141 * @brief Join an adhoc network found in a previous scan
65 * 142 *
66 * @param priv A pointer to struct lbs_private structure 143 * @param priv A pointer to struct lbs_private structure
67 * @param pbssdesc Pointer to a BSS descriptor found in a previous scan 144 * @param assoc_req The association request describing the BSS to join
68 * to attempt to join
69 * 145 *
70 * @return 0--success, -1--fail 146 * @return 0 on success, error on failure
71 */ 147 */
72static int lbs_join_adhoc_network(struct lbs_private *priv, 148static int lbs_adhoc_join(struct lbs_private *priv,
73 struct assoc_request *assoc_req) 149 struct assoc_request *assoc_req)
74{ 150{
151 struct cmd_ds_802_11_ad_hoc_join cmd;
75 struct bss_descriptor *bss = &assoc_req->bss; 152 struct bss_descriptor *bss = &assoc_req->bss;
153 u8 preamble = RADIO_PREAMBLE_LONG;
154 DECLARE_MAC_BUF(mac);
155 u16 ratesize = 0;
76 int ret = 0; 156 int ret = 0;
77 157
158 lbs_deb_enter(LBS_DEB_ASSOC);
159
78 lbs_deb_join("current SSID '%s', ssid length %u\n", 160 lbs_deb_join("current SSID '%s', ssid length %u\n",
79 escape_essid(priv->curbssparams.ssid, 161 escape_essid(priv->curbssparams.ssid,
80 priv->curbssparams.ssid_len), 162 priv->curbssparams.ssid_len),
@@ -106,29 +188,106 @@ static int lbs_join_adhoc_network(struct lbs_private *priv,
106 goto out; 188 goto out;
107 } 189 }
108 190
109 /* Use shortpreamble only when both creator and card supports 191 /* Use short preamble only when both the BSS and firmware support it */
110 short preamble */ 192 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
111 if (!(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) || 193 (bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
112 !(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
113 lbs_deb_join("AdhocJoin: Long preamble\n");
114 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
115 } else {
116 lbs_deb_join("AdhocJoin: Short preamble\n"); 194 lbs_deb_join("AdhocJoin: Short preamble\n");
117 priv->preamble = CMD_TYPE_SHORT_PREAMBLE; 195 preamble = RADIO_PREAMBLE_SHORT;
118 } 196 }
119 197
120 lbs_set_radio_control(priv); 198 ret = lbs_set_radio(priv, preamble, 1);
199 if (ret)
200 goto out;
121 201
122 lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel); 202 lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
123 lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); 203 lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
124 204
125 priv->adhoccreate = 0; 205 priv->adhoccreate = 0;
206 priv->curbssparams.channel = bss->channel;
126 207
127 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN, 208 /* Build the join command */
128 0, CMD_OPTION_WAITFORRSP, 209 memset(&cmd, 0, sizeof(cmd));
129 OID_802_11_SSID, assoc_req); 210 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
211
212 cmd.bss.type = CMD_BSS_TYPE_IBSS;
213 cmd.bss.beaconperiod = cpu_to_le16(bss->beaconperiod);
214
215 memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN);
216 memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len);
217
218 memcpy(&cmd.bss.phyparamset, &bss->phyparamset,
219 sizeof(union ieeetypes_phyparamset));
220
221 memcpy(&cmd.bss.ssparamset, &bss->ssparamset,
222 sizeof(union IEEEtypes_ssparamset));
223
224 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
225 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
226 bss->capability, CAPINFO_MASK);
227
228 /* information on BSSID descriptor passed to FW */
229 lbs_deb_join("ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n",
230 print_mac(mac, cmd.bss.bssid), cmd.bss.ssid);
231
232 /* Only v8 and below support setting these */
233 if (priv->fwrelease < 0x09000000) {
234 /* failtimeout */
235 cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
236 /* probedelay */
237 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
238 }
239
240 /* Copy Data rates from the rates recorded in scan response */
241 memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates));
242 ratesize = min_t(u16, sizeof(cmd.bss.rates), MAX_RATES);
243 memcpy(cmd.bss.rates, bss->rates, ratesize);
244 if (get_common_rates(priv, cmd.bss.rates, &ratesize)) {
245 lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n");
246 ret = -1;
247 goto out;
248 }
249
250 /* Copy the ad-hoc creation rates into Current BSS state structure */
251 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
252 memcpy(&priv->curbssparams.rates, cmd.bss.rates, ratesize);
253
254 /* Set MSB on basic rates as the firmware requires, but _after_
255 * copying to current bss rates.
256 */
257 lbs_set_basic_rate_flags(cmd.bss.rates, ratesize);
258
259 cmd.bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow);
260
261 if (assoc_req->secinfo.wep_enabled) {
262 u16 tmp = le16_to_cpu(cmd.bss.capability);
263 tmp |= WLAN_CAPABILITY_PRIVACY;
264 cmd.bss.capability = cpu_to_le16(tmp);
265 }
266
267 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
268 __le32 local_ps_mode = cpu_to_le32(LBS802_11POWERMODECAM);
269
270 /* wake up first */
271 ret = lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
272 CMD_ACT_SET, 0, 0,
273 &local_ps_mode);
274 if (ret) {
275 ret = -1;
276 goto out;
277 }
278 }
279
280 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
281 ret = -1;
282 goto out;
283 }
284
285 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
286 if (ret == 0)
287 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd);
130 288
131out: 289out:
290 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
132 return ret; 291 return ret;
133} 292}
134 293
@@ -136,39 +295,131 @@ out:
136 * @brief Start an Adhoc Network 295 * @brief Start an Adhoc Network
137 * 296 *
138 * @param priv A pointer to struct lbs_private structure 297 * @param priv A pointer to struct lbs_private structure
139 * @param adhocssid The ssid of the Adhoc Network 298 * @param assoc_req The association request describing the BSS to start
140 * @return 0--success, -1--fail 299 *
300 * @return 0 on success, error on failure
141 */ 301 */
142static int lbs_start_adhoc_network(struct lbs_private *priv, 302static int lbs_adhoc_start(struct lbs_private *priv,
143 struct assoc_request *assoc_req) 303 struct assoc_request *assoc_req)
144{ 304{
305 struct cmd_ds_802_11_ad_hoc_start cmd;
306 u8 preamble = RADIO_PREAMBLE_LONG;
307 size_t ratesize = 0;
308 u16 tmpcap = 0;
145 int ret = 0; 309 int ret = 0;
146 310
147 priv->adhoccreate = 1; 311 lbs_deb_enter(LBS_DEB_ASSOC);
148 312
149 if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) { 313 if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
150 lbs_deb_join("AdhocStart: Short preamble\n"); 314 lbs_deb_join("ADHOC_START: Will use short preamble\n");
151 priv->preamble = CMD_TYPE_SHORT_PREAMBLE; 315 preamble = RADIO_PREAMBLE_SHORT;
152 } else {
153 lbs_deb_join("AdhocStart: Long preamble\n");
154 priv->preamble = CMD_TYPE_LONG_PREAMBLE;
155 } 316 }
156 317
157 lbs_set_radio_control(priv); 318 ret = lbs_set_radio(priv, preamble, 1);
319 if (ret)
320 goto out;
158 321
159 lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel); 322 /* Build the start command */
160 lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band); 323 memset(&cmd, 0, sizeof(cmd));
324 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
161 325
162 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START, 326 memcpy(cmd.ssid, assoc_req->ssid, assoc_req->ssid_len);
163 0, CMD_OPTION_WAITFORRSP, 0, assoc_req); 327
328 lbs_deb_join("ADHOC_START: SSID '%s', ssid length %u\n",
329 escape_essid(assoc_req->ssid, assoc_req->ssid_len),
330 assoc_req->ssid_len);
164 331
332 cmd.bsstype = CMD_BSS_TYPE_IBSS;
333
334 if (priv->beacon_period == 0)
335 priv->beacon_period = MRVDRV_BEACON_INTERVAL;
336 cmd.beaconperiod = cpu_to_le16(priv->beacon_period);
337
338 WARN_ON(!assoc_req->channel);
339
340 /* set Physical parameter set */
341 cmd.phyparamset.dsparamset.elementid = MFIE_TYPE_DS_SET;
342 cmd.phyparamset.dsparamset.len = 1;
343 cmd.phyparamset.dsparamset.currentchan = assoc_req->channel;
344
345 /* set IBSS parameter set */
346 cmd.ssparamset.ibssparamset.elementid = MFIE_TYPE_IBSS_SET;
347 cmd.ssparamset.ibssparamset.len = 2;
348 cmd.ssparamset.ibssparamset.atimwindow = 0;
349
350 /* set capability info */
351 tmpcap = WLAN_CAPABILITY_IBSS;
352 if (assoc_req->secinfo.wep_enabled) {
353 lbs_deb_join("ADHOC_START: WEP enabled, setting privacy on\n");
354 tmpcap |= WLAN_CAPABILITY_PRIVACY;
355 } else
356 lbs_deb_join("ADHOC_START: WEP disabled, setting privacy off\n");
357
358 cmd.capability = cpu_to_le16(tmpcap);
359
360 /* Only v8 and below support setting probe delay */
361 if (priv->fwrelease < 0x09000000)
362 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
363
364 ratesize = min(sizeof(cmd.rates), sizeof(lbs_bg_rates));
365 memcpy(cmd.rates, lbs_bg_rates, ratesize);
366
367 /* Copy the ad-hoc creating rates into Current BSS state structure */
368 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
369 memcpy(&priv->curbssparams.rates, &cmd.rates, ratesize);
370
371 /* Set MSB on basic rates as the firmware requires, but _after_
372 * copying to current bss rates.
373 */
374 lbs_set_basic_rate_flags(cmd.rates, ratesize);
375
376 lbs_deb_join("ADHOC_START: rates=%02x %02x %02x %02x\n",
377 cmd.rates[0], cmd.rates[1], cmd.rates[2], cmd.rates[3]);
378
379 if (lbs_create_dnld_countryinfo_11d(priv)) {
380 lbs_deb_join("ADHOC_START: dnld_countryinfo_11d failed\n");
381 ret = -1;
382 goto out;
383 }
384
385 lbs_deb_join("ADHOC_START: Starting Ad-Hoc BSS on channel %d, band %d\n",
386 assoc_req->channel, assoc_req->band);
387
388 priv->adhoccreate = 1;
389 priv->mode = IW_MODE_ADHOC;
390
391 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
392 if (ret == 0)
393 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd);
394
395out:
396 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
165 return ret; 397 return ret;
166} 398}
167 399
168int lbs_stop_adhoc_network(struct lbs_private *priv) 400/**
401 * @brief Stop and Ad-Hoc network and exit Ad-Hoc mode
402 *
403 * @param priv A pointer to struct lbs_private structure
404 * @return 0 on success, or an error
405 */
406int lbs_adhoc_stop(struct lbs_private *priv)
169{ 407{
170 return lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP, 408 struct cmd_ds_802_11_ad_hoc_stop cmd;
171 0, CMD_OPTION_WAITFORRSP, 0, NULL); 409 int ret;
410
411 lbs_deb_enter(LBS_DEB_JOIN);
412
413 memset(&cmd, 0, sizeof (cmd));
414 cmd.hdr.size = cpu_to_le16 (sizeof (cmd));
415
416 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
417
418 /* Clean up everything even if there was an error */
419 lbs_mac_event_disconnected(priv);
420
421 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
422 return ret;
172} 423}
173 424
174static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, 425static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
@@ -480,14 +731,14 @@ static int assoc_helper_essid(struct lbs_private *priv,
480 if (bss != NULL) { 731 if (bss != NULL) {
481 lbs_deb_assoc("SSID found, will join\n"); 732 lbs_deb_assoc("SSID found, will join\n");
482 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 733 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
483 lbs_join_adhoc_network(priv, assoc_req); 734 lbs_adhoc_join(priv, assoc_req);
484 } else { 735 } else {
485 /* else send START command */ 736 /* else send START command */
486 lbs_deb_assoc("SSID not found, creating adhoc network\n"); 737 lbs_deb_assoc("SSID not found, creating adhoc network\n");
487 memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, 738 memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
488 IW_ESSID_MAX_SIZE); 739 IW_ESSID_MAX_SIZE);
489 assoc_req->bss.ssid_len = assoc_req->ssid_len; 740 assoc_req->bss.ssid_len = assoc_req->ssid_len;
490 lbs_start_adhoc_network(priv, assoc_req); 741 lbs_adhoc_start(priv, assoc_req);
491 } 742 }
492 } 743 }
493 744
@@ -520,7 +771,7 @@ static int assoc_helper_bssid(struct lbs_private *priv,
520 ret = lbs_associate(priv, assoc_req); 771 ret = lbs_associate(priv, assoc_req);
521 lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret); 772 lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret);
522 } else if (assoc_req->mode == IW_MODE_ADHOC) { 773 } else if (assoc_req->mode == IW_MODE_ADHOC) {
523 lbs_join_adhoc_network(priv, assoc_req); 774 lbs_adhoc_join(priv, assoc_req);
524 } 775 }
525 776
526out: 777out:
@@ -1029,7 +1280,9 @@ void lbs_association_worker(struct work_struct *work)
1029 */ 1280 */
1030 if (priv->mode == IW_MODE_INFRA) { 1281 if (priv->mode == IW_MODE_INFRA) {
1031 if (should_deauth_infrastructure(priv, assoc_req)) { 1282 if (should_deauth_infrastructure(priv, assoc_req)) {
1032 ret = lbs_send_deauthentication(priv); 1283 ret = lbs_cmd_80211_deauthenticate(priv,
1284 priv->curbssparams.bssid,
1285 WLAN_REASON_DEAUTH_LEAVING);
1033 if (ret) { 1286 if (ret) {
1034 lbs_deb_assoc("Deauthentication due to new " 1287 lbs_deb_assoc("Deauthentication due to new "
1035 "configuration request failed: %d\n", 1288 "configuration request failed: %d\n",
@@ -1038,7 +1291,7 @@ void lbs_association_worker(struct work_struct *work)
1038 } 1291 }
1039 } else if (priv->mode == IW_MODE_ADHOC) { 1292 } else if (priv->mode == IW_MODE_ADHOC) {
1040 if (should_stop_adhoc(priv, assoc_req)) { 1293 if (should_stop_adhoc(priv, assoc_req)) {
1041 ret = lbs_stop_adhoc_network(priv); 1294 ret = lbs_adhoc_stop(priv);
1042 if (ret) { 1295 if (ret) {
1043 lbs_deb_assoc("Teardown of AdHoc network due to " 1296 lbs_deb_assoc("Teardown of AdHoc network due to "
1044 "new configuration request failed: %d\n", 1297 "new configuration request failed: %d\n",
@@ -1214,94 +1467,6 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
1214 1467
1215 1468
1216/** 1469/**
1217 * @brief This function finds common rates between rate1 and card rates.
1218 *
1219 * It will fill common rates in rate1 as output if found.
1220 *
1221 * NOTE: Setting the MSB of the basic rates need to be taken
1222 * care, either before or after calling this function
1223 *
1224 * @param priv A pointer to struct lbs_private structure
1225 * @param rate1 the buffer which keeps input and output
1226 * @param rate1_size the size of rate1 buffer; new size of buffer on return
1227 *
1228 * @return 0 or -1
1229 */
1230static int get_common_rates(struct lbs_private *priv,
1231 u8 *rates,
1232 u16 *rates_size)
1233{
1234 u8 *card_rates = lbs_bg_rates;
1235 size_t num_card_rates = sizeof(lbs_bg_rates);
1236 int ret = 0, i, j;
1237 u8 tmp[30];
1238 size_t tmp_size = 0;
1239
1240 /* For each rate in card_rates that exists in rate1, copy to tmp */
1241 for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
1242 for (j = 0; rates[j] && (j < *rates_size); j++) {
1243 if (rates[j] == card_rates[i])
1244 tmp[tmp_size++] = card_rates[i];
1245 }
1246 }
1247
1248 lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size);
1249 lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates);
1250 lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
1251 lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
1252
1253 if (!priv->enablehwauto) {
1254 for (i = 0; i < tmp_size; i++) {
1255 if (tmp[i] == priv->cur_rate)
1256 goto done;
1257 }
1258 lbs_pr_alert("Previously set fixed data rate %#x isn't "
1259 "compatible with the network.\n", priv->cur_rate);
1260 ret = -1;
1261 goto done;
1262 }
1263 ret = 0;
1264
1265done:
1266 memset(rates, 0, *rates_size);
1267 *rates_size = min_t(int, tmp_size, *rates_size);
1268 memcpy(rates, tmp, *rates_size);
1269 return ret;
1270}
1271
1272
1273/**
1274 * @brief Sets the MSB on basic rates as the firmware requires
1275 *
1276 * Scan through an array and set the MSB for basic data rates.
1277 *
1278 * @param rates buffer of data rates
1279 * @param len size of buffer
1280 */
1281static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
1282{
1283 int i;
1284
1285 for (i = 0; i < len; i++) {
1286 if (rates[i] == 0x02 || rates[i] == 0x04 ||
1287 rates[i] == 0x0b || rates[i] == 0x16)
1288 rates[i] |= 0x80;
1289 }
1290}
1291
1292/**
1293 * @brief Send Deauthentication Request
1294 *
1295 * @param priv A pointer to struct lbs_private structure
1296 * @return 0--success, -1--fail
1297 */
1298int lbs_send_deauthentication(struct lbs_private *priv)
1299{
1300 return lbs_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE,
1301 0, CMD_OPTION_WAITFORRSP, 0, NULL);
1302}
1303
1304/**
1305 * @brief This function prepares command of authenticate. 1470 * @brief This function prepares command of authenticate.
1306 * 1471 *
1307 * @param priv A pointer to struct lbs_private structure 1472 * @param priv A pointer to struct lbs_private structure
@@ -1353,26 +1518,37 @@ out:
1353 return ret; 1518 return ret;
1354} 1519}
1355 1520
1356int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, 1521/**
1357 struct cmd_ds_command *cmd) 1522 * @brief Deauthenticate from a specific BSS
1523 *
1524 * @param priv A pointer to struct lbs_private structure
1525 * @param bssid The specific BSS to deauthenticate from
1526 * @param reason The 802.11 sec. 7.3.1.7 Reason Code for deauthenticating
1527 *
1528 * @return 0 on success, error on failure
1529 */
1530int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN],
1531 u16 reason)
1358{ 1532{
1359 struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth; 1533 struct cmd_ds_802_11_deauthenticate cmd;
1534 int ret;
1360 1535
1361 lbs_deb_enter(LBS_DEB_JOIN); 1536 lbs_deb_enter(LBS_DEB_JOIN);
1362 1537
1363 cmd->command = cpu_to_le16(CMD_802_11_DEAUTHENTICATE); 1538 memset(&cmd, 0, sizeof(cmd));
1364 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_deauthenticate) + 1539 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1365 S_DS_GEN); 1540 memcpy(cmd.macaddr, &bssid[0], ETH_ALEN);
1541 cmd.reasoncode = cpu_to_le16(reason);
1366 1542
1367 /* set AP MAC address */ 1543 ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd);
1368 memmove(dauth->macaddr, priv->curbssparams.bssid, ETH_ALEN);
1369 1544
1370 /* Reason code 3 = Station is leaving */ 1545 /* Clean up everything even if there was an error; can't assume that
1371#define REASON_CODE_STA_LEAVING 3 1546 * we're still authenticated to the AP after trying to deauth.
1372 dauth->reasoncode = cpu_to_le16(REASON_CODE_STA_LEAVING); 1547 */
1548 lbs_mac_event_disconnected(priv);
1373 1549
1374 lbs_deb_leave(LBS_DEB_JOIN); 1550 lbs_deb_leave(LBS_DEB_JOIN);
1375 return 0; 1551 return ret;
1376} 1552}
1377 1553
1378int lbs_cmd_80211_associate(struct lbs_private *priv, 1554int lbs_cmd_80211_associate(struct lbs_private *priv,
@@ -1489,231 +1665,6 @@ done:
1489 return ret; 1665 return ret;
1490} 1666}
1491 1667
1492int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
1493 struct cmd_ds_command *cmd, void *pdata_buf)
1494{
1495 struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
1496 int ret = 0;
1497 int cmdappendsize = 0;
1498 struct assoc_request *assoc_req = pdata_buf;
1499 u16 tmpcap = 0;
1500 size_t ratesize = 0;
1501
1502 lbs_deb_enter(LBS_DEB_JOIN);
1503
1504 if (!priv) {
1505 ret = -1;
1506 goto done;
1507 }
1508
1509 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_START);
1510
1511 /*
1512 * Fill in the parameters for 2 data structures:
1513 * 1. cmd_ds_802_11_ad_hoc_start command
1514 * 2. priv->scantable[i]
1515 *
1516 * Driver will fill up SSID, bsstype,IBSS param, Physical Param,
1517 * probe delay, and cap info.
1518 *
1519 * Firmware will fill up beacon period, DTIM, Basic rates
1520 * and operational rates.
1521 */
1522
1523 memset(adhs->ssid, 0, IW_ESSID_MAX_SIZE);
1524 memcpy(adhs->ssid, assoc_req->ssid, assoc_req->ssid_len);
1525
1526 lbs_deb_join("ADHOC_S_CMD: SSID '%s', ssid length %u\n",
1527 escape_essid(assoc_req->ssid, assoc_req->ssid_len),
1528 assoc_req->ssid_len);
1529
1530 /* set the BSS type */
1531 adhs->bsstype = CMD_BSS_TYPE_IBSS;
1532 priv->mode = IW_MODE_ADHOC;
1533 if (priv->beacon_period == 0)
1534 priv->beacon_period = MRVDRV_BEACON_INTERVAL;
1535 adhs->beaconperiod = cpu_to_le16(priv->beacon_period);
1536
1537 /* set Physical param set */
1538#define DS_PARA_IE_ID 3
1539#define DS_PARA_IE_LEN 1
1540
1541 adhs->phyparamset.dsparamset.elementid = DS_PARA_IE_ID;
1542 adhs->phyparamset.dsparamset.len = DS_PARA_IE_LEN;
1543
1544 WARN_ON(!assoc_req->channel);
1545
1546 lbs_deb_join("ADHOC_S_CMD: Creating ADHOC on channel %d\n",
1547 assoc_req->channel);
1548
1549 adhs->phyparamset.dsparamset.currentchan = assoc_req->channel;
1550
1551 /* set IBSS param set */
1552#define IBSS_PARA_IE_ID 6
1553#define IBSS_PARA_IE_LEN 2
1554
1555 adhs->ssparamset.ibssparamset.elementid = IBSS_PARA_IE_ID;
1556 adhs->ssparamset.ibssparamset.len = IBSS_PARA_IE_LEN;
1557 adhs->ssparamset.ibssparamset.atimwindow = 0;
1558
1559 /* set capability info */
1560 tmpcap = WLAN_CAPABILITY_IBSS;
1561 if (assoc_req->secinfo.wep_enabled) {
1562 lbs_deb_join("ADHOC_S_CMD: WEP enabled, "
1563 "setting privacy on\n");
1564 tmpcap |= WLAN_CAPABILITY_PRIVACY;
1565 } else {
1566 lbs_deb_join("ADHOC_S_CMD: WEP disabled, "
1567 "setting privacy off\n");
1568 }
1569 adhs->capability = cpu_to_le16(tmpcap);
1570
1571 /* probedelay */
1572 adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1573
1574 memset(adhs->rates, 0, sizeof(adhs->rates));
1575 ratesize = min(sizeof(adhs->rates), sizeof(lbs_bg_rates));
1576 memcpy(adhs->rates, lbs_bg_rates, ratesize);
1577
1578 /* Copy the ad-hoc creating rates into Current BSS state structure */
1579 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1580 memcpy(&priv->curbssparams.rates, &adhs->rates, ratesize);
1581
1582 /* Set MSB on basic rates as the firmware requires, but _after_
1583 * copying to current bss rates.
1584 */
1585 lbs_set_basic_rate_flags(adhs->rates, ratesize);
1586
1587 lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
1588 adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]);
1589
1590 lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
1591
1592 if (lbs_create_dnld_countryinfo_11d(priv)) {
1593 lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
1594 ret = -1;
1595 goto done;
1596 }
1597
1598 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_start) +
1599 S_DS_GEN + cmdappendsize);
1600
1601 ret = 0;
1602done:
1603 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1604 return ret;
1605}
1606
1607int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd)
1608{
1609 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP);
1610 cmd->size = cpu_to_le16(S_DS_GEN);
1611
1612 return 0;
1613}
1614
1615int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
1616 struct cmd_ds_command *cmd, void *pdata_buf)
1617{
1618 struct cmd_ds_802_11_ad_hoc_join *join_cmd = &cmd->params.adj;
1619 struct assoc_request *assoc_req = pdata_buf;
1620 struct bss_descriptor *bss = &assoc_req->bss;
1621 int cmdappendsize = 0;
1622 int ret = 0;
1623 u16 ratesize = 0;
1624 DECLARE_MAC_BUF(mac);
1625
1626 lbs_deb_enter(LBS_DEB_JOIN);
1627
1628 cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_JOIN);
1629
1630 join_cmd->bss.type = CMD_BSS_TYPE_IBSS;
1631 join_cmd->bss.beaconperiod = cpu_to_le16(bss->beaconperiod);
1632
1633 memcpy(&join_cmd->bss.bssid, &bss->bssid, ETH_ALEN);
1634 memcpy(&join_cmd->bss.ssid, &bss->ssid, bss->ssid_len);
1635
1636 memcpy(&join_cmd->bss.phyparamset, &bss->phyparamset,
1637 sizeof(union ieeetypes_phyparamset));
1638
1639 memcpy(&join_cmd->bss.ssparamset, &bss->ssparamset,
1640 sizeof(union IEEEtypes_ssparamset));
1641
1642 join_cmd->bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
1643 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
1644 bss->capability, CAPINFO_MASK);
1645
1646 /* information on BSSID descriptor passed to FW */
1647 lbs_deb_join(
1648 "ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n",
1649 print_mac(mac, join_cmd->bss.bssid),
1650 join_cmd->bss.ssid);
1651
1652 /* failtimeout */
1653 join_cmd->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
1654
1655 /* probedelay */
1656 join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1657
1658 priv->curbssparams.channel = bss->channel;
1659
1660 /* Copy Data rates from the rates recorded in scan response */
1661 memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates));
1662 ratesize = min_t(u16, sizeof(join_cmd->bss.rates), MAX_RATES);
1663 memcpy(join_cmd->bss.rates, bss->rates, ratesize);
1664 if (get_common_rates(priv, join_cmd->bss.rates, &ratesize)) {
1665 lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
1666 ret = -1;
1667 goto done;
1668 }
1669
1670 /* Copy the ad-hoc creating rates into Current BSS state structure */
1671 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1672 memcpy(&priv->curbssparams.rates, join_cmd->bss.rates, ratesize);
1673
1674 /* Set MSB on basic rates as the firmware requires, but _after_
1675 * copying to current bss rates.
1676 */
1677 lbs_set_basic_rate_flags(join_cmd->bss.rates, ratesize);
1678
1679 join_cmd->bss.ssparamset.ibssparamset.atimwindow =
1680 cpu_to_le16(bss->atimwindow);
1681
1682 if (assoc_req->secinfo.wep_enabled) {
1683 u16 tmp = le16_to_cpu(join_cmd->bss.capability);
1684 tmp |= WLAN_CAPABILITY_PRIVACY;
1685 join_cmd->bss.capability = cpu_to_le16(tmp);
1686 }
1687
1688 if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
1689 /* wake up first */
1690 __le32 Localpsmode;
1691
1692 Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
1693 ret = lbs_prepare_and_send_command(priv,
1694 CMD_802_11_PS_MODE,
1695 CMD_ACT_SET,
1696 0, 0, &Localpsmode);
1697
1698 if (ret) {
1699 ret = -1;
1700 goto done;
1701 }
1702 }
1703
1704 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
1705 ret = -1;
1706 goto done;
1707 }
1708
1709 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ad_hoc_join) +
1710 S_DS_GEN + cmdappendsize);
1711
1712done:
1713 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1714 return ret;
1715}
1716
1717int lbs_ret_80211_associate(struct lbs_private *priv, 1668int lbs_ret_80211_associate(struct lbs_private *priv,
1718 struct cmd_ds_command *resp) 1669 struct cmd_ds_command *resp)
1719{ 1670{
@@ -1815,34 +1766,19 @@ done:
1815 return ret; 1766 return ret;
1816} 1767}
1817 1768
1818int lbs_ret_80211_disassociate(struct lbs_private *priv) 1769static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
1819{
1820 lbs_deb_enter(LBS_DEB_JOIN);
1821
1822 lbs_mac_event_disconnected(priv);
1823
1824 lbs_deb_leave(LBS_DEB_JOIN);
1825 return 0;
1826}
1827
1828int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
1829 struct cmd_ds_command *resp)
1830{ 1770{
1831 int ret = 0; 1771 int ret = 0;
1832 u16 command = le16_to_cpu(resp->command); 1772 u16 command = le16_to_cpu(resp->command);
1833 u16 result = le16_to_cpu(resp->result); 1773 u16 result = le16_to_cpu(resp->result);
1834 struct cmd_ds_802_11_ad_hoc_result *padhocresult; 1774 struct cmd_ds_802_11_ad_hoc_result *adhoc_resp;
1835 union iwreq_data wrqu; 1775 union iwreq_data wrqu;
1836 struct bss_descriptor *bss; 1776 struct bss_descriptor *bss;
1837 DECLARE_MAC_BUF(mac); 1777 DECLARE_MAC_BUF(mac);
1838 1778
1839 lbs_deb_enter(LBS_DEB_JOIN); 1779 lbs_deb_enter(LBS_DEB_JOIN);
1840 1780
1841 padhocresult = &resp->params.result; 1781 adhoc_resp = (struct cmd_ds_802_11_ad_hoc_result *) resp;
1842
1843 lbs_deb_join("ADHOC_RESP: size = %d\n", le16_to_cpu(resp->size));
1844 lbs_deb_join("ADHOC_RESP: command = %x\n", command);
1845 lbs_deb_join("ADHOC_RESP: result = %x\n", result);
1846 1782
1847 if (!priv->in_progress_assoc_req) { 1783 if (!priv->in_progress_assoc_req) {
1848 lbs_deb_join("ADHOC_RESP: no in-progress association " 1784 lbs_deb_join("ADHOC_RESP: no in-progress association "
@@ -1856,26 +1792,19 @@ int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
1856 * Join result code 0 --> SUCCESS 1792 * Join result code 0 --> SUCCESS
1857 */ 1793 */
1858 if (result) { 1794 if (result) {
1859 lbs_deb_join("ADHOC_RESP: failed\n"); 1795 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
1860 if (priv->connect_status == LBS_CONNECTED) 1796 if (priv->connect_status == LBS_CONNECTED)
1861 lbs_mac_event_disconnected(priv); 1797 lbs_mac_event_disconnected(priv);
1862 ret = -1; 1798 ret = -1;
1863 goto done; 1799 goto done;
1864 } 1800 }
1865 1801
1866 /*
1867 * Now the join cmd should be successful
1868 * If BSSID has changed use SSID to compare instead of BSSID
1869 */
1870 lbs_deb_join("ADHOC_RESP: associated to '%s'\n",
1871 escape_essid(bss->ssid, bss->ssid_len));
1872
1873 /* Send a Media Connected event, according to the Spec */ 1802 /* Send a Media Connected event, according to the Spec */
1874 priv->connect_status = LBS_CONNECTED; 1803 priv->connect_status = LBS_CONNECTED;
1875 1804
1876 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) { 1805 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
1877 /* Update the created network descriptor with the new BSSID */ 1806 /* Update the created network descriptor with the new BSSID */
1878 memcpy(bss->bssid, padhocresult->bssid, ETH_ALEN); 1807 memcpy(bss->bssid, adhoc_resp->bssid, ETH_ALEN);
1879 } 1808 }
1880 1809
1881 /* Set the BSSID from the joined/started descriptor */ 1810 /* Set the BSSID from the joined/started descriptor */
@@ -1894,22 +1823,13 @@ int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
1894 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 1823 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1895 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 1824 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1896 1825
1897 lbs_deb_join("ADHOC_RESP: - Joined/Started Ad Hoc\n"); 1826 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %s, channel %d\n",
1898 lbs_deb_join("ADHOC_RESP: channel = %d\n", priv->curbssparams.channel); 1827 escape_essid(bss->ssid, bss->ssid_len),
1899 lbs_deb_join("ADHOC_RESP: BSSID = %s\n", 1828 print_mac(mac, priv->curbssparams.bssid),
1900 print_mac(mac, padhocresult->bssid)); 1829 priv->curbssparams.channel);
1901 1830
1902done: 1831done:
1903 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); 1832 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1904 return ret; 1833 return ret;
1905} 1834}
1906 1835
1907int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv)
1908{
1909 lbs_deb_enter(LBS_DEB_JOIN);
1910
1911 lbs_mac_event_disconnected(priv);
1912
1913 lbs_deb_leave(LBS_DEB_JOIN);
1914 return 0;
1915}
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index c516fbe518fd..8b7336dd02a3 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -12,28 +12,18 @@ struct cmd_ds_command;
12int lbs_cmd_80211_authenticate(struct lbs_private *priv, 12int lbs_cmd_80211_authenticate(struct lbs_private *priv,
13 struct cmd_ds_command *cmd, 13 struct cmd_ds_command *cmd,
14 void *pdata_buf); 14 void *pdata_buf);
15int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv, 15
16 struct cmd_ds_command *cmd, 16int lbs_adhoc_stop(struct lbs_private *priv);
17 void *pdata_buf); 17
18int lbs_cmd_80211_ad_hoc_stop(struct cmd_ds_command *cmd);
19int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
20 struct cmd_ds_command *cmd,
21 void *pdata_buf);
22int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, 18int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
23 struct cmd_ds_command *cmd); 19 u8 bssid[ETH_ALEN], u16 reason);
24int lbs_cmd_80211_associate(struct lbs_private *priv, 20int lbs_cmd_80211_associate(struct lbs_private *priv,
25 struct cmd_ds_command *cmd, 21 struct cmd_ds_command *cmd,
26 void *pdata_buf); 22 void *pdata_buf);
27 23
28int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv, 24int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
29 struct cmd_ds_command *resp); 25 struct cmd_ds_command *resp);
30int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv);
31int lbs_ret_80211_disassociate(struct lbs_private *priv);
32int lbs_ret_80211_associate(struct lbs_private *priv, 26int lbs_ret_80211_associate(struct lbs_private *priv,
33 struct cmd_ds_command *resp); 27 struct cmd_ds_command *resp);
34 28
35int lbs_stop_adhoc_network(struct lbs_private *priv);
36
37int lbs_send_deauthentication(struct lbs_private *priv);
38
39#endif /* _LBS_ASSOC_H */ 29#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index af5fd709887f..802547e79671 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -614,47 +614,67 @@ static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
614 return 0; 614 return 0;
615} 615}
616 616
617static int lbs_cmd_802_11_rf_tx_power(struct cmd_ds_command *cmd, 617/**
618 u16 cmd_action, void *pdata_buf) 618 * @brief Get the min, max, and current TX power
619 *
620 * @param priv A pointer to struct lbs_private structure
621 * @param curlevel Current power level in dBm
622 * @param minlevel Minimum supported power level in dBm (optional)
623 * @param maxlevel Maximum supported power level in dBm (optional)
624 *
625 * @return 0 on success, error on failure
626 */
627int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
628 s16 *maxlevel)
619{ 629{
620 630 struct cmd_ds_802_11_rf_tx_power cmd;
621 struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp; 631 int ret;
622 632
623 lbs_deb_enter(LBS_DEB_CMD); 633 lbs_deb_enter(LBS_DEB_CMD);
624 634
625 cmd->size = 635 memset(&cmd, 0, sizeof(cmd));
626 cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN); 636 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
627 cmd->command = cpu_to_le16(CMD_802_11_RF_TX_POWER); 637 cmd.action = cpu_to_le16(CMD_ACT_GET);
628 prtp->action = cpu_to_le16(cmd_action); 638
639 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
640 if (ret == 0) {
641 *curlevel = le16_to_cpu(cmd.curlevel);
642 if (minlevel)
643 *minlevel = le16_to_cpu(cmd.minlevel);
644 if (maxlevel)
645 *maxlevel = le16_to_cpu(cmd.maxlevel);
646 }
629 647
630 lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", 648 lbs_deb_leave(LBS_DEB_CMD);
631 le16_to_cpu(cmd->size), le16_to_cpu(cmd->command), 649 return ret;
632 le16_to_cpu(prtp->action)); 650}
633 651
634 switch (cmd_action) { 652/**
635 case CMD_ACT_TX_POWER_OPT_GET: 653 * @brief Set the TX power
636 prtp->action = cpu_to_le16(CMD_ACT_GET); 654 *
637 prtp->currentlevel = 0; 655 * @param priv A pointer to struct lbs_private structure
638 break; 656 * @param dbm The desired power level in dBm
657 *
658 * @return 0 on success, error on failure
659 */
660int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
661{
662 struct cmd_ds_802_11_rf_tx_power cmd;
663 int ret;
639 664
640 case CMD_ACT_TX_POWER_OPT_SET_HIGH: 665 lbs_deb_enter(LBS_DEB_CMD);
641 prtp->action = cpu_to_le16(CMD_ACT_SET);
642 prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_HIGH);
643 break;
644 666
645 case CMD_ACT_TX_POWER_OPT_SET_MID: 667 memset(&cmd, 0, sizeof(cmd));
646 prtp->action = cpu_to_le16(CMD_ACT_SET); 668 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
647 prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_MID); 669 cmd.action = cpu_to_le16(CMD_ACT_SET);
648 break; 670 cmd.curlevel = cpu_to_le16(dbm);
649 671
650 case CMD_ACT_TX_POWER_OPT_SET_LOW: 672 lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm);
651 prtp->action = cpu_to_le16(CMD_ACT_SET); 673
652 prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf)); 674 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
653 break;
654 }
655 675
656 lbs_deb_leave(LBS_DEB_CMD); 676 lbs_deb_leave(LBS_DEB_CMD);
657 return 0; 677 return ret;
658} 678}
659 679
660static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd, 680static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd,
@@ -1269,41 +1289,47 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1269 priv->cur_cmd = NULL; 1289 priv->cur_cmd = NULL;
1270} 1290}
1271 1291
1272int lbs_set_radio_control(struct lbs_private *priv) 1292int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
1273{ 1293{
1274 int ret = 0;
1275 struct cmd_ds_802_11_radio_control cmd; 1294 struct cmd_ds_802_11_radio_control cmd;
1295 int ret = -EINVAL;
1276 1296
1277 lbs_deb_enter(LBS_DEB_CMD); 1297 lbs_deb_enter(LBS_DEB_CMD);
1278 1298
1279 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1299 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1280 cmd.action = cpu_to_le16(CMD_ACT_SET); 1300 cmd.action = cpu_to_le16(CMD_ACT_SET);
1281 1301
1282 switch (priv->preamble) { 1302 /* Only v8 and below support setting the preamble */
1283 case CMD_TYPE_SHORT_PREAMBLE: 1303 if (priv->fwrelease < 0x09000000) {
1284 cmd.control = cpu_to_le16(SET_SHORT_PREAMBLE); 1304 switch (preamble) {
1285 break; 1305 case RADIO_PREAMBLE_SHORT:
1286 1306 if (!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
1287 case CMD_TYPE_LONG_PREAMBLE: 1307 goto out;
1288 cmd.control = cpu_to_le16(SET_LONG_PREAMBLE); 1308 /* Fall through */
1289 break; 1309 case RADIO_PREAMBLE_AUTO:
1310 case RADIO_PREAMBLE_LONG:
1311 cmd.control = cpu_to_le16(preamble);
1312 break;
1313 default:
1314 goto out;
1315 }
1316 }
1290 1317
1291 case CMD_TYPE_AUTO_PREAMBLE: 1318 if (radio_on)
1292 default: 1319 cmd.control |= cpu_to_le16(0x1);
1293 cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE); 1320 else {
1294 break; 1321 cmd.control &= cpu_to_le16(~0x1);
1322 priv->txpower_cur = 0;
1295 } 1323 }
1296 1324
1297 if (priv->radioon) 1325 lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
1298 cmd.control |= cpu_to_le16(TURN_ON_RF); 1326 radio_on ? "ON" : "OFF", preamble);
1299 else
1300 cmd.control &= cpu_to_le16(~TURN_ON_RF);
1301 1327
1302 lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon, 1328 priv->radio_on = radio_on;
1303 priv->preamble);
1304 1329
1305 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); 1330 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
1306 1331
1332out:
1307 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 1333 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
1308 return ret; 1334 return ret;
1309} 1335}
@@ -1393,14 +1419,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1393 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf); 1419 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
1394 break; 1420 break;
1395 1421
1396 case CMD_802_11_DEAUTHENTICATE:
1397 ret = lbs_cmd_80211_deauthenticate(priv, cmdptr);
1398 break;
1399
1400 case CMD_802_11_AD_HOC_START:
1401 ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
1402 break;
1403
1404 case CMD_802_11_RESET: 1422 case CMD_802_11_RESET:
1405 ret = lbs_cmd_802_11_reset(cmdptr, cmd_action); 1423 ret = lbs_cmd_802_11_reset(cmdptr, cmd_action);
1406 break; 1424 break;
@@ -1420,28 +1438,15 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1420 ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf); 1438 ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf);
1421 break; 1439 break;
1422 1440
1423 case CMD_802_11_RF_TX_POWER:
1424 ret = lbs_cmd_802_11_rf_tx_power(cmdptr,
1425 cmd_action, pdata_buf);
1426 break;
1427
1428 case CMD_802_11_MONITOR_MODE: 1441 case CMD_802_11_MONITOR_MODE:
1429 ret = lbs_cmd_802_11_monitor_mode(cmdptr, 1442 ret = lbs_cmd_802_11_monitor_mode(cmdptr,
1430 cmd_action, pdata_buf); 1443 cmd_action, pdata_buf);
1431 break; 1444 break;
1432 1445
1433 case CMD_802_11_AD_HOC_JOIN:
1434 ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
1435 break;
1436
1437 case CMD_802_11_RSSI: 1446 case CMD_802_11_RSSI:
1438 ret = lbs_cmd_802_11_rssi(priv, cmdptr); 1447 ret = lbs_cmd_802_11_rssi(priv, cmdptr);
1439 break; 1448 break;
1440 1449
1441 case CMD_802_11_AD_HOC_STOP:
1442 ret = lbs_cmd_80211_ad_hoc_stop(cmdptr);
1443 break;
1444
1445 case CMD_802_11_SET_AFC: 1450 case CMD_802_11_SET_AFC:
1446 case CMD_802_11_GET_AFC: 1451 case CMD_802_11_GET_AFC:
1447 1452
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index a53b51f8bdb4..11ac996e895e 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -61,4 +61,10 @@ int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
61int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, 61int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
62 struct assoc_request *assoc); 62 struct assoc_request *assoc);
63 63
64int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
65 s16 *maxlevel);
66int lbs_set_tx_power(struct lbs_private *priv, s16 dbm);
67
68int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
69
64#endif /* _LBS_CMD_H */ 70#endif /* _LBS_CMD_H */
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 24de3c3cf877..0371c83f5661 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -188,21 +188,6 @@ static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv,
188 return 0; 188 return 0;
189} 189}
190 190
191static int lbs_ret_802_11_rf_tx_power(struct lbs_private *priv,
192 struct cmd_ds_command *resp)
193{
194 struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;
195
196 lbs_deb_enter(LBS_DEB_CMD);
197
198 priv->txpowerlevel = le16_to_cpu(rtp->currentlevel);
199
200 lbs_deb_cmd("TX power currently %d\n", priv->txpowerlevel);
201
202 lbs_deb_leave(LBS_DEB_CMD);
203 return 0;
204}
205
206static int lbs_ret_802_11_rssi(struct lbs_private *priv, 191static int lbs_ret_802_11_rssi(struct lbs_private *priv,
207 struct cmd_ds_command *resp) 192 struct cmd_ds_command *resp)
208{ 193{
@@ -273,24 +258,10 @@ static inline int handle_cmd_response(struct lbs_private *priv,
273 ret = lbs_ret_80211_associate(priv, resp); 258 ret = lbs_ret_80211_associate(priv, resp);
274 break; 259 break;
275 260
276 case CMD_RET(CMD_802_11_DISASSOCIATE):
277 case CMD_RET(CMD_802_11_DEAUTHENTICATE):
278 ret = lbs_ret_80211_disassociate(priv);
279 break;
280
281 case CMD_RET(CMD_802_11_AD_HOC_START):
282 case CMD_RET(CMD_802_11_AD_HOC_JOIN):
283 ret = lbs_ret_80211_ad_hoc_start(priv, resp);
284 break;
285
286 case CMD_RET(CMD_802_11_SNMP_MIB): 261 case CMD_RET(CMD_802_11_SNMP_MIB):
287 ret = lbs_ret_802_11_snmp_mib(priv, resp); 262 ret = lbs_ret_802_11_snmp_mib(priv, resp);
288 break; 263 break;
289 264
290 case CMD_RET(CMD_802_11_RF_TX_POWER):
291 ret = lbs_ret_802_11_rf_tx_power(priv, resp);
292 break;
293
294 case CMD_RET(CMD_802_11_SET_AFC): 265 case CMD_RET(CMD_802_11_SET_AFC):
295 case CMD_RET(CMD_802_11_GET_AFC): 266 case CMD_RET(CMD_802_11_GET_AFC):
296 spin_lock_irqsave(&priv->driver_lock, flags); 267 spin_lock_irqsave(&priv->driver_lock, flags);
@@ -309,10 +280,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
309 ret = lbs_ret_802_11_rssi(priv, resp); 280 ret = lbs_ret_802_11_rssi(priv, resp);
310 break; 281 break;
311 282
312 case CMD_RET(CMD_802_11_AD_HOC_STOP):
313 ret = lbs_ret_80211_ad_hoc_stop(priv);
314 break;
315
316 case CMD_RET(CMD_802_11D_DOMAIN_INFO): 283 case CMD_RET(CMD_802_11D_DOMAIN_INFO):
317 ret = lbs_ret_802_11d_domain_info(resp); 284 ret = lbs_ret_802_11d_domain_info(resp);
318 break; 285 break;
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index a8ac974dacac..1a8888cceadc 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -34,7 +34,6 @@ int lbs_process_event(struct lbs_private *priv, u32 event);
34void lbs_queue_event(struct lbs_private *priv, u32 event); 34void lbs_queue_event(struct lbs_private *priv, u32 event);
35void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx); 35void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);
36 36
37int lbs_set_radio_control(struct lbs_private *priv);
38u32 lbs_fw_index_to_data_rate(u8 index); 37u32 lbs_fw_index_to_data_rate(u8 index);
39u8 lbs_data_rate_to_fw_index(u32 rate); 38u8 lbs_data_rate_to_fw_index(u32 rate);
40 39
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index f5bb40c54d85..fd59e1816460 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -253,7 +253,9 @@ struct lbs_private {
253 u32 connect_status; 253 u32 connect_status;
254 u32 mesh_connect_status; 254 u32 mesh_connect_status;
255 u16 regioncode; 255 u16 regioncode;
256 u16 txpowerlevel; 256 s16 txpower_cur;
257 s16 txpower_min;
258 s16 txpower_max;
257 259
258 /** POWER MANAGEMENT AND PnP SUPPORT */ 260 /** POWER MANAGEMENT AND PnP SUPPORT */
259 u8 surpriseremoved; 261 u8 surpriseremoved;
@@ -291,8 +293,7 @@ struct lbs_private {
291 u16 nextSNRNF; 293 u16 nextSNRNF;
292 u16 numSNRNF; 294 u16 numSNRNF;
293 295
294 u8 radioon; 296 u8 radio_on;
295 u32 preamble;
296 297
297 /** data rate stuff */ 298 /** data rate stuff */
298 u8 cur_rate; 299 u8 cur_rate;
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index c92e41b4faf4..da618fc997ce 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -61,7 +61,6 @@
61#define CMD_RF_REG_MAP 0x0023 61#define CMD_RF_REG_MAP 0x0023
62#define CMD_802_11_DEAUTHENTICATE 0x0024 62#define CMD_802_11_DEAUTHENTICATE 0x0024
63#define CMD_802_11_REASSOCIATE 0x0025 63#define CMD_802_11_REASSOCIATE 0x0025
64#define CMD_802_11_DISASSOCIATE 0x0026
65#define CMD_MAC_CONTROL 0x0028 64#define CMD_MAC_CONTROL 0x0028
66#define CMD_802_11_AD_HOC_START 0x002b 65#define CMD_802_11_AD_HOC_START 0x002b
67#define CMD_802_11_AD_HOC_JOIN 0x002c 66#define CMD_802_11_AD_HOC_JOIN 0x002c
@@ -153,11 +152,6 @@
153#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100 152#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100
154#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400 153#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400
155 154
156/* Define action or option for CMD_802_11_RADIO_CONTROL */
157#define CMD_TYPE_AUTO_PREAMBLE 0x0001
158#define CMD_TYPE_SHORT_PREAMBLE 0x0002
159#define CMD_TYPE_LONG_PREAMBLE 0x0003
160
161/* Event flags for CMD_802_11_SUBSCRIBE_EVENT */ 155/* Event flags for CMD_802_11_SUBSCRIBE_EVENT */
162#define CMD_SUBSCRIBE_RSSI_LOW 0x0001 156#define CMD_SUBSCRIBE_RSSI_LOW 0x0001
163#define CMD_SUBSCRIBE_SNR_LOW 0x0002 157#define CMD_SUBSCRIBE_SNR_LOW 0x0002
@@ -166,28 +160,14 @@
166#define CMD_SUBSCRIBE_RSSI_HIGH 0x0010 160#define CMD_SUBSCRIBE_RSSI_HIGH 0x0010
167#define CMD_SUBSCRIBE_SNR_HIGH 0x0020 161#define CMD_SUBSCRIBE_SNR_HIGH 0x0020
168 162
169#define TURN_ON_RF 0x01 163#define RADIO_PREAMBLE_LONG 0x00
170#define RADIO_ON 0x01 164#define RADIO_PREAMBLE_SHORT 0x02
171#define RADIO_OFF 0x00 165#define RADIO_PREAMBLE_AUTO 0x04
172
173#define SET_AUTO_PREAMBLE 0x05
174#define SET_SHORT_PREAMBLE 0x03
175#define SET_LONG_PREAMBLE 0x01
176 166
177/* Define action or option for CMD_802_11_RF_CHANNEL */ 167/* Define action or option for CMD_802_11_RF_CHANNEL */
178#define CMD_OPT_802_11_RF_CHANNEL_GET 0x00 168#define CMD_OPT_802_11_RF_CHANNEL_GET 0x00
179#define CMD_OPT_802_11_RF_CHANNEL_SET 0x01 169#define CMD_OPT_802_11_RF_CHANNEL_SET 0x01
180 170
181/* Define action or option for CMD_802_11_RF_TX_POWER */
182#define CMD_ACT_TX_POWER_OPT_GET 0x0000
183#define CMD_ACT_TX_POWER_OPT_SET_HIGH 0x8007
184#define CMD_ACT_TX_POWER_OPT_SET_MID 0x8004
185#define CMD_ACT_TX_POWER_OPT_SET_LOW 0x8000
186
187#define CMD_ACT_TX_POWER_INDEX_HIGH 0x0007
188#define CMD_ACT_TX_POWER_INDEX_MID 0x0004
189#define CMD_ACT_TX_POWER_INDEX_LOW 0x0000
190
191/* Define action or option for CMD_802_11_DATA_RATE */ 171/* Define action or option for CMD_802_11_DATA_RATE */
192#define CMD_ACT_SET_TX_AUTO 0x0000 172#define CMD_ACT_SET_TX_AUTO 0x0000
193#define CMD_ACT_SET_TX_FIX_RATE 0x0001 173#define CMD_ACT_SET_TX_FIX_RATE 0x0001
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index 913b480211a9..d27c276b2191 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -232,7 +232,9 @@ struct cmd_ds_802_11_authenticate {
232}; 232};
233 233
234struct cmd_ds_802_11_deauthenticate { 234struct cmd_ds_802_11_deauthenticate {
235 u8 macaddr[6]; 235 struct cmd_header hdr;
236
237 u8 macaddr[ETH_ALEN];
236 __le16 reasoncode; 238 __le16 reasoncode;
237}; 239};
238 240
@@ -251,20 +253,10 @@ struct cmd_ds_802_11_associate {
251#endif 253#endif
252} __attribute__ ((packed)); 254} __attribute__ ((packed));
253 255
254struct cmd_ds_802_11_disassociate {
255 u8 destmacaddr[6];
256 __le16 reasoncode;
257};
258
259struct cmd_ds_802_11_associate_rsp { 256struct cmd_ds_802_11_associate_rsp {
260 struct ieeetypes_assocrsp assocRsp; 257 struct ieeetypes_assocrsp assocRsp;
261}; 258};
262 259
263struct cmd_ds_802_11_ad_hoc_result {
264 u8 pad[3];
265 u8 bssid[ETH_ALEN];
266};
267
268struct cmd_ds_802_11_set_wep { 260struct cmd_ds_802_11_set_wep {
269 struct cmd_header hdr; 261 struct cmd_header hdr;
270 262
@@ -435,8 +427,12 @@ struct cmd_ds_802_11_mac_address {
435}; 427};
436 428
437struct cmd_ds_802_11_rf_tx_power { 429struct cmd_ds_802_11_rf_tx_power {
430 struct cmd_header hdr;
431
438 __le16 action; 432 __le16 action;
439 __le16 currentlevel; 433 __le16 curlevel;
434 s8 maxlevel;
435 s8 minlevel;
440}; 436};
441 437
442struct cmd_ds_802_11_rf_antenna { 438struct cmd_ds_802_11_rf_antenna {
@@ -507,10 +503,12 @@ struct cmd_ds_802_11_rate_adapt_rateset {
507}; 503};
508 504
509struct cmd_ds_802_11_ad_hoc_start { 505struct cmd_ds_802_11_ad_hoc_start {
506 struct cmd_header hdr;
507
510 u8 ssid[IW_ESSID_MAX_SIZE]; 508 u8 ssid[IW_ESSID_MAX_SIZE];
511 u8 bsstype; 509 u8 bsstype;
512 __le16 beaconperiod; 510 __le16 beaconperiod;
513 u8 dtimperiod; 511 u8 dtimperiod; /* Reserved on v9 and later */
514 union IEEEtypes_ssparamset ssparamset; 512 union IEEEtypes_ssparamset ssparamset;
515 union ieeetypes_phyparamset phyparamset; 513 union ieeetypes_phyparamset phyparamset;
516 __le16 probedelay; 514 __le16 probedelay;
@@ -519,9 +517,16 @@ struct cmd_ds_802_11_ad_hoc_start {
519 u8 tlv_memory_size_pad[100]; 517 u8 tlv_memory_size_pad[100];
520} __attribute__ ((packed)); 518} __attribute__ ((packed));
521 519
520struct cmd_ds_802_11_ad_hoc_result {
521 struct cmd_header hdr;
522
523 u8 pad[3];
524 u8 bssid[ETH_ALEN];
525};
526
522struct adhoc_bssdesc { 527struct adhoc_bssdesc {
523 u8 bssid[6]; 528 u8 bssid[ETH_ALEN];
524 u8 ssid[32]; 529 u8 ssid[IW_ESSID_MAX_SIZE];
525 u8 type; 530 u8 type;
526 __le16 beaconperiod; 531 __le16 beaconperiod;
527 u8 dtimperiod; 532 u8 dtimperiod;
@@ -539,10 +544,15 @@ struct adhoc_bssdesc {
539} __attribute__ ((packed)); 544} __attribute__ ((packed));
540 545
541struct cmd_ds_802_11_ad_hoc_join { 546struct cmd_ds_802_11_ad_hoc_join {
547 struct cmd_header hdr;
548
542 struct adhoc_bssdesc bss; 549 struct adhoc_bssdesc bss;
543 __le16 failtimeout; 550 __le16 failtimeout; /* Reserved on v9 and later */
544 __le16 probedelay; 551 __le16 probedelay; /* Reserved on v9 and later */
552} __attribute__ ((packed));
545 553
554struct cmd_ds_802_11_ad_hoc_stop {
555 struct cmd_header hdr;
546} __attribute__ ((packed)); 556} __attribute__ ((packed));
547 557
548struct cmd_ds_802_11_enable_rsn { 558struct cmd_ds_802_11_enable_rsn {
@@ -693,21 +703,15 @@ struct cmd_ds_command {
693 union { 703 union {
694 struct cmd_ds_802_11_ps_mode psmode; 704 struct cmd_ds_802_11_ps_mode psmode;
695 struct cmd_ds_802_11_associate associate; 705 struct cmd_ds_802_11_associate associate;
696 struct cmd_ds_802_11_deauthenticate deauth;
697 struct cmd_ds_802_11_ad_hoc_start ads;
698 struct cmd_ds_802_11_reset reset; 706 struct cmd_ds_802_11_reset reset;
699 struct cmd_ds_802_11_ad_hoc_result result;
700 struct cmd_ds_802_11_authenticate auth; 707 struct cmd_ds_802_11_authenticate auth;
701 struct cmd_ds_802_11_get_stat gstat; 708 struct cmd_ds_802_11_get_stat gstat;
702 struct cmd_ds_802_3_get_stat gstat_8023; 709 struct cmd_ds_802_3_get_stat gstat_8023;
703 struct cmd_ds_802_11_snmp_mib smib; 710 struct cmd_ds_802_11_snmp_mib smib;
704 struct cmd_ds_802_11_rf_tx_power txp;
705 struct cmd_ds_802_11_rf_antenna rant; 711 struct cmd_ds_802_11_rf_antenna rant;
706 struct cmd_ds_802_11_monitor_mode monitor; 712 struct cmd_ds_802_11_monitor_mode monitor;
707 struct cmd_ds_802_11_ad_hoc_join adj;
708 struct cmd_ds_802_11_rssi rssi; 713 struct cmd_ds_802_11_rssi rssi;
709 struct cmd_ds_802_11_rssi_rsp rssirsp; 714 struct cmd_ds_802_11_rssi_rsp rssirsp;
710 struct cmd_ds_802_11_disassociate dassociate;
711 struct cmd_ds_mac_reg_access macreg; 715 struct cmd_ds_mac_reg_access macreg;
712 struct cmd_ds_bbp_reg_access bbpreg; 716 struct cmd_ds_bbp_reg_access bbpreg;
713 struct cmd_ds_rf_reg_access rfreg; 717 struct cmd_ds_rf_reg_access rfreg;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index bd32ac0b4e07..2436634b6b7e 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -291,9 +291,11 @@ static ssize_t lbs_rtap_set(struct device *dev,
291 if (priv->infra_open || priv->mesh_open) 291 if (priv->infra_open || priv->mesh_open)
292 return -EBUSY; 292 return -EBUSY;
293 if (priv->mode == IW_MODE_INFRA) 293 if (priv->mode == IW_MODE_INFRA)
294 lbs_send_deauthentication(priv); 294 lbs_cmd_80211_deauthenticate(priv,
295 priv->curbssparams.bssid,
296 WLAN_REASON_DEAUTH_LEAVING);
295 else if (priv->mode == IW_MODE_ADHOC) 297 else if (priv->mode == IW_MODE_ADHOC)
296 lbs_stop_adhoc_network(priv); 298 lbs_adhoc_stop(priv);
297 lbs_add_rtap(priv); 299 lbs_add_rtap(priv);
298 } 300 }
299 priv->monitormode = monitor_mode; 301 priv->monitormode = monitor_mode;
@@ -956,17 +958,24 @@ EXPORT_SYMBOL_GPL(lbs_resume);
956static int lbs_setup_firmware(struct lbs_private *priv) 958static int lbs_setup_firmware(struct lbs_private *priv)
957{ 959{
958 int ret = -1; 960 int ret = -1;
961 s16 curlevel = 0, minlevel = 0, maxlevel = 0;
959 962
960 lbs_deb_enter(LBS_DEB_FW); 963 lbs_deb_enter(LBS_DEB_FW);
961 964
962 /* 965 /* Read MAC address from firmware */
963 * Read MAC address from HW
964 */
965 memset(priv->current_addr, 0xff, ETH_ALEN); 966 memset(priv->current_addr, 0xff, ETH_ALEN);
966 ret = lbs_update_hw_spec(priv); 967 ret = lbs_update_hw_spec(priv);
967 if (ret) 968 if (ret)
968 goto done; 969 goto done;
969 970
971 /* Read power levels if available */
972 ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
973 if (ret == 0) {
974 priv->txpower_cur = curlevel;
975 priv->txpower_min = minlevel;
976 priv->txpower_max = maxlevel;
977 }
978
970 lbs_set_mac_control(priv); 979 lbs_set_mac_control(priv);
971done: 980done:
972 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); 981 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
@@ -1042,7 +1051,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
1042 priv->mode = IW_MODE_INFRA; 1051 priv->mode = IW_MODE_INFRA;
1043 priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; 1052 priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
1044 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 1053 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
1045 priv->radioon = RADIO_ON; 1054 priv->radio_on = 1;
1046 priv->enablehwauto = 1; 1055 priv->enablehwauto = 1;
1047 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; 1056 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
1048 priv->psmode = LBS802_11POWERMODECAM; 1057 priv->psmode = LBS802_11POWERMODECAM;
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 4b274562f965..8f66903641b9 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -944,6 +944,11 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
944 944
945 lbs_deb_enter(LBS_DEB_WEXT); 945 lbs_deb_enter(LBS_DEB_WEXT);
946 946
947 if (!priv->radio_on) {
948 ret = -EINVAL;
949 goto out;
950 }
951
947 if (!netif_running(dev)) { 952 if (!netif_running(dev)) {
948 ret = -ENETDOWN; 953 ret = -ENETDOWN;
949 goto out; 954 goto out;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 8b3ed77860b3..426f1fe3bb42 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -120,34 +120,6 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(
120 return cfp; 120 return cfp;
121} 121}
122 122
123
124/**
125 * @brief Set Radio On/OFF
126 *
127 * @param priv A pointer to struct lbs_private structure
128 * @option Radio Option
129 * @return 0 --success, otherwise fail
130 */
131static int lbs_radio_ioctl(struct lbs_private *priv, u8 option)
132{
133 int ret = 0;
134
135 lbs_deb_enter(LBS_DEB_WEXT);
136
137 if (priv->radioon != option) {
138 lbs_deb_wext("switching radio %s\n", option ? "on" : "off");
139 priv->radioon = option;
140
141 ret = lbs_prepare_and_send_command(priv,
142 CMD_802_11_RADIO_CONTROL,
143 CMD_ACT_SET,
144 CMD_OPTION_WAITFORRSP, 0, NULL);
145 }
146
147 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
148 return ret;
149}
150
151/** 123/**
152 * @brief Copy active data rates based on adapter mode and status 124 * @brief Copy active data rates based on adapter mode and status
153 * 125 *
@@ -420,28 +392,30 @@ static int lbs_get_txpow(struct net_device *dev,
420 struct iw_request_info *info, 392 struct iw_request_info *info,
421 struct iw_param *vwrq, char *extra) 393 struct iw_param *vwrq, char *extra)
422{ 394{
423 int ret = 0;
424 struct lbs_private *priv = dev->priv; 395 struct lbs_private *priv = dev->priv;
396 s16 curlevel = 0;
397 int ret = 0;
425 398
426 lbs_deb_enter(LBS_DEB_WEXT); 399 lbs_deb_enter(LBS_DEB_WEXT);
427 400
428 ret = lbs_prepare_and_send_command(priv, 401 if (!priv->radio_on) {
429 CMD_802_11_RF_TX_POWER, 402 lbs_deb_wext("tx power off\n");
430 CMD_ACT_TX_POWER_OPT_GET, 403 vwrq->value = 0;
431 CMD_OPTION_WAITFORRSP, 0, NULL); 404 vwrq->disabled = 1;
405 goto out;
406 }
432 407
408 ret = lbs_get_tx_power(priv, &curlevel, NULL, NULL);
433 if (ret) 409 if (ret)
434 goto out; 410 goto out;
435 411
436 lbs_deb_wext("tx power level %d dbm\n", priv->txpowerlevel); 412 lbs_deb_wext("tx power level %d dbm\n", curlevel);
437 vwrq->value = priv->txpowerlevel; 413 priv->txpower_cur = curlevel;
414
415 vwrq->value = curlevel;
438 vwrq->fixed = 1; 416 vwrq->fixed = 1;
439 if (priv->radioon) { 417 vwrq->disabled = 0;
440 vwrq->disabled = 0; 418 vwrq->flags = IW_TXPOW_DBM;
441 vwrq->flags = IW_TXPOW_DBM;
442 } else {
443 vwrq->disabled = 1;
444 }
445 419
446out: 420out:
447 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 421 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
@@ -693,22 +667,12 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
693 667
694 range->sensitivity = 0; 668 range->sensitivity = 0;
695 669
696 /* 670 /* Setup the supported power level ranges */
697 * Setup the supported power level ranges
698 */
699 memset(range->txpower, 0, sizeof(range->txpower)); 671 memset(range->txpower, 0, sizeof(range->txpower));
700 range->txpower[0] = 5; 672 range->txpower_capa = IW_TXPOW_DBM | IW_TXPOW_RANGE;
701 range->txpower[1] = 7; 673 range->txpower[0] = priv->txpower_min;
702 range->txpower[2] = 9; 674 range->txpower[1] = priv->txpower_max;
703 range->txpower[3] = 11; 675 range->num_txpower = 2;
704 range->txpower[4] = 13;
705 range->txpower[5] = 15;
706 range->txpower[6] = 17;
707 range->txpower[7] = 19;
708
709 range->num_txpower = 8;
710 range->txpower_capa = IW_TXPOW_DBM;
711 range->txpower_capa |= IW_TXPOW_RANGE;
712 676
713 range->event_capa[0] = (IW_EVENT_CAPA_K_0 | 677 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
714 IW_EVENT_CAPA_MASK(SIOCGIWAP) | 678 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
@@ -998,9 +962,11 @@ static int lbs_mesh_set_freq(struct net_device *dev,
998 if (fwrq->m != priv->curbssparams.channel) { 962 if (fwrq->m != priv->curbssparams.channel) {
999 lbs_deb_wext("mesh channel change forces eth disconnect\n"); 963 lbs_deb_wext("mesh channel change forces eth disconnect\n");
1000 if (priv->mode == IW_MODE_INFRA) 964 if (priv->mode == IW_MODE_INFRA)
1001 lbs_send_deauthentication(priv); 965 lbs_cmd_80211_deauthenticate(priv,
966 priv->curbssparams.bssid,
967 WLAN_REASON_DEAUTH_LEAVING);
1002 else if (priv->mode == IW_MODE_ADHOC) 968 else if (priv->mode == IW_MODE_ADHOC)
1003 lbs_stop_adhoc_network(priv); 969 lbs_adhoc_stop(priv);
1004 } 970 }
1005 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m); 971 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m);
1006 lbs_update_channel(priv); 972 lbs_update_channel(priv);
@@ -1844,39 +1810,50 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
1844{ 1810{
1845 int ret = 0; 1811 int ret = 0;
1846 struct lbs_private *priv = dev->priv; 1812 struct lbs_private *priv = dev->priv;
1847 1813 s16 dbm = (s16) vwrq->value;
1848 u16 dbm;
1849 1814
1850 lbs_deb_enter(LBS_DEB_WEXT); 1815 lbs_deb_enter(LBS_DEB_WEXT);
1851 1816
1852 if (vwrq->disabled) { 1817 if (vwrq->disabled) {
1853 lbs_radio_ioctl(priv, RADIO_OFF); 1818 lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 0);
1854 return 0; 1819 goto out;
1855 } 1820 }
1856 1821
1857 priv->preamble = CMD_TYPE_AUTO_PREAMBLE; 1822 if (vwrq->fixed == 0) {
1858 1823 /* Auto power control */
1859 lbs_radio_ioctl(priv, RADIO_ON); 1824 dbm = priv->txpower_max;
1825 } else {
1826 /* Userspace check in iwrange if it should use dBm or mW,
1827 * therefore this should never happen... Jean II */
1828 if ((vwrq->flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) {
1829 ret = -EOPNOTSUPP;
1830 goto out;
1831 }
1860 1832
1861 /* Userspace check in iwrange if it should use dBm or mW, 1833 /* Validate requested power level against firmware allowed levels */
1862 * therefore this should never happen... Jean II */ 1834 if (priv->txpower_min && (dbm < priv->txpower_min)) {
1863 if ((vwrq->flags & IW_TXPOW_TYPE) == IW_TXPOW_MWATT) { 1835 ret = -EINVAL;
1864 return -EOPNOTSUPP; 1836 goto out;
1865 } else 1837 }
1866 dbm = (u16) vwrq->value;
1867 1838
1868 /* auto tx power control */ 1839 if (priv->txpower_max && (dbm > priv->txpower_max)) {
1840 ret = -EINVAL;
1841 goto out;
1842 }
1843 }
1869 1844
1870 if (vwrq->fixed == 0) 1845 /* If the radio was off, turn it on */
1871 dbm = 0xffff; 1846 if (!priv->radio_on) {
1847 ret = lbs_set_radio(priv, RADIO_PREAMBLE_AUTO, 1);
1848 if (ret)
1849 goto out;
1850 }
1872 1851
1873 lbs_deb_wext("txpower set %d dbm\n", dbm); 1852 lbs_deb_wext("txpower set %d dBm\n", dbm);
1874 1853
1875 ret = lbs_prepare_and_send_command(priv, 1854 ret = lbs_set_tx_power(priv, dbm);
1876 CMD_802_11_RF_TX_POWER,
1877 CMD_ACT_TX_POWER_OPT_SET_LOW,
1878 CMD_OPTION_WAITFORRSP, 0, (void *)&dbm);
1879 1855
1856out:
1880 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1857 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1881 return ret; 1858 return ret;
1882} 1859}
@@ -1928,6 +1905,11 @@ static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
1928 1905
1929 lbs_deb_enter(LBS_DEB_WEXT); 1906 lbs_deb_enter(LBS_DEB_WEXT);
1930 1907
1908 if (!priv->radio_on) {
1909 ret = -EINVAL;
1910 goto out;
1911 }
1912
1931 /* Check the size of the string */ 1913 /* Check the size of the string */
1932 if (in_ssid_len > IW_ESSID_MAX_SIZE) { 1914 if (in_ssid_len > IW_ESSID_MAX_SIZE) {
1933 ret = -E2BIG; 1915 ret = -E2BIG;
@@ -2005,6 +1987,11 @@ static int lbs_mesh_set_essid(struct net_device *dev,
2005 1987
2006 lbs_deb_enter(LBS_DEB_WEXT); 1988 lbs_deb_enter(LBS_DEB_WEXT);
2007 1989
1990 if (!priv->radio_on) {
1991 ret = -EINVAL;
1992 goto out;
1993 }
1994
2008 /* Check the size of the string */ 1995 /* Check the size of the string */
2009 if (dwrq->length > IW_ESSID_MAX_SIZE) { 1996 if (dwrq->length > IW_ESSID_MAX_SIZE) {
2010 ret = -E2BIG; 1997 ret = -E2BIG;
@@ -2046,6 +2033,9 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
2046 2033
2047 lbs_deb_enter(LBS_DEB_WEXT); 2034 lbs_deb_enter(LBS_DEB_WEXT);
2048 2035
2036 if (!priv->radio_on)
2037 return -EINVAL;
2038
2049 if (awrq->sa_family != ARPHRD_ETHER) 2039 if (awrq->sa_family != ARPHRD_ETHER)
2050 return -EINVAL; 2040 return -EINVAL;
2051 2041
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 2c1d680d2c55..c948021bff6a 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -477,9 +477,9 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
477{ 477{
478 struct ieee80211_rx_status stats; 478 struct ieee80211_rx_status stats;
479 struct rxpd *prxpd; 479 struct rxpd *prxpd;
480 bool is_qos, is_4addr, is_amsdu, need_padding; 480 int need_padding;
481 unsigned int flags; 481 unsigned int flags;
482 u16 fc, fc_le; 482 struct ieee80211_hdr *hdr;
483 483
484 prxpd = (struct rxpd *) skb->data; 484 prxpd = (struct rxpd *) skb->data;
485 485
@@ -497,19 +497,15 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
497 stats.rate_idx = prxpd->rx_rate; 497 stats.rate_idx = prxpd->rx_rate;
498 skb_pull(skb, sizeof(struct rxpd)); 498 skb_pull(skb, sizeof(struct rxpd));
499 499
500 fc_le = *((__le16 *) skb->data); 500 hdr = (struct ieee80211_hdr *)skb->data;
501 fc = le16_to_cpu(fc_le);
502 flags = le32_to_cpu(*(__le32 *)(skb->data + 4)); 501 flags = le32_to_cpu(*(__le32 *)(skb->data + 4));
503 502
504 is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && 503 need_padding = ieee80211_is_data_qos(hdr->frame_control);
505 (fc & IEEE80211_STYPE_QOS_DATA); 504 need_padding ^= ieee80211_has_a4(hdr->frame_control);
506 is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 505 need_padding ^= ieee80211_is_data_qos(hdr->frame_control) &&
507 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); 506 (*ieee80211_get_qos_ctl(hdr) &
508 is_amsdu = ((fc & 0x8C) == 0x88) && 507 IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
509 (*(skb->data + ieee80211_hdrlen(fc_le) - QOS_CONTROL_LEN)
510 & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
511 508
512 need_padding = is_qos ^ is_4addr ^ is_amsdu;
513 if (need_padding) { 509 if (need_padding) {
514 memmove(skb->data + 2, skb->data, skb->len); 510 memmove(skb->data + 2, skb->data, skb->len);
515 skb_reserve(skb, 2); 511 skb_reserve(skb, 2);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 248d31a7aa33..732429d49122 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -446,7 +446,8 @@ static int __init init_mac80211_hwsim(void)
446 SET_IEEE80211_PERM_ADDR(hw, addr); 446 SET_IEEE80211_PERM_ADDR(hw, addr);
447 447
448 hw->channel_change_time = 1; 448 hw->channel_change_time = 1;
449 hw->queues = 1; 449 hw->queues = 4;
450 hw->ampdu_queues = 1;
450 451
451 memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); 452 memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
452 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); 453 memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
@@ -454,6 +455,19 @@ static int __init init_mac80211_hwsim(void)
454 data->band.n_channels = ARRAY_SIZE(hwsim_channels); 455 data->band.n_channels = ARRAY_SIZE(hwsim_channels);
455 data->band.bitrates = data->rates; 456 data->band.bitrates = data->rates;
456 data->band.n_bitrates = ARRAY_SIZE(hwsim_rates); 457 data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
458 data->band.ht_info.ht_supported = 1;
459 data->band.ht_info.cap = IEEE80211_HT_CAP_SUP_WIDTH |
460 IEEE80211_HT_CAP_GRN_FLD |
461 IEEE80211_HT_CAP_SGI_40 |
462 IEEE80211_HT_CAP_DSSSCCK40;
463 data->band.ht_info.ampdu_factor = 0x3;
464 data->band.ht_info.ampdu_density = 0x6;
465 memset(data->band.ht_info.supp_mcs_set, 0,
466 sizeof(data->band.ht_info.supp_mcs_set));
467 data->band.ht_info.supp_mcs_set[0] = 0xff;
468 data->band.ht_info.supp_mcs_set[1] = 0xff;
469 data->band.ht_info.supp_mcs_set[12] =
470 IEEE80211_HT_CAP_MCS_TX_DEFINED;
457 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; 471 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
458 472
459 err = ieee80211_register_hw(hw); 473 err = ieee80211_register_hw(hw);
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 10df07de9e52..fca8762fa069 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -66,7 +66,7 @@ struct p54_common {
66 unsigned int tx_hdr_len; 66 unsigned int tx_hdr_len;
67 void *cached_vdcf; 67 void *cached_vdcf;
68 unsigned int fw_var; 68 unsigned int fw_var;
69 struct ieee80211_tx_queue_stats tx_stats[4]; 69 struct ieee80211_tx_queue_stats tx_stats[8];
70}; 70};
71 71
72int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); 72int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 29be3dc8ee09..17e06bbc996a 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -146,23 +146,23 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
146 146
147 if (priv->fw_var >= 0x300) { 147 if (priv->fw_var >= 0x300) {
148 /* Firmware supports QoS, use it! */ 148 /* Firmware supports QoS, use it! */
149 priv->tx_stats[0].limit = 3; 149 priv->tx_stats[4].limit = 3;
150 priv->tx_stats[1].limit = 4; 150 priv->tx_stats[5].limit = 4;
151 priv->tx_stats[2].limit = 3; 151 priv->tx_stats[6].limit = 3;
152 priv->tx_stats[3].limit = 1; 152 priv->tx_stats[7].limit = 1;
153 dev->queues = 4; 153 dev->queues = 4;
154 } 154 }
155} 155}
156EXPORT_SYMBOL_GPL(p54_parse_firmware); 156EXPORT_SYMBOL_GPL(p54_parse_firmware);
157 157
158static int p54_convert_rev0_to_rev1(struct ieee80211_hw *dev, 158static int p54_convert_rev0(struct ieee80211_hw *dev,
159 struct pda_pa_curve_data *curve_data) 159 struct pda_pa_curve_data *curve_data)
160{ 160{
161 struct p54_common *priv = dev->priv; 161 struct p54_common *priv = dev->priv;
162 struct pda_pa_curve_data_sample_rev1 *rev1; 162 struct p54_pa_curve_data_sample *dst;
163 struct pda_pa_curve_data_sample_rev0 *rev0; 163 struct pda_pa_curve_data_sample_rev0 *src;
164 size_t cd_len = sizeof(*curve_data) + 164 size_t cd_len = sizeof(*curve_data) +
165 (curve_data->points_per_channel*sizeof(*rev1) + 2) * 165 (curve_data->points_per_channel*sizeof(*dst) + 2) *
166 curve_data->channels; 166 curve_data->channels;
167 unsigned int i, j; 167 unsigned int i, j;
168 void *source, *target; 168 void *source, *target;
@@ -180,27 +180,63 @@ static int p54_convert_rev0_to_rev1(struct ieee80211_hw *dev,
180 *((__le16 *)target) = *freq; 180 *((__le16 *)target) = *freq;
181 target += sizeof(__le16); 181 target += sizeof(__le16);
182 for (j = 0; j < curve_data->points_per_channel; j++) { 182 for (j = 0; j < curve_data->points_per_channel; j++) {
183 rev1 = target; 183 dst = target;
184 rev0 = source; 184 src = source;
185 185
186 rev1->rf_power = rev0->rf_power; 186 dst->rf_power = src->rf_power;
187 rev1->pa_detector = rev0->pa_detector; 187 dst->pa_detector = src->pa_detector;
188 rev1->data_64qam = rev0->pcv; 188 dst->data_64qam = src->pcv;
189 /* "invent" the points for the other modulations */ 189 /* "invent" the points for the other modulations */
190#define SUB(x,y) (u8)((x) - (y)) > (x) ? 0 : (x) - (y) 190#define SUB(x,y) (u8)((x) - (y)) > (x) ? 0 : (x) - (y)
191 rev1->data_16qam = SUB(rev0->pcv, 12); 191 dst->data_16qam = SUB(src->pcv, 12);
192 rev1->data_qpsk = SUB(rev1->data_16qam, 12); 192 dst->data_qpsk = SUB(dst->data_16qam, 12);
193 rev1->data_bpsk = SUB(rev1->data_qpsk, 12); 193 dst->data_bpsk = SUB(dst->data_qpsk, 12);
194 rev1->data_barker= SUB(rev1->data_bpsk, 14); 194 dst->data_barker = SUB(dst->data_bpsk, 14);
195#undef SUB 195#undef SUB
196 target += sizeof(*rev1); 196 target += sizeof(*dst);
197 source += sizeof(*rev0); 197 source += sizeof(*src);
198 } 198 }
199 } 199 }
200 200
201 return 0; 201 return 0;
202} 202}
203 203
204static int p54_convert_rev1(struct ieee80211_hw *dev,
205 struct pda_pa_curve_data *curve_data)
206{
207 struct p54_common *priv = dev->priv;
208 struct p54_pa_curve_data_sample *dst;
209 struct pda_pa_curve_data_sample_rev1 *src;
210 size_t cd_len = sizeof(*curve_data) +
211 (curve_data->points_per_channel*sizeof(*dst) + 2) *
212 curve_data->channels;
213 unsigned int i, j;
214 void *source, *target;
215
216 priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
217 if (!priv->curve_data)
218 return -ENOMEM;
219
220 memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
221 source = curve_data->data;
222 target = priv->curve_data->data;
223 for (i = 0; i < curve_data->channels; i++) {
224 __le16 *freq = source;
225 source += sizeof(__le16);
226 *((__le16 *)target) = *freq;
227 target += sizeof(__le16);
228 for (j = 0; j < curve_data->points_per_channel; j++) {
229 memcpy(target, source, sizeof(*src));
230
231 target += sizeof(*dst);
232 source += sizeof(*src);
233 }
234 source++;
235 }
236
237 return 0;
238}
239
204int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) 240int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
205{ 241{
206 struct p54_common *priv = dev->priv; 242 struct p54_common *priv = dev->priv;
@@ -250,27 +286,32 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
250 entry->data[1]*sizeof(*priv->output_limit)); 286 entry->data[1]*sizeof(*priv->output_limit));
251 priv->output_limit_len = entry->data[1]; 287 priv->output_limit_len = entry->data[1];
252 break; 288 break;
253 case PDR_PRISM_PA_CAL_CURVE_DATA: 289 case PDR_PRISM_PA_CAL_CURVE_DATA: {
254 if (data_len < sizeof(struct pda_pa_curve_data)) { 290 struct pda_pa_curve_data *curve_data =
291 (struct pda_pa_curve_data *)entry->data;
292 if (data_len < sizeof(*curve_data)) {
255 err = -EINVAL; 293 err = -EINVAL;
256 goto err; 294 goto err;
257 } 295 }
258 296
259 if (((struct pda_pa_curve_data *)entry->data)->cal_method_rev) { 297 switch (curve_data->cal_method_rev) {
260 priv->curve_data = kmalloc(data_len, GFP_KERNEL); 298 case 0:
261 if (!priv->curve_data) { 299 err = p54_convert_rev0(dev, curve_data);
262 err = -ENOMEM; 300 break;
263 goto err; 301 case 1:
264 } 302 err = p54_convert_rev1(dev, curve_data);
265 303 break;
266 memcpy(priv->curve_data, entry->data, data_len); 304 default:
267 } else { 305 printk(KERN_ERR "p54: unknown curve data "
268 err = p54_convert_rev0_to_rev1(dev, (struct pda_pa_curve_data *)entry->data); 306 "revision %d\n",
269 if (err) 307 curve_data->cal_method_rev);
270 goto err; 308 err = -ENODEV;
309 break;
271 } 310 }
311 if (err)
312 goto err;
272 313
273 break; 314 }
274 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION: 315 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
275 priv->iq_autocal = kmalloc(data_len, GFP_KERNEL); 316 priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
276 if (!priv->iq_autocal) { 317 if (!priv->iq_autocal) {
@@ -377,7 +418,7 @@ static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
377 int i; 418 int i;
378 419
379 for (i = 0; i < dev->queues; i++) 420 for (i = 0; i < dev->queues; i++)
380 if (priv->tx_stats[i].len < priv->tx_stats[i].limit) 421 if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit)
381 ieee80211_wake_queue(dev, i); 422 ieee80211_wake_queue(dev, i);
382} 423}
383 424
@@ -391,7 +432,9 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
391 struct memrecord *range = NULL; 432 struct memrecord *range = NULL;
392 u32 freed = 0; 433 u32 freed = 0;
393 u32 last_addr = priv->rx_start; 434 u32 last_addr = priv->rx_start;
435 unsigned long flags;
394 436
437 spin_lock_irqsave(&priv->tx_queue.lock, flags);
395 while (entry != (struct sk_buff *)&priv->tx_queue) { 438 while (entry != (struct sk_buff *)&priv->tx_queue) {
396 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); 439 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
397 range = (void *)info->driver_data; 440 range = (void *)info->driver_data;
@@ -412,13 +455,15 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
412 455
413 last_addr = range->end_addr; 456 last_addr = range->end_addr;
414 __skb_unlink(entry, &priv->tx_queue); 457 __skb_unlink(entry, &priv->tx_queue);
458 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
459
415 memset(&info->status, 0, sizeof(info->status)); 460 memset(&info->status, 0, sizeof(info->status));
416 entry_hdr = (struct p54_control_hdr *) entry->data; 461 entry_hdr = (struct p54_control_hdr *) entry->data;
417 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; 462 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
418 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) 463 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
419 pad = entry_data->align[0]; 464 pad = entry_data->align[0];
420 465
421 priv->tx_stats[entry_data->hw_queue - 4].len--; 466 priv->tx_stats[entry_data->hw_queue].len--;
422 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { 467 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
423 if (!(payload->status & 0x01)) 468 if (!(payload->status & 0x01))
424 info->flags |= IEEE80211_TX_STAT_ACK; 469 info->flags |= IEEE80211_TX_STAT_ACK;
@@ -429,12 +474,14 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
429 info->status.ack_signal = le16_to_cpu(payload->ack_rssi); 474 info->status.ack_signal = le16_to_cpu(payload->ack_rssi);
430 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); 475 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
431 ieee80211_tx_status_irqsafe(dev, entry); 476 ieee80211_tx_status_irqsafe(dev, entry);
432 break; 477 goto out;
433 } else 478 } else
434 last_addr = range->end_addr; 479 last_addr = range->end_addr;
435 entry = entry->next; 480 entry = entry->next;
436 } 481 }
482 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
437 483
484out:
438 if (freed >= IEEE80211_MAX_RTS_THRESHOLD + 0x170 + 485 if (freed >= IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
439 sizeof(struct p54_control_hdr)) 486 sizeof(struct p54_control_hdr))
440 p54_wake_free_queues(dev); 487 p54_wake_free_queues(dev);
@@ -559,7 +606,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
559 u8 rate; 606 u8 rate;
560 u8 cts_rate = 0x20; 607 u8 cts_rate = 0x20;
561 608
562 current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)]; 609 current_queue = &priv->tx_stats[skb_get_queue_mapping(skb) + 4];
563 if (unlikely(current_queue->len > current_queue->limit)) 610 if (unlikely(current_queue->len > current_queue->limit))
564 return NETDEV_TX_BUSY; 611 return NETDEV_TX_BUSY;
565 current_queue->len++; 612 current_queue->len++;
@@ -672,12 +719,9 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
672 struct p54_control_hdr *hdr; 719 struct p54_control_hdr *hdr;
673 struct p54_tx_control_channel *chan; 720 struct p54_tx_control_channel *chan;
674 unsigned int i; 721 unsigned int i;
675 size_t payload_len = sizeof(*chan) + sizeof(u32)*2 +
676 sizeof(*chan->curve_data) *
677 priv->curve_data->points_per_channel;
678 void *entry; 722 void *entry;
679 723
680 hdr = kzalloc(sizeof(*hdr) + payload_len + 724 hdr = kzalloc(sizeof(*hdr) + sizeof(*chan) +
681 priv->tx_hdr_len, GFP_KERNEL); 725 priv->tx_hdr_len, GFP_KERNEL);
682 if (!hdr) 726 if (!hdr)
683 return -ENOMEM; 727 return -ENOMEM;
@@ -689,10 +733,10 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
689 hdr->magic1 = cpu_to_le16(0x8001); 733 hdr->magic1 = cpu_to_le16(0x8001);
690 hdr->len = cpu_to_le16(sizeof(*chan)); 734 hdr->len = cpu_to_le16(sizeof(*chan));
691 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE); 735 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
692 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len); 736 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*chan));
693 737
694 chan->magic1 = cpu_to_le16(0x1); 738 chan->flags = cpu_to_le16(0x1);
695 chan->magic2 = cpu_to_le16(0x0); 739 chan->dwell = cpu_to_le16(0x0);
696 740
697 for (i = 0; i < priv->iq_autocal_len; i++) { 741 for (i = 0; i < priv->iq_autocal_len; i++) {
698 if (priv->iq_autocal[i].freq != freq) 742 if (priv->iq_autocal[i].freq != freq)
@@ -710,35 +754,41 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
710 continue; 754 continue;
711 755
712 chan->val_barker = 0x38; 756 chan->val_barker = 0x38;
713 chan->val_bpsk = priv->output_limit[i].val_bpsk; 757 chan->val_bpsk = chan->dup_bpsk =
714 chan->val_qpsk = priv->output_limit[i].val_qpsk; 758 priv->output_limit[i].val_bpsk;
715 chan->val_16qam = priv->output_limit[i].val_16qam; 759 chan->val_qpsk = chan->dup_qpsk =
716 chan->val_64qam = priv->output_limit[i].val_64qam; 760 priv->output_limit[i].val_qpsk;
761 chan->val_16qam = chan->dup_16qam =
762 priv->output_limit[i].val_16qam;
763 chan->val_64qam = chan->dup_64qam =
764 priv->output_limit[i].val_64qam;
717 break; 765 break;
718 } 766 }
719 if (i == priv->output_limit_len) 767 if (i == priv->output_limit_len)
720 goto err; 768 goto err;
721 769
722 chan->pa_points_per_curve = priv->curve_data->points_per_channel;
723
724 entry = priv->curve_data->data; 770 entry = priv->curve_data->data;
725 for (i = 0; i < priv->curve_data->channels; i++) { 771 for (i = 0; i < priv->curve_data->channels; i++) {
726 if (*((__le16 *)entry) != freq) { 772 if (*((__le16 *)entry) != freq) {
727 entry += sizeof(__le16); 773 entry += sizeof(__le16);
728 entry += sizeof(struct pda_pa_curve_data_sample_rev1) * 774 entry += sizeof(struct p54_pa_curve_data_sample) *
729 chan->pa_points_per_curve; 775 priv->curve_data->points_per_channel;
730 continue; 776 continue;
731 } 777 }
732 778
733 entry += sizeof(__le16); 779 entry += sizeof(__le16);
780 chan->pa_points_per_curve =
781 min(priv->curve_data->points_per_channel, (u8) 8);
782
734 memcpy(chan->curve_data, entry, sizeof(*chan->curve_data) * 783 memcpy(chan->curve_data, entry, sizeof(*chan->curve_data) *
735 chan->pa_points_per_curve); 784 chan->pa_points_per_curve);
736 break; 785 break;
737 } 786 }
738 787
739 memcpy(hdr->data + payload_len - 4, &chan->val_bpsk, 4); 788 chan->rssical_mul = cpu_to_le16(130);
789 chan->rssical_add = cpu_to_le16(0xfe70); /* -400 */
740 790
741 priv->tx(dev, hdr, sizeof(*hdr) + payload_len, 1); 791 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*chan), 1);
742 return 0; 792 return 0;
743 793
744 err: 794 err:
@@ -987,7 +1037,7 @@ static int p54_get_tx_stats(struct ieee80211_hw *dev,
987{ 1037{
988 struct p54_common *priv = dev->priv; 1038 struct p54_common *priv = dev->priv;
989 1039
990 memcpy(stats, &priv->tx_stats, sizeof(stats[0]) * dev->queues); 1040 memcpy(stats, &priv->tx_stats[4], sizeof(stats[0]) * dev->queues);
991 1041
992 return 0; 1042 return 0;
993} 1043}
@@ -1025,7 +1075,11 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
1025 dev->channel_change_time = 1000; /* TODO: find actual value */ 1075 dev->channel_change_time = 1000; /* TODO: find actual value */
1026 dev->max_signal = 127; 1076 dev->max_signal = 127;
1027 1077
1028 priv->tx_stats[0].limit = 5; 1078 priv->tx_stats[0].limit = 1;
1079 priv->tx_stats[1].limit = 1;
1080 priv->tx_stats[2].limit = 1;
1081 priv->tx_stats[3].limit = 1;
1082 priv->tx_stats[4].limit = 5;
1029 dev->queues = 1; 1083 dev->queues = 1;
1030 1084
1031 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 + 1085 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 9bc2a1cf4b57..a79c1a146917 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -89,6 +89,16 @@ struct pda_pa_curve_data_sample_rev1 {
89 u8 data_qpsk; 89 u8 data_qpsk;
90 u8 data_16qam; 90 u8 data_16qam;
91 u8 data_64qam; 91 u8 data_64qam;
92} __attribute__ ((packed));
93
94struct p54_pa_curve_data_sample {
95 u8 rf_power;
96 u8 pa_detector;
97 u8 data_barker;
98 u8 data_bpsk;
99 u8 data_qpsk;
100 u8 data_16qam;
101 u8 data_64qam;
92 u8 padding; 102 u8 padding;
93} __attribute__ ((packed)); 103} __attribute__ ((packed));
94 104
@@ -212,8 +222,8 @@ struct p54_tx_control_filter {
212} __attribute__ ((packed)); 222} __attribute__ ((packed));
213 223
214struct p54_tx_control_channel { 224struct p54_tx_control_channel {
215 __le16 magic1; 225 __le16 flags;
216 __le16 magic2; 226 __le16 dwell;
217 u8 padding1[20]; 227 u8 padding1[20];
218 struct pda_iq_autocal_entry iq_autocal; 228 struct pda_iq_autocal_entry iq_autocal;
219 u8 pa_points_per_curve; 229 u8 pa_points_per_curve;
@@ -222,8 +232,13 @@ struct p54_tx_control_channel {
222 u8 val_qpsk; 232 u8 val_qpsk;
223 u8 val_16qam; 233 u8 val_16qam;
224 u8 val_64qam; 234 u8 val_64qam;
225 struct pda_pa_curve_data_sample_rev1 curve_data[0]; 235 struct pda_pa_curve_data_sample_rev1 curve_data[8];
226 /* additional padding/data after curve_data */ 236 u8 dup_bpsk;
237 u8 dup_qpsk;
238 u8 dup_16qam;
239 u8 dup_64qam;
240 __le16 rssical_mul;
241 __le16 rssical_add;
227} __attribute__ ((packed)); 242} __attribute__ ((packed));
228 243
229struct p54_tx_control_led { 244struct p54_tx_control_led {
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index ea2dc3d93c4d..e9db4495c626 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -3,6 +3,7 @@
3 * Linux device driver for PCI based Prism54 3 * Linux device driver for PCI based Prism54
4 * 4 *
5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> 5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
6 * Copyright (c) 2008, Christian Lamparter <chunkeey@web.de>
6 * 7 *
7 * Based on the islsm (softmac prism54) driver, which is: 8 * Based on the islsm (softmac prism54) driver, which is:
8 * Copyright 2004-2006 Jean-Baptiste Note <jean-baptiste.note@m4x.org>, et al. 9 * Copyright 2004-2006 Jean-Baptiste Note <jean-baptiste.note@m4x.org>, et al.
@@ -237,20 +238,22 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev)
237 return err; 238 return err;
238} 239}
239 240
240static void p54p_refill_rx_ring(struct ieee80211_hw *dev) 241static void p54p_refill_rx_ring(struct ieee80211_hw *dev,
242 int ring_index, struct p54p_desc *ring, u32 ring_limit,
243 struct sk_buff **rx_buf)
241{ 244{
242 struct p54p_priv *priv = dev->priv; 245 struct p54p_priv *priv = dev->priv;
243 struct p54p_ring_control *ring_control = priv->ring_control; 246 struct p54p_ring_control *ring_control = priv->ring_control;
244 u32 limit, host_idx, idx; 247 u32 limit, idx, i;
245 248
246 host_idx = le32_to_cpu(ring_control->host_idx[0]); 249 idx = le32_to_cpu(ring_control->host_idx[ring_index]);
247 limit = host_idx; 250 limit = idx;
248 limit -= le32_to_cpu(ring_control->device_idx[0]); 251 limit -= le32_to_cpu(ring_control->device_idx[ring_index]);
249 limit = ARRAY_SIZE(ring_control->rx_data) - limit; 252 limit = ring_limit - limit;
250 253
251 idx = host_idx % ARRAY_SIZE(ring_control->rx_data); 254 i = idx % ring_limit;
252 while (limit-- > 1) { 255 while (limit-- > 1) {
253 struct p54p_desc *desc = &ring_control->rx_data[idx]; 256 struct p54p_desc *desc = &ring[i];
254 257
255 if (!desc->host_addr) { 258 if (!desc->host_addr) {
256 struct sk_buff *skb; 259 struct sk_buff *skb;
@@ -267,16 +270,106 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev)
267 desc->device_addr = 0; // FIXME: necessary? 270 desc->device_addr = 0; // FIXME: necessary?
268 desc->len = cpu_to_le16(MAX_RX_SIZE); 271 desc->len = cpu_to_le16(MAX_RX_SIZE);
269 desc->flags = 0; 272 desc->flags = 0;
270 priv->rx_buf[idx] = skb; 273 rx_buf[i] = skb;
271 } 274 }
272 275
276 i++;
273 idx++; 277 idx++;
274 host_idx++; 278 i %= ring_limit;
275 idx %= ARRAY_SIZE(ring_control->rx_data);
276 } 279 }
277 280
278 wmb(); 281 wmb();
279 ring_control->host_idx[0] = cpu_to_le32(host_idx); 282 ring_control->host_idx[ring_index] = cpu_to_le32(idx);
283}
284
285static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
286 int ring_index, struct p54p_desc *ring, u32 ring_limit,
287 struct sk_buff **rx_buf)
288{
289 struct p54p_priv *priv = dev->priv;
290 struct p54p_ring_control *ring_control = priv->ring_control;
291 struct p54p_desc *desc;
292 u32 idx, i;
293
294 i = (*index) % ring_limit;
295 (*index) = idx = le32_to_cpu(ring_control->device_idx[ring_index]);
296 idx %= ring_limit;
297 while (i != idx) {
298 u16 len;
299 struct sk_buff *skb;
300 desc = &ring[i];
301 len = le16_to_cpu(desc->len);
302 skb = rx_buf[i];
303
304 if (!skb)
305 continue;
306
307 skb_put(skb, len);
308
309 if (p54_rx(dev, skb)) {
310 pci_unmap_single(priv->pdev,
311 le32_to_cpu(desc->host_addr),
312 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
313 rx_buf[i] = NULL;
314 desc->host_addr = 0;
315 } else {
316 skb_trim(skb, 0);
317 desc->len = cpu_to_le16(MAX_RX_SIZE);
318 }
319
320 i++;
321 i %= ring_limit;
322 }
323
324 p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf);
325}
326
327/* caller must hold priv->lock */
328static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
329 int ring_index, struct p54p_desc *ring, u32 ring_limit,
330 void **tx_buf)
331{
332 struct p54p_priv *priv = dev->priv;
333 struct p54p_ring_control *ring_control = priv->ring_control;
334 struct p54p_desc *desc;
335 u32 idx, i;
336
337 i = (*index) % ring_limit;
338 (*index) = idx = le32_to_cpu(ring_control->device_idx[1]);
339 idx %= ring_limit;
340
341 while (i != idx) {
342 desc = &ring[i];
343 kfree(tx_buf[i]);
344 tx_buf[i] = NULL;
345
346 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
347 le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
348
349 desc->host_addr = 0;
350 desc->device_addr = 0;
351 desc->len = 0;
352 desc->flags = 0;
353
354 i++;
355 i %= ring_limit;
356 }
357}
358
359static void p54p_rx_tasklet(unsigned long dev_id)
360{
361 struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id;
362 struct p54p_priv *priv = dev->priv;
363 struct p54p_ring_control *ring_control = priv->ring_control;
364
365 p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt,
366 ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt);
367
368 p54p_check_rx_ring(dev, &priv->rx_idx_data, 0, ring_control->rx_data,
369 ARRAY_SIZE(ring_control->rx_data), priv->rx_buf_data);
370
371 wmb();
372 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
280} 373}
281 374
282static irqreturn_t p54p_interrupt(int irq, void *dev_id) 375static irqreturn_t p54p_interrupt(int irq, void *dev_id)
@@ -298,65 +391,18 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
298 reg &= P54P_READ(int_enable); 391 reg &= P54P_READ(int_enable);
299 392
300 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) { 393 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) {
301 struct p54p_desc *desc; 394 p54p_check_tx_ring(dev, &priv->tx_idx_mgmt,
302 u32 idx, i; 395 3, ring_control->tx_mgmt,
303 i = priv->tx_idx; 396 ARRAY_SIZE(ring_control->tx_mgmt),
304 i %= ARRAY_SIZE(ring_control->tx_data); 397 priv->tx_buf_mgmt);
305 priv->tx_idx = idx = le32_to_cpu(ring_control->device_idx[1]);
306 idx %= ARRAY_SIZE(ring_control->tx_data);
307
308 while (i != idx) {
309 desc = &ring_control->tx_data[i];
310 if (priv->tx_buf[i]) {
311 kfree(priv->tx_buf[i]);
312 priv->tx_buf[i] = NULL;
313 }
314
315 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
316 le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
317 398
318 desc->host_addr = 0; 399 p54p_check_tx_ring(dev, &priv->tx_idx_data,
319 desc->device_addr = 0; 400 1, ring_control->tx_data,
320 desc->len = 0; 401 ARRAY_SIZE(ring_control->tx_data),
321 desc->flags = 0; 402 priv->tx_buf_data);
322 403
323 i++; 404 tasklet_schedule(&priv->rx_tasklet);
324 i %= ARRAY_SIZE(ring_control->tx_data);
325 }
326
327 i = priv->rx_idx;
328 i %= ARRAY_SIZE(ring_control->rx_data);
329 priv->rx_idx = idx = le32_to_cpu(ring_control->device_idx[0]);
330 idx %= ARRAY_SIZE(ring_control->rx_data);
331 while (i != idx) {
332 u16 len;
333 struct sk_buff *skb;
334 desc = &ring_control->rx_data[i];
335 len = le16_to_cpu(desc->len);
336 skb = priv->rx_buf[i];
337
338 skb_put(skb, len);
339
340 if (p54_rx(dev, skb)) {
341 pci_unmap_single(priv->pdev,
342 le32_to_cpu(desc->host_addr),
343 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
344
345 priv->rx_buf[i] = NULL;
346 desc->host_addr = 0;
347 } else {
348 skb_trim(skb, 0);
349 desc->len = cpu_to_le16(MAX_RX_SIZE);
350 }
351
352 i++;
353 i %= ARRAY_SIZE(ring_control->rx_data);
354 }
355 405
356 p54p_refill_rx_ring(dev);
357
358 wmb();
359 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
360 } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)) 406 } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
361 complete(&priv->boot_comp); 407 complete(&priv->boot_comp);
362 408
@@ -392,7 +438,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
392 ring_control->host_idx[1] = cpu_to_le32(idx + 1); 438 ring_control->host_idx[1] = cpu_to_le32(idx + 1);
393 439
394 if (free_on_tx) 440 if (free_on_tx)
395 priv->tx_buf[i] = data; 441 priv->tx_buf_data[i] = data;
396 442
397 spin_unlock_irqrestore(&priv->lock, flags); 443 spin_unlock_irqrestore(&priv->lock, flags);
398 444
@@ -420,8 +466,14 @@ static int p54p_open(struct ieee80211_hw *dev)
420 } 466 }
421 467
422 memset(priv->ring_control, 0, sizeof(*priv->ring_control)); 468 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
423 priv->rx_idx = priv->tx_idx = 0; 469 priv->rx_idx_data = priv->tx_idx_data = 0;
424 p54p_refill_rx_ring(dev); 470 priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0;
471
472 p54p_refill_rx_ring(dev, 0, priv->ring_control->rx_data,
473 ARRAY_SIZE(priv->ring_control->rx_data), priv->rx_buf_data);
474
475 p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt,
476 ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt);
425 477
426 p54p_upload_firmware(dev); 478 p54p_upload_firmware(dev);
427 479
@@ -465,6 +517,8 @@ static void p54p_stop(struct ieee80211_hw *dev)
465 unsigned int i; 517 unsigned int i;
466 struct p54p_desc *desc; 518 struct p54p_desc *desc;
467 519
520 tasklet_kill(&priv->rx_tasklet);
521
468 P54P_WRITE(int_enable, cpu_to_le32(0)); 522 P54P_WRITE(int_enable, cpu_to_le32(0));
469 P54P_READ(int_enable); 523 P54P_READ(int_enable);
470 udelay(10); 524 udelay(10);
@@ -473,26 +527,51 @@ static void p54p_stop(struct ieee80211_hw *dev)
473 527
474 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); 528 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
475 529
476 for (i = 0; i < ARRAY_SIZE(priv->rx_buf); i++) { 530 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
477 desc = &ring_control->rx_data[i]; 531 desc = &ring_control->rx_data[i];
478 if (desc->host_addr) 532 if (desc->host_addr)
479 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), 533 pci_unmap_single(priv->pdev,
534 le32_to_cpu(desc->host_addr),
480 MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 535 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
481 kfree_skb(priv->rx_buf[i]); 536 kfree_skb(priv->rx_buf_data[i]);
482 priv->rx_buf[i] = NULL; 537 priv->rx_buf_data[i] = NULL;
483 } 538 }
484 539
485 for (i = 0; i < ARRAY_SIZE(priv->tx_buf); i++) { 540 for (i = 0; i < ARRAY_SIZE(priv->rx_buf_mgmt); i++) {
541 desc = &ring_control->rx_mgmt[i];
542 if (desc->host_addr)
543 pci_unmap_single(priv->pdev,
544 le32_to_cpu(desc->host_addr),
545 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
546 kfree_skb(priv->rx_buf_mgmt[i]);
547 priv->rx_buf_mgmt[i] = NULL;
548 }
549
550 for (i = 0; i < ARRAY_SIZE(priv->tx_buf_data); i++) {
486 desc = &ring_control->tx_data[i]; 551 desc = &ring_control->tx_data[i];
487 if (desc->host_addr) 552 if (desc->host_addr)
488 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), 553 pci_unmap_single(priv->pdev,
489 le16_to_cpu(desc->len), PCI_DMA_TODEVICE); 554 le32_to_cpu(desc->host_addr),
555 le16_to_cpu(desc->len),
556 PCI_DMA_TODEVICE);
557
558 kfree(priv->tx_buf_data[i]);
559 priv->tx_buf_data[i] = NULL;
560 }
561
562 for (i = 0; i < ARRAY_SIZE(priv->tx_buf_mgmt); i++) {
563 desc = &ring_control->tx_mgmt[i];
564 if (desc->host_addr)
565 pci_unmap_single(priv->pdev,
566 le32_to_cpu(desc->host_addr),
567 le16_to_cpu(desc->len),
568 PCI_DMA_TODEVICE);
490 569
491 kfree(priv->tx_buf[i]); 570 kfree(priv->tx_buf_mgmt[i]);
492 priv->tx_buf[i] = NULL; 571 priv->tx_buf_mgmt[i] = NULL;
493 } 572 }
494 573
495 memset(ring_control, 0, sizeof(ring_control)); 574 memset(ring_control, 0, sizeof(*ring_control));
496} 575}
497 576
498static int __devinit p54p_probe(struct pci_dev *pdev, 577static int __devinit p54p_probe(struct pci_dev *pdev,
@@ -585,6 +664,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
585 priv->common.tx = p54p_tx; 664 priv->common.tx = p54p_tx;
586 665
587 spin_lock_init(&priv->lock); 666 spin_lock_init(&priv->lock);
667 tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev);
588 668
589 err = ieee80211_register_hw(dev); 669 err = ieee80211_register_hw(dev);
590 if (err) { 670 if (err) {
diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h
index 07678ef5ddc8..4a6778070afc 100644
--- a/drivers/net/wireless/p54/p54pci.h
+++ b/drivers/net/wireless/p54/p54pci.h
@@ -92,13 +92,17 @@ struct p54p_priv {
92 struct p54_common common; 92 struct p54_common common;
93 struct pci_dev *pdev; 93 struct pci_dev *pdev;
94 struct p54p_csr __iomem *map; 94 struct p54p_csr __iomem *map;
95 struct tasklet_struct rx_tasklet;
95 96
96 spinlock_t lock; 97 spinlock_t lock;
97 struct p54p_ring_control *ring_control; 98 struct p54p_ring_control *ring_control;
98 dma_addr_t ring_control_dma; 99 dma_addr_t ring_control_dma;
99 u32 rx_idx, tx_idx; 100 u32 rx_idx_data, tx_idx_data;
100 struct sk_buff *rx_buf[8]; 101 u32 rx_idx_mgmt, tx_idx_mgmt;
101 void *tx_buf[32]; 102 struct sk_buff *rx_buf_data[8];
103 struct sk_buff *rx_buf_mgmt[4];
104 void *tx_buf_data[32];
105 void *tx_buf_mgmt[4];
102 struct completion boot_comp; 106 struct completion boot_comp;
103}; 107};
104 108
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 0107cec18b26..18b703c3fc2c 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1241,7 +1241,7 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
1241 if (!reg) 1241 if (!reg)
1242 return IRQ_NONE; 1242 return IRQ_NONE;
1243 1243
1244 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 1244 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1245 return IRQ_HANDLED; 1245 return IRQ_HANDLED;
1246 1246
1247 /* 1247 /*
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index e0ff76ff490d..2a96a011f2ad 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1316,6 +1316,8 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry,
1316 1316
1317 if (rt2x00_get_field32(word0, RXD_W0_OFDM)) 1317 if (rt2x00_get_field32(word0, RXD_W0_OFDM))
1318 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; 1318 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
1319 else
1320 rxdesc->dev_flags |= RXDONE_SIGNAL_BITRATE;
1319 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) 1321 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
1320 rxdesc->dev_flags |= RXDONE_MY_BSS; 1322 rxdesc->dev_flags |= RXDONE_MY_BSS;
1321} 1323}
@@ -1377,7 +1379,7 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
1377 if (!reg) 1379 if (!reg)
1378 return IRQ_NONE; 1380 return IRQ_NONE;
1379 1381
1380 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 1382 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
1381 return IRQ_HANDLED; 1383 return IRQ_HANDLED;
1382 1384
1383 /* 1385 /*
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 3b90ed622148..0e008b606f70 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1114,8 +1114,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1114 rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, 1114 rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
1115 test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); 1115 test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
1116 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); 1116 rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
1117 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, 1117 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
1118 skb->len - skbdesc->desc_len);
1119 rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); 1118 rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE);
1120 rt2x00_desc_write(txd, 0, word); 1119 rt2x00_desc_write(txd, 0, word);
1121} 1120}
@@ -1280,6 +1279,8 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
1280 1279
1281 if (rt2x00_get_field32(word0, RXD_W0_OFDM)) 1280 if (rt2x00_get_field32(word0, RXD_W0_OFDM))
1282 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; 1281 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
1282 else
1283 rxdesc->dev_flags |= RXDONE_SIGNAL_BITRATE;
1283 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) 1284 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
1284 rxdesc->dev_flags |= RXDONE_MY_BSS; 1285 rxdesc->dev_flags |= RXDONE_MY_BSS;
1285 1286
@@ -1297,7 +1298,7 @@ static void rt2500usb_beacondone(struct urb *urb)
1297 struct queue_entry *entry = (struct queue_entry *)urb->context; 1298 struct queue_entry *entry = (struct queue_entry *)urb->context;
1298 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; 1299 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
1299 1300
1300 if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) 1301 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags))
1301 return; 1302 return;
1302 1303
1303 /* 1304 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 3fa3d5b006a6..6f296cef76ad 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -44,7 +44,7 @@
44/* 44/*
45 * Module information. 45 * Module information.
46 */ 46 */
47#define DRV_VERSION "2.2.0" 47#define DRV_VERSION "2.2.1"
48#define DRV_PROJECT "http://rt2x00.serialmonkey.com" 48#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
49 49
50/* 50/*
@@ -629,14 +629,13 @@ enum rt2x00_flags {
629 /* 629 /*
630 * Device state flags 630 * Device state flags
631 */ 631 */
632 DEVICE_PRESENT, 632 DEVICE_STATE_PRESENT,
633 DEVICE_REGISTERED_HW, 633 DEVICE_STATE_REGISTERED_HW,
634 DEVICE_INITIALIZED, 634 DEVICE_STATE_INITIALIZED,
635 DEVICE_STARTED, 635 DEVICE_STATE_STARTED,
636 DEVICE_STARTED_SUSPEND, 636 DEVICE_STATE_STARTED_SUSPEND,
637 DEVICE_ENABLED_RADIO, 637 DEVICE_STATE_ENABLED_RADIO,
638 DEVICE_DISABLED_RADIO_HW, 638 DEVICE_STATE_DISABLED_RADIO_HW,
639 DEVICE_DIRTY_CONFIG,
640 639
641 /* 640 /*
642 * Driver requirements 641 * Driver requirements
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index ea37c7962043..ca051f50ef10 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -121,7 +121,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
121 * Antenna setup changes require the RX to be disabled, 121 * Antenna setup changes require the RX to be disabled,
122 * else the changes will be ignored by the device. 122 * else the changes will be ignored by the device.
123 */ 123 */
124 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 124 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
125 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); 125 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK);
126 126
127 /* 127 /*
@@ -136,7 +136,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
136 rt2x00dev->link.ant.active.rx = libconf.ant.rx; 136 rt2x00dev->link.ant.active.rx = libconf.ant.rx;
137 rt2x00dev->link.ant.active.tx = libconf.ant.tx; 137 rt2x00dev->link.ant.active.tx = libconf.ant.tx;
138 138
139 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 139 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
140 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); 140 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
141} 141}
142 142
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 328ff8bc4c16..369b0b2d8643 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -34,7 +34,7 @@
34 */ 34 */
35void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) 35void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
36{ 36{
37 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 37 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
38 return; 38 return;
39 39
40 /* 40 /*
@@ -94,8 +94,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
94 * Don't enable the radio twice. 94 * Don't enable the radio twice.
95 * And check if the hardware button has been disabled. 95 * And check if the hardware button has been disabled.
96 */ 96 */
97 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 97 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
98 test_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags)) 98 test_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags))
99 return 0; 99 return 0;
100 100
101 /* 101 /*
@@ -117,7 +117,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
117 rt2x00leds_led_radio(rt2x00dev, true); 117 rt2x00leds_led_radio(rt2x00dev, true);
118 rt2x00led_led_activity(rt2x00dev, true); 118 rt2x00led_led_activity(rt2x00dev, true);
119 119
120 __set_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags); 120 set_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
121 121
122 /* 122 /*
123 * Enable RX. 123 * Enable RX.
@@ -134,7 +134,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
134 134
135void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) 135void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
136{ 136{
137 if (!__test_and_clear_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 137 if (!test_and_clear_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
138 return; 138 return;
139 139
140 /* 140 /*
@@ -354,7 +354,7 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
354 * When the radio is shutting down we should 354 * When the radio is shutting down we should
355 * immediately cease all link tuning. 355 * immediately cease all link tuning.
356 */ 356 */
357 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 357 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
358 return; 358 return;
359 359
360 /* 360 /*
@@ -431,7 +431,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
431 * note that in the spinlock protected area above the delayed_flags 431 * note that in the spinlock protected area above the delayed_flags
432 * have been cleared correctly. 432 * have been cleared correctly.
433 */ 433 */
434 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 434 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
435 return; 435 return;
436 436
437 if (delayed_flags & DELAYED_UPDATE_BEACON) 437 if (delayed_flags & DELAYED_UPDATE_BEACON)
@@ -484,7 +484,7 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
484 484
485void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) 485void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
486{ 486{
487 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 487 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
488 return; 488 return;
489 489
490 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, 490 ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw,
@@ -572,7 +572,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
572 572
573 rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry); 573 rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
574 574
575 __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 575 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
576 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 576 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
577 577
578 /* 578 /*
@@ -653,7 +653,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
653 653
654 if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && 654 if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
655 (rate->plcp == rxdesc.signal)) || 655 (rate->plcp == rxdesc.signal)) ||
656 (!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && 656 ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
657 (rate->bitrate == rxdesc.signal))) { 657 (rate->bitrate == rxdesc.signal))) {
658 idx = i; 658 idx = i;
659 break; 659 break;
@@ -888,7 +888,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
888 888
889static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) 889static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
890{ 890{
891 if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) 891 if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
892 ieee80211_unregister_hw(rt2x00dev->hw); 892 ieee80211_unregister_hw(rt2x00dev->hw);
893 893
894 if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) { 894 if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) {
@@ -906,6 +906,9 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
906 struct hw_mode_spec *spec = &rt2x00dev->spec; 906 struct hw_mode_spec *spec = &rt2x00dev->spec;
907 int status; 907 int status;
908 908
909 if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
910 return 0;
911
909 /* 912 /*
910 * Initialize HW modes. 913 * Initialize HW modes.
911 */ 914 */
@@ -927,7 +930,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
927 return status; 930 return status;
928 } 931 }
929 932
930 __set_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags); 933 set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);
931 934
932 return 0; 935 return 0;
933} 936}
@@ -937,7 +940,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
937 */ 940 */
938static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) 941static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
939{ 942{
940 if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) 943 if (!test_and_clear_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags))
941 return; 944 return;
942 945
943 /* 946 /*
@@ -960,7 +963,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
960{ 963{
961 int status; 964 int status;
962 965
963 if (test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) 966 if (test_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags))
964 return 0; 967 return 0;
965 968
966 /* 969 /*
@@ -979,7 +982,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
979 return status; 982 return status;
980 } 983 }
981 984
982 __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); 985 set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags);
983 986
984 /* 987 /*
985 * Register the extra components. 988 * Register the extra components.
@@ -993,7 +996,7 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
993{ 996{
994 int retval; 997 int retval;
995 998
996 if (test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 999 if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
997 return 0; 1000 return 0;
998 1001
999 /* 1002 /*
@@ -1011,28 +1014,18 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
1011 if (retval) 1014 if (retval)
1012 return retval; 1015 return retval;
1013 1016
1014 /*
1015 * Enable radio.
1016 */
1017 retval = rt2x00lib_enable_radio(rt2x00dev);
1018 if (retval) {
1019 rt2x00lib_uninitialize(rt2x00dev);
1020 return retval;
1021 }
1022
1023 rt2x00dev->intf_ap_count = 0; 1017 rt2x00dev->intf_ap_count = 0;
1024 rt2x00dev->intf_sta_count = 0; 1018 rt2x00dev->intf_sta_count = 0;
1025 rt2x00dev->intf_associated = 0; 1019 rt2x00dev->intf_associated = 0;
1026 1020
1027 __set_bit(DEVICE_STARTED, &rt2x00dev->flags); 1021 set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
1028 __set_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags);
1029 1022
1030 return 0; 1023 return 0;
1031} 1024}
1032 1025
1033void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) 1026void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
1034{ 1027{
1035 if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 1028 if (!test_and_clear_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
1036 return; 1029 return;
1037 1030
1038 /* 1031 /*
@@ -1044,8 +1037,6 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
1044 rt2x00dev->intf_ap_count = 0; 1037 rt2x00dev->intf_ap_count = 0;
1045 rt2x00dev->intf_sta_count = 0; 1038 rt2x00dev->intf_sta_count = 0;
1046 rt2x00dev->intf_associated = 0; 1039 rt2x00dev->intf_associated = 0;
1047
1048 __clear_bit(DEVICE_STARTED, &rt2x00dev->flags);
1049} 1040}
1050 1041
1051/* 1042/*
@@ -1100,7 +1091,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1100 rt2x00rfkill_allocate(rt2x00dev); 1091 rt2x00rfkill_allocate(rt2x00dev);
1101 rt2x00debug_register(rt2x00dev); 1092 rt2x00debug_register(rt2x00dev);
1102 1093
1103 __set_bit(DEVICE_PRESENT, &rt2x00dev->flags); 1094 set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
1104 1095
1105 return 0; 1096 return 0;
1106 1097
@@ -1113,7 +1104,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_probe_dev);
1113 1104
1114void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) 1105void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1115{ 1106{
1116 __clear_bit(DEVICE_PRESENT, &rt2x00dev->flags); 1107 clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
1117 1108
1118 /* 1109 /*
1119 * Disable radio. 1110 * Disable radio.
@@ -1158,14 +1149,15 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
1158 int retval; 1149 int retval;
1159 1150
1160 NOTICE(rt2x00dev, "Going to sleep.\n"); 1151 NOTICE(rt2x00dev, "Going to sleep.\n");
1161 __clear_bit(DEVICE_PRESENT, &rt2x00dev->flags);
1162 1152
1163 /* 1153 /*
1164 * Only continue if mac80211 has open interfaces. 1154 * Only continue if mac80211 has open interfaces.
1165 */ 1155 */
1166 if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 1156 if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
1157 !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
1167 goto exit; 1158 goto exit;
1168 __set_bit(DEVICE_STARTED_SUSPEND, &rt2x00dev->flags); 1159
1160 set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags);
1169 1161
1170 /* 1162 /*
1171 * Disable radio. 1163 * Disable radio.
@@ -1237,7 +1229,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1237 /* 1229 /*
1238 * Only continue if mac80211 had open interfaces. 1230 * Only continue if mac80211 had open interfaces.
1239 */ 1231 */
1240 if (!__test_and_clear_bit(DEVICE_STARTED_SUSPEND, &rt2x00dev->flags)) 1232 if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags))
1241 return 0; 1233 return 0;
1242 1234
1243 /* 1235 /*
@@ -1264,7 +1256,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1264 /* 1256 /*
1265 * We are ready again to receive requests from mac80211. 1257 * We are ready again to receive requests from mac80211.
1266 */ 1258 */
1267 __set_bit(DEVICE_PRESENT, &rt2x00dev->flags); 1259 set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
1268 1260
1269 /* 1261 /*
1270 * It is possible that during that mac80211 has attempted 1262 * It is possible that during that mac80211 has attempted
@@ -1284,7 +1276,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1284 return 0; 1276 return 0;
1285 1277
1286exit: 1278exit:
1287 rt2x00lib_disable_radio(rt2x00dev); 1279 rt2x00lib_stop(rt2x00dev);
1288 rt2x00lib_uninitialize(rt2x00dev); 1280 rt2x00lib_uninitialize(rt2x00dev);
1289 rt2x00debug_deregister(rt2x00dev); 1281 rt2x00debug_deregister(rt2x00dev);
1290 1282
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 3af427339417..56829fad3471 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -117,7 +117,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
117 * Note that we can only stop the TX queues inside the TX path 117 * Note that we can only stop the TX queues inside the TX path
118 * due to possible race conditions in mac80211. 118 * due to possible race conditions in mac80211.
119 */ 119 */
120 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 120 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
121 goto exit_fail; 121 goto exit_fail;
122 122
123 /* 123 /*
@@ -175,7 +175,7 @@ int rt2x00mac_start(struct ieee80211_hw *hw)
175{ 175{
176 struct rt2x00_dev *rt2x00dev = hw->priv; 176 struct rt2x00_dev *rt2x00dev = hw->priv;
177 177
178 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 178 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
179 return 0; 179 return 0;
180 180
181 return rt2x00lib_start(rt2x00dev); 181 return rt2x00lib_start(rt2x00dev);
@@ -186,7 +186,7 @@ void rt2x00mac_stop(struct ieee80211_hw *hw)
186{ 186{
187 struct rt2x00_dev *rt2x00dev = hw->priv; 187 struct rt2x00_dev *rt2x00dev = hw->priv;
188 188
189 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 189 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
190 return; 190 return;
191 191
192 rt2x00lib_stop(rt2x00dev); 192 rt2x00lib_stop(rt2x00dev);
@@ -206,8 +206,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
206 * Don't allow interfaces to be added 206 * Don't allow interfaces to be added
207 * the device has disappeared. 207 * the device has disappeared.
208 */ 208 */
209 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || 209 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
210 !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 210 !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
211 return -ENODEV; 211 return -ENODEV;
212 212
213 switch (conf->type) { 213 switch (conf->type) {
@@ -256,7 +256,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
256 */ 256 */
257 for (i = 0; i < queue->limit; i++) { 257 for (i = 0; i < queue->limit; i++) {
258 entry = &queue->entries[i]; 258 entry = &queue->entries[i];
259 if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) 259 if (!test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags))
260 break; 260 break;
261 } 261 }
262 262
@@ -310,7 +310,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
310 * either the device has disappeared or when 310 * either the device has disappeared or when
311 * no interface is present. 311 * no interface is present.
312 */ 312 */
313 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || 313 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
314 (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || 314 (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) ||
315 (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) 315 (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count))
316 return; 316 return;
@@ -324,7 +324,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
324 * Release beacon entry so it is available for 324 * Release beacon entry so it is available for
325 * new interfaces again. 325 * new interfaces again.
326 */ 326 */
327 __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); 327 clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags);
328 328
329 /* 329 /*
330 * Make sure the bssid and mac address registers 330 * Make sure the bssid and mac address registers
@@ -338,45 +338,45 @@ EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
338int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 338int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
339{ 339{
340 struct rt2x00_dev *rt2x00dev = hw->priv; 340 struct rt2x00_dev *rt2x00dev = hw->priv;
341 int force_reconfig; 341 int radio_on;
342 int status;
342 343
343 /* 344 /*
344 * Mac80211 might be calling this function while we are trying 345 * Mac80211 might be calling this function while we are trying
345 * to remove the device or perhaps suspending it. 346 * to remove the device or perhaps suspending it.
346 */ 347 */
347 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 348 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
348 return 0; 349 return 0;
349 350
350 /* 351 /*
351 * Check if we need to disable the radio, 352 * Only change device state when the radio is enabled. It does not
352 * if this is not the case, at least the RX must be disabled. 353 * matter what parameters we have configured when the radio is disabled
354 * because we won't be able to send or receive anyway. Also note that
355 * some configuration parameters (e.g. channel and antenna values) can
356 * only be set when the radio is enabled.
353 */ 357 */
354 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) { 358 radio_on = test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
355 if (!conf->radio_enabled) 359 if (conf->radio_enabled) {
356 rt2x00lib_disable_radio(rt2x00dev); 360 /* For programming the values, we have to turn RX off */
357 else 361 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
358 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
359 }
360 362
361 /* 363 /* Enable the radio */
362 * When the DEVICE_DIRTY_CONFIG flag is set, the device has recently 364 status = rt2x00lib_enable_radio(rt2x00dev);
363 * been started and the configuration must be forced upon the hardware. 365 if (unlikely(status))
364 * Otherwise registers will not be intialized correctly and could 366 return status;
365 * result in non-working hardware because essential registers aren't
366 * initialized.
367 */
368 force_reconfig =
369 __test_and_clear_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags);
370 367
371 rt2x00lib_config(rt2x00dev, conf, force_reconfig); 368 /*
369 * When we've just turned on the radio, we want to reprogram
370 * everything to ensure a consistent state
371 */
372 rt2x00lib_config(rt2x00dev, conf, !radio_on);
372 373
373 /* 374 /* Turn RX back on */
374 * Reenable RX only if the radio should be on.
375 */
376 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
377 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); 375 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
378 else if (conf->radio_enabled) 376 } else {
379 return rt2x00lib_enable_radio(rt2x00dev); 377 /* Disable the radio */
378 rt2x00lib_disable_radio(rt2x00dev);
379 }
380 380
381 return 0; 381 return 0;
382} 382}
@@ -395,7 +395,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
395 * Mac80211 might be calling this function while we are trying 395 * Mac80211 might be calling this function while we are trying
396 * to remove the device or perhaps suspending it. 396 * to remove the device or perhaps suspending it.
397 */ 397 */
398 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 398 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
399 return 0; 399 return 0;
400 400
401 spin_lock(&intf->lock); 401 spin_lock(&intf->lock);
@@ -666,10 +666,11 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
666 queue->cw_max = 10; /* cw_min: 2^10 = 1024. */ 666 queue->cw_max = 10; /* cw_min: 2^10 = 1024. */
667 667
668 queue->aifs = params->aifs; 668 queue->aifs = params->aifs;
669 queue->txop = params->txop;
669 670
670 INFO(rt2x00dev, 671 INFO(rt2x00dev,
671 "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", 672 "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d.\n",
672 queue_idx, queue->cw_min, queue->cw_max, queue->aifs); 673 queue_idx, queue->cw_min, queue->cw_max, queue->aifs, queue->txop);
673 674
674 return 0; 675 return 0;
675} 676}
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index c0f97c53e5ce..a5e965068c83 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -100,8 +100,21 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
100{ 100{
101 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); 101 struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
102 102
103 skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, 103 /*
104 DMA_TO_DEVICE); 104 * If device has requested headroom, we should make sure that
105 * is also mapped to the DMA so it can be used for transfering
106 * additional descriptor information to the hardware.
107 */
108 skb_push(skb, rt2x00dev->hw->extra_tx_headroom);
109
110 skbdesc->skb_dma =
111 dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
112
113 /*
114 * Restore data pointer to original location again.
115 */
116 skb_pull(skb, rt2x00dev->hw->extra_tx_headroom);
117
105 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; 118 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
106} 119}
107EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); 120EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
@@ -117,7 +130,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
117 } 130 }
118 131
119 if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { 132 if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
120 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, 133 /*
134 * Add headroom to the skb length, it has been removed
135 * by the driver, but it was actually mapped to DMA.
136 */
137 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
138 skb->len + rt2x00dev->hw->extra_tx_headroom,
121 DMA_TO_DEVICE); 139 DMA_TO_DEVICE);
122 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; 140 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
123 } 141 }
@@ -356,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
356 if (unlikely(rt2x00queue_full(queue))) 374 if (unlikely(rt2x00queue_full(queue)))
357 return -EINVAL; 375 return -EINVAL;
358 376
359 if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { 377 if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
360 ERROR(queue->rt2x00dev, 378 ERROR(queue->rt2x00dev,
361 "Arrived at non-free entry in the non-full queue %d.\n" 379 "Arrived at non-free entry in the non-full queue %d.\n"
362 "Please file bug report to %s.\n", 380 "Please file bug report to %s.\n",
@@ -396,7 +414,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
396 * the frame to mac80211 because the skb->cb has now been tainted. 414 * the frame to mac80211 because the skb->cb has now been tainted.
397 */ 415 */
398 if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { 416 if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
399 __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 417 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
400 dev_kfree_skb_any(entry->skb); 418 dev_kfree_skb_any(entry->skb);
401 entry->skb = NULL; 419 entry->skb = NULL;
402 return 0; 420 return 0;
@@ -405,7 +423,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
405 if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) 423 if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
406 rt2x00queue_map_txskb(queue->rt2x00dev, skb); 424 rt2x00queue_map_txskb(queue->rt2x00dev, skb);
407 425
408 __set_bit(ENTRY_DATA_PENDING, &entry->flags); 426 set_bit(ENTRY_DATA_PENDING, &entry->flags);
409 427
410 rt2x00queue_index_inc(queue, Q_INDEX); 428 rt2x00queue_index_inc(queue, Q_INDEX);
411 rt2x00queue_write_tx_descriptor(entry, &txdesc); 429 rt2x00queue_write_tx_descriptor(entry, &txdesc);
@@ -718,6 +736,7 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
718 736
719 queue->rt2x00dev = rt2x00dev; 737 queue->rt2x00dev = rt2x00dev;
720 queue->qid = qid; 738 queue->qid = qid;
739 queue->txop = 0;
721 queue->aifs = 2; 740 queue->aifs = 2;
722 queue->cw_min = 5; 741 queue->cw_min = 5;
723 queue->cw_max = 10; 742 queue->cw_max = 10;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 37f3f98d58a2..9dbf04f0f04c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -140,13 +140,14 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
140/** 140/**
141 * enum rxdone_entry_desc_flags: Flags for &struct rxdone_entry_desc 141 * enum rxdone_entry_desc_flags: Flags for &struct rxdone_entry_desc
142 * 142 *
143 * @RXDONE_SIGNAL_PLCP: Does the signal field contain the plcp value, 143 * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value.
144 * or does it contain the bitrate itself. 144 * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value.
145 * @RXDONE_MY_BSS: Does this frame originate from device's BSS. 145 * @RXDONE_MY_BSS: Does this frame originate from device's BSS.
146 */ 146 */
147enum rxdone_entry_desc_flags { 147enum rxdone_entry_desc_flags {
148 RXDONE_SIGNAL_PLCP = 1 << 0, 148 RXDONE_SIGNAL_PLCP = 1 << 0,
149 RXDONE_MY_BSS = 1 << 1, 149 RXDONE_SIGNAL_BITRATE = 1 << 1,
150 RXDONE_MY_BSS = 1 << 2,
150}; 151};
151 152
152/** 153/**
@@ -368,6 +369,7 @@ enum queue_index {
368 * @length: Number of frames in queue. 369 * @length: Number of frames in queue.
369 * @index: Index pointers to entry positions in the queue, 370 * @index: Index pointers to entry positions in the queue,
370 * use &enum queue_index to get a specific index field. 371 * use &enum queue_index to get a specific index field.
372 * @txop: maximum burst time.
371 * @aifs: The aifs value for outgoing frames (field ignored in RX queue). 373 * @aifs: The aifs value for outgoing frames (field ignored in RX queue).
372 * @cw_min: The cw min value for outgoing frames (field ignored in RX queue). 374 * @cw_min: The cw min value for outgoing frames (field ignored in RX queue).
373 * @cw_max: The cw max value for outgoing frames (field ignored in RX queue). 375 * @cw_max: The cw max value for outgoing frames (field ignored in RX queue).
@@ -387,6 +389,7 @@ struct data_queue {
387 unsigned short length; 389 unsigned short length;
388 unsigned short index[Q_INDEX_MAX]; 390 unsigned short index[Q_INDEX_MAX];
389 391
392 unsigned short txop;
390 unsigned short aifs; 393 unsigned short aifs;
391 unsigned short cw_min; 394 unsigned short cw_min;
392 unsigned short cw_max; 395 unsigned short cw_max;
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 04b29716d356..8a2fefb365b7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -41,16 +41,16 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
41 /* 41 /*
42 * Only continue if there are enabled interfaces. 42 * Only continue if there are enabled interfaces.
43 */ 43 */
44 if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 44 if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
45 return 0; 45 return 0;
46 46
47 if (state == RFKILL_STATE_UNBLOCKED) { 47 if (state == RFKILL_STATE_UNBLOCKED) {
48 INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); 48 INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n");
49 __clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); 49 clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
50 retval = rt2x00lib_enable_radio(rt2x00dev); 50 retval = rt2x00lib_enable_radio(rt2x00dev);
51 } else if (state == RFKILL_STATE_SOFT_BLOCKED) { 51 } else if (state == RFKILL_STATE_SOFT_BLOCKED) {
52 INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); 52 INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n");
53 __set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); 53 set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
54 rt2x00lib_disable_radio(rt2x00dev); 54 rt2x00lib_disable_radio(rt2x00dev);
55 } else { 55 } else {
56 WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n", 56 WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n",
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 2050227ea530..b73a7e0aeed4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -163,16 +163,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
163 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 163 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
164 struct txdone_entry_desc txdesc; 164 struct txdone_entry_desc txdesc;
165 165
166 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 166 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
167 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 167 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
168 return; 168 return;
169 169
170 /* 170 /*
171 * Remove the descriptor data from the buffer.
172 */
173 skb_pull(entry->skb, entry->queue->desc_size);
174
175 /*
176 * Obtain the status about this packet. 171 * Obtain the status about this packet.
177 * Note that when the status is 0 it does not mean the 172 * Note that when the status is 0 it does not mean the
178 * frame was send out correctly. It only means the frame 173 * frame was send out correctly. It only means the frame
@@ -224,6 +219,12 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry)
224 entry->skb->data, length, 219 entry->skb->data, length,
225 rt2x00usb_interrupt_txdone, entry); 220 rt2x00usb_interrupt_txdone, entry);
226 221
222 /*
223 * Make sure the skb->data pointer points to the frame, not the
224 * descriptor.
225 */
226 skb_pull(entry->skb, entry->queue->desc_size);
227
227 return 0; 228 return 0;
228} 229}
229EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); 230EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);
@@ -232,7 +233,7 @@ static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
232{ 233{
233 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 234 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
234 235
235 if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) 236 if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
236 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 237 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
237} 238}
238 239
@@ -283,7 +284,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
283 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 284 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
284 u8 rxd[32]; 285 u8 rxd[32];
285 286
286 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 287 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
287 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 288 !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
288 return; 289 return;
289 290
@@ -293,7 +294,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
293 * a problem. 294 * a problem.
294 */ 295 */
295 if (urb->actual_length < entry->queue->desc_size || urb->status) { 296 if (urb->actual_length < entry->queue->desc_size || urb->status) {
296 __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 297 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
297 usb_submit_urb(urb, GFP_ATOMIC); 298 usb_submit_urb(urb, GFP_ATOMIC);
298 return; 299 return;
299 } 300 }
@@ -361,7 +362,7 @@ void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
361 entry->skb->data, entry->skb->len, 362 entry->skb->data, entry->skb->len,
362 rt2x00usb_interrupt_rxdone, entry); 363 rt2x00usb_interrupt_rxdone, entry);
363 364
364 __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 365 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
365 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 366 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
366} 367}
367EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); 368EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 23cf93dfda06..d740f560ccd0 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1478,16 +1478,6 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
1478 1478
1479 rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff); 1479 rt2x00pci_register_write(rt2x00dev, M2H_CMD_DONE_CSR, 0xffffffff);
1480 1480
1481 rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
1482 rt2x00_set_field32(&reg, AC_TXOP_CSR0_AC0_TX_OP, 0);
1483 rt2x00_set_field32(&reg, AC_TXOP_CSR0_AC1_TX_OP, 0);
1484 rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
1485
1486 rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
1487 rt2x00_set_field32(&reg, AC_TXOP_CSR1_AC2_TX_OP, 192);
1488 rt2x00_set_field32(&reg, AC_TXOP_CSR1_AC3_TX_OP, 48);
1489 rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
1490
1491 /* 1481 /*
1492 * Clear all beacons 1482 * Clear all beacons
1493 * For the Beacon base registers we only need to clear 1483 * For the Beacon base registers we only need to clear
@@ -2001,6 +1991,8 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,
2001 1991
2002 if (rt2x00_get_field32(word0, RXD_W0_OFDM)) 1992 if (rt2x00_get_field32(word0, RXD_W0_OFDM))
2003 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; 1993 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
1994 else
1995 rxdesc->dev_flags |= RXDONE_SIGNAL_BITRATE;
2004 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) 1996 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
2005 rxdesc->dev_flags |= RXDONE_MY_BSS; 1997 rxdesc->dev_flags |= RXDONE_MY_BSS;
2006} 1998}
@@ -2121,7 +2113,7 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
2121 if (!reg && !reg_mcu) 2113 if (!reg && !reg_mcu)
2122 return IRQ_NONE; 2114 return IRQ_NONE;
2123 2115
2124 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 2116 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
2125 return IRQ_HANDLED; 2117 return IRQ_HANDLED;
2126 2118
2127 /* 2119 /*
@@ -2652,6 +2644,63 @@ static int rt61pci_set_retry_limit(struct ieee80211_hw *hw,
2652 return 0; 2644 return 0;
2653} 2645}
2654 2646
2647static 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, &reg);
2674 rt2x00_set_field32(&reg, 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, &reg);
2681 rt2x00_set_field32(&reg, 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, &reg);
2690 rt2x00_set_field32(&reg, field, queue->aifs);
2691 rt2x00pci_register_write(rt2x00dev, AIFSN_CSR, reg);
2692
2693 rt2x00pci_register_read(rt2x00dev, CWMIN_CSR, &reg);
2694 rt2x00_set_field32(&reg, field, queue->cw_min);
2695 rt2x00pci_register_write(rt2x00dev, CWMIN_CSR, reg);
2696
2697 rt2x00pci_register_read(rt2x00dev, CWMAX_CSR, &reg);
2698 rt2x00_set_field32(&reg, field, queue->cw_max);
2699 rt2x00pci_register_write(rt2x00dev, CWMAX_CSR, reg);
2700
2701 return 0;
2702}
2703
2655static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) 2704static u64 rt61pci_get_tsf(struct ieee80211_hw *hw)
2656{ 2705{
2657 struct rt2x00_dev *rt2x00dev = hw->priv; 2706 struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -2679,7 +2728,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2679 .get_stats = rt2x00mac_get_stats, 2728 .get_stats = rt2x00mac_get_stats,
2680 .set_retry_limit = rt61pci_set_retry_limit, 2729 .set_retry_limit = rt61pci_set_retry_limit,
2681 .bss_info_changed = rt2x00mac_bss_info_changed, 2730 .bss_info_changed = rt2x00mac_bss_info_changed,
2682 .conf_tx = rt2x00mac_conf_tx, 2731 .conf_tx = rt61pci_conf_tx,
2683 .get_tx_stats = rt2x00mac_get_tx_stats, 2732 .get_tx_stats = rt2x00mac_get_tx_stats,
2684 .get_tsf = rt61pci_get_tsf, 2733 .get_tsf = rt61pci_get_tsf,
2685}; 2734};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index f58fd059c9a0..e698ae0efbce 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1277,16 +1277,6 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
1277 rt73usb_register_write(rt2x00dev, PHY_CSR6, 0x00080606); 1277 rt73usb_register_write(rt2x00dev, PHY_CSR6, 0x00080606);
1278 rt73usb_register_write(rt2x00dev, PHY_CSR7, 0x00000408); 1278 rt73usb_register_write(rt2x00dev, PHY_CSR7, 0x00000408);
1279 1279
1280 rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
1281 rt2x00_set_field32(&reg, AC_TXOP_CSR0_AC0_TX_OP, 0);
1282 rt2x00_set_field32(&reg, AC_TXOP_CSR0_AC1_TX_OP, 0);
1283 rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
1284
1285 rt73usb_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
1286 rt2x00_set_field32(&reg, AC_TXOP_CSR1_AC2_TX_OP, 192);
1287 rt2x00_set_field32(&reg, AC_TXOP_CSR1_AC3_TX_OP, 48);
1288 rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
1289
1290 rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg); 1280 rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg);
1291 rt2x00_set_field32(&reg, MAC_CSR9_CW_SELECT, 0); 1281 rt2x00_set_field32(&reg, MAC_CSR9_CW_SELECT, 0);
1292 rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); 1282 rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
@@ -1566,8 +1556,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1566 rt2x00_set_field32(&word, TXD_W0_KEY_TABLE, 1556 rt2x00_set_field32(&word, TXD_W0_KEY_TABLE,
1567 test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags)); 1557 test_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags));
1568 rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx); 1558 rt2x00_set_field32(&word, TXD_W0_KEY_INDEX, txdesc->key_idx);
1569 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, 1559 rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
1570 skb->len - skbdesc->desc_len);
1571 rt2x00_set_field32(&word, TXD_W0_BURST2, 1560 rt2x00_set_field32(&word, TXD_W0_BURST2,
1572 test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 1561 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
1573 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher); 1562 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, txdesc->cipher);
@@ -1776,6 +1765,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
1776 1765
1777 if (rt2x00_get_field32(word0, RXD_W0_OFDM)) 1766 if (rt2x00_get_field32(word0, RXD_W0_OFDM))
1778 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; 1767 rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
1768 else
1769 rxdesc->dev_flags |= RXDONE_SIGNAL_BITRATE;
1779 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) 1770 if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
1780 rxdesc->dev_flags |= RXDONE_MY_BSS; 1771 rxdesc->dev_flags |= RXDONE_MY_BSS;
1781 1772
@@ -2246,6 +2237,63 @@ static int rt73usb_set_retry_limit(struct ieee80211_hw *hw,
2246 return 0; 2237 return 0;
2247} 2238}
2248 2239
2240static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
2241 const struct ieee80211_tx_queue_params *params)
2242{
2243 struct rt2x00_dev *rt2x00dev = hw->priv;
2244 struct data_queue *queue;
2245 struct rt2x00_field32 field;
2246 int retval;
2247 u32 reg;
2248
2249 /*
2250 * First pass the configuration through rt2x00lib, that will
2251 * update the queue settings and validate the input. After that
2252 * we are free to update the registers based on the value
2253 * in the queue parameter.
2254 */
2255 retval = rt2x00mac_conf_tx(hw, queue_idx, params);
2256 if (retval)
2257 return retval;
2258
2259 queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
2260
2261 /* Update WMM TXOP register */
2262 if (queue_idx < 2) {
2263 field.bit_offset = queue_idx * 16;
2264 field.bit_mask = 0xffff << field.bit_offset;
2265
2266 rt73usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
2267 rt2x00_set_field32(&reg, field, queue->txop);
2268 rt73usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
2269 } else if (queue_idx < 4) {
2270 field.bit_offset = (queue_idx - 2) * 16;
2271 field.bit_mask = 0xffff << field.bit_offset;
2272
2273 rt73usb_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
2274 rt2x00_set_field32(&reg, field, queue->txop);
2275 rt73usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
2276 }
2277
2278 /* Update WMM registers */
2279 field.bit_offset = queue_idx * 4;
2280 field.bit_mask = 0xf << field.bit_offset;
2281
2282 rt73usb_register_read(rt2x00dev, AIFSN_CSR, &reg);
2283 rt2x00_set_field32(&reg, field, queue->aifs);
2284 rt73usb_register_write(rt2x00dev, AIFSN_CSR, reg);
2285
2286 rt73usb_register_read(rt2x00dev, CWMIN_CSR, &reg);
2287 rt2x00_set_field32(&reg, field, queue->cw_min);
2288 rt73usb_register_write(rt2x00dev, CWMIN_CSR, reg);
2289
2290 rt73usb_register_read(rt2x00dev, CWMAX_CSR, &reg);
2291 rt2x00_set_field32(&reg, field, queue->cw_max);
2292 rt73usb_register_write(rt2x00dev, CWMAX_CSR, reg);
2293
2294 return 0;
2295}
2296
2249#if 0 2297#if 0
2250/* 2298/*
2251 * Mac80211 demands get_tsf must be atomic. 2299 * Mac80211 demands get_tsf must be atomic.
@@ -2283,7 +2331,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2283 .get_stats = rt2x00mac_get_stats, 2331 .get_stats = rt2x00mac_get_stats,
2284 .set_retry_limit = rt73usb_set_retry_limit, 2332 .set_retry_limit = rt73usb_set_retry_limit,
2285 .bss_info_changed = rt2x00mac_bss_info_changed, 2333 .bss_info_changed = rt2x00mac_bss_info_changed,
2286 .conf_tx = rt2x00mac_conf_tx, 2334 .conf_tx = rt73usb_conf_tx,
2287 .get_tx_stats = rt2x00mac_get_tx_stats, 2335 .get_tx_stats = rt2x00mac_get_tx_stats,
2288 .get_tsf = rt73usb_get_tsf, 2336 .get_tsf = rt73usb_get_tsf,
2289}; 2337};
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index f883dcfffe06..d5cde051806b 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -327,11 +327,9 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
327 s8 gain; 327 s8 gain;
328 u16 loc[3]; 328 u16 loc[3];
329 329
330 if (out->revision == 3) { /* rev 3 moved MAC */ 330 if (out->revision == 3) /* rev 3 moved MAC */
331 loc[0] = SSB_SPROM3_IL0MAC; 331 loc[0] = SSB_SPROM3_IL0MAC;
332 loc[1] = SSB_SPROM3_ET0MAC; 332 else {
333 loc[2] = SSB_SPROM3_ET1MAC;
334 } else {
335 loc[0] = SSB_SPROM1_IL0MAC; 333 loc[0] = SSB_SPROM1_IL0MAC;
336 loc[1] = SSB_SPROM1_ET0MAC; 334 loc[1] = SSB_SPROM1_ET0MAC;
337 loc[2] = SSB_SPROM1_ET1MAC; 335 loc[2] = SSB_SPROM1_ET1MAC;
@@ -340,13 +338,15 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
340 v = in[SPOFF(loc[0]) + i]; 338 v = in[SPOFF(loc[0]) + i];
341 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); 339 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
342 } 340 }
343 for (i = 0; i < 3; i++) { 341 if (out->revision < 3) { /* only rev 1-2 have et0, et1 */
344 v = in[SPOFF(loc[1]) + i]; 342 for (i = 0; i < 3; i++) {
345 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); 343 v = in[SPOFF(loc[1]) + i];
346 } 344 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
347 for (i = 0; i < 3; i++) { 345 }
348 v = in[SPOFF(loc[2]) + i]; 346 for (i = 0; i < 3; i++) {
349 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); 347 v = in[SPOFF(loc[2]) + i];
348 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
349 }
350 } 350 }
351 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); 351 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
352 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, 352 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
@@ -399,30 +399,33 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
399 out->antenna_gain.ghz5.a3 = gain; 399 out->antenna_gain.ghz5.a3 = gain;
400} 400}
401 401
402static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) 402static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
403{ 403{
404 int i; 404 int i;
405 u16 v; 405 u16 v;
406 u16 il0mac_offset;
406 407
407 /* extract the equivalent of the r1 variables */ 408 if (out->revision == 4)
409 il0mac_offset = SSB_SPROM4_IL0MAC;
410 else
411 il0mac_offset = SSB_SPROM5_IL0MAC;
412 /* extract the MAC address */
408 for (i = 0; i < 3; i++) { 413 for (i = 0; i < 3; i++) {
409 v = in[SPOFF(SSB_SPROM4_IL0MAC) + i]; 414 v = in[SPOFF(il0mac_offset) + i];
410 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); 415 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
411 } 416 }
412 for (i = 0; i < 3; i++) {
413 v = in[SPOFF(SSB_SPROM4_ET0MAC) + i];
414 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
415 }
416 for (i = 0; i < 3; i++) {
417 v = in[SPOFF(SSB_SPROM4_ET1MAC) + i];
418 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
419 }
420 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); 417 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
421 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, 418 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
422 SSB_SPROM4_ETHPHY_ET1A_SHIFT); 419 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
423 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); 420 if (out->revision == 4) {
424 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); 421 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
425 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); 422 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
423 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
424 } else {
425 SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
426 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
427 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
428 }
426 SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, 429 SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
427 SSB_SPROM4_ANTAVAIL_A_SHIFT); 430 SSB_SPROM4_ANTAVAIL_A_SHIFT);
428 SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, 431 SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
@@ -433,12 +436,21 @@ static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in)
433 SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); 436 SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
434 SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, 437 SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
435 SSB_SPROM4_ITSSI_A_SHIFT); 438 SSB_SPROM4_ITSSI_A_SHIFT);
436 SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); 439 if (out->revision == 4) {
437 SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, 440 SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
438 SSB_SPROM4_GPIOA_P1_SHIFT); 441 SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
439 SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); 442 SSB_SPROM4_GPIOA_P1_SHIFT);
440 SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, 443 SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
441 SSB_SPROM4_GPIOB_P3_SHIFT); 444 SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
445 SSB_SPROM4_GPIOB_P3_SHIFT);
446 } else {
447 SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0);
448 SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1,
449 SSB_SPROM5_GPIOA_P1_SHIFT);
450 SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0);
451 SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3,
452 SSB_SPROM5_GPIOB_P3_SHIFT);
453 }
442 454
443 /* Extract the antenna gain values. */ 455 /* Extract the antenna gain values. */
444 SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, 456 SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
@@ -462,6 +474,8 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
462 474
463 out->revision = in[size - 1] & 0x00FF; 475 out->revision = in[size - 1] & 0x00FF;
464 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); 476 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
477 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
478 memset(out->et1mac, 0xFF, 6);
465 if ((bus->chip_id & 0xFF00) == 0x4400) { 479 if ((bus->chip_id & 0xFF00) == 0x4400) {
466 /* Workaround: The BCM44XX chip has a stupid revision 480 /* Workaround: The BCM44XX chip has a stupid revision
467 * number stored in the SPROM. 481 * number stored in the SPROM.
@@ -471,16 +485,16 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
471 } else if (bus->chip_id == 0x4321) { 485 } else if (bus->chip_id == 0x4321) {
472 /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ 486 /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
473 out->revision = 4; 487 out->revision = 4;
474 sprom_extract_r4(out, in); 488 sprom_extract_r45(out, in);
475 } else { 489 } else {
476 if (out->revision == 0) 490 if (out->revision == 0)
477 goto unsupported; 491 goto unsupported;
478 if (out->revision >= 1 && out->revision <= 3) { 492 if (out->revision >= 1 && out->revision <= 3) {
479 sprom_extract_r123(out, in); 493 sprom_extract_r123(out, in);
480 } 494 }
481 if (out->revision == 4) 495 if (out->revision == 4 || out->revision == 5)
482 sprom_extract_r4(out, in); 496 sprom_extract_r45(out, in);
483 if (out->revision >= 5) 497 if (out->revision > 5)
484 goto unsupported; 498 goto unsupported;
485 } 499 }
486 500