aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-03-11 22:17:18 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-11 22:17:18 -0400
commitba73d4c84a7344f1b5635c2b4e96796e8c13a126 (patch)
treed4a3e2cfc5f3a046a2b9baa898f0c201c75ba898 /drivers/net/wireless
parentb8ad0cbc58f703972e9e37c4e2a8081dd7e6a551 (diff)
parentdeedf504302ff747985db081352e045ff7087a11 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.26
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h53
-rw-r--r--drivers/net/wireless/ath5k/base.c147
-rw-r--r--drivers/net/wireless/ath5k/debug.c37
-rw-r--r--drivers/net/wireless/ath5k/debug.h6
-rw-r--r--drivers/net/wireless/ath5k/hw.c441
-rw-r--r--drivers/net/wireless/ath5k/hw.h150
-rw-r--r--drivers/net/wireless/ath5k/initvals.c233
-rw-r--r--drivers/net/wireless/ath5k/phy.c174
-rw-r--r--drivers/net/wireless/ath5k/reg.h4
-rw-r--r--drivers/net/wireless/b43/b43.h53
-rw-r--r--drivers/net/wireless/b43/dma.c386
-rw-r--r--drivers/net/wireless/b43/dma.h11
-rw-r--r--drivers/net/wireless/b43/main.c196
-rw-r--r--drivers/net/wireless/b43/main.h4
-rw-r--r--drivers/net/wireless/b43/xmit.c27
-rw-r--r--drivers/net/wireless/b43/xmit.h12
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig5
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-core.h80
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debug.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h174
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c387
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-commands.h40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-debug.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h175
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c98
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c352
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h84
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h259
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c205
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h399
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c531
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c351
-rw-r--r--drivers/net/wireless/libertas/assoc.c12
-rw-r--r--drivers/net/wireless/libertas/cmd.c131
-rw-r--r--drivers/net/wireless/libertas/cmd.h2
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c63
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h19
-rw-r--r--drivers/net/wireless/libertas/scan.c537
-rw-r--r--drivers/net/wireless/libertas/scan.h54
-rw-r--r--drivers/net/wireless/libertas/types.h13
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h8
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c75
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c11
54 files changed, 3832 insertions, 2466 deletions
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 18223d9833f1..b21830771ea5 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -140,7 +140,8 @@ enum ath5k_radio {
140 AR5K_RF5110 = 0, 140 AR5K_RF5110 = 0,
141 AR5K_RF5111 = 1, 141 AR5K_RF5111 = 1,
142 AR5K_RF5112 = 2, 142 AR5K_RF5112 = 2,
143 AR5K_RF5413 = 3, 143 AR5K_RF2413 = 3,
144 AR5K_RF5413 = 4,
144}; 145};
145 146
146/* 147/*
@@ -168,12 +169,15 @@ struct ath5k_srev_name {
168#define AR5K_SREV_VER_AR5212 0x50 169#define AR5K_SREV_VER_AR5212 0x50
169#define AR5K_SREV_VER_AR5213 0x55 170#define AR5K_SREV_VER_AR5213 0x55
170#define AR5K_SREV_VER_AR5213A 0x59 171#define AR5K_SREV_VER_AR5213A 0x59
171#define AR5K_SREV_VER_AR2424 0xa0 172#define AR5K_SREV_VER_AR2413 0x78
172#define AR5K_SREV_VER_AR5424 0xa3 173#define AR5K_SREV_VER_AR2414 0x79
174#define AR5K_SREV_VER_AR2424 0xa0 /* PCI-E */
175#define AR5K_SREV_VER_AR5424 0xa3 /* PCI-E */
173#define AR5K_SREV_VER_AR5413 0xa4 176#define AR5K_SREV_VER_AR5413 0xa4
174#define AR5K_SREV_VER_AR5414 0xa5 177#define AR5K_SREV_VER_AR5414 0xa5
175#define AR5K_SREV_VER_AR5416 0xc0 /* ? */ 178#define AR5K_SREV_VER_AR5416 0xc0 /* PCI-E */
176#define AR5K_SREV_VER_AR5418 0xca 179#define AR5K_SREV_VER_AR5418 0xca /* PCI-E */
180#define AR5K_SREV_VER_AR2425 0xe2 /* PCI-E */
177 181
178#define AR5K_SREV_RAD_5110 0x00 182#define AR5K_SREV_RAD_5110 0x00
179#define AR5K_SREV_RAD_5111 0x10 183#define AR5K_SREV_RAD_5111 0x10
@@ -183,8 +187,9 @@ struct ath5k_srev_name {
183#define AR5K_SREV_RAD_5112A 0x35 187#define AR5K_SREV_RAD_5112A 0x35
184#define AR5K_SREV_RAD_2112 0x40 188#define AR5K_SREV_RAD_2112 0x40
185#define AR5K_SREV_RAD_2112A 0x45 189#define AR5K_SREV_RAD_2112A 0x45
190#define AR5K_SREV_RAD_SC0 0x56 /* Found on 2413/2414 */
186#define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */ 191#define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */
187#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424/5424 */ 192#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424-5/5424 */
188#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */ 193#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */
189 194
190/* IEEE defs */ 195/* IEEE defs */
@@ -268,12 +273,13 @@ enum ath5k_driver_mode {
268#define SHPREAMBLE_FLAG(_ix) \ 273#define SHPREAMBLE_FLAG(_ix) \
269 (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) 274 (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0)
270 275
276
271/****************\ 277/****************\
272 TX DEFINITIONS 278 TX DEFINITIONS
273\****************/ 279\****************/
274 280
275/* 281/*
276 * Tx Descriptor 282 * TX Status
277 */ 283 */
278struct ath5k_tx_status { 284struct ath5k_tx_status {
279 u16 ts_seqnum; 285 u16 ts_seqnum;
@@ -421,7 +427,7 @@ enum ath5k_dmasize {
421\****************/ 427\****************/
422 428
423/* 429/*
424 * Rx Descriptor 430 * RX Status
425 */ 431 */
426struct ath5k_rx_status { 432struct ath5k_rx_status {
427 u16 rs_datalen; 433 u16 rs_datalen;
@@ -452,8 +458,6 @@ struct ath5k_mib_stats {
452}; 458};
453 459
454 460
455
456
457/**************************\ 461/**************************\
458 BEACON TIMERS DEFINITIONS 462 BEACON TIMERS DEFINITIONS
459\**************************/ 463\**************************/
@@ -495,29 +499,23 @@ struct ath5k_beacon_state {
495#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10) 499#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
496 500
497 501
498
499/********************\ 502/********************\
500 COMMON DEFINITIONS 503 COMMON DEFINITIONS
501\********************/ 504\********************/
502 505
503/* 506/*
504 * Atheros descriptor 507 * Atheros hardware descriptor
508 * This is read and written to by the hardware
505 */ 509 */
506struct ath5k_desc { 510struct ath5k_desc {
507 u32 ds_link; 511 u32 ds_link; /* physical address of the next descriptor */
508 u32 ds_data; 512 u32 ds_data; /* physical address of data buffer (skb) */
509 u32 ds_ctl0;
510 u32 ds_ctl1;
511 u32 ds_hw[4];
512 513
513 union { 514 union {
514 struct ath5k_rx_status rx; 515 struct ath5k_hw_5210_tx_desc ds_tx5210;
515 struct ath5k_tx_status tx; 516 struct ath5k_hw_5212_tx_desc ds_tx5212;
516 } ds_us; 517 struct ath5k_hw_all_rx_desc ds_rx;
517 518 } ud;
518#define ds_rxstat ds_us.rx
519#define ds_txstat ds_us.tx
520
521} __packed; 519} __packed;
522 520
523#define AR5K_RXDESC_INTREQ 0x0020 521#define AR5K_RXDESC_INTREQ 0x0020
@@ -961,6 +959,7 @@ struct ath5k_hw {
961 u16 ah_phy_revision; 959 u16 ah_phy_revision;
962 u16 ah_radio_5ghz_revision; 960 u16 ah_radio_5ghz_revision;
963 u16 ah_radio_2ghz_revision; 961 u16 ah_radio_2ghz_revision;
962 u32 ah_phy_spending;
964 963
965 enum ath5k_version ah_version; 964 enum ath5k_version ah_version;
966 enum ath5k_radio ah_radio; 965 enum ath5k_radio ah_radio;
@@ -1036,8 +1035,10 @@ struct ath5k_hw {
1036 int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, 1035 int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1037 unsigned int, unsigned int, unsigned int, unsigned int, 1036 unsigned int, unsigned int, unsigned int, unsigned int,
1038 unsigned int, unsigned int); 1037 unsigned int, unsigned int);
1039 int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *); 1038 int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1040 int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *); 1039 struct ath5k_tx_status *);
1040 int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1041 struct ath5k_rx_status *);
1041}; 1042};
1042 1043
1043/* 1044/*
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 393b5f3c25a7..b5c0a0d7a81c 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -118,6 +118,8 @@ static struct ath5k_srev_name srev_names[] = {
118 { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 }, 118 { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 },
119 { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 }, 119 { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 },
120 { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A }, 120 { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A },
121 { "2413", AR5K_VERSION_VER, AR5K_SREV_VER_AR2413 },
122 { "2414", AR5K_VERSION_VER, AR5K_SREV_VER_AR2414 },
121 { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 }, 123 { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 },
122 { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 }, 124 { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 },
123 { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 }, 125 { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 },
@@ -132,6 +134,7 @@ static struct ath5k_srev_name srev_names[] = {
132 { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, 134 { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A },
133 { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, 135 { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 },
134 { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, 136 { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A },
137 { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC0 },
135 { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 }, 138 { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 },
136 { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 }, 139 { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 },
137 { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, 140 { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
@@ -280,7 +283,8 @@ static int ath5k_rx_start(struct ath5k_softc *sc);
280static void ath5k_rx_stop(struct ath5k_softc *sc); 283static void ath5k_rx_stop(struct ath5k_softc *sc);
281static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, 284static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
282 struct ath5k_desc *ds, 285 struct ath5k_desc *ds,
283 struct sk_buff *skb); 286 struct sk_buff *skb,
287 struct ath5k_rx_status *rs);
284static void ath5k_tasklet_rx(unsigned long data); 288static void ath5k_tasklet_rx(unsigned long data);
285/* Tx handling */ 289/* Tx handling */
286static void ath5k_tx_processq(struct ath5k_softc *sc, 290static void ath5k_tx_processq(struct ath5k_softc *sc,
@@ -1560,8 +1564,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1560 */ 1564 */
1561 spin_lock_bh(&txq->lock); 1565 spin_lock_bh(&txq->lock);
1562 list_for_each_entry_safe(bf, bf0, &txq->q, list) { 1566 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
1563 ath5k_debug_printtxbuf(sc, bf, !sc->ah->ah_proc_tx_desc(sc->ah, 1567 ath5k_debug_printtxbuf(sc, bf);
1564 bf->desc));
1565 1568
1566 ath5k_txbuf_free(sc, bf); 1569 ath5k_txbuf_free(sc, bf);
1567 1570
@@ -1686,20 +1689,20 @@ ath5k_rx_stop(struct ath5k_softc *sc)
1686 1689
1687static unsigned int 1690static unsigned int
1688ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, 1691ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
1689 struct sk_buff *skb) 1692 struct sk_buff *skb, struct ath5k_rx_status *rs)
1690{ 1693{
1691 struct ieee80211_hdr *hdr = (void *)skb->data; 1694 struct ieee80211_hdr *hdr = (void *)skb->data;
1692 unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb); 1695 unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb);
1693 1696
1694 if (!(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) && 1697 if (!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
1695 ds->ds_rxstat.rs_keyix != AR5K_RXKEYIX_INVALID) 1698 rs->rs_keyix != AR5K_RXKEYIX_INVALID)
1696 return RX_FLAG_DECRYPTED; 1699 return RX_FLAG_DECRYPTED;
1697 1700
1698 /* Apparently when a default key is used to decrypt the packet 1701 /* Apparently when a default key is used to decrypt the packet
1699 the hw does not set the index used to decrypt. In such cases 1702 the hw does not set the index used to decrypt. In such cases
1700 get the index from the packet. */ 1703 get the index from the packet. */
1701 if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) && 1704 if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) &&
1702 !(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) && 1705 !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
1703 skb->len >= hlen + 4) { 1706 skb->len >= hlen + 4) {
1704 keyix = skb->data[hlen + 3] >> 6; 1707 keyix = skb->data[hlen + 3] >> 6;
1705 1708
@@ -1712,8 +1715,10 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
1712 1715
1713 1716
1714static void 1717static void
1715ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb) 1718ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
1719 struct ieee80211_rx_status *rxs)
1716{ 1720{
1721 u64 tsf, bc_tstamp;
1717 u32 hw_tu; 1722 u32 hw_tu;
1718 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1723 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1719 1724
@@ -1724,16 +1729,45 @@ ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb)
1724 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && 1729 le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
1725 memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { 1730 memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
1726 /* 1731 /*
1727 * Received an IBSS beacon with the same BSSID. Hardware might 1732 * Received an IBSS beacon with the same BSSID. Hardware *must*
1728 * have updated the TSF, check if we need to update timers. 1733 * have updated the local TSF. We have to work around various
1734 * hardware bugs, though...
1729 */ 1735 */
1730 hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah)); 1736 tsf = ath5k_hw_get_tsf64(sc->ah);
1731 if (hw_tu >= sc->nexttbtt) { 1737 bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
1732 ath5k_beacon_update_timers(sc, 1738 hw_tu = TSF_TO_TU(tsf);
1733 le64_to_cpu(mgmt->u.beacon.timestamp)); 1739
1740 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
1741 "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
1742 bc_tstamp, rxs->mactime,
1743 (rxs->mactime - bc_tstamp), tsf);
1744
1745 /*
1746 * Sometimes the HW will give us a wrong tstamp in the rx
1747 * status, causing the timestamp extension to go wrong.
1748 * (This seems to happen especially with beacon frames bigger
1749 * than 78 byte (incl. FCS))
1750 * But we know that the receive timestamp must be later than the
1751 * timestamp of the beacon since HW must have synced to that.
1752 *
1753 * NOTE: here we assume mactime to be after the frame was
1754 * received, not like mac80211 which defines it at the start.
1755 */
1756 if (bc_tstamp > rxs->mactime) {
1734 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, 1757 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
1735 "detected HW merge from received beacon\n"); 1758 "fixing mactime from %llx to %llx\n",
1759 rxs->mactime, tsf);
1760 rxs->mactime = tsf;
1736 } 1761 }
1762
1763 /*
1764 * Local TSF might have moved higher than our beacon timers,
1765 * in that case we have to update them to continue sending
1766 * beacons. This also takes care of synchronizing beacon sending
1767 * times with other stations.
1768 */
1769 if (hw_tu >= sc->nexttbtt)
1770 ath5k_beacon_update_timers(sc, bc_tstamp);
1737 } 1771 }
1738} 1772}
1739 1773
@@ -1742,12 +1776,11 @@ static void
1742ath5k_tasklet_rx(unsigned long data) 1776ath5k_tasklet_rx(unsigned long data)
1743{ 1777{
1744 struct ieee80211_rx_status rxs = {}; 1778 struct ieee80211_rx_status rxs = {};
1779 struct ath5k_rx_status rs = {};
1745 struct sk_buff *skb; 1780 struct sk_buff *skb;
1746 struct ath5k_softc *sc = (void *)data; 1781 struct ath5k_softc *sc = (void *)data;
1747 struct ath5k_buf *bf; 1782 struct ath5k_buf *bf;
1748 struct ath5k_desc *ds; 1783 struct ath5k_desc *ds;
1749 u16 len;
1750 u8 stat;
1751 int ret; 1784 int ret;
1752 int hdrlen; 1785 int hdrlen;
1753 int pad; 1786 int pad;
@@ -1770,7 +1803,7 @@ ath5k_tasklet_rx(unsigned long data)
1770 if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */ 1803 if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */
1771 break; 1804 break;
1772 1805
1773 ret = sc->ah->ah_proc_rx_desc(sc->ah, ds); 1806 ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
1774 if (unlikely(ret == -EINPROGRESS)) 1807 if (unlikely(ret == -EINPROGRESS))
1775 break; 1808 break;
1776 else if (unlikely(ret)) { 1809 else if (unlikely(ret)) {
@@ -1779,16 +1812,15 @@ ath5k_tasklet_rx(unsigned long data)
1779 return; 1812 return;
1780 } 1813 }
1781 1814
1782 if (unlikely(ds->ds_rxstat.rs_more)) { 1815 if (unlikely(rs.rs_more)) {
1783 ATH5K_WARN(sc, "unsupported jumbo\n"); 1816 ATH5K_WARN(sc, "unsupported jumbo\n");
1784 goto next; 1817 goto next;
1785 } 1818 }
1786 1819
1787 stat = ds->ds_rxstat.rs_status; 1820 if (unlikely(rs.rs_status)) {
1788 if (unlikely(stat)) { 1821 if (rs.rs_status & AR5K_RXERR_PHY)
1789 if (stat & AR5K_RXERR_PHY)
1790 goto next; 1822 goto next;
1791 if (stat & AR5K_RXERR_DECRYPT) { 1823 if (rs.rs_status & AR5K_RXERR_DECRYPT) {
1792 /* 1824 /*
1793 * Decrypt error. If the error occurred 1825 * Decrypt error. If the error occurred
1794 * because there was no hardware key, then 1826 * because there was no hardware key, then
@@ -1799,30 +1831,29 @@ ath5k_tasklet_rx(unsigned long data)
1799 * 1831 *
1800 * XXX do key cache faulting 1832 * XXX do key cache faulting
1801 */ 1833 */
1802 if (ds->ds_rxstat.rs_keyix == 1834 if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
1803 AR5K_RXKEYIX_INVALID && 1835 !(rs.rs_status & AR5K_RXERR_CRC))
1804 !(stat & AR5K_RXERR_CRC))
1805 goto accept; 1836 goto accept;
1806 } 1837 }
1807 if (stat & AR5K_RXERR_MIC) { 1838 if (rs.rs_status & AR5K_RXERR_MIC) {
1808 rxs.flag |= RX_FLAG_MMIC_ERROR; 1839 rxs.flag |= RX_FLAG_MMIC_ERROR;
1809 goto accept; 1840 goto accept;
1810 } 1841 }
1811 1842
1812 /* let crypto-error packets fall through in MNTR */ 1843 /* let crypto-error packets fall through in MNTR */
1813 if ((stat & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || 1844 if ((rs.rs_status &
1845 ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
1814 sc->opmode != IEEE80211_IF_TYPE_MNTR) 1846 sc->opmode != IEEE80211_IF_TYPE_MNTR)
1815 goto next; 1847 goto next;
1816 } 1848 }
1817accept: 1849accept:
1818 len = ds->ds_rxstat.rs_datalen; 1850 pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr,
1819 pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, len, 1851 rs.rs_datalen, PCI_DMA_FROMDEVICE);
1820 PCI_DMA_FROMDEVICE);
1821 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, 1852 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
1822 PCI_DMA_FROMDEVICE); 1853 PCI_DMA_FROMDEVICE);
1823 bf->skb = NULL; 1854 bf->skb = NULL;
1824 1855
1825 skb_put(skb, len); 1856 skb_put(skb, rs.rs_datalen);
1826 1857
1827 /* 1858 /*
1828 * the hardware adds a padding to 4 byte boundaries between 1859 * the hardware adds a padding to 4 byte boundaries between
@@ -1844,8 +1875,19 @@ accept:
1844 * 15bit only. that means TSF extension has to be done within 1875 * 15bit only. that means TSF extension has to be done within
1845 * 32768usec (about 32ms). it might be necessary to move this to 1876 * 32768usec (about 32ms). it might be necessary to move this to
1846 * the interrupt handler, like it is done in madwifi. 1877 * the interrupt handler, like it is done in madwifi.
1878 *
1879 * Unfortunately we don't know when the hardware takes the rx
1880 * timestamp (beginning of phy frame, data frame, end of rx?).
1881 * The only thing we know is that it is hardware specific...
1882 * On AR5213 it seems the rx timestamp is at the end of the
1883 * frame, but i'm not sure.
1884 *
1885 * NOTE: mac80211 defines mactime at the beginning of the first
1886 * data symbol. Since we don't have any time references it's
1887 * impossible to comply to that. This affects IBSS merge only
1888 * right now, so it's not too bad...
1847 */ 1889 */
1848 rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp); 1890 rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
1849 rxs.flag |= RX_FLAG_TSFT; 1891 rxs.flag |= RX_FLAG_TSFT;
1850 1892
1851 rxs.freq = sc->curchan->center_freq; 1893 rxs.freq = sc->curchan->center_freq;
@@ -1859,26 +1901,25 @@ accept:
1859 /* noise floor in dBm, from the last noise calibration */ 1901 /* noise floor in dBm, from the last noise calibration */
1860 rxs.noise = sc->ah->ah_noise_floor; 1902 rxs.noise = sc->ah->ah_noise_floor;
1861 /* signal level in dBm */ 1903 /* signal level in dBm */
1862 rxs.ssi = rxs.noise + ds->ds_rxstat.rs_rssi; 1904 rxs.ssi = rxs.noise + rs.rs_rssi;
1863 /* 1905 /*
1864 * "signal" is actually displayed as Link Quality by iwconfig 1906 * "signal" is actually displayed as Link Quality by iwconfig
1865 * we provide a percentage based on rssi (assuming max rssi 64) 1907 * we provide a percentage based on rssi (assuming max rssi 64)
1866 */ 1908 */
1867 rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64; 1909 rxs.signal = rs.rs_rssi * 100 / 64;
1868 1910
1869 rxs.antenna = ds->ds_rxstat.rs_antenna; 1911 rxs.antenna = rs.rs_antenna;
1870 rxs.rate_idx = ath5k_hw_to_driver_rix(sc, 1912 rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
1871 ds->ds_rxstat.rs_rate); 1913 rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
1872 rxs.flag |= ath5k_rx_decrypted(sc, ds, skb);
1873 1914
1874 ath5k_debug_dump_skb(sc, skb, "RX ", 0); 1915 ath5k_debug_dump_skb(sc, skb, "RX ", 0);
1875 1916
1876 /* check beacons in IBSS mode */ 1917 /* check beacons in IBSS mode */
1877 if (sc->opmode == IEEE80211_IF_TYPE_IBSS) 1918 if (sc->opmode == IEEE80211_IF_TYPE_IBSS)
1878 ath5k_check_ibss_hw_merge(sc, skb); 1919 ath5k_check_ibss_tsf(sc, skb, &rxs);
1879 1920
1880 __ieee80211_rx(sc->hw, skb, &rxs); 1921 __ieee80211_rx(sc->hw, skb, &rxs);
1881 sc->led_rxrate = ds->ds_rxstat.rs_rate; 1922 sc->led_rxrate = rs.rs_rate;
1882 ath5k_led_event(sc, ATH_LED_RX); 1923 ath5k_led_event(sc, ATH_LED_RX);
1883next: 1924next:
1884 list_move_tail(&bf->list, &sc->rxbuf); 1925 list_move_tail(&bf->list, &sc->rxbuf);
@@ -1897,6 +1938,7 @@ static void
1897ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) 1938ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1898{ 1939{
1899 struct ieee80211_tx_status txs = {}; 1940 struct ieee80211_tx_status txs = {};
1941 struct ath5k_tx_status ts = {};
1900 struct ath5k_buf *bf, *bf0; 1942 struct ath5k_buf *bf, *bf0;
1901 struct ath5k_desc *ds; 1943 struct ath5k_desc *ds;
1902 struct sk_buff *skb; 1944 struct sk_buff *skb;
@@ -1909,7 +1951,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1909 /* TODO only one segment */ 1951 /* TODO only one segment */
1910 pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr, 1952 pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,
1911 sc->desc_len, PCI_DMA_FROMDEVICE); 1953 sc->desc_len, PCI_DMA_FROMDEVICE);
1912 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds); 1954 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
1913 if (unlikely(ret == -EINPROGRESS)) 1955 if (unlikely(ret == -EINPROGRESS))
1914 break; 1956 break;
1915 else if (unlikely(ret)) { 1957 else if (unlikely(ret)) {
@@ -1924,17 +1966,16 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1924 PCI_DMA_TODEVICE); 1966 PCI_DMA_TODEVICE);
1925 1967
1926 txs.control = bf->ctl; 1968 txs.control = bf->ctl;
1927 txs.retry_count = ds->ds_txstat.ts_shortretry + 1969 txs.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
1928 ds->ds_txstat.ts_longretry / 6; 1970 if (unlikely(ts.ts_status)) {
1929 if (unlikely(ds->ds_txstat.ts_status)) {
1930 sc->ll_stats.dot11ACKFailureCount++; 1971 sc->ll_stats.dot11ACKFailureCount++;
1931 if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY) 1972 if (ts.ts_status & AR5K_TXERR_XRETRY)
1932 txs.excessive_retries = 1; 1973 txs.excessive_retries = 1;
1933 else if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT) 1974 else if (ts.ts_status & AR5K_TXERR_FILT)
1934 txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED; 1975 txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED;
1935 } else { 1976 } else {
1936 txs.flags |= IEEE80211_TX_STATUS_ACK; 1977 txs.flags |= IEEE80211_TX_STATUS_ACK;
1937 txs.ack_signal = ds->ds_txstat.ts_rssi; 1978 txs.ack_signal = ts.ts_rssi;
1938 } 1979 }
1939 1980
1940 ieee80211_tx_status(sc->hw, skb, &txs); 1981 ieee80211_tx_status(sc->hw, skb, &txs);
@@ -2108,7 +2149,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2108 * beacon timer registers. 2149 * beacon timer registers.
2109 * 2150 *
2110 * This is called in a variety of situations, e.g. when a beacon is received, 2151 * This is called in a variety of situations, e.g. when a beacon is received,
2111 * when a HW merge has been detected, but also when an new IBSS is created or 2152 * when a TSF update has been detected, but also when an new IBSS is created or
2112 * when we otherwise know we have to update the timers, but we keep it in this 2153 * when we otherwise know we have to update the timers, but we keep it in this
2113 * function to have it all together in one place. 2154 * function to have it all together in one place.
2114 */ 2155 */
@@ -2208,7 +2249,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
2208 * another AP to associate with. 2249 * another AP to associate with.
2209 * 2250 *
2210 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA 2251 * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
2211 * interrupts to detect HW merges only. 2252 * interrupts to detect TSF updates only.
2212 * 2253 *
2213 * AP mode is missing. 2254 * AP mode is missing.
2214 */ 2255 */
@@ -2228,7 +2269,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
2228 * hardware send the beacons automatically. We have to load it 2269 * hardware send the beacons automatically. We have to load it
2229 * only once here. 2270 * only once here.
2230 * We use the SWBA interrupt only to keep track of the beacon 2271 * We use the SWBA interrupt only to keep track of the beacon
2231 * timers in order to detect HW merges (automatic TSF updates). 2272 * timers in order to detect automatic TSF updates.
2232 */ 2273 */
2233 ath5k_beaconq_config(sc); 2274 ath5k_beaconq_config(sc);
2234 2275
@@ -2441,8 +2482,8 @@ ath5k_intr(int irq, void *dev_id)
2441 * 2482 *
2442 * In IBSS mode we use this interrupt just to 2483 * In IBSS mode we use this interrupt just to
2443 * keep track of the next TBTT (target beacon 2484 * keep track of the next TBTT (target beacon
2444 * transmission time) in order to detect hardware 2485 * transmission time) in order to detect wether
2445 * merges (TSF updates). 2486 * automatic TSF updates happened.
2446 */ 2487 */
2447 if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { 2488 if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
2448 /* XXX: only if VEOL suppported */ 2489 /* XXX: only if VEOL suppported */
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index 05bf4fb8f907..41d5fa34b544 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -200,7 +200,8 @@ static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
200{ 200{
201 struct ath5k_softc *sc = file->private_data; 201 struct ath5k_softc *sc = file->private_data;
202 char buf[100]; 202 char buf[100];
203 snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah)); 203 snprintf(buf, sizeof(buf), "0x%016llx\n",
204 (unsigned long long)ath5k_hw_get_tsf64(sc->ah));
204 return simple_read_from_buffer(user_buf, count, ppos, buf, 19); 205 return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
205} 206}
206 207
@@ -271,7 +272,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
271 272
272 tsf = ath5k_hw_get_tsf64(sc->ah); 273 tsf = ath5k_hw_get_tsf64(sc->ah);
273 len += snprintf(buf+len, sizeof(buf)-len, 274 len += snprintf(buf+len, sizeof(buf)-len,
274 "TSF\t\t0x%016llx\tTU: %08x\n", tsf, TSF_TO_TU(tsf)); 275 "TSF\t\t0x%016llx\tTU: %08x\n",
276 (unsigned long long)tsf, TSF_TO_TU(tsf));
275 277
276 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 278 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
277} 279}
@@ -497,15 +499,18 @@ ath5k_debug_dump_bands(struct ath5k_softc *sc)
497} 499}
498 500
499static inline void 501static inline void
500ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done) 502ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
503 struct ath5k_rx_status *rs)
501{ 504{
502 struct ath5k_desc *ds = bf->desc; 505 struct ath5k_desc *ds = bf->desc;
506 struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
503 507
504 printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n", 508 printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
505 ds, (unsigned long long)bf->daddr, 509 ds, (unsigned long long)bf->daddr,
506 ds->ds_link, ds->ds_data, ds->ds_ctl0, ds->ds_ctl1, 510 ds->ds_link, ds->ds_data,
507 ds->ds_hw[0], ds->ds_hw[1], 511 rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
508 !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!'); 512 rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0,
513 !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
509} 514}
510 515
511void 516void
@@ -513,6 +518,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
513{ 518{
514 struct ath5k_desc *ds; 519 struct ath5k_desc *ds;
515 struct ath5k_buf *bf; 520 struct ath5k_buf *bf;
521 struct ath5k_rx_status rs = {};
516 int status; 522 int status;
517 523
518 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) 524 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
@@ -524,9 +530,9 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
524 spin_lock_bh(&sc->rxbuflock); 530 spin_lock_bh(&sc->rxbuflock);
525 list_for_each_entry(bf, &sc->rxbuf, list) { 531 list_for_each_entry(bf, &sc->rxbuf, list) {
526 ds = bf->desc; 532 ds = bf->desc;
527 status = ah->ah_proc_rx_desc(ah, ds); 533 status = ah->ah_proc_rx_desc(ah, ds, &rs);
528 if (!status) 534 if (!status)
529 ath5k_debug_printrxbuf(bf, status == 0); 535 ath5k_debug_printrxbuf(bf, status == 0, &rs);
530 } 536 }
531 spin_unlock_bh(&sc->rxbuflock); 537 spin_unlock_bh(&sc->rxbuflock);
532} 538}
@@ -550,19 +556,24 @@ ath5k_debug_dump_skb(struct ath5k_softc *sc,
550} 556}
551 557
552void 558void
553ath5k_debug_printtxbuf(struct ath5k_softc *sc, 559ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
554 struct ath5k_buf *bf, int done)
555{ 560{
556 struct ath5k_desc *ds = bf->desc; 561 struct ath5k_desc *ds = bf->desc;
562 struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
563 struct ath5k_tx_status ts = {};
564 int done;
557 565
558 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) 566 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
559 return; 567 return;
560 568
569 done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
570
561 printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x " 571 printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
562 "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link, 572 "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
563 ds->ds_data, ds->ds_ctl0, ds->ds_ctl1, 573 ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
564 ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3], 574 td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
565 !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!'); 575 td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
576 done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
566} 577}
567 578
568#endif /* ifdef CONFIG_ATH5K_DEBUG */ 579#endif /* ifdef CONFIG_ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
index 8c0b5c57c76b..2cf8d18b10e3 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -160,8 +160,7 @@ ath5k_debug_dump_skb(struct ath5k_softc *sc,
160 struct sk_buff *skb, const char *prefix, int tx); 160 struct sk_buff *skb, const char *prefix, int tx);
161 161
162void 162void
163ath5k_debug_printtxbuf(struct ath5k_softc *sc, 163ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
164 struct ath5k_buf *bf, int done);
165 164
166#else /* no debugging */ 165#else /* no debugging */
167 166
@@ -199,8 +198,7 @@ ath5k_debug_dump_skb(struct ath5k_softc *sc,
199 struct sk_buff *skb, const char *prefix, int tx) {} 198 struct sk_buff *skb, const char *prefix, int tx) {}
200 199
201static inline void 200static inline void
202ath5k_debug_printtxbuf(struct ath5k_softc *sc, 201ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
203 struct ath5k_buf *bf, int done) {}
204 202
205#endif /* ifdef CONFIG_ATH5K_DEBUG */ 203#endif /* ifdef CONFIG_ATH5K_DEBUG */
206 204
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index eec2b806a0de..a4e312d4226e 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -48,14 +48,18 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
48static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *, 48static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
49 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, 49 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
50 unsigned int); 50 unsigned int);
51static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *); 51static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
52 struct ath5k_tx_status *);
52static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, 53static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
53 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, 54 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
54 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, 55 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
55 unsigned int, unsigned int); 56 unsigned int, unsigned int);
56static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *); 57static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *,
57static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *, struct ath5k_desc *); 58 struct ath5k_tx_status *);
58static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *, struct ath5k_desc *); 59static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *, struct ath5k_desc *,
60 struct ath5k_rx_status *);
61static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *, struct ath5k_desc *,
62 struct ath5k_rx_status *);
59static int ath5k_hw_get_capabilities(struct ath5k_hw *); 63static int ath5k_hw_get_capabilities(struct ath5k_hw *);
60 64
61static int ath5k_eeprom_init(struct ath5k_hw *); 65static int ath5k_eeprom_init(struct ath5k_hw *);
@@ -174,9 +178,9 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
174 } 178 }
175 179
176 if (ah->ah_version == AR5K_AR5212) 180 if (ah->ah_version == AR5K_AR5212)
177 ah->ah_proc_rx_desc = ath5k_hw_proc_new_rx_status; 181 ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
178 else if (ah->ah_version <= AR5K_AR5211) 182 else if (ah->ah_version <= AR5K_AR5211)
179 ah->ah_proc_rx_desc = ath5k_hw_proc_old_rx_status; 183 ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
180 184
181 /* Bring device out of sleep and reset it's units */ 185 /* Bring device out of sleep and reset it's units */
182 ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true); 186 ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true);
@@ -208,7 +212,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
208 212
209 /* Identify single chip solutions */ 213 /* Identify single chip solutions */
210 if((srev <= AR5K_SREV_VER_AR5414) && 214 if((srev <= AR5K_SREV_VER_AR5414) &&
211 (srev >= AR5K_SREV_VER_AR2424)) { 215 (srev >= AR5K_SREV_VER_AR2413)) {
212 ah->ah_single_chip = true; 216 ah->ah_single_chip = true;
213 } else { 217 } else {
214 ah->ah_single_chip = false; 218 ah->ah_single_chip = false;
@@ -223,10 +227,33 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
223 ah->ah_radio = AR5K_RF5110; 227 ah->ah_radio = AR5K_RF5110;
224 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) { 228 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
225 ah->ah_radio = AR5K_RF5111; 229 ah->ah_radio = AR5K_RF5111;
226 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) { 230 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
231 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
232
227 ah->ah_radio = AR5K_RF5112; 233 ah->ah_radio = AR5K_RF5112;
234
235 if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
236 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
237 } else {
238 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
239 }
240
241 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
242 ah->ah_radio = AR5K_RF2413;
243 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
228 } else { 244 } else {
245
229 ah->ah_radio = AR5K_RF5413; 246 ah->ah_radio = AR5K_RF5413;
247
248 if (ah->ah_mac_srev <= AR5K_SREV_VER_AR5424 &&
249 ah->ah_mac_srev >= AR5K_SREV_VER_AR2424)
250 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
251 else if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2425)
252 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
253 else
254 ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
255
256
230 } 257 }
231 258
232 ah->ah_phy = AR5K_PHY(0); 259 ah->ah_phy = AR5K_PHY(0);
@@ -277,7 +304,8 @@ err:
277 */ 304 */
278static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) 305static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
279{ 306{
280 u32 turbo, mode, clock; 307 struct pci_dev *pdev = ah->ah_sc->pdev;
308 u32 turbo, mode, clock, bus_flags;
281 int ret; 309 int ret;
282 310
283 turbo = 0; 311 turbo = 0;
@@ -354,9 +382,15 @@ static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
354 AR5K_PHY_TURBO); 382 AR5K_PHY_TURBO);
355 } 383 }
356 384
357 /* ...reset chipset and PCI device */ 385 /* reseting PCI on PCI-E cards results card to hang
358 if (ah->ah_single_chip == false && ath5k_hw_nic_reset(ah, 386 * and always return 0xffff... so we ingore that flag
359 AR5K_RESET_CTL_CHIP | AR5K_RESET_CTL_PCI)) { 387 * for PCI-E cards */
388 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
389
390 /* Reset chipset */
391 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
392 AR5K_RESET_CTL_BASEBAND | bus_flags);
393 if (ret) {
360 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip + PCI\n"); 394 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip + PCI\n");
361 return -EIO; 395 return -EIO;
362 } 396 }
@@ -565,7 +599,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
565 struct ieee80211_channel *channel, bool change_channel) 599 struct ieee80211_channel *channel, bool change_channel)
566{ 600{
567 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 601 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
568 u32 data, s_seq, s_ant, s_led[3]; 602 struct pci_dev *pdev = ah->ah_sc->pdev;
603 u32 data, s_seq, s_ant, s_led[3], dma_size;
569 unsigned int i, mode, freq, ee_mode, ant[2]; 604 unsigned int i, mode, freq, ee_mode, ant[2];
570 int ret; 605 int ret;
571 606
@@ -617,7 +652,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
617 if (ah->ah_version != AR5K_AR5210) { 652 if (ah->ah_version != AR5K_AR5210) {
618 if (ah->ah_radio != AR5K_RF5111 && 653 if (ah->ah_radio != AR5K_RF5111 &&
619 ah->ah_radio != AR5K_RF5112 && 654 ah->ah_radio != AR5K_RF5112 &&
620 ah->ah_radio != AR5K_RF5413) { 655 ah->ah_radio != AR5K_RF5413 &&
656 ah->ah_radio != AR5K_RF2413) {
621 ATH5K_ERR(ah->ah_sc, 657 ATH5K_ERR(ah->ah_sc,
622 "invalid phy radio: %u\n", ah->ah_radio); 658 "invalid phy radio: %u\n", ah->ah_radio);
623 return -EINVAL; 659 return -EINVAL;
@@ -692,15 +728,26 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
692 /* 728 /*
693 * Write some more initial register settings 729 * Write some more initial register settings
694 */ 730 */
695 if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ 731 if (ah->ah_version == AR5K_AR5212) {
696 ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); 732 ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
697 733
698 if (channel->hw_value == CHANNEL_G) 734 if (channel->hw_value == CHANNEL_G)
699 ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ 735 if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
736 ath5k_hw_reg_write(ah, 0x00f80d80,
737 AR5K_PHY(83));
738 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
739 ath5k_hw_reg_write(ah, 0x00380140,
740 AR5K_PHY(83));
741 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
742 ath5k_hw_reg_write(ah, 0x00fc0ec0,
743 AR5K_PHY(83));
744 else /* 2425 */
745 ath5k_hw_reg_write(ah, 0x00fc0fc0,
746 AR5K_PHY(83));
700 else 747 else
701 ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); 748 ath5k_hw_reg_write(ah, 0x00000000,
749 AR5K_PHY(83));
702 750
703 ath5k_hw_reg_write(ah, 0x000001b5, 0xa228); /* 0x000009b5 */
704 ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); 751 ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
705 ath5k_hw_reg_write(ah, 0x0000000f, 0x8060); 752 ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
706 ath5k_hw_reg_write(ah, 0x00000000, 0xa254); 753 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
@@ -876,13 +923,24 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
876 923
877 /* 924 /*
878 * Set Rx/Tx DMA Configuration 925 * Set Rx/Tx DMA Configuration
879 *(passing dma size not available on 5210) 926 *
927 * Set maximum DMA size (512) except for PCI-E cards since
928 * it causes rx overruns and tx errors (tested on 5424 but since
929 * rx overruns also occur on 5416/5418 with madwifi we set 128
930 * for all PCI-E cards to be safe).
931 *
932 * In dumps this is 128 for allchips.
933 *
934 * XXX: need to check 5210 for this
935 * TODO: Check out tx triger level, it's always 64 on dumps but I
936 * guess we can tweak it and see how it goes ;-)
880 */ 937 */
938 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
881 if (ah->ah_version != AR5K_AR5210) { 939 if (ah->ah_version != AR5K_AR5210) {
882 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR, 940 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
883 AR5K_DMASIZE_512B | AR5K_TXCFG_DMASIZE); 941 AR5K_TXCFG_SDMAMR, dma_size);
884 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_SDMAMW, 942 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
885 AR5K_DMASIZE_512B); 943 AR5K_RXCFG_SDMAMW, dma_size);
886 } 944 }
887 945
888 /* 946 /*
@@ -972,6 +1030,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
972 1030
973 /* 1031 /*
974 * Set the 32MHz reference clock on 5212 phy clock sleep register 1032 * Set the 32MHz reference clock on 5212 phy clock sleep register
1033 *
1034 * TODO: Find out how to switch to external 32Khz clock to save power
975 */ 1035 */
976 if (ah->ah_version == AR5K_AR5212) { 1036 if (ah->ah_version == AR5K_AR5212) {
977 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR); 1037 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
@@ -979,9 +1039,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
979 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL); 1039 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
980 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); 1040 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
981 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); 1041 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
982 ath5k_hw_reg_write(ah, ah->ah_radio == AR5K_RF5111 ? 1042 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
983 AR5K_PHY_SPENDING_RF5111 : AR5K_PHY_SPENDING_RF5112, 1043 }
984 AR5K_PHY_SPENDING); 1044
1045 if (ah->ah_version == AR5K_AR5212) {
1046 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
1047 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
1048 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
1049 if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
1050 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
985 } 1051 }
986 1052
987 /* 1053 /*
@@ -2228,8 +2294,8 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
2228 * Set simple BSSID mask on 5212 2294 * Set simple BSSID mask on 5212
2229 */ 2295 */
2230 if (ah->ah_version == AR5K_AR5212) { 2296 if (ah->ah_version == AR5K_AR5212) {
2231 ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM0); 2297 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
2232 ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM1); 2298 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
2233 } 2299 }
2234 2300
2235 /* 2301 /*
@@ -2374,6 +2440,8 @@ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
2374{ 2440{
2375 ATH5K_TRACE(ah->ah_sc); 2441 ATH5K_TRACE(ah->ah_sc);
2376 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); 2442 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
2443
2444 /* TODO: ANI Support */
2377} 2445}
2378 2446
2379/* 2447/*
@@ -2383,6 +2451,8 @@ void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah)
2383{ 2451{
2384 ATH5K_TRACE(ah->ah_sc); 2452 ATH5K_TRACE(ah->ah_sc);
2385 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); 2453 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
2454
2455 /* TODO: ANI Support */
2386} 2456}
2387 2457
2388/* 2458/*
@@ -3456,10 +3526,10 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3456 unsigned int rtscts_rate, unsigned int rtscts_duration) 3526 unsigned int rtscts_rate, unsigned int rtscts_duration)
3457{ 3527{
3458 u32 frame_type; 3528 u32 frame_type;
3459 struct ath5k_hw_2w_tx_desc *tx_desc; 3529 struct ath5k_hw_2w_tx_ctl *tx_ctl;
3460 unsigned int frame_len; 3530 unsigned int frame_len;
3461 3531
3462 tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0; 3532 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
3463 3533
3464 /* 3534 /*
3465 * Validate input 3535 * Validate input
@@ -3478,12 +3548,8 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3478 return -EINVAL; 3548 return -EINVAL;
3479 } 3549 }
3480 3550
3481 /* Clear status descriptor */ 3551 /* Clear descriptor */
3482 memset(desc->ds_hw, 0, sizeof(struct ath5k_hw_tx_status)); 3552 memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
3483
3484 /* Initialize control descriptor */
3485 tx_desc->tx_control_0 = 0;
3486 tx_desc->tx_control_1 = 0;
3487 3553
3488 /* Setup control descriptor */ 3554 /* Setup control descriptor */
3489 3555
@@ -3495,7 +3561,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3495 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) 3561 if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
3496 return -EINVAL; 3562 return -EINVAL;
3497 3563
3498 tx_desc->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; 3564 tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
3499 3565
3500 /* Verify and set buffer length */ 3566 /* Verify and set buffer length */
3501 3567
@@ -3506,7 +3572,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3506 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) 3572 if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
3507 return -EINVAL; 3573 return -EINVAL;
3508 3574
3509 tx_desc->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; 3575 tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
3510 3576
3511 /* 3577 /*
3512 * Verify and set header length 3578 * Verify and set header length
@@ -3515,7 +3581,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3515 if (ah->ah_version == AR5K_AR5210) { 3581 if (ah->ah_version == AR5K_AR5210) {
3516 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) 3582 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
3517 return -EINVAL; 3583 return -EINVAL;
3518 tx_desc->tx_control_0 |= 3584 tx_ctl->tx_control_0 |=
3519 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); 3585 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
3520 } 3586 }
3521 3587
@@ -3531,19 +3597,19 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3531 frame_type = type /*<< 2 ?*/; 3597 frame_type = type /*<< 2 ?*/;
3532 } 3598 }
3533 3599
3534 tx_desc->tx_control_0 |= 3600 tx_ctl->tx_control_0 |=
3535 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | 3601 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
3536 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); 3602 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3537 } else { 3603 } else {
3538 tx_desc->tx_control_0 |= 3604 tx_ctl->tx_control_0 |=
3539 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | 3605 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
3540 AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); 3606 AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
3541 tx_desc->tx_control_1 |= 3607 tx_ctl->tx_control_1 |=
3542 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); 3608 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
3543 } 3609 }
3544#define _TX_FLAGS(_c, _flag) \ 3610#define _TX_FLAGS(_c, _flag) \
3545 if (flags & AR5K_TXDESC_##_flag) \ 3611 if (flags & AR5K_TXDESC_##_flag) \
3546 tx_desc->tx_control_##_c |= \ 3612 tx_ctl->tx_control_##_c |= \
3547 AR5K_2W_TX_DESC_CTL##_c##_##_flag 3613 AR5K_2W_TX_DESC_CTL##_c##_##_flag
3548 3614
3549 _TX_FLAGS(0, CLRDMASK); 3615 _TX_FLAGS(0, CLRDMASK);
@@ -3558,9 +3624,9 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3558 * WEP crap 3624 * WEP crap
3559 */ 3625 */
3560 if (key_index != AR5K_TXKEYIX_INVALID) { 3626 if (key_index != AR5K_TXKEYIX_INVALID) {
3561 tx_desc->tx_control_0 |= 3627 tx_ctl->tx_control_0 |=
3562 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 3628 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3563 tx_desc->tx_control_1 |= 3629 tx_ctl->tx_control_1 |=
3564 AR5K_REG_SM(key_index, 3630 AR5K_REG_SM(key_index,
3565 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); 3631 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3566 } 3632 }
@@ -3570,7 +3636,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3570 */ 3636 */
3571 if ((ah->ah_version == AR5K_AR5210) && 3637 if ((ah->ah_version == AR5K_AR5210) &&
3572 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) 3638 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
3573 tx_desc->tx_control_1 |= rtscts_duration & 3639 tx_ctl->tx_control_1 |= rtscts_duration &
3574 AR5K_2W_TX_DESC_CTL1_RTS_DURATION; 3640 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
3575 3641
3576 return 0; 3642 return 0;
@@ -3586,13 +3652,11 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3586 unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate, 3652 unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate,
3587 unsigned int rtscts_duration) 3653 unsigned int rtscts_duration)
3588{ 3654{
3589 struct ath5k_hw_4w_tx_desc *tx_desc; 3655 struct ath5k_hw_4w_tx_ctl *tx_ctl;
3590 struct ath5k_hw_tx_status *tx_status;
3591 unsigned int frame_len; 3656 unsigned int frame_len;
3592 3657
3593 ATH5K_TRACE(ah->ah_sc); 3658 ATH5K_TRACE(ah->ah_sc);
3594 tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; 3659 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
3595 tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2];
3596 3660
3597 /* 3661 /*
3598 * Validate input 3662 * Validate input
@@ -3611,14 +3675,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3611 return -EINVAL; 3675 return -EINVAL;
3612 } 3676 }
3613 3677
3614 /* Clear status descriptor */ 3678 /* Clear descriptor */
3615 memset(tx_status, 0, sizeof(struct ath5k_hw_tx_status)); 3679 memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
3616
3617 /* Initialize control descriptor */
3618 tx_desc->tx_control_0 = 0;
3619 tx_desc->tx_control_1 = 0;
3620 tx_desc->tx_control_2 = 0;
3621 tx_desc->tx_control_3 = 0;
3622 3680
3623 /* Setup control descriptor */ 3681 /* Setup control descriptor */
3624 3682
@@ -3630,7 +3688,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3630 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) 3688 if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
3631 return -EINVAL; 3689 return -EINVAL;
3632 3690
3633 tx_desc->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; 3691 tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
3634 3692
3635 /* Verify and set buffer length */ 3693 /* Verify and set buffer length */
3636 3694
@@ -3641,20 +3699,20 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3641 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) 3699 if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
3642 return -EINVAL; 3700 return -EINVAL;
3643 3701
3644 tx_desc->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; 3702 tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
3645 3703
3646 tx_desc->tx_control_0 |= 3704 tx_ctl->tx_control_0 |=
3647 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | 3705 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
3648 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); 3706 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
3649 tx_desc->tx_control_1 |= AR5K_REG_SM(type, 3707 tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
3650 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); 3708 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
3651 tx_desc->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, 3709 tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
3652 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); 3710 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
3653 tx_desc->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; 3711 tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
3654 3712
3655#define _TX_FLAGS(_c, _flag) \ 3713#define _TX_FLAGS(_c, _flag) \
3656 if (flags & AR5K_TXDESC_##_flag) \ 3714 if (flags & AR5K_TXDESC_##_flag) \
3657 tx_desc->tx_control_##_c |= \ 3715 tx_ctl->tx_control_##_c |= \
3658 AR5K_4W_TX_DESC_CTL##_c##_##_flag 3716 AR5K_4W_TX_DESC_CTL##_c##_##_flag
3659 3717
3660 _TX_FLAGS(0, CLRDMASK); 3718 _TX_FLAGS(0, CLRDMASK);
@@ -3670,8 +3728,8 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3670 * WEP crap 3728 * WEP crap
3671 */ 3729 */
3672 if (key_index != AR5K_TXKEYIX_INVALID) { 3730 if (key_index != AR5K_TXKEYIX_INVALID) {
3673 tx_desc->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; 3731 tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3674 tx_desc->tx_control_1 |= AR5K_REG_SM(key_index, 3732 tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
3675 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); 3733 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3676 } 3734 }
3677 3735
@@ -3682,9 +3740,9 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3682 if ((flags & AR5K_TXDESC_RTSENA) && 3740 if ((flags & AR5K_TXDESC_RTSENA) &&
3683 (flags & AR5K_TXDESC_CTSENA)) 3741 (flags & AR5K_TXDESC_CTSENA))
3684 return -EINVAL; 3742 return -EINVAL;
3685 tx_desc->tx_control_2 |= rtscts_duration & 3743 tx_ctl->tx_control_2 |= rtscts_duration &
3686 AR5K_4W_TX_DESC_CTL2_RTS_DURATION; 3744 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
3687 tx_desc->tx_control_3 |= AR5K_REG_SM(rtscts_rate, 3745 tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
3688 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); 3746 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
3689 } 3747 }
3690 3748
@@ -3699,7 +3757,7 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3699 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2, 3757 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
3700 unsigned int tx_rate3, u_int tx_tries3) 3758 unsigned int tx_rate3, u_int tx_tries3)
3701{ 3759{
3702 struct ath5k_hw_4w_tx_desc *tx_desc; 3760 struct ath5k_hw_4w_tx_ctl *tx_ctl;
3703 3761
3704 /* 3762 /*
3705 * Rates can be 0 as long as the retry count is 0 too. 3763 * Rates can be 0 as long as the retry count is 0 too.
@@ -3716,14 +3774,14 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3716 } 3774 }
3717 3775
3718 if (ah->ah_version == AR5K_AR5212) { 3776 if (ah->ah_version == AR5K_AR5212) {
3719 tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; 3777 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
3720 3778
3721#define _XTX_TRIES(_n) \ 3779#define _XTX_TRIES(_n) \
3722 if (tx_tries##_n) { \ 3780 if (tx_tries##_n) { \
3723 tx_desc->tx_control_2 |= \ 3781 tx_ctl->tx_control_2 |= \
3724 AR5K_REG_SM(tx_tries##_n, \ 3782 AR5K_REG_SM(tx_tries##_n, \
3725 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \ 3783 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
3726 tx_desc->tx_control_3 |= \ 3784 tx_ctl->tx_control_3 |= \
3727 AR5K_REG_SM(tx_rate##_n, \ 3785 AR5K_REG_SM(tx_rate##_n, \
3728 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \ 3786 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
3729 } 3787 }
@@ -3744,13 +3802,15 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3744 * Proccess the tx status descriptor on 5210/5211 3802 * Proccess the tx status descriptor on 5210/5211
3745 */ 3803 */
3746static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, 3804static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
3747 struct ath5k_desc *desc) 3805 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
3748{ 3806{
3807 struct ath5k_hw_2w_tx_ctl *tx_ctl;
3749 struct ath5k_hw_tx_status *tx_status; 3808 struct ath5k_hw_tx_status *tx_status;
3750 struct ath5k_hw_2w_tx_desc *tx_desc;
3751 3809
3752 tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0; 3810 ATH5K_TRACE(ah->ah_sc);
3753 tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[0]; 3811
3812 tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
3813 tx_status = &desc->ud.ds_tx5210.tx_stat;
3754 3814
3755 /* No frame has been send or error */ 3815 /* No frame has been send or error */
3756 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) 3816 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
@@ -3759,32 +3819,32 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
3759 /* 3819 /*
3760 * Get descriptor status 3820 * Get descriptor status
3761 */ 3821 */
3762 desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, 3822 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
3763 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 3823 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
3764 desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 3824 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
3765 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 3825 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
3766 desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 3826 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
3767 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 3827 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
3768 /*TODO: desc->ds_us.tx.ts_virtcol + test*/ 3828 /*TODO: ts->ts_virtcol + test*/
3769 desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 3829 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
3770 AR5K_DESC_TX_STATUS1_SEQ_NUM); 3830 AR5K_DESC_TX_STATUS1_SEQ_NUM);
3771 desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 3831 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
3772 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 3832 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
3773 desc->ds_us.tx.ts_antenna = 1; 3833 ts->ts_antenna = 1;
3774 desc->ds_us.tx.ts_status = 0; 3834 ts->ts_status = 0;
3775 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_0, 3835 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0,
3776 AR5K_2W_TX_DESC_CTL0_XMIT_RATE); 3836 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3777 3837
3778 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ 3838 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3779 if (tx_status->tx_status_0 & 3839 if (tx_status->tx_status_0 &
3780 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) 3840 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
3781 desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY; 3841 ts->ts_status |= AR5K_TXERR_XRETRY;
3782 3842
3783 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 3843 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
3784 desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO; 3844 ts->ts_status |= AR5K_TXERR_FIFO;
3785 3845
3786 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) 3846 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
3787 desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT; 3847 ts->ts_status |= AR5K_TXERR_FILT;
3788 } 3848 }
3789 3849
3790 return 0; 3850 return 0;
@@ -3794,14 +3854,15 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
3794 * Proccess a tx descriptor on 5212 3854 * Proccess a tx descriptor on 5212
3795 */ 3855 */
3796static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, 3856static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
3797 struct ath5k_desc *desc) 3857 struct ath5k_desc *desc, struct ath5k_tx_status *ts)
3798{ 3858{
3859 struct ath5k_hw_4w_tx_ctl *tx_ctl;
3799 struct ath5k_hw_tx_status *tx_status; 3860 struct ath5k_hw_tx_status *tx_status;
3800 struct ath5k_hw_4w_tx_desc *tx_desc;
3801 3861
3802 ATH5K_TRACE(ah->ah_sc); 3862 ATH5K_TRACE(ah->ah_sc);
3803 tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0; 3863
3804 tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2]; 3864 tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
3865 tx_status = &desc->ud.ds_tx5212.tx_stat;
3805 3866
3806 /* No frame has been send or error */ 3867 /* No frame has been send or error */
3807 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) 3868 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
@@ -3810,42 +3871,42 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
3810 /* 3871 /*
3811 * Get descriptor status 3872 * Get descriptor status
3812 */ 3873 */
3813 desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, 3874 ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
3814 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); 3875 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
3815 desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, 3876 ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
3816 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); 3877 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
3817 desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, 3878 ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
3818 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); 3879 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
3819 desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, 3880 ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
3820 AR5K_DESC_TX_STATUS1_SEQ_NUM); 3881 AR5K_DESC_TX_STATUS1_SEQ_NUM);
3821 desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, 3882 ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
3822 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 3883 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
3823 desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 & 3884 ts->ts_antenna = (tx_status->tx_status_1 &
3824 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; 3885 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
3825 desc->ds_us.tx.ts_status = 0; 3886 ts->ts_status = 0;
3826 3887
3827 switch (AR5K_REG_MS(tx_status->tx_status_1, 3888 switch (AR5K_REG_MS(tx_status->tx_status_1,
3828 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) { 3889 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
3829 case 0: 3890 case 0:
3830 desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 & 3891 ts->ts_rate = tx_ctl->tx_control_3 &
3831 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; 3892 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
3832 break; 3893 break;
3833 case 1: 3894 case 1:
3834 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, 3895 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
3835 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); 3896 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
3836 desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, 3897 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
3837 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); 3898 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
3838 break; 3899 break;
3839 case 2: 3900 case 2:
3840 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, 3901 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
3841 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); 3902 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
3842 desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, 3903 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
3843 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); 3904 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
3844 break; 3905 break;
3845 case 3: 3906 case 3:
3846 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3, 3907 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
3847 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); 3908 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
3848 desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2, 3909 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
3849 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3); 3910 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
3850 break; 3911 break;
3851 } 3912 }
@@ -3853,13 +3914,13 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
3853 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ 3914 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3854 if (tx_status->tx_status_0 & 3915 if (tx_status->tx_status_0 &
3855 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) 3916 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
3856 desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY; 3917 ts->ts_status |= AR5K_TXERR_XRETRY;
3857 3918
3858 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) 3919 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
3859 desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO; 3920 ts->ts_status |= AR5K_TXERR_FIFO;
3860 3921
3861 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) 3922 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
3862 desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT; 3923 ts->ts_status |= AR5K_TXERR_FILT;
3863 } 3924 }
3864 3925
3865 return 0; 3926 return 0;
@@ -3875,31 +3936,27 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
3875int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, 3936int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3876 u32 size, unsigned int flags) 3937 u32 size, unsigned int flags)
3877{ 3938{
3878 struct ath5k_rx_desc *rx_desc; 3939 struct ath5k_hw_rx_ctl *rx_ctl;
3879 3940
3880 ATH5K_TRACE(ah->ah_sc); 3941 ATH5K_TRACE(ah->ah_sc);
3881 rx_desc = (struct ath5k_rx_desc *)&desc->ds_ctl0; 3942 rx_ctl = &desc->ud.ds_rx.rx_ctl;
3882 3943
3883 /* 3944 /*
3884 *Clear ds_hw 3945 * Clear the descriptor
3885 * If we don't clean the status descriptor, 3946 * If we don't clean the status descriptor,
3886 * while scanning we get too many results, 3947 * while scanning we get too many results,
3887 * most of them virtual, after some secs 3948 * most of them virtual, after some secs
3888 * of scanning system hangs. M.F. 3949 * of scanning system hangs. M.F.
3889 */ 3950 */
3890 memset(desc->ds_hw, 0, sizeof(desc->ds_hw)); 3951 memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
3891
3892 /*Initialize rx descriptor*/
3893 rx_desc->rx_control_0 = 0;
3894 rx_desc->rx_control_1 = 0;
3895 3952
3896 /* Setup descriptor */ 3953 /* Setup descriptor */
3897 rx_desc->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; 3954 rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
3898 if (unlikely(rx_desc->rx_control_1 != size)) 3955 if (unlikely(rx_ctl->rx_control_1 != size))
3899 return -EINVAL; 3956 return -EINVAL;
3900 3957
3901 if (flags & AR5K_RXDESC_INTREQ) 3958 if (flags & AR5K_RXDESC_INTREQ)
3902 rx_desc->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; 3959 rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
3903 3960
3904 return 0; 3961 return 0;
3905} 3962}
@@ -3907,67 +3964,68 @@ int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3907/* 3964/*
3908 * Proccess the rx status descriptor on 5210/5211 3965 * Proccess the rx status descriptor on 5210/5211
3909 */ 3966 */
3910static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *ah, 3967static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
3911 struct ath5k_desc *desc) 3968 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
3912{ 3969{
3913 struct ath5k_hw_old_rx_status *rx_status; 3970 struct ath5k_hw_rx_status *rx_status;
3914 3971
3915 rx_status = (struct ath5k_hw_old_rx_status *)&desc->ds_hw[0]; 3972 rx_status = &desc->ud.ds_rx.u.rx_stat;
3916 3973
3917 /* No frame received / not ready */ 3974 /* No frame received / not ready */
3918 if (unlikely((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_DONE) 3975 if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE)
3919 == 0)) 3976 == 0))
3920 return -EINPROGRESS; 3977 return -EINPROGRESS;
3921 3978
3922 /* 3979 /*
3923 * Frame receive status 3980 * Frame receive status
3924 */ 3981 */
3925 desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 & 3982 rs->rs_datalen = rx_status->rx_status_0 &
3926 AR5K_OLD_RX_DESC_STATUS0_DATA_LEN; 3983 AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
3927 desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, 3984 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
3928 AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL); 3985 AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
3929 desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 3986 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
3930 AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE); 3987 AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
3931 desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 & 3988 rs->rs_antenna = rx_status->rx_status_0 &
3932 AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA; 3989 AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA;
3933 desc->ds_us.rx.rs_more = rx_status->rx_status_0 & 3990 rs->rs_more = rx_status->rx_status_0 &
3934 AR5K_OLD_RX_DESC_STATUS0_MORE; 3991 AR5K_5210_RX_DESC_STATUS0_MORE;
3935 desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, 3992 /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
3936 AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 3993 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
3937 desc->ds_us.rx.rs_status = 0; 3994 AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
3995 rs->rs_status = 0;
3938 3996
3939 /* 3997 /*
3940 * Key table status 3998 * Key table status
3941 */ 3999 */
3942 if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID) 4000 if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
3943 desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 4001 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
3944 AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX); 4002 AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
3945 else 4003 else
3946 desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID; 4004 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
3947 4005
3948 /* 4006 /*
3949 * Receive/descriptor errors 4007 * Receive/descriptor errors
3950 */ 4008 */
3951 if ((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK) 4009 if ((rx_status->rx_status_1 &
3952 == 0) { 4010 AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
3953 if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR) 4011 if (rx_status->rx_status_1 &
3954 desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC; 4012 AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
4013 rs->rs_status |= AR5K_RXERR_CRC;
3955 4014
3956 if (rx_status->rx_status_1 & 4015 if (rx_status->rx_status_1 &
3957 AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN) 4016 AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
3958 desc->ds_us.rx.rs_status |= AR5K_RXERR_FIFO; 4017 rs->rs_status |= AR5K_RXERR_FIFO;
3959 4018
3960 if (rx_status->rx_status_1 & 4019 if (rx_status->rx_status_1 &
3961 AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR) { 4020 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
3962 desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY; 4021 rs->rs_status |= AR5K_RXERR_PHY;
3963 desc->ds_us.rx.rs_phyerr = 4022 rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
3964 AR5K_REG_MS(rx_status->rx_status_1, 4023 AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
3965 AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR);
3966 } 4024 }
3967 4025
3968 if (rx_status->rx_status_1 & 4026 if (rx_status->rx_status_1 &
3969 AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) 4027 AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
3970 desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT; 4028 rs->rs_status |= AR5K_RXERR_DECRYPT;
3971 } 4029 }
3972 4030
3973 return 0; 4031 return 0;
@@ -3976,71 +4034,72 @@ static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *ah,
3976/* 4034/*
3977 * Proccess the rx status descriptor on 5212 4035 * Proccess the rx status descriptor on 5212
3978 */ 4036 */
3979static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *ah, 4037static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
3980 struct ath5k_desc *desc) 4038 struct ath5k_desc *desc, struct ath5k_rx_status *rs)
3981{ 4039{
3982 struct ath5k_hw_new_rx_status *rx_status; 4040 struct ath5k_hw_rx_status *rx_status;
3983 struct ath5k_hw_rx_error *rx_err; 4041 struct ath5k_hw_rx_error *rx_err;
3984 4042
3985 ATH5K_TRACE(ah->ah_sc); 4043 ATH5K_TRACE(ah->ah_sc);
3986 rx_status = (struct ath5k_hw_new_rx_status *)&desc->ds_hw[0]; 4044 rx_status = &desc->ud.ds_rx.u.rx_stat;
3987 4045
3988 /* Overlay on error */ 4046 /* Overlay on error */
3989 rx_err = (struct ath5k_hw_rx_error *)&desc->ds_hw[0]; 4047 rx_err = &desc->ud.ds_rx.u.rx_err;
3990 4048
3991 /* No frame received / not ready */ 4049 /* No frame received / not ready */
3992 if (unlikely((rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_DONE) 4050 if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE)
3993 == 0)) 4051 == 0))
3994 return -EINPROGRESS; 4052 return -EINPROGRESS;
3995 4053
3996 /* 4054 /*
3997 * Frame receive status 4055 * Frame receive status
3998 */ 4056 */
3999 desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 & 4057 rs->rs_datalen = rx_status->rx_status_0 &
4000 AR5K_NEW_RX_DESC_STATUS0_DATA_LEN; 4058 AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
4001 desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, 4059 rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
4002 AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL); 4060 AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
4003 desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0, 4061 rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
4004 AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE); 4062 AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
4005 desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 & 4063 rs->rs_antenna = rx_status->rx_status_0 &
4006 AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA; 4064 AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA;
4007 desc->ds_us.rx.rs_more = rx_status->rx_status_0 & 4065 rs->rs_more = rx_status->rx_status_0 &
4008 AR5K_NEW_RX_DESC_STATUS0_MORE; 4066 AR5K_5212_RX_DESC_STATUS0_MORE;
4009 desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, 4067 rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
4010 AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); 4068 AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
4011 desc->ds_us.rx.rs_status = 0; 4069 rs->rs_status = 0;
4012 4070
4013 /* 4071 /*
4014 * Key table status 4072 * Key table status
4015 */ 4073 */
4016 if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID) 4074 if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
4017 desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, 4075 rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
4018 AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX); 4076 AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
4019 else 4077 else
4020 desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID; 4078 rs->rs_keyix = AR5K_RXKEYIX_INVALID;
4021 4079
4022 /* 4080 /*
4023 * Receive/descriptor errors 4081 * Receive/descriptor errors
4024 */ 4082 */
4025 if ((rx_status->rx_status_1 & 4083 if ((rx_status->rx_status_1 &
4026 AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) { 4084 AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4027 if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR) 4085 if (rx_status->rx_status_1 &
4028 desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC; 4086 AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
4087 rs->rs_status |= AR5K_RXERR_CRC;
4029 4088
4030 if (rx_status->rx_status_1 & 4089 if (rx_status->rx_status_1 &
4031 AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR) { 4090 AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
4032 desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY; 4091 rs->rs_status |= AR5K_RXERR_PHY;
4033 desc->ds_us.rx.rs_phyerr = 4092 rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1,
4034 AR5K_REG_MS(rx_err->rx_error_1, 4093 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
4035 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
4036 } 4094 }
4037 4095
4038 if (rx_status->rx_status_1 & 4096 if (rx_status->rx_status_1 &
4039 AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) 4097 AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
4040 desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT; 4098 rs->rs_status |= AR5K_RXERR_DECRYPT;
4041 4099
4042 if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR) 4100 if (rx_status->rx_status_1 &
4043 desc->ds_us.rx.rs_status |= AR5K_RXERR_MIC; 4101 AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
4102 rs->rs_status |= AR5K_RXERR_MIC;
4044 } 4103 }
4045 4104
4046 return 0; 4105 return 0;
diff --git a/drivers/net/wireless/ath5k/hw.h b/drivers/net/wireless/ath5k/hw.h
index d9a7c0973f53..64fca8dcb386 100644
--- a/drivers/net/wireless/ath5k/hw.h
+++ b/drivers/net/wireless/ath5k/hw.h
@@ -173,7 +173,10 @@ struct ath5k_eeprom_info {
173 * (rX: reserved fields possibily used by future versions of the ar5k chipset) 173 * (rX: reserved fields possibily used by future versions of the ar5k chipset)
174 */ 174 */
175 175
176struct ath5k_rx_desc { 176/*
177 * common hardware RX control descriptor
178 */
179struct ath5k_hw_rx_ctl {
177 u32 rx_control_0; /* RX control word 0 */ 180 u32 rx_control_0; /* RX control word 0 */
178 181
179#define AR5K_DESC_RX_CTL0 0x00000000 182#define AR5K_DESC_RX_CTL0 0x00000000
@@ -185,69 +188,63 @@ struct ath5k_rx_desc {
185} __packed; 188} __packed;
186 189
187/* 190/*
188 * 5210/5211 rx status descriptor 191 * common hardware RX status descriptor
192 * 5210/11 and 5212 differ only in the flags defined below
189 */ 193 */
190struct ath5k_hw_old_rx_status { 194struct ath5k_hw_rx_status {
191 u32 rx_status_0; /* RX status word 0 */ 195 u32 rx_status_0; /* RX status word 0 */
192
193#define AR5K_OLD_RX_DESC_STATUS0_DATA_LEN 0x00000fff
194#define AR5K_OLD_RX_DESC_STATUS0_MORE 0x00001000
195#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000
196#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE_S 15
197#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000
198#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19
199#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000
200#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27
201
202 u32 rx_status_1; /* RX status word 1 */ 196 u32 rx_status_1; /* RX status word 1 */
203
204#define AR5K_OLD_RX_DESC_STATUS1_DONE 0x00000001
205#define AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
206#define AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR 0x00000004
207#define AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008
208#define AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010
209#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR 0x000000e0
210#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR_S 5
211#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
212#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX 0x00007e00
213#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_S 9
214#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000
215#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15
216#define AR5K_OLD_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000
217} __packed; 197} __packed;
218 198
199/* 5210/5211 */
200#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff
201#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000
202#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000
203#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15
204#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000
205#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19
206#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000
207#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27
208#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001
209#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
210#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004
211#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008
212#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010
213#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0
214#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5
215#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
216#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00
217#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9
218#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000
219#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15
220#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000
221
222/* 5212 */
223#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff
224#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000
225#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000
226#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000
227#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15
228#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000
229#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20
230#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000
231#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28
232#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001
233#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
234#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004
235#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008
236#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010
237#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020
238#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
239#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00
240#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9
241#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000
242#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16
243#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000
244
219/* 245/*
220 * 5212 rx status descriptor 246 * common hardware RX error descriptor
221 */ 247 */
222struct ath5k_hw_new_rx_status {
223 u32 rx_status_0; /* RX status word 0 */
224
225#define AR5K_NEW_RX_DESC_STATUS0_DATA_LEN 0x00000fff
226#define AR5K_NEW_RX_DESC_STATUS0_MORE 0x00001000
227#define AR5K_NEW_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000
228#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000
229#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE_S 15
230#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000
231#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20
232#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000
233#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28
234
235 u32 rx_status_1; /* RX status word 1 */
236
237#define AR5K_NEW_RX_DESC_STATUS1_DONE 0x00000001
238#define AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
239#define AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR 0x00000004
240#define AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008
241#define AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR 0x00000010
242#define AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR 0x00000020
243#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
244#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00
245#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_S 9
246#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000
247#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16
248#define AR5K_NEW_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000
249} __packed;
250
251struct ath5k_hw_rx_error { 248struct ath5k_hw_rx_error {
252 u32 rx_error_0; /* RX error word 0 */ 249 u32 rx_error_0; /* RX error word 0 */
253 250
@@ -268,7 +265,10 @@ struct ath5k_hw_rx_error {
268#define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0 265#define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0
269#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0 266#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0
270 267
271struct ath5k_hw_2w_tx_desc { 268/*
269 * 5210/5211 hardware 2-word TX control descriptor
270 */
271struct ath5k_hw_2w_tx_ctl {
272 u32 tx_control_0; /* TX control word 0 */ 272 u32 tx_control_0; /* TX control word 0 */
273 273
274#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff 274#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff
@@ -314,9 +314,9 @@ struct ath5k_hw_2w_tx_desc {
314#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10 314#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10
315 315
316/* 316/*
317 * 5212 4-word tx control descriptor 317 * 5212 hardware 4-word TX control descriptor
318 */ 318 */
319struct ath5k_hw_4w_tx_desc { 319struct ath5k_hw_4w_tx_ctl {
320 u32 tx_control_0; /* TX control word 0 */ 320 u32 tx_control_0; /* TX control word 0 */
321 321
322#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff 322#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff
@@ -374,7 +374,7 @@ struct ath5k_hw_4w_tx_desc {
374} __packed; 374} __packed;
375 375
376/* 376/*
377 * Common tx status descriptor 377 * Common TX status descriptor
378 */ 378 */
379struct ath5k_hw_tx_status { 379struct ath5k_hw_tx_status {
380 u32 tx_status_0; /* TX status word 0 */ 380 u32 tx_status_0; /* TX status word 0 */
@@ -415,6 +415,34 @@ struct ath5k_hw_tx_status {
415 415
416 416
417/* 417/*
418 * 5210/5211 hardware TX descriptor
419 */
420struct ath5k_hw_5210_tx_desc {
421 struct ath5k_hw_2w_tx_ctl tx_ctl;
422 struct ath5k_hw_tx_status tx_stat;
423} __packed;
424
425/*
426 * 5212 hardware TX descriptor
427 */
428struct ath5k_hw_5212_tx_desc {
429 struct ath5k_hw_4w_tx_ctl tx_ctl;
430 struct ath5k_hw_tx_status tx_stat;
431} __packed;
432
433/*
434 * common hardware RX descriptor
435 */
436struct ath5k_hw_all_rx_desc {
437 struct ath5k_hw_rx_ctl rx_ctl;
438 union {
439 struct ath5k_hw_rx_status rx_stat;
440 struct ath5k_hw_rx_error rx_err;
441 } u;
442} __packed;
443
444
445/*
418 * AR5K REGISTER ACCESS 446 * AR5K REGISTER ACCESS
419 */ 447 */
420 448
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index cfcb1fe7bd34..fdbab2f08178 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -678,8 +678,8 @@ static const struct ath5k_ini ar5212_ini[] = {
678 { AR5K_PHY(644), 0x00806333 }, 678 { AR5K_PHY(644), 0x00806333 },
679 { AR5K_PHY(645), 0x00106c10 }, 679 { AR5K_PHY(645), 0x00106c10 },
680 { AR5K_PHY(646), 0x009c4060 }, 680 { AR5K_PHY(646), 0x009c4060 },
681 /*{ AR5K_PHY(647), 0x1483800a },*/ /* Old value */
682 { AR5K_PHY(647), 0x1483800a }, 681 { AR5K_PHY(647), 0x1483800a },
682 /* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413 */
683 { AR5K_PHY(648), 0x01831061 }, 683 { AR5K_PHY(648), 0x01831061 },
684 { AR5K_PHY(649), 0x00000400 }, 684 { AR5K_PHY(649), 0x00000400 },
685 /*{ AR5K_PHY(650), 0x000001b5 },*/ 685 /*{ AR5K_PHY(650), 0x000001b5 },*/
@@ -1081,6 +1081,207 @@ static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
1081 { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } }, 1081 { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
1082}; 1082};
1083 1083
1084/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
1085/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
1086 * minor tweaking based on dumps from other chips */
1087static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
1088 { AR5K_TXCFG,
1089 /* b g gTurbo */
1090 { 0x00000015, 0x00000015, 0x00000015 } },
1091 { AR5K_USEC_5211,
1092 { 0x04e01395, 0x12e013ab, 0x098813cf } },
1093 { AR5K_PHY(10),
1094 { 0x05020000, 0x0a020001, 0x0a020001 } },
1095 { AR5K_PHY(13),
1096 { 0x00000e00, 0x00000e00, 0x00000e00 } },
1097 { AR5K_PHY(14),
1098 { 0x0000000a, 0x0000000a, 0x0000000a } },
1099 { AR5K_PHY(18),
1100 { 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
1101 { AR5K_PHY(20),
1102 { 0x0de8b0da, 0x0c98b0da, 0x0c98b0da } },
1103 { AR5K_PHY_SIG,
1104 { 0x7ee80d2e, 0x7ec80d2e, 0x7ec80d2e } },
1105 { AR5K_PHY_AGCCOARSE,
1106 { 0x3137665e, 0x3139605e, 0x3139605e } },
1107 { AR5K_PHY(27),
1108 { 0x050cb081, 0x050cb081, 0x050cb081 } },
1109 { AR5K_PHY_RX_DELAY,
1110 { 0x0000044c, 0x00000898, 0x000007d0 } },
1111 { AR5K_PHY_FRAME_CTL_5211,
1112 { 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
1113 { AR5K_PHY_CCKTXCTL,
1114 { 0x00000000, 0x00000000, 0x00000000 } },
1115 { AR5K_PHY(642),
1116 { 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
1117 { AR5K_PHY_GAIN_2GHZ,
1118 { 0x0042c140, 0x0042c140, 0x0042c140 } },
1119 { 0xa21c,
1120 { 0x1863800a, 0x1883800a, 0x1883800a } },
1121 { AR5K_DCU_FP,
1122 { 0x000003e0, 0x000003e0, 0x000003e0 } },
1123 { 0x8060,
1124 { 0x0000000f, 0x0000000f, 0x0000000f } },
1125 { 0x8118,
1126 { 0x00000000, 0x00000000, 0x00000000 } },
1127 { 0x811c,
1128 { 0x00000000, 0x00000000, 0x00000000 } },
1129 { 0x8120,
1130 { 0x00000000, 0x00000000, 0x00000000 } },
1131 { 0x8124,
1132 { 0x00000000, 0x00000000, 0x00000000 } },
1133 { 0x8128,
1134 { 0x00000000, 0x00000000, 0x00000000 } },
1135 { 0x812c,
1136 { 0x00000000, 0x00000000, 0x00000000 } },
1137 { 0x8130,
1138 { 0x00000000, 0x00000000, 0x00000000 } },
1139 { 0x8134,
1140 { 0x00000000, 0x00000000, 0x00000000 } },
1141 { 0x8138,
1142 { 0x00000000, 0x00000000, 0x00000000 } },
1143 { 0x813c,
1144 { 0x00000000, 0x00000000, 0x00000000 } },
1145 { 0x8140,
1146 { 0x800000a8, 0x800000a8, 0x800000a8 } },
1147 { 0x8144,
1148 { 0x00000000, 0x00000000, 0x00000000 } },
1149 { AR5K_PHY_AGC,
1150 { 0x00000000, 0x00000000, 0x00000000 } },
1151 { AR5K_PHY(11),
1152 { 0x0000a000, 0x0000a000, 0x0000a000 } },
1153 { AR5K_PHY(15),
1154 { 0x00200400, 0x00200400, 0x00200400 } },
1155 { AR5K_PHY(19),
1156 { 0x1284233c, 0x1284233c, 0x1284233c } },
1157 { AR5K_PHY_SCR,
1158 { 0x0000001f, 0x0000001f, 0x0000001f } },
1159 { AR5K_PHY_SLMT,
1160 { 0x00000080, 0x00000080, 0x00000080 } },
1161 { AR5K_PHY_SCAL,
1162 { 0x0000000e, 0x0000000e, 0x0000000e } },
1163 { AR5K_PHY(86),
1164 { 0x000000ff, 0x000000ff, 0x000000ff } },
1165 { AR5K_PHY(96),
1166 { 0x00000000, 0x00000000, 0x00000000 } },
1167 { AR5K_PHY(97),
1168 { 0x02800000, 0x02800000, 0x02800000 } },
1169 { AR5K_PHY(104),
1170 { 0x00000000, 0x00000000, 0x00000000 } },
1171 { AR5K_PHY(120),
1172 { 0x00000000, 0x00000000, 0x00000000 } },
1173 { AR5K_PHY(121),
1174 { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
1175 { AR5K_PHY(122),
1176 { 0x3c466478, 0x3c466478, 0x3c466478 } },
1177 { AR5K_PHY(123),
1178 { 0x000000aa, 0x000000aa, 0x000000aa } },
1179 { AR5K_PHY_SCLOCK,
1180 { 0x0000000c, 0x0000000c, 0x0000000c } },
1181 { AR5K_PHY_SDELAY,
1182 { 0x000000ff, 0x000000ff, 0x000000ff } },
1183 { AR5K_PHY_SPENDING,
1184 { 0x00000014, 0x00000014, 0x00000014 } },
1185 { 0xa228,
1186 { 0x000009b5, 0x000009b5, 0x000009b5 } },
1187 { 0xa23c,
1188 { 0x93c889af, 0x93c889af, 0x93c889af } },
1189 { 0xa24c,
1190 { 0x00000001, 0x00000001, 0x00000001 } },
1191 { 0xa250,
1192 { 0x0000a000, 0x0000a000, 0x0000a000 } },
1193 { 0xa254,
1194 { 0x00000000, 0x00000000, 0x00000000 } },
1195 { 0xa258,
1196 { 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
1197 { 0xa25c,
1198 { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
1199 { 0xa260,
1200 { 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
1201 { 0xa264,
1202 { 0x00418a11, 0x00418a11, 0x00418a11 } },
1203 { 0xa268,
1204 { 0x00000000, 0x00000000, 0x00000000 } },
1205 { 0xa26c,
1206 { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
1207 { 0xa270,
1208 { 0x00820820, 0x00820820, 0x00820820 } },
1209 { 0xa274,
1210 { 0x001b7caa, 0x001b7caa, 0x001b7caa } },
1211 { 0xa278,
1212 { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
1213 { 0xa27c,
1214 { 0x051701ce, 0x051701ce, 0x051701ce } },
1215 { 0xa300,
1216 { 0x18010000, 0x18010000, 0x18010000 } },
1217 { 0xa304,
1218 { 0x30032602, 0x30032602, 0x30032602 } },
1219 { 0xa308,
1220 { 0x48073e06, 0x48073e06, 0x48073e06 } },
1221 { 0xa30c,
1222 { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
1223 { 0xa310,
1224 { 0x641a600f, 0x641a600f, 0x641a600f } },
1225 { 0xa314,
1226 { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
1227 { 0xa318,
1228 { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
1229 { 0xa31c,
1230 { 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
1231 { 0xa320,
1232 { 0x9d4f970f, 0x9d4f970f, 0x9d4f970f } },
1233 { 0xa324,
1234 { 0xa5cfa18f, 0xa5cfa18f, 0xa5cfa18f } },
1235 { 0xa328,
1236 { 0xb55faf1f, 0xb55faf1f, 0xb55faf1f } },
1237 { 0xa32c,
1238 { 0xbddfb99f, 0xbddfb99f, 0xbddfb99f } },
1239 { 0xa330,
1240 { 0xcd7fc73f, 0xcd7fc73f, 0xcd7fc73f } },
1241 { 0xa334,
1242 { 0xd5ffd1bf, 0xd5ffd1bf, 0xd5ffd1bf } },
1243 { 0xa338,
1244 { 0x00000000, 0x00000000, 0x00000000 } },
1245 { 0xa33c,
1246 { 0x00000000, 0x00000000, 0x00000000 } },
1247 { 0xa340,
1248 { 0x00000000, 0x00000000, 0x00000000 } },
1249 { 0xa344,
1250 { 0x00000000, 0x00000000, 0x00000000 } },
1251 { 0xa348,
1252 { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1253 { 0xa34c,
1254 { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1255 { 0xa350,
1256 { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1257 { 0xa354,
1258 { 0x0003ffff, 0x0003ffff, 0x0003ffff } },
1259 { 0xa358,
1260 { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
1261 { 0xa35c,
1262 { 0x066c420f, 0x066c420f, 0x066c420f } },
1263 { 0xa360,
1264 { 0x0f282207, 0x0f282207, 0x0f282207 } },
1265 { 0xa364,
1266 { 0x17601685, 0x17601685, 0x17601685 } },
1267 { 0xa368,
1268 { 0x1f801104, 0x1f801104, 0x1f801104 } },
1269 { 0xa36c,
1270 { 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
1271 { 0xa370,
1272 { 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
1273 { 0xa374,
1274 { 0x57c00803, 0x57c00803, 0x57c00803 } },
1275 { 0xa378,
1276 { 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
1277 { 0xa37c,
1278 { 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
1279 { 0xa380,
1280 { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
1281 { 0xa384,
1282 { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
1283};
1284
1084/* 1285/*
1085 * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with 1286 * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with
1086 * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI) 1287 * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI)
@@ -1290,29 +1491,57 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1290 1491
1291 /* Second set of mode-specific settings */ 1492 /* Second set of mode-specific settings */
1292 if (ah->ah_radio == AR5K_RF5111){ 1493 if (ah->ah_radio == AR5K_RF5111){
1494
1293 ath5k_hw_ini_mode_registers(ah, 1495 ath5k_hw_ini_mode_registers(ah,
1294 ARRAY_SIZE(ar5212_rf5111_ini_mode_end), 1496 ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
1295 ar5212_rf5111_ini_mode_end, mode); 1497 ar5212_rf5111_ini_mode_end, mode);
1498
1296 /* Baseband gain table */ 1499 /* Baseband gain table */
1297 ath5k_hw_ini_registers(ah, 1500 ath5k_hw_ini_registers(ah,
1298 ARRAY_SIZE(rf5111_ini_bbgain), 1501 ARRAY_SIZE(rf5111_ini_bbgain),
1299 rf5111_ini_bbgain, change_channel); 1502 rf5111_ini_bbgain, change_channel);
1503
1300 } else if (ah->ah_radio == AR5K_RF5112){ 1504 } else if (ah->ah_radio == AR5K_RF5112){
1505
1301 ath5k_hw_ini_mode_registers(ah, 1506 ath5k_hw_ini_mode_registers(ah,
1302 ARRAY_SIZE(ar5212_rf5112_ini_mode_end), 1507 ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
1303 ar5212_rf5112_ini_mode_end, mode); 1508 ar5212_rf5112_ini_mode_end, mode);
1304 /* Baseband gain table */ 1509
1305 ath5k_hw_ini_registers(ah, 1510 ath5k_hw_ini_registers(ah,
1306 ARRAY_SIZE(rf5112_ini_bbgain), 1511 ARRAY_SIZE(rf5112_ini_bbgain),
1307 rf5112_ini_bbgain, change_channel); 1512 rf5112_ini_bbgain, change_channel);
1513
1308 } else if (ah->ah_radio == AR5K_RF5413){ 1514 } else if (ah->ah_radio == AR5K_RF5413){
1515
1309 ath5k_hw_ini_mode_registers(ah, 1516 ath5k_hw_ini_mode_registers(ah,
1310 ARRAY_SIZE(rf5413_ini_mode_end), 1517 ARRAY_SIZE(rf5413_ini_mode_end),
1311 rf5413_ini_mode_end, mode); 1518 rf5413_ini_mode_end, mode);
1519
1520 ath5k_hw_ini_registers(ah,
1521 ARRAY_SIZE(rf5112_ini_bbgain),
1522 rf5112_ini_bbgain, change_channel);
1523
1524 } else if (ah->ah_radio == AR5K_RF2413) {
1525
1526 if (mode < 2) {
1527 ATH5K_ERR(ah->ah_sc,
1528 "unsupported channel mode: %d\n", mode);
1529 return -EINVAL;
1530 }
1531 mode = mode - 2;
1532
1533 /* Override a setting from ar5212_ini */
1534 ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
1535
1536 ath5k_hw_ini_mode_registers(ah,
1537 ARRAY_SIZE(rf2413_ini_mode_end),
1538 rf2413_ini_mode_end, mode);
1539
1312 /* Baseband gain table */ 1540 /* Baseband gain table */
1313 ath5k_hw_ini_registers(ah, 1541 ath5k_hw_ini_registers(ah,
1314 ARRAY_SIZE(rf5112_ini_bbgain), 1542 ARRAY_SIZE(rf5112_ini_bbgain),
1315 rf5112_ini_bbgain, change_channel); 1543 rf5112_ini_bbgain, change_channel);
1544
1316 } 1545 }
1317 /* For AR5211 */ 1546 /* For AR5211 */
1318 } else if (ah->ah_version == AR5K_AR5211) { 1547 } else if (ah->ah_version == AR5K_AR5211) {
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 405195ffb24d..ee1dc0fc6ea2 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -666,6 +666,75 @@ static const struct ath5k_ini_rf rfregs_5413[] = {
666 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } }, 666 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
667}; 667};
668 668
669/* RF2413/2414 mode-specific init registers */
670static const struct ath5k_ini_rf rfregs_2413[] = {
671 { 1, AR5K_RF_BUFFER_CONTROL_4,
672 { 0x00000020, 0x00000020, 0x00000020 } },
673 { 2, AR5K_RF_BUFFER_CONTROL_3,
674 { 0x02001408, 0x02001408, 0x02001408 } },
675 { 3, AR5K_RF_BUFFER_CONTROL_6,
676 { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
677 { 6, AR5K_RF_BUFFER,
678 { 0xf0000000, 0xf0000000, 0xf0000000 } },
679 { 6, AR5K_RF_BUFFER,
680 { 0x00000000, 0x00000000, 0x00000000 } },
681 { 6, AR5K_RF_BUFFER,
682 { 0x03000000, 0x03000000, 0x03000000 } },
683 { 6, AR5K_RF_BUFFER,
684 { 0x00000000, 0x00000000, 0x00000000 } },
685 { 6, AR5K_RF_BUFFER,
686 { 0x00000000, 0x00000000, 0x00000000 } },
687 { 6, AR5K_RF_BUFFER,
688 { 0x00000000, 0x00000000, 0x00000000 } },
689 { 6, AR5K_RF_BUFFER,
690 { 0x00000000, 0x00000000, 0x00000000 } },
691 { 6, AR5K_RF_BUFFER,
692 { 0x00000000, 0x00000000, 0x00000000 } },
693 { 6, AR5K_RF_BUFFER,
694 { 0x40400000, 0x40400000, 0x40400000 } },
695 { 6, AR5K_RF_BUFFER,
696 { 0x65050000, 0x65050000, 0x65050000 } },
697 { 6, AR5K_RF_BUFFER,
698 { 0x00000000, 0x00000000, 0x00000000 } },
699 { 6, AR5K_RF_BUFFER,
700 { 0x00000000, 0x00000000, 0x00000000 } },
701 { 6, AR5K_RF_BUFFER,
702 { 0x00420000, 0x00420000, 0x00420000 } },
703 { 6, AR5K_RF_BUFFER,
704 { 0x00b50000, 0x00b50000, 0x00b50000 } },
705 { 6, AR5K_RF_BUFFER,
706 { 0x00030000, 0x00030000, 0x00030000 } },
707 { 6, AR5K_RF_BUFFER,
708 { 0x00f70000, 0x00f70000, 0x00f70000 } },
709 { 6, AR5K_RF_BUFFER,
710 { 0x009d0000, 0x009d0000, 0x009d0000 } },
711 { 6, AR5K_RF_BUFFER,
712 { 0x00220000, 0x00220000, 0x00220000 } },
713 { 6, AR5K_RF_BUFFER,
714 { 0x04220000, 0x04220000, 0x04220000 } },
715 { 6, AR5K_RF_BUFFER,
716 { 0x00230018, 0x00230018, 0x00230018 } },
717 { 6, AR5K_RF_BUFFER,
718 { 0x00280050, 0x00280050, 0x00280050 } },
719 { 6, AR5K_RF_BUFFER,
720 { 0x005000c3, 0x005000c3, 0x005000c3 } },
721 { 6, AR5K_RF_BUFFER,
722 { 0x0004007f, 0x0004007f, 0x0004007f } },
723 { 6, AR5K_RF_BUFFER,
724 { 0x00000458, 0x00000458, 0x00000458 } },
725 { 6, AR5K_RF_BUFFER,
726 { 0x00000000, 0x00000000, 0x00000000 } },
727 { 6, AR5K_RF_BUFFER,
728 { 0x0000c000, 0x0000c000, 0x0000c000 } },
729 { 6, AR5K_RF_BUFFER_CONTROL_5,
730 { 0x00400230, 0x00400230, 0x00400230 } },
731 { 7, AR5K_RF_BUFFER,
732 { 0x00006400, 0x00006400, 0x00006400 } },
733 { 7, AR5K_RF_BUFFER,
734 { 0x00000800, 0x00000800, 0x00000800 } },
735 { 7, AR5K_RF_BUFFER_CONTROL_2,
736 { 0x0000000e, 0x0000000e, 0x0000000e } },
737};
669 738
670/* Initial RF Gain settings for RF5112 */ 739/* Initial RF Gain settings for RF5112 */
671static const struct ath5k_ini_rfgain rfgain_5112[] = { 740static const struct ath5k_ini_rfgain rfgain_5112[] = {
@@ -805,6 +874,74 @@ static const struct ath5k_ini_rfgain rfgain_5413[] = {
805 { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } }, 874 { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
806}; 875};
807 876
877/* Initial RF Gain settings for RF2413 */
878static const struct ath5k_ini_rfgain rfgain_2413[] = {
879 { AR5K_RF_GAIN(0), { 0x00000000 } },
880 { AR5K_RF_GAIN(1), { 0x00000040 } },
881 { AR5K_RF_GAIN(2), { 0x00000080 } },
882 { AR5K_RF_GAIN(3), { 0x00000181 } },
883 { AR5K_RF_GAIN(4), { 0x000001c1 } },
884 { AR5K_RF_GAIN(5), { 0x00000001 } },
885 { AR5K_RF_GAIN(6), { 0x00000041 } },
886 { AR5K_RF_GAIN(7), { 0x00000081 } },
887 { AR5K_RF_GAIN(8), { 0x00000168 } },
888 { AR5K_RF_GAIN(9), { 0x000001a8 } },
889 { AR5K_RF_GAIN(10), { 0x000001e8 } },
890 { AR5K_RF_GAIN(11), { 0x00000028 } },
891 { AR5K_RF_GAIN(12), { 0x00000068 } },
892 { AR5K_RF_GAIN(13), { 0x00000189 } },
893 { AR5K_RF_GAIN(14), { 0x000001c9 } },
894 { AR5K_RF_GAIN(15), { 0x00000009 } },
895 { AR5K_RF_GAIN(16), { 0x00000049 } },
896 { AR5K_RF_GAIN(17), { 0x00000089 } },
897 { AR5K_RF_GAIN(18), { 0x00000190 } },
898 { AR5K_RF_GAIN(19), { 0x000001d0 } },
899 { AR5K_RF_GAIN(20), { 0x00000010 } },
900 { AR5K_RF_GAIN(21), { 0x00000050 } },
901 { AR5K_RF_GAIN(22), { 0x00000090 } },
902 { AR5K_RF_GAIN(23), { 0x00000191 } },
903 { AR5K_RF_GAIN(24), { 0x000001d1 } },
904 { AR5K_RF_GAIN(25), { 0x00000011 } },
905 { AR5K_RF_GAIN(26), { 0x00000051 } },
906 { AR5K_RF_GAIN(27), { 0x00000091 } },
907 { AR5K_RF_GAIN(28), { 0x00000178 } },
908 { AR5K_RF_GAIN(29), { 0x000001b8 } },
909 { AR5K_RF_GAIN(30), { 0x000001f8 } },
910 { AR5K_RF_GAIN(31), { 0x00000038 } },
911 { AR5K_RF_GAIN(32), { 0x00000078 } },
912 { AR5K_RF_GAIN(33), { 0x00000199 } },
913 { AR5K_RF_GAIN(34), { 0x000001d9 } },
914 { AR5K_RF_GAIN(35), { 0x00000019 } },
915 { AR5K_RF_GAIN(36), { 0x00000059 } },
916 { AR5K_RF_GAIN(37), { 0x00000099 } },
917 { AR5K_RF_GAIN(38), { 0x000000d9 } },
918 { AR5K_RF_GAIN(39), { 0x000000f9 } },
919 { AR5K_RF_GAIN(40), { 0x000000f9 } },
920 { AR5K_RF_GAIN(41), { 0x000000f9 } },
921 { AR5K_RF_GAIN(42), { 0x000000f9 } },
922 { AR5K_RF_GAIN(43), { 0x000000f9 } },
923 { AR5K_RF_GAIN(44), { 0x000000f9 } },
924 { AR5K_RF_GAIN(45), { 0x000000f9 } },
925 { AR5K_RF_GAIN(46), { 0x000000f9 } },
926 { AR5K_RF_GAIN(47), { 0x000000f9 } },
927 { AR5K_RF_GAIN(48), { 0x000000f9 } },
928 { AR5K_RF_GAIN(49), { 0x000000f9 } },
929 { AR5K_RF_GAIN(50), { 0x000000f9 } },
930 { AR5K_RF_GAIN(51), { 0x000000f9 } },
931 { AR5K_RF_GAIN(52), { 0x000000f9 } },
932 { AR5K_RF_GAIN(53), { 0x000000f9 } },
933 { AR5K_RF_GAIN(54), { 0x000000f9 } },
934 { AR5K_RF_GAIN(55), { 0x000000f9 } },
935 { AR5K_RF_GAIN(56), { 0x000000f9 } },
936 { AR5K_RF_GAIN(57), { 0x000000f9 } },
937 { AR5K_RF_GAIN(58), { 0x000000f9 } },
938 { AR5K_RF_GAIN(59), { 0x000000f9 } },
939 { AR5K_RF_GAIN(60), { 0x000000f9 } },
940 { AR5K_RF_GAIN(61), { 0x000000f9 } },
941 { AR5K_RF_GAIN(62), { 0x000000f9 } },
942 { AR5K_RF_GAIN(63), { 0x000000f9 } },
943};
944
808static const struct ath5k_gain_opt rfgain_opt_5112 = { 945static const struct ath5k_gain_opt rfgain_opt_5112 = {
809 1, 946 1,
810 8, 947 8,
@@ -955,7 +1092,6 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
955 go = &rfgain_opt_5111; 1092 go = &rfgain_opt_5111;
956 break; 1093 break;
957 case AR5K_RF5112: 1094 case AR5K_RF5112:
958 case AR5K_RF5413: /* ??? */
959 go = &rfgain_opt_5112; 1095 go = &rfgain_opt_5112;
960 break; 1096 break;
961 default: 1097 default:
@@ -1226,8 +1362,21 @@ static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
1226 1362
1227 rf = ah->ah_rf_banks; 1363 rf = ah->ah_rf_banks;
1228 1364
1229 rf_ini = rfregs_5413; 1365 if (ah->ah_radio == AR5K_RF5413) {
1230 rf_size = ARRAY_SIZE(rfregs_5413); 1366 rf_ini = rfregs_5413;
1367 rf_size = ARRAY_SIZE(rfregs_5413);
1368 } else if (ah->ah_radio == AR5K_RF2413) {
1369 rf_ini = rfregs_2413;
1370 rf_size = ARRAY_SIZE(rfregs_2413);
1371 if (mode < 2) {
1372 ATH5K_ERR(ah->ah_sc,
1373 "invalid channel mode: %i\n", mode);
1374 return -EINVAL;
1375 }
1376 mode = mode - 2;
1377 } else {
1378 return -EINVAL;
1379 }
1231 1380
1232 /* Copy values to modify them */ 1381 /* Copy values to modify them */
1233 for (i = 0; i < rf_size; i++) { 1382 for (i = 0; i < rf_size; i++) {
@@ -1286,6 +1435,10 @@ int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1286 ah->ah_rf_banks_size = sizeof(rfregs_5413); 1435 ah->ah_rf_banks_size = sizeof(rfregs_5413);
1287 func = ath5k_hw_rf5413_rfregs; 1436 func = ath5k_hw_rf5413_rfregs;
1288 break; 1437 break;
1438 case AR5K_RF2413:
1439 ah->ah_rf_banks_size = sizeof(rfregs_2413);
1440 func = ath5k_hw_rf5413_rfregs;
1441 break;
1289 default: 1442 default:
1290 return -EINVAL; 1443 return -EINVAL;
1291 } 1444 }
@@ -1324,6 +1477,11 @@ int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
1324 ath5k_rfg = rfgain_5413; 1477 ath5k_rfg = rfgain_5413;
1325 size = ARRAY_SIZE(rfgain_5413); 1478 size = ARRAY_SIZE(rfgain_5413);
1326 break; 1479 break;
1480 case AR5K_RF2413:
1481 ath5k_rfg = rfgain_2413;
1482 size = ARRAY_SIZE(rfgain_2413);
1483 freq = 0; /* only 2Ghz */
1484 break;
1327 default: 1485 default:
1328 return -EINVAL; 1486 return -EINVAL;
1329 } 1487 }
@@ -1398,7 +1556,6 @@ int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah)
1398 ah->ah_gain.g_active = 1; 1556 ah->ah_gain.g_active = 1;
1399 break; 1557 break;
1400 case AR5K_RF5112: 1558 case AR5K_RF5112:
1401 case AR5K_RF5413: /* ??? */
1402 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default; 1559 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
1403 ah->ah_gain.g_step = 1560 ah->ah_gain.g_step =
1404 &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx]; 1561 &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
@@ -2019,6 +2176,15 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2019 return -EINVAL; 2176 return -EINVAL;
2020 } 2177 }
2021 2178
2179 /*
2180 * RF2413 for some reason can't
2181 * transmit anything if we call
2182 * this funtion, so we skip it
2183 * until we fix txpower.
2184 */
2185 if (ah->ah_radio == AR5K_RF2413)
2186 return 0;
2187
2022 /* Reset TX power values */ 2188 /* Reset TX power values */
2023 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); 2189 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
2024 ah->ah_txpower.txp_tpc = tpc; 2190 ah->ah_txpower.txp_tpc = tpc;
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 2f41c8398602..30629b3e37c2 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -1923,7 +1923,9 @@ after DFS is enabled */
1923#define AR5K_PHY_SDELAY_32MHZ 0x000000ff 1923#define AR5K_PHY_SDELAY_32MHZ 0x000000ff
1924#define AR5K_PHY_SPENDING 0x99f8 1924#define AR5K_PHY_SPENDING 0x99f8
1925#define AR5K_PHY_SPENDING_RF5111 0x00000018 1925#define AR5K_PHY_SPENDING_RF5111 0x00000018
1926#define AR5K_PHY_SPENDING_RF5112 0x00000014 1926#define AR5K_PHY_SPENDING_RF5112 0x00000014 /* <- i 've only seen this on 2425 dumps ! */
1927#define AR5K_PHY_SPENDING_RF5112A 0x0000000e /* but since i only have 5112A-based chips */
1928#define AR5K_PHY_SPENDING_RF5424 0x00000012 /* to test it might be also for old 5112. */
1927 1929
1928/* 1930/*
1929 * Misc PHY/radio registers [5110 - 5111] 1931 * Misc PHY/radio registers [5110 - 5111]
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 33459d61a717..d40be1568517 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -99,6 +99,8 @@
99#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ 99#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
100#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ 100#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
101#define B43_MMIO_RNG 0x65A 101#define B43_MMIO_RNG 0x65A
102#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
103#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
102#define B43_MMIO_POWERUP_DELAY 0x6A8 104#define B43_MMIO_POWERUP_DELAY 0x6A8
103 105
104/* SPROM boardflags_lo values */ 106/* SPROM boardflags_lo values */
@@ -587,15 +589,13 @@ struct b43_phy {
587 589
588/* Data structures for DMA transmission, per 80211 core. */ 590/* Data structures for DMA transmission, per 80211 core. */
589struct b43_dma { 591struct b43_dma {
590 struct b43_dmaring *tx_ring0; 592 struct b43_dmaring *tx_ring_AC_BK; /* Background */
591 struct b43_dmaring *tx_ring1; 593 struct b43_dmaring *tx_ring_AC_BE; /* Best Effort */
592 struct b43_dmaring *tx_ring2; 594 struct b43_dmaring *tx_ring_AC_VI; /* Video */
593 struct b43_dmaring *tx_ring3; 595 struct b43_dmaring *tx_ring_AC_VO; /* Voice */
594 struct b43_dmaring *tx_ring4; 596 struct b43_dmaring *tx_ring_mcast; /* Multicast */
595 struct b43_dmaring *tx_ring5; 597
596 598 struct b43_dmaring *rx_ring;
597 struct b43_dmaring *rx_ring0;
598 struct b43_dmaring *rx_ring3; /* only available on core.rev < 5 */
599}; 599};
600 600
601/* Context information for a noise calculation (Link Quality). */ 601/* Context information for a noise calculation (Link Quality). */
@@ -621,6 +621,35 @@ struct b43_key {
621 u8 algorithm; 621 u8 algorithm;
622}; 622};
623 623
624/* SHM offsets to the QOS data structures for the 4 different queues. */
625#define B43_QOS_PARAMS(queue) (B43_SHM_SH_EDCFQ + \
626 (B43_NR_QOSPARAMS * sizeof(u16) * (queue)))
627#define B43_QOS_BACKGROUND B43_QOS_PARAMS(0)
628#define B43_QOS_BESTEFFORT B43_QOS_PARAMS(1)
629#define B43_QOS_VIDEO B43_QOS_PARAMS(2)
630#define B43_QOS_VOICE B43_QOS_PARAMS(3)
631
632/* QOS parameter hardware data structure offsets. */
633#define B43_NR_QOSPARAMS 22
634enum {
635 B43_QOSPARAM_TXOP = 0,
636 B43_QOSPARAM_CWMIN,
637 B43_QOSPARAM_CWMAX,
638 B43_QOSPARAM_CWCUR,
639 B43_QOSPARAM_AIFS,
640 B43_QOSPARAM_BSLOTS,
641 B43_QOSPARAM_REGGAP,
642 B43_QOSPARAM_STATUS,
643};
644
645/* QOS parameters for a queue. */
646struct b43_qos_params {
647 /* The QOS parameters */
648 struct ieee80211_tx_queue_params p;
649 /* Does this need to get uploaded to hardware? */
650 bool need_hw_update;
651};
652
624struct b43_wldev; 653struct b43_wldev;
625 654
626/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */ 655/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
@@ -673,6 +702,12 @@ struct b43_wl {
673 struct sk_buff *current_beacon; 702 struct sk_buff *current_beacon;
674 bool beacon0_uploaded; 703 bool beacon0_uploaded;
675 bool beacon1_uploaded; 704 bool beacon1_uploaded;
705
706 /* The current QOS parameters for the 4 queues.
707 * This is protected by the irq_lock. */
708 struct b43_qos_params qos_params[4];
709 /* Workqueue for updating QOS parameters in hardware. */
710 struct work_struct qos_update_work;
676}; 711};
677 712
678/* In-memory representation of a cached microcode file. */ 713/* In-memory representation of a cached microcode file. */
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3dfb28a34be9..663aed4e9e05 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -38,6 +38,7 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/skbuff.h> 39#include <linux/skbuff.h>
40#include <linux/etherdevice.h> 40#include <linux/etherdevice.h>
41#include <asm/div64.h>
41 42
42 43
43/* 32bit DMA ops. */ 44/* 32bit DMA ops. */
@@ -291,52 +292,6 @@ static inline int request_slot(struct b43_dmaring *ring)
291 return slot; 292 return slot;
292} 293}
293 294
294/* Mac80211-queue to b43-ring mapping */
295static struct b43_dmaring *priority_to_txring(struct b43_wldev *dev,
296 int queue_priority)
297{
298 struct b43_dmaring *ring;
299
300/*FIXME: For now we always run on TX-ring-1 */
301 return dev->dma.tx_ring1;
302
303 /* 0 = highest priority */
304 switch (queue_priority) {
305 default:
306 B43_WARN_ON(1);
307 /* fallthrough */
308 case 0:
309 ring = dev->dma.tx_ring3;
310 break;
311 case 1:
312 ring = dev->dma.tx_ring2;
313 break;
314 case 2:
315 ring = dev->dma.tx_ring1;
316 break;
317 case 3:
318 ring = dev->dma.tx_ring0;
319 break;
320 }
321
322 return ring;
323}
324
325/* b43-ring to mac80211-queue mapping */
326static inline int txring_to_priority(struct b43_dmaring *ring)
327{
328 static const u8 idx_to_prio[] = { 3, 2, 1, 0, };
329 unsigned int index;
330
331/*FIXME: have only one queue, for now */
332 return 0;
333
334 index = ring->index;
335 if (B43_WARN_ON(index >= ARRAY_SIZE(idx_to_prio)))
336 index = 0;
337 return idx_to_prio[index];
338}
339
340static u16 b43_dmacontroller_base(enum b43_dmatype type, int controller_idx) 295static u16 b43_dmacontroller_base(enum b43_dmatype type, int controller_idx)
341{ 296{
342 static const u16 map64[] = { 297 static const u16 map64[] = {
@@ -924,16 +879,52 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
924 goto out; 879 goto out;
925} 880}
926 881
882#define divide(a, b) ({ \
883 typeof(a) __a = a; \
884 do_div(__a, b); \
885 __a; \
886 })
887
888#define modulo(a, b) ({ \
889 typeof(a) __a = a; \
890 do_div(__a, b); \
891 })
892
927/* Main cleanup function. */ 893/* Main cleanup function. */
928static void b43_destroy_dmaring(struct b43_dmaring *ring) 894static void b43_destroy_dmaring(struct b43_dmaring *ring,
895 const char *ringname)
929{ 896{
930 if (!ring) 897 if (!ring)
931 return; 898 return;
932 899
933 b43dbg(ring->dev->wl, "DMA-%u 0x%04X (%s) max used slots: %d/%d\n", 900#ifdef CONFIG_B43_DEBUG
934 (unsigned int)(ring->type), 901 {
935 ring->mmio_base, 902 /* Print some statistics. */
936 (ring->tx) ? "TX" : "RX", ring->max_used_slots, ring->nr_slots); 903 u64 failed_packets = ring->nr_failed_tx_packets;
904 u64 succeed_packets = ring->nr_succeed_tx_packets;
905 u64 nr_packets = failed_packets + succeed_packets;
906 u64 permille_failed = 0, average_tries = 0;
907
908 if (nr_packets)
909 permille_failed = divide(failed_packets * 1000, nr_packets);
910 if (nr_packets)
911 average_tries = divide(ring->nr_total_packet_tries * 100, nr_packets);
912
913 b43dbg(ring->dev->wl, "DMA-%u %s: "
914 "Used slots %d/%d, Failed frames %llu/%llu = %llu.%01llu%%, "
915 "Average tries %llu.%02llu\n",
916 (unsigned int)(ring->type), ringname,
917 ring->max_used_slots,
918 ring->nr_slots,
919 (unsigned long long)failed_packets,
920 (unsigned long long)nr_packets,
921 (unsigned long long)divide(permille_failed, 10),
922 (unsigned long long)modulo(permille_failed, 10),
923 (unsigned long long)divide(average_tries, 100),
924 (unsigned long long)modulo(average_tries, 100));
925 }
926#endif /* DEBUG */
927
937 /* Device IRQs are disabled prior entering this function, 928 /* Device IRQs are disabled prior entering this function,
938 * so no need to take care of concurrency with rx handler stuff. 929 * so no need to take care of concurrency with rx handler stuff.
939 */ 930 */
@@ -946,33 +937,26 @@ static void b43_destroy_dmaring(struct b43_dmaring *ring)
946 kfree(ring); 937 kfree(ring);
947} 938}
948 939
940#define destroy_ring(dma, ring) do { \
941 b43_destroy_dmaring((dma)->ring, __stringify(ring)); \
942 (dma)->ring = NULL; \
943 } while (0)
944
949void b43_dma_free(struct b43_wldev *dev) 945void b43_dma_free(struct b43_wldev *dev)
950{ 946{
951 struct b43_dma *dma = &dev->dma; 947 struct b43_dma *dma = &dev->dma;
952 948
953 b43_destroy_dmaring(dma->rx_ring3); 949 destroy_ring(dma, rx_ring);
954 dma->rx_ring3 = NULL; 950 destroy_ring(dma, tx_ring_AC_BK);
955 b43_destroy_dmaring(dma->rx_ring0); 951 destroy_ring(dma, tx_ring_AC_BE);
956 dma->rx_ring0 = NULL; 952 destroy_ring(dma, tx_ring_AC_VI);
957 953 destroy_ring(dma, tx_ring_AC_VO);
958 b43_destroy_dmaring(dma->tx_ring5); 954 destroy_ring(dma, tx_ring_mcast);
959 dma->tx_ring5 = NULL;
960 b43_destroy_dmaring(dma->tx_ring4);
961 dma->tx_ring4 = NULL;
962 b43_destroy_dmaring(dma->tx_ring3);
963 dma->tx_ring3 = NULL;
964 b43_destroy_dmaring(dma->tx_ring2);
965 dma->tx_ring2 = NULL;
966 b43_destroy_dmaring(dma->tx_ring1);
967 dma->tx_ring1 = NULL;
968 b43_destroy_dmaring(dma->tx_ring0);
969 dma->tx_ring0 = NULL;
970} 955}
971 956
972int b43_dma_init(struct b43_wldev *dev) 957int b43_dma_init(struct b43_wldev *dev)
973{ 958{
974 struct b43_dma *dma = &dev->dma; 959 struct b43_dma *dma = &dev->dma;
975 struct b43_dmaring *ring;
976 int err; 960 int err;
977 u64 dmamask; 961 u64 dmamask;
978 enum b43_dmatype type; 962 enum b43_dmatype type;
@@ -1002,83 +986,57 @@ int b43_dma_init(struct b43_wldev *dev)
1002 986
1003 err = -ENOMEM; 987 err = -ENOMEM;
1004 /* setup TX DMA channels. */ 988 /* setup TX DMA channels. */
1005 ring = b43_setup_dmaring(dev, 0, 1, type); 989 dma->tx_ring_AC_BK = b43_setup_dmaring(dev, 0, 1, type);
1006 if (!ring) 990 if (!dma->tx_ring_AC_BK)
1007 goto out; 991 goto out;
1008 dma->tx_ring0 = ring;
1009 992
1010 ring = b43_setup_dmaring(dev, 1, 1, type); 993 dma->tx_ring_AC_BE = b43_setup_dmaring(dev, 1, 1, type);
1011 if (!ring) 994 if (!dma->tx_ring_AC_BE)
1012 goto err_destroy_tx0; 995 goto err_destroy_bk;
1013 dma->tx_ring1 = ring;
1014 996
1015 ring = b43_setup_dmaring(dev, 2, 1, type); 997 dma->tx_ring_AC_VI = b43_setup_dmaring(dev, 2, 1, type);
1016 if (!ring) 998 if (!dma->tx_ring_AC_VI)
1017 goto err_destroy_tx1; 999 goto err_destroy_be;
1018 dma->tx_ring2 = ring;
1019 1000
1020 ring = b43_setup_dmaring(dev, 3, 1, type); 1001 dma->tx_ring_AC_VO = b43_setup_dmaring(dev, 3, 1, type);
1021 if (!ring) 1002 if (!dma->tx_ring_AC_VO)
1022 goto err_destroy_tx2; 1003 goto err_destroy_vi;
1023 dma->tx_ring3 = ring;
1024 1004
1025 ring = b43_setup_dmaring(dev, 4, 1, type); 1005 dma->tx_ring_mcast = b43_setup_dmaring(dev, 4, 1, type);
1026 if (!ring) 1006 if (!dma->tx_ring_mcast)
1027 goto err_destroy_tx3; 1007 goto err_destroy_vo;
1028 dma->tx_ring4 = ring;
1029 1008
1030 ring = b43_setup_dmaring(dev, 5, 1, type); 1009 /* setup RX DMA channel. */
1031 if (!ring) 1010 dma->rx_ring = b43_setup_dmaring(dev, 0, 0, type);
1032 goto err_destroy_tx4; 1011 if (!dma->rx_ring)
1033 dma->tx_ring5 = ring; 1012 goto err_destroy_mcast;
1034 1013
1035 /* setup RX DMA channels. */ 1014 /* No support for the TX status DMA ring. */
1036 ring = b43_setup_dmaring(dev, 0, 0, type); 1015 B43_WARN_ON(dev->dev->id.revision < 5);
1037 if (!ring)
1038 goto err_destroy_tx5;
1039 dma->rx_ring0 = ring;
1040
1041 if (dev->dev->id.revision < 5) {
1042 ring = b43_setup_dmaring(dev, 3, 0, type);
1043 if (!ring)
1044 goto err_destroy_rx0;
1045 dma->rx_ring3 = ring;
1046 }
1047 1016
1048 b43dbg(dev->wl, "%u-bit DMA initialized\n", 1017 b43dbg(dev->wl, "%u-bit DMA initialized\n",
1049 (unsigned int)type); 1018 (unsigned int)type);
1050 err = 0; 1019 err = 0;
1051 out: 1020out:
1052 return err; 1021 return err;
1053 1022
1054 err_destroy_rx0: 1023err_destroy_mcast:
1055 b43_destroy_dmaring(dma->rx_ring0); 1024 destroy_ring(dma, tx_ring_mcast);
1056 dma->rx_ring0 = NULL; 1025err_destroy_vo:
1057 err_destroy_tx5: 1026 destroy_ring(dma, tx_ring_AC_VO);
1058 b43_destroy_dmaring(dma->tx_ring5); 1027err_destroy_vi:
1059 dma->tx_ring5 = NULL; 1028 destroy_ring(dma, tx_ring_AC_VI);
1060 err_destroy_tx4: 1029err_destroy_be:
1061 b43_destroy_dmaring(dma->tx_ring4); 1030 destroy_ring(dma, tx_ring_AC_BE);
1062 dma->tx_ring4 = NULL; 1031err_destroy_bk:
1063 err_destroy_tx3: 1032 destroy_ring(dma, tx_ring_AC_BK);
1064 b43_destroy_dmaring(dma->tx_ring3); 1033 return err;
1065 dma->tx_ring3 = NULL;
1066 err_destroy_tx2:
1067 b43_destroy_dmaring(dma->tx_ring2);
1068 dma->tx_ring2 = NULL;
1069 err_destroy_tx1:
1070 b43_destroy_dmaring(dma->tx_ring1);
1071 dma->tx_ring1 = NULL;
1072 err_destroy_tx0:
1073 b43_destroy_dmaring(dma->tx_ring0);
1074 dma->tx_ring0 = NULL;
1075 goto out;
1076} 1034}
1077 1035
1078/* Generate a cookie for the TX header. */ 1036/* Generate a cookie for the TX header. */
1079static u16 generate_cookie(struct b43_dmaring *ring, int slot) 1037static u16 generate_cookie(struct b43_dmaring *ring, int slot)
1080{ 1038{
1081 u16 cookie = 0x1000; 1039 u16 cookie;
1082 1040
1083 /* Use the upper 4 bits of the cookie as 1041 /* Use the upper 4 bits of the cookie as
1084 * DMA controller ID and store the slot number 1042 * DMA controller ID and store the slot number
@@ -1088,30 +1046,9 @@ static u16 generate_cookie(struct b43_dmaring *ring, int slot)
1088 * It can also not be 0xFFFF because that is special 1046 * It can also not be 0xFFFF because that is special
1089 * for multicast frames. 1047 * for multicast frames.
1090 */ 1048 */
1091 switch (ring->index) { 1049 cookie = (((u16)ring->index + 1) << 12);
1092 case 0:
1093 cookie = 0x1000;
1094 break;
1095 case 1:
1096 cookie = 0x2000;
1097 break;
1098 case 2:
1099 cookie = 0x3000;
1100 break;
1101 case 3:
1102 cookie = 0x4000;
1103 break;
1104 case 4:
1105 cookie = 0x5000;
1106 break;
1107 case 5:
1108 cookie = 0x6000;
1109 break;
1110 default:
1111 B43_WARN_ON(1);
1112 }
1113 B43_WARN_ON(slot & ~0x0FFF); 1050 B43_WARN_ON(slot & ~0x0FFF);
1114 cookie |= (u16) slot; 1051 cookie |= (u16)slot;
1115 1052
1116 return cookie; 1053 return cookie;
1117} 1054}
@@ -1125,22 +1062,19 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
1125 1062
1126 switch (cookie & 0xF000) { 1063 switch (cookie & 0xF000) {
1127 case 0x1000: 1064 case 0x1000:
1128 ring = dma->tx_ring0; 1065 ring = dma->tx_ring_AC_BK;
1129 break; 1066 break;
1130 case 0x2000: 1067 case 0x2000:
1131 ring = dma->tx_ring1; 1068 ring = dma->tx_ring_AC_BE;
1132 break; 1069 break;
1133 case 0x3000: 1070 case 0x3000:
1134 ring = dma->tx_ring2; 1071 ring = dma->tx_ring_AC_VI;
1135 break; 1072 break;
1136 case 0x4000: 1073 case 0x4000:
1137 ring = dma->tx_ring3; 1074 ring = dma->tx_ring_AC_VO;
1138 break; 1075 break;
1139 case 0x5000: 1076 case 0x5000:
1140 ring = dma->tx_ring4; 1077 ring = dma->tx_ring_mcast;
1141 break;
1142 case 0x6000:
1143 ring = dma->tx_ring5;
1144 break; 1078 break;
1145 default: 1079 default:
1146 B43_WARN_ON(1); 1080 B43_WARN_ON(1);
@@ -1272,6 +1206,37 @@ static inline int should_inject_overflow(struct b43_dmaring *ring)
1272 return 0; 1206 return 0;
1273} 1207}
1274 1208
1209/* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
1210static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
1211 u8 queue_prio)
1212{
1213 struct b43_dmaring *ring;
1214
1215 if (b43_modparam_qos) {
1216 /* 0 = highest priority */
1217 switch (queue_prio) {
1218 default:
1219 B43_WARN_ON(1);
1220 /* fallthrough */
1221 case 0:
1222 ring = dev->dma.tx_ring_AC_VO;
1223 break;
1224 case 1:
1225 ring = dev->dma.tx_ring_AC_VI;
1226 break;
1227 case 2:
1228 ring = dev->dma.tx_ring_AC_BE;
1229 break;
1230 case 3:
1231 ring = dev->dma.tx_ring_AC_BK;
1232 break;
1233 }
1234 } else
1235 ring = dev->dma.tx_ring_AC_BE;
1236
1237 return ring;
1238}
1239
1275int b43_dma_tx(struct b43_wldev *dev, 1240int b43_dma_tx(struct b43_wldev *dev,
1276 struct sk_buff *skb, struct ieee80211_tx_control *ctl) 1241 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
1277{ 1242{
@@ -1288,13 +1253,13 @@ int b43_dma_tx(struct b43_wldev *dev,
1288 hdr = (struct ieee80211_hdr *)skb->data; 1253 hdr = (struct ieee80211_hdr *)skb->data;
1289 if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) { 1254 if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
1290 /* The multicast ring will be sent after the DTIM */ 1255 /* The multicast ring will be sent after the DTIM */
1291 ring = dev->dma.tx_ring4; 1256 ring = dev->dma.tx_ring_mcast;
1292 /* Set the more-data bit. Ucode will clear it on 1257 /* Set the more-data bit. Ucode will clear it on
1293 * the last frame for us. */ 1258 * the last frame for us. */
1294 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1259 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1295 } else { 1260 } else {
1296 /* Decide by priority where to put this frame. */ 1261 /* Decide by priority where to put this frame. */
1297 ring = priority_to_txring(dev, ctl->queue); 1262 ring = select_ring_by_priority(dev, ctl->queue);
1298 } 1263 }
1299 1264
1300 spin_lock_irqsave(&ring->lock, flags); 1265 spin_lock_irqsave(&ring->lock, flags);
@@ -1309,6 +1274,11 @@ int b43_dma_tx(struct b43_wldev *dev,
1309 * That would be a mac80211 bug. */ 1274 * That would be a mac80211 bug. */
1310 B43_WARN_ON(ring->stopped); 1275 B43_WARN_ON(ring->stopped);
1311 1276
1277 /* Assign the queue number to the ring (if not already done before)
1278 * so TX status handling can use it. The queue to ring mapping is
1279 * static, so we don't need to store it per frame. */
1280 ring->queue_prio = ctl->queue;
1281
1312 err = dma_tx_fragment(ring, skb, ctl); 1282 err = dma_tx_fragment(ring, skb, ctl);
1313 if (unlikely(err == -ENOKEY)) { 1283 if (unlikely(err == -ENOKEY)) {
1314 /* Drop this packet, as we don't have the encryption key 1284 /* Drop this packet, as we don't have the encryption key
@@ -1325,7 +1295,7 @@ int b43_dma_tx(struct b43_wldev *dev,
1325 if ((free_slots(ring) < SLOTS_PER_PACKET) || 1295 if ((free_slots(ring) < SLOTS_PER_PACKET) ||
1326 should_inject_overflow(ring)) { 1296 should_inject_overflow(ring)) {
1327 /* This TX ring is full. */ 1297 /* This TX ring is full. */
1328 ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); 1298 ieee80211_stop_queue(dev->wl->hw, ctl->queue);
1329 ring->stopped = 1; 1299 ring->stopped = 1;
1330 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1300 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1331 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); 1301 b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1337,6 +1307,38 @@ out_unlock:
1337 return err; 1307 return err;
1338} 1308}
1339 1309
1310static void b43_fill_txstatus_report(struct b43_dmaring *ring,
1311 struct ieee80211_tx_status *report,
1312 const struct b43_txstatus *status)
1313{
1314 bool frame_failed = 0;
1315
1316 if (status->acked) {
1317 /* The frame was ACKed. */
1318 report->flags |= IEEE80211_TX_STATUS_ACK;
1319 } else {
1320 /* The frame was not ACKed... */
1321 if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
1322 /* ...but we expected an ACK. */
1323 frame_failed = 1;
1324 report->excessive_retries = 1;
1325 }
1326 }
1327 if (status->frame_count == 0) {
1328 /* The frame was not transmitted at all. */
1329 report->retry_count = 0;
1330 } else {
1331 report->retry_count = status->frame_count - 1;
1332#ifdef CONFIG_B43_DEBUG
1333 if (frame_failed)
1334 ring->nr_failed_tx_packets++;
1335 else
1336 ring->nr_succeed_tx_packets++;
1337 ring->nr_total_packet_tries += status->frame_count;
1338#endif /* DEBUG */
1339 }
1340}
1341
1340void b43_dma_handle_txstatus(struct b43_wldev *dev, 1342void b43_dma_handle_txstatus(struct b43_wldev *dev,
1341 const struct b43_txstatus *status) 1343 const struct b43_txstatus *status)
1342{ 1344{
@@ -1371,18 +1373,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1371 * status of the transmission. 1373 * status of the transmission.
1372 * Some fields of txstat are already filled in dma_tx(). 1374 * Some fields of txstat are already filled in dma_tx().
1373 */ 1375 */
1374 if (status->acked) { 1376 b43_fill_txstatus_report(ring, &(meta->txstat), status);
1375 meta->txstat.flags |= IEEE80211_TX_STATUS_ACK;
1376 } else {
1377 if (!(meta->txstat.control.flags
1378 & IEEE80211_TXCTL_NO_ACK))
1379 meta->txstat.excessive_retries = 1;
1380 }
1381 if (status->frame_count == 0) {
1382 /* The frame was not transmitted at all. */
1383 meta->txstat.retry_count = 0;
1384 } else
1385 meta->txstat.retry_count = status->frame_count - 1;
1386 ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb, 1377 ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
1387 &(meta->txstat)); 1378 &(meta->txstat));
1388 /* skb is freed by ieee80211_tx_status_irqsafe() */ 1379 /* skb is freed by ieee80211_tx_status_irqsafe() */
@@ -1404,7 +1395,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
1404 dev->stats.last_tx = jiffies; 1395 dev->stats.last_tx = jiffies;
1405 if (ring->stopped) { 1396 if (ring->stopped) {
1406 B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET); 1397 B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
1407 ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring)); 1398 ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
1408 ring->stopped = 0; 1399 ring->stopped = 0;
1409 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { 1400 if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
1410 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); 1401 b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
@@ -1425,7 +1416,7 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
1425 1416
1426 for (i = 0; i < nr_queues; i++) { 1417 for (i = 0; i < nr_queues; i++) {
1427 data = &(stats->data[i]); 1418 data = &(stats->data[i]);
1428 ring = priority_to_txring(dev, i); 1419 ring = select_ring_by_priority(dev, i);
1429 1420
1430 spin_lock_irqsave(&ring->lock, flags); 1421 spin_lock_irqsave(&ring->lock, flags);
1431 data->len = ring->used_slots / SLOTS_PER_PACKET; 1422 data->len = ring->used_slots / SLOTS_PER_PACKET;
@@ -1451,25 +1442,6 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
1451 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize); 1442 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
1452 skb = meta->skb; 1443 skb = meta->skb;
1453 1444
1454 if (ring->index == 3) {
1455 /* We received an xmit status. */
1456 struct b43_hwtxstatus *hw = (struct b43_hwtxstatus *)skb->data;
1457 int i = 0;
1458
1459 while (hw->cookie == 0) {
1460 if (i > 100)
1461 break;
1462 i++;
1463 udelay(2);
1464 barrier();
1465 }
1466 b43_handle_hwtxstatus(ring->dev, hw);
1467 /* recycle the descriptor buffer. */
1468 sync_descbuffer_for_device(ring, meta->dmaaddr,
1469 ring->rx_buffersize);
1470
1471 return;
1472 }
1473 rxhdr = (struct b43_rxhdr_fw4 *)skb->data; 1445 rxhdr = (struct b43_rxhdr_fw4 *)skb->data;
1474 len = le16_to_cpu(rxhdr->frame_len); 1446 len = le16_to_cpu(rxhdr->frame_len);
1475 if (len == 0) { 1447 if (len == 0) {
@@ -1526,7 +1498,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
1526 skb_pull(skb, ring->frameoffset); 1498 skb_pull(skb, ring->frameoffset);
1527 1499
1528 b43_rx(ring->dev, skb, rxhdr); 1500 b43_rx(ring->dev, skb, rxhdr);
1529 drop: 1501drop:
1530 return; 1502 return;
1531} 1503}
1532 1504
@@ -1572,21 +1544,19 @@ static void b43_dma_tx_resume_ring(struct b43_dmaring *ring)
1572void b43_dma_tx_suspend(struct b43_wldev *dev) 1544void b43_dma_tx_suspend(struct b43_wldev *dev)
1573{ 1545{
1574 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); 1546 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
1575 b43_dma_tx_suspend_ring(dev->dma.tx_ring0); 1547 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BK);
1576 b43_dma_tx_suspend_ring(dev->dma.tx_ring1); 1548 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_BE);
1577 b43_dma_tx_suspend_ring(dev->dma.tx_ring2); 1549 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VI);
1578 b43_dma_tx_suspend_ring(dev->dma.tx_ring3); 1550 b43_dma_tx_suspend_ring(dev->dma.tx_ring_AC_VO);
1579 b43_dma_tx_suspend_ring(dev->dma.tx_ring4); 1551 b43_dma_tx_suspend_ring(dev->dma.tx_ring_mcast);
1580 b43_dma_tx_suspend_ring(dev->dma.tx_ring5);
1581} 1552}
1582 1553
1583void b43_dma_tx_resume(struct b43_wldev *dev) 1554void b43_dma_tx_resume(struct b43_wldev *dev)
1584{ 1555{
1585 b43_dma_tx_resume_ring(dev->dma.tx_ring5); 1556 b43_dma_tx_resume_ring(dev->dma.tx_ring_mcast);
1586 b43_dma_tx_resume_ring(dev->dma.tx_ring4); 1557 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VO);
1587 b43_dma_tx_resume_ring(dev->dma.tx_ring3); 1558 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_VI);
1588 b43_dma_tx_resume_ring(dev->dma.tx_ring2); 1559 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BE);
1589 b43_dma_tx_resume_ring(dev->dma.tx_ring1); 1560 b43_dma_tx_resume_ring(dev->dma.tx_ring_AC_BK);
1590 b43_dma_tx_resume_ring(dev->dma.tx_ring0);
1591 b43_power_saving_ctl_bits(dev, 0); 1561 b43_power_saving_ctl_bits(dev, 0);
1592} 1562}
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index c0d6b69e6501..ea27085dec0e 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -245,6 +245,9 @@ struct b43_dmaring {
245 enum b43_dmatype type; 245 enum b43_dmatype type;
246 /* Boolean. Is this ring stopped at ieee80211 level? */ 246 /* Boolean. Is this ring stopped at ieee80211 level? */
247 bool stopped; 247 bool stopped;
248 /* The QOS priority assigned to this ring. Only used for TX rings.
249 * This is the mac80211 "queue" value. */
250 u8 queue_prio;
248 /* Lock, only used for TX. */ 251 /* Lock, only used for TX. */
249 spinlock_t lock; 252 spinlock_t lock;
250 struct b43_wldev *dev; 253 struct b43_wldev *dev;
@@ -253,7 +256,13 @@ struct b43_dmaring {
253 int max_used_slots; 256 int max_used_slots;
254 /* Last time we injected a ring overflow. */ 257 /* Last time we injected a ring overflow. */
255 unsigned long last_injected_overflow; 258 unsigned long last_injected_overflow;
256#endif /* CONFIG_B43_DEBUG */ 259 /* Statistics: Number of successfully transmitted packets */
260 u64 nr_succeed_tx_packets;
261 /* Statistics: Number of failed TX packets */
262 u64 nr_failed_tx_packets;
263 /* Statistics: Total number of TX plus all retries. */
264 u64 nr_total_packet_tries;
265#endif /* CONFIG_B43_DEBUG */
257}; 266};
258 267
259static inline u32 b43_dma_read(struct b43_dmaring *ring, u16 offset) 268static inline u32 b43_dma_read(struct b43_dmaring *ring, u16 offset)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index f745308faaad..694e29570e5d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -78,6 +78,11 @@ static int modparam_nohwcrypt;
78module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); 78module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
79MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 79MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
80 80
81int b43_modparam_qos = 1;
82module_param_named(qos, b43_modparam_qos, int, 0444);
83MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
84
85
81static const struct ssb_device_id b43_ssb_tbl[] = { 86static const struct ssb_device_id b43_ssb_tbl[] = {
82 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), 87 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
83 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), 88 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6),
@@ -1589,11 +1594,10 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1589 1594
1590 /* Check the DMA reason registers for received data. */ 1595 /* Check the DMA reason registers for received data. */
1591 if (dma_reason[0] & B43_DMAIRQ_RX_DONE) 1596 if (dma_reason[0] & B43_DMAIRQ_RX_DONE)
1592 b43_dma_rx(dev->dma.rx_ring0); 1597 b43_dma_rx(dev->dma.rx_ring);
1593 if (dma_reason[3] & B43_DMAIRQ_RX_DONE)
1594 b43_dma_rx(dev->dma.rx_ring3);
1595 B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE); 1598 B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
1596 B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE); 1599 B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
1600 B43_WARN_ON(dma_reason[3] & B43_DMAIRQ_RX_DONE);
1597 B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE); 1601 B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE);
1598 B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE); 1602 B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE);
1599 1603
@@ -2708,10 +2712,178 @@ out:
2708 return NETDEV_TX_OK; 2712 return NETDEV_TX_OK;
2709} 2713}
2710 2714
2715/* Locking: wl->irq_lock */
2716static void b43_qos_params_upload(struct b43_wldev *dev,
2717 const struct ieee80211_tx_queue_params *p,
2718 u16 shm_offset)
2719{
2720 u16 params[B43_NR_QOSPARAMS];
2721 int cw_min, cw_max, aifs, bslots, tmp;
2722 unsigned int i;
2723
2724 const u16 aCWmin = 0x0001;
2725 const u16 aCWmax = 0x03FF;
2726
2727 /* Calculate the default values for the parameters, if needed. */
2728 switch (shm_offset) {
2729 case B43_QOS_VOICE:
2730 aifs = (p->aifs == -1) ? 2 : p->aifs;
2731 cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 4 - 1) : p->cw_min;
2732 cw_max = (p->cw_max == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_max;
2733 break;
2734 case B43_QOS_VIDEO:
2735 aifs = (p->aifs == -1) ? 2 : p->aifs;
2736 cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_min;
2737 cw_max = (p->cw_max == 0) ? aCWmin : p->cw_max;
2738 break;
2739 case B43_QOS_BESTEFFORT:
2740 aifs = (p->aifs == -1) ? 3 : p->aifs;
2741 cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
2742 cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
2743 break;
2744 case B43_QOS_BACKGROUND:
2745 aifs = (p->aifs == -1) ? 7 : p->aifs;
2746 cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
2747 cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
2748 break;
2749 default:
2750 B43_WARN_ON(1);
2751 return;
2752 }
2753 if (cw_min <= 0)
2754 cw_min = aCWmin;
2755 if (cw_max <= 0)
2756 cw_max = aCWmin;
2757 bslots = b43_read16(dev, B43_MMIO_RNG) % cw_min;
2758
2759 memset(&params, 0, sizeof(params));
2760
2761 params[B43_QOSPARAM_TXOP] = p->txop * 32;
2762 params[B43_QOSPARAM_CWMIN] = cw_min;
2763 params[B43_QOSPARAM_CWMAX] = cw_max;
2764 params[B43_QOSPARAM_CWCUR] = cw_min;
2765 params[B43_QOSPARAM_AIFS] = aifs;
2766 params[B43_QOSPARAM_BSLOTS] = bslots;
2767 params[B43_QOSPARAM_REGGAP] = bslots + aifs;
2768
2769 for (i = 0; i < ARRAY_SIZE(params); i++) {
2770 if (i == B43_QOSPARAM_STATUS) {
2771 tmp = b43_shm_read16(dev, B43_SHM_SHARED,
2772 shm_offset + (i * 2));
2773 /* Mark the parameters as updated. */
2774 tmp |= 0x100;
2775 b43_shm_write16(dev, B43_SHM_SHARED,
2776 shm_offset + (i * 2),
2777 tmp);
2778 } else {
2779 b43_shm_write16(dev, B43_SHM_SHARED,
2780 shm_offset + (i * 2),
2781 params[i]);
2782 }
2783 }
2784}
2785
2786/* Update the QOS parameters in hardware. */
2787static void b43_qos_update(struct b43_wldev *dev)
2788{
2789 struct b43_wl *wl = dev->wl;
2790 struct b43_qos_params *params;
2791 unsigned long flags;
2792 unsigned int i;
2793
2794 /* Mapping of mac80211 queues to b43 SHM offsets. */
2795 static const u16 qos_shm_offsets[] = {
2796 [0] = B43_QOS_VOICE,
2797 [1] = B43_QOS_VIDEO,
2798 [2] = B43_QOS_BESTEFFORT,
2799 [3] = B43_QOS_BACKGROUND,
2800 };
2801 BUILD_BUG_ON(ARRAY_SIZE(qos_shm_offsets) != ARRAY_SIZE(wl->qos_params));
2802
2803 b43_mac_suspend(dev);
2804 spin_lock_irqsave(&wl->irq_lock, flags);
2805
2806 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
2807 params = &(wl->qos_params[i]);
2808 if (params->need_hw_update) {
2809 b43_qos_params_upload(dev, &(params->p),
2810 qos_shm_offsets[i]);
2811 params->need_hw_update = 0;
2812 }
2813 }
2814
2815 spin_unlock_irqrestore(&wl->irq_lock, flags);
2816 b43_mac_enable(dev);
2817}
2818
2819static void b43_qos_clear(struct b43_wl *wl)
2820{
2821 struct b43_qos_params *params;
2822 unsigned int i;
2823
2824 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
2825 params = &(wl->qos_params[i]);
2826
2827 memset(&(params->p), 0, sizeof(params->p));
2828 params->p.aifs = -1;
2829 params->need_hw_update = 1;
2830 }
2831}
2832
2833/* Initialize the core's QOS capabilities */
2834static void b43_qos_init(struct b43_wldev *dev)
2835{
2836 struct b43_wl *wl = dev->wl;
2837 unsigned int i;
2838
2839 /* Upload the current QOS parameters. */
2840 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++)
2841 wl->qos_params[i].need_hw_update = 1;
2842 b43_qos_update(dev);
2843
2844 /* Enable QOS support. */
2845 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
2846 b43_write16(dev, B43_MMIO_IFSCTL,
2847 b43_read16(dev, B43_MMIO_IFSCTL)
2848 | B43_MMIO_IFSCTL_USE_EDCF);
2849}
2850
2851static void b43_qos_update_work(struct work_struct *work)
2852{
2853 struct b43_wl *wl = container_of(work, struct b43_wl, qos_update_work);
2854 struct b43_wldev *dev;
2855
2856 mutex_lock(&wl->mutex);
2857 dev = wl->current_dev;
2858 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED)))
2859 b43_qos_update(dev);
2860 mutex_unlock(&wl->mutex);
2861}
2862
2711static int b43_op_conf_tx(struct ieee80211_hw *hw, 2863static int b43_op_conf_tx(struct ieee80211_hw *hw,
2712 int queue, 2864 int _queue,
2713 const struct ieee80211_tx_queue_params *params) 2865 const struct ieee80211_tx_queue_params *params)
2714{ 2866{
2867 struct b43_wl *wl = hw_to_b43_wl(hw);
2868 unsigned long flags;
2869 unsigned int queue = (unsigned int)_queue;
2870 struct b43_qos_params *p;
2871
2872 if (queue >= ARRAY_SIZE(wl->qos_params)) {
2873 /* Queue not available or don't support setting
2874 * params on this queue. Return success to not
2875 * confuse mac80211. */
2876 return 0;
2877 }
2878
2879 spin_lock_irqsave(&wl->irq_lock, flags);
2880 p = &(wl->qos_params[queue]);
2881 memcpy(&(p->p), params, sizeof(p->p));
2882 p->need_hw_update = 1;
2883 spin_unlock_irqrestore(&wl->irq_lock, flags);
2884
2885 queue_work(hw->workqueue, &wl->qos_update_work);
2886
2715 return 0; 2887 return 0;
2716} 2888}
2717 2889
@@ -3732,6 +3904,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
3732 memset(wl->mac_addr, 0, ETH_ALEN); 3904 memset(wl->mac_addr, 0, ETH_ALEN);
3733 wl->filter_flags = 0; 3905 wl->filter_flags = 0;
3734 wl->radiotap_enabled = 0; 3906 wl->radiotap_enabled = 0;
3907 b43_qos_clear(wl);
3735 3908
3736 /* First register RFkill. 3909 /* First register RFkill.
3737 * LEDs that are registered later depend on it. */ 3910 * LEDs that are registered later depend on it. */
@@ -3773,6 +3946,7 @@ static void b43_op_stop(struct ieee80211_hw *hw)
3773 struct b43_wldev *dev = wl->current_dev; 3946 struct b43_wldev *dev = wl->current_dev;
3774 3947
3775 b43_rfkill_exit(dev); 3948 b43_rfkill_exit(dev);
3949 cancel_work_sync(&(wl->qos_update_work));
3776 3950
3777 mutex_lock(&wl->mutex); 3951 mutex_lock(&wl->mutex);
3778 if (b43_status(dev) >= B43_STAT_STARTED) 3952 if (b43_status(dev) >= B43_STAT_STARTED)
@@ -3835,6 +4009,16 @@ static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw,
3835 return 0; 4009 return 0;
3836} 4010}
3837 4011
4012static void b43_op_sta_notify(struct ieee80211_hw *hw,
4013 struct ieee80211_vif *vif,
4014 enum sta_notify_cmd notify_cmd,
4015 const u8 *addr)
4016{
4017 struct b43_wl *wl = hw_to_b43_wl(hw);
4018
4019 B43_WARN_ON(!vif || wl->vif != vif);
4020}
4021
3838static const struct ieee80211_ops b43_hw_ops = { 4022static const struct ieee80211_ops b43_hw_ops = {
3839 .tx = b43_op_tx, 4023 .tx = b43_op_tx,
3840 .conf_tx = b43_op_conf_tx, 4024 .conf_tx = b43_op_conf_tx,
@@ -3851,6 +4035,7 @@ static const struct ieee80211_ops b43_hw_ops = {
3851 .set_retry_limit = b43_op_set_retry_limit, 4035 .set_retry_limit = b43_op_set_retry_limit,
3852 .set_tim = b43_op_beacon_set_tim, 4036 .set_tim = b43_op_beacon_set_tim,
3853 .beacon_update = b43_op_ibss_beacon_update, 4037 .beacon_update = b43_op_ibss_beacon_update,
4038 .sta_notify = b43_op_sta_notify,
3854}; 4039};
3855 4040
3856/* Hard-reset the chip. Do not call this directly. 4041/* Hard-reset the chip. Do not call this directly.
@@ -4122,7 +4307,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4122 hw->max_signal = 100; 4307 hw->max_signal = 100;
4123 hw->max_rssi = -110; 4308 hw->max_rssi = -110;
4124 hw->max_noise = -110; 4309 hw->max_noise = -110;
4125 hw->queues = 1; /* FIXME: hardware has more queues */ 4310 hw->queues = b43_modparam_qos ? 4 : 1;
4126 SET_IEEE80211_DEV(hw, dev->dev); 4311 SET_IEEE80211_DEV(hw, dev->dev);
4127 if (is_valid_ether_addr(sprom->et1mac)) 4312 if (is_valid_ether_addr(sprom->et1mac))
4128 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); 4313 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
@@ -4138,6 +4323,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4138 spin_lock_init(&wl->shm_lock); 4323 spin_lock_init(&wl->shm_lock);
4139 mutex_init(&wl->mutex); 4324 mutex_init(&wl->mutex);
4140 INIT_LIST_HEAD(&wl->devlist); 4325 INIT_LIST_HEAD(&wl->devlist);
4326 INIT_WORK(&wl->qos_update_work, b43_qos_update_work);
4141 4327
4142 ssb_set_devtypedata(dev, wl); 4328 ssb_set_devtypedata(dev, wl);
4143 b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); 4329 b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 24a79f5d6ff5..1197975f9207 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -38,6 +38,10 @@
38/* Magic helper macro to pad structures. Ignore those above. It's magic. */ 38/* Magic helper macro to pad structures. Ignore those above. It's magic. */
39#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) 39#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes))
40 40
41
42extern int b43_modparam_qos;
43
44
41/* Lightweight function to convert a frequency (in Mhz) to a channel number. */ 45/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
42static inline u8 b43_freq_to_channel_5ghz(int freq) 46static inline u8 b43_freq_to_channel_5ghz(int freq)
43{ 47{
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 187c11bee0f1..ec10a8e182f9 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -705,30 +705,3 @@ void b43_tx_resume(struct b43_wldev *dev)
705{ 705{
706 b43_dma_tx_resume(dev); 706 b43_dma_tx_resume(dev);
707} 707}
708
709#if 0
710static void upload_qos_parms(struct b43_wldev *dev,
711 const u16 * parms, u16 offset)
712{
713 int i;
714
715 for (i = 0; i < B43_NR_QOSPARMS; i++) {
716 b43_shm_write16(dev, B43_SHM_SHARED,
717 offset + (i * 2), parms[i]);
718 }
719}
720#endif
721
722/* Initialize the QoS parameters */
723void b43_qos_init(struct b43_wldev *dev)
724{
725 /* FIXME: This function must probably be called from the mac80211
726 * config callback. */
727 return;
728
729 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
730 //FIXME kill magic
731 b43_write16(dev, 0x688, b43_read16(dev, 0x688) | 0x4);
732
733 /*TODO: We might need some stack support here to get the values. */
734}
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 41765039552b..bf58a8a85258 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -302,18 +302,6 @@ void b43_handle_hwtxstatus(struct b43_wldev *dev,
302void b43_tx_suspend(struct b43_wldev *dev); 302void b43_tx_suspend(struct b43_wldev *dev);
303void b43_tx_resume(struct b43_wldev *dev); 303void b43_tx_resume(struct b43_wldev *dev);
304 304
305#define B43_NR_QOSPARMS 22
306enum {
307 B43_QOSPARM_TXOP = 0,
308 B43_QOSPARM_CWMIN,
309 B43_QOSPARM_CWMAX,
310 B43_QOSPARM_CWCUR,
311 B43_QOSPARM_AIFS,
312 B43_QOSPARM_BSLOTS,
313 B43_QOSPARM_REGGAP,
314 B43_QOSPARM_STATUS,
315};
316void b43_qos_init(struct b43_wldev *dev);
317 305
318/* Helper functions for converting the key-table index from "firmware-format" 306/* Helper functions for converting the key-table index from "firmware-format"
319 * to "raw-format" and back. The firmware API changed for this at some revision. 307 * to "raw-format" and back. The firmware API changed for this at some revision.
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 24c3e3ddafc6..5b7c0160e1fa 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,7 +1,12 @@
1config IWLCORE
2 tristate "Intel Wireless Wifi Core"
3 depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
4
1config IWL4965 5config IWL4965
2 tristate "Intel Wireless WiFi 4965AGN" 6 tristate "Intel Wireless WiFi 4965AGN"
3 depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL 7 depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
4 select FW_LOADER 8 select FW_LOADER
9 select IWLCORE
5 ---help--- 10 ---help---
6 Select to build the driver supporting the: 11 Select to build the driver supporting the:
7 12
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 3bbd38358d53..6b85cca9b3f1 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,3 +1,6 @@
1obj-$(CONFIG_IWLCORE) += iwlcore.o
2iwlcore-objs = iwl-core.o
3
1obj-$(CONFIG_IWL3945) += iwl3945.o 4obj-$(CONFIG_IWL3945) += iwl3945.o
2iwl3945-objs = iwl3945-base.o iwl-3945.o iwl-3945-rs.o 5iwl3945-objs = iwl3945-base.o iwl-3945.o iwl-3945-rs.o
3 6
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
index 20fbb32c33bd..8b7ef9f1b57b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
@@ -666,26 +666,26 @@ struct iwl3945_rx_frame_hdr {
666 u8 payload[0]; 666 u8 payload[0];
667} __attribute__ ((packed)); 667} __attribute__ ((packed));
668 668
669#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) 669#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0)
670#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) 670#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1)
671 671
672#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) 672#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0)
673#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) 673#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1)
674#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) 674#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2)
675#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) 675#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3)
676#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) 676#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0)
677 677
678#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) 678#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
679#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) 679#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
680#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) 680#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8)
681#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) 681#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8)
682#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) 682#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8)
683 683
684#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) 684#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11)
685#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) 685#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11)
686#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) 686#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11)
687#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) 687#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11)
688#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) 688#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11)
689 689
690struct iwl3945_rx_frame_end { 690struct iwl3945_rx_frame_end {
691 __le32 status; 691 __le32 status;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-core.h b/drivers/net/wireless/iwlwifi/iwl-3945-core.h
new file mode 100644
index 000000000000..bc12f97ba0b1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-core.h
@@ -0,0 +1,80 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Tomas Winkler <tomas.winkler@intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __iwl_3945_dev_h__
64#define __iwl_3945_dev_h__
65
66#define IWL_PCI_DEVICE(dev, subdev, cfg) \
67 .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
68 .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
69 .driver_data = (kernel_ulong_t)&(cfg)
70
71#define IWL_SKU_G 0x1
72#define IWL_SKU_A 0x2
73
74struct iwl_3945_cfg {
75 const char *name;
76 const char *fw_name;
77 unsigned int sku;
78};
79
80#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
index f853c6b9f76e..28ecfe8d39a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
@@ -40,6 +40,15 @@ do { if (iwl3945_debug_level & (level)) \
40do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \ 40do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \
41 printk(KERN_ERR DRV_NAME": %c %s " fmt, \ 41 printk(KERN_ERR DRV_NAME": %c %s " fmt, \
42 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) 42 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
43
44static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
45{
46 if (!(iwl3945_debug_level & level))
47 return;
48
49 print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
50 p, len, 1);
51}
43#else 52#else
44static inline void IWL_DEBUG(int level, const char *fmt, ...) 53static inline void IWL_DEBUG(int level, const char *fmt, ...)
45{ 54{
@@ -47,7 +56,12 @@ static inline void IWL_DEBUG(int level, const char *fmt, ...)
47static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) 56static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
48{ 57{
49} 58}
50#endif /* CONFIG_IWL3945_DEBUG */ 59static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
60{
61}
62#endif /* CONFIG_IWL3945_DEBUG */
63
64
51 65
52/* 66/*
53 * To use the debug system; 67 * To use the debug system;
@@ -143,6 +157,7 @@ static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
143 IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) 157 IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
144#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a) 158#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
145#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) 159#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
160#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
146#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) 161#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
147#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) 162#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
148#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) 163#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 6693767adc9f..7dc19136f41a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -321,180 +321,6 @@ struct iwl3945_eeprom {
321#define PCI_REG_WUM8 0x0E8 321#define PCI_REG_WUM8 0x0E8
322#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) 322#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
323 323
324/*=== CSR (control and status registers) ===*/
325#define CSR_BASE (0x000)
326
327#define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */
328#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */
329#define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */
330#define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */
331#define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/
332#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */
333#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
334#define CSR_GP_CNTRL (CSR_BASE+0x024)
335
336/*
337 * Hardware revision info
338 * Bit fields:
339 * 31-8: Reserved
340 * 7-4: Type of device: 0x0 = 4965, 0xd = 3945
341 * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D
342 * 1-0: "Dash" value, as in A-1, etc.
343 */
344#define CSR_HW_REV (CSR_BASE+0x028)
345
346/* EEPROM reads */
347#define CSR_EEPROM_REG (CSR_BASE+0x02c)
348#define CSR_EEPROM_GP (CSR_BASE+0x030)
349#define CSR_GP_UCODE (CSR_BASE+0x044)
350#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
351#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)
352#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
353#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060)
354#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
355
356/* Analog phase-lock-loop configuration (3945 only)
357 * Set bit 24. */
358#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
359
360/* Bits for CSR_HW_IF_CONFIG_REG */
361#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB (0x00000100)
362#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM (0x00000200)
363#define CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400)
364#define CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800)
365#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
366#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
367#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
368
369/* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
370 * acknowledged (reset) by host writing "1" to flagged bits. */
371#define CSR_INT_BIT_FH_RX (1 << 31) /* Rx DMA, cmd responses, FH_INT[17:16] */
372#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
373#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
374#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
375#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
376#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
377#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
378#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
379#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */
380#define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */
381#define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */
382
383#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \
384 CSR_INT_BIT_HW_ERR | \
385 CSR_INT_BIT_FH_TX | \
386 CSR_INT_BIT_SW_ERR | \
387 CSR_INT_BIT_RF_KILL | \
388 CSR_INT_BIT_SW_RX | \
389 CSR_INT_BIT_WAKEUP | \
390 CSR_INT_BIT_ALIVE)
391
392/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
393#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */
394#define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */
395#define CSR_FH_INT_BIT_RX_CHNL2 (1 << 18) /* Rx channel 2 (3945 only) */
396#define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */
397#define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */
398#define CSR_FH_INT_BIT_TX_CHNL6 (1 << 6) /* Tx channel 6 (3945 only) */
399#define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */
400#define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */
401
402#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
403 CSR_FH_INT_BIT_RX_CHNL2 | \
404 CSR_FH_INT_BIT_RX_CHNL1 | \
405 CSR_FH_INT_BIT_RX_CHNL0)
406
407#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL6 | \
408 CSR_FH_INT_BIT_TX_CHNL1 | \
409 CSR_FH_INT_BIT_TX_CHNL0)
410
411
412/* RESET */
413#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001)
414#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002)
415#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080)
416#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100)
417#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200)
418
419/* GP (general purpose) CONTROL */
420#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001)
421#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004)
422#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008)
423#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010)
424
425#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001)
426
427#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000)
428#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000)
429#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000)
430
431
432/* EEPROM REG */
433#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
434#define CSR_EEPROM_REG_BIT_CMD (0x00000002)
435
436/* EEPROM GP */
437#define CSR_EEPROM_GP_VALID_MSK (0x00000006)
438#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000)
439#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180)
440
441/* UCODE DRV GP */
442#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001)
443#define CSR_UCODE_SW_BIT_RFKILL (0x00000002)
444#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
445#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
446
447/* GPIO */
448#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
449#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000)
450#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC CSR_GPIO_IN_BIT_AUX_POWER
451
452/* GI Chicken Bits */
453#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
454#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000)
455
456/* CSR_ANA_PLL_CFG */
457#define CSR_ANA_PLL_CFG_SH (0x00880300)
458
459/*=== HBUS (Host-side Bus) ===*/
460#define HBUS_BASE (0x400)
461
462/*
463 * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM
464 * structures, error log, event log, verifying uCode load).
465 * First write to address register, then read from or write to data register
466 * to complete the job. Once the address register is set up, accesses to
467 * data registers auto-increment the address by one dword.
468 * Bit usage for address registers (read or write):
469 * 0-31: memory address within device
470 */
471#define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c)
472#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010)
473#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018)
474#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c)
475
476/*
477 * Registers for accessing device's internal peripheral registers
478 * (e.g. SCD, BSM, etc.). First write to address register,
479 * then read from or write to data register to complete the job.
480 * Bit usage for address registers (read or write):
481 * 0-15: register address (offset) within device
482 * 24-25: (# bytes - 1) to read or write (e.g. 3 for dword)
483 */
484#define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044)
485#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048)
486#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c)
487#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050)
488
489/*
490 * Per-Tx-queue write pointer (index, really!) (3945 and 4965).
491 * Indicates index to next TFD that driver will fill (1 past latest filled).
492 * Bit usage:
493 * 0-7: queue write index
494 * 11-8: queue selector
495 */
496#define HBUS_TARG_WRPTR (HBUS_BASE+0x060)
497
498/* SCD (3945 Tx Frame Scheduler) */ 324/* SCD (3945 Tx Frame Scheduler) */
499#define SCD_BASE (CSR_BASE + 0x2E00) 325#define SCD_BASE (CSR_BASE + 0x2E00)
500 326
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index a8223c4cc97c..08604eb8291b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -158,9 +158,9 @@ static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window)
158{ 158{
159 window->data = 0; 159 window->data = 0;
160 window->success_counter = 0; 160 window->success_counter = 0;
161 window->success_ratio = IWL_INVALID_VALUE; 161 window->success_ratio = -1;
162 window->counter = 0; 162 window->counter = 0;
163 window->average_tpt = IWL_INVALID_VALUE; 163 window->average_tpt = IWL_INV_TPT;
164 window->stamp = 0; 164 window->stamp = 0;
165} 165}
166 166
@@ -459,22 +459,23 @@ static void rs_tx_status(void *priv_rate,
459 struct iwl3945_rs_sta *rs_sta; 459 struct iwl3945_rs_sta *rs_sta;
460 struct ieee80211_supported_band *sband; 460 struct ieee80211_supported_band *sband;
461 461
462 IWL_DEBUG_RATE("enter\n");
463
462 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 464 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
463 465
464 IWL_DEBUG_RATE("enter\n");
465 466
466 retries = tx_resp->retry_count; 467 retries = tx_resp->retry_count;
467 /* FIXME : this is wrong */ 468 first_index = tx_resp->control.tx_rate->hw_value;
468 first_index = &sband->bitrates[0] - tx_resp->control.tx_rate;
469 if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { 469 if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
470 IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); 470 IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
471 return; 471 return;
472 } 472 }
473 473
474 rcu_read_lock();
475
474 sta = sta_info_get(local, hdr->addr1); 476 sta = sta_info_get(local, hdr->addr1);
475 if (!sta || !sta->rate_ctrl_priv) { 477 if (!sta || !sta->rate_ctrl_priv) {
476 if (sta) 478 rcu_read_unlock();
477 sta_info_put(sta);
478 IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); 479 IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
479 return; 480 return;
480 } 481 }
@@ -547,7 +548,7 @@ static void rs_tx_status(void *priv_rate,
547 548
548 spin_unlock_irqrestore(&rs_sta->lock, flags); 549 spin_unlock_irqrestore(&rs_sta->lock, flags);
549 550
550 sta_info_put(sta); 551 rcu_read_unlock();
551 552
552 IWL_DEBUG_RATE("leave\n"); 553 IWL_DEBUG_RATE("leave\n");
553 554
@@ -633,7 +634,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
633 * 634 *
634 */ 635 */
635static void rs_get_rate(void *priv_rate, struct net_device *dev, 636static void rs_get_rate(void *priv_rate, struct net_device *dev,
636 struct ieee80211_supported_band *band, 637 struct ieee80211_supported_band *sband,
637 struct sk_buff *skb, 638 struct sk_buff *skb,
638 struct rate_selection *sel) 639 struct rate_selection *sel)
639{ 640{
@@ -643,9 +644,9 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
643 int index; 644 int index;
644 struct iwl3945_rs_sta *rs_sta; 645 struct iwl3945_rs_sta *rs_sta;
645 struct iwl3945_rate_scale_data *window = NULL; 646 struct iwl3945_rate_scale_data *window = NULL;
646 int current_tpt = IWL_INVALID_VALUE; 647 int current_tpt = IWL_INV_TPT;
647 int low_tpt = IWL_INVALID_VALUE; 648 int low_tpt = IWL_INV_TPT;
648 int high_tpt = IWL_INVALID_VALUE; 649 int high_tpt = IWL_INV_TPT;
649 u32 fail_count; 650 u32 fail_count;
650 s8 scale_action = 0; 651 s8 scale_action = 0;
651 unsigned long flags; 652 unsigned long flags;
@@ -658,6 +659,8 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
658 659
659 IWL_DEBUG_RATE("enter\n"); 660 IWL_DEBUG_RATE("enter\n");
660 661
662 rcu_read_lock();
663
661 sta = sta_info_get(local, hdr->addr1); 664 sta = sta_info_get(local, hdr->addr1);
662 665
663 /* Send management frames and broadcast/multicast data using lowest 666 /* Send management frames and broadcast/multicast data using lowest
@@ -667,16 +670,15 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
667 is_multicast_ether_addr(hdr->addr1) || 670 is_multicast_ether_addr(hdr->addr1) ||
668 !sta || !sta->rate_ctrl_priv) { 671 !sta || !sta->rate_ctrl_priv) {
669 IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); 672 IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
670 sel->rate = rate_lowest(local, band, sta); 673 sel->rate = rate_lowest(local, sband, sta);
671 if (sta) 674 rcu_read_unlock();
672 sta_info_put(sta);
673 return; 675 return;
674 } 676 }
675 677
676 rate_mask = sta->supp_rates[band->band]; 678 rate_mask = sta->supp_rates[sband->band];
677 index = min(sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); 679 index = min(sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
678 680
679 if (priv->band == IEEE80211_BAND_5GHZ) 681 if (sband->band == IEEE80211_BAND_5GHZ)
680 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; 682 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
681 683
682 rs_sta = (void *)sta->rate_ctrl_priv; 684 rs_sta = (void *)sta->rate_ctrl_priv;
@@ -708,7 +710,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
708 710
709 if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) && 711 if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
710 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { 712 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
711 window->average_tpt = IWL_INVALID_VALUE; 713 window->average_tpt = IWL_INV_TPT;
712 spin_unlock_irqrestore(&rs_sta->lock, flags); 714 spin_unlock_irqrestore(&rs_sta->lock, flags);
713 715
714 IWL_DEBUG_RATE("Invalid average_tpt on rate %d: " 716 IWL_DEBUG_RATE("Invalid average_tpt on rate %d: "
@@ -727,7 +729,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
727 current_tpt = window->average_tpt; 729 current_tpt = window->average_tpt;
728 730
729 high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, 731 high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask,
730 band->band); 732 sband->band);
731 low = high_low & 0xff; 733 low = high_low & 0xff;
732 high = (high_low >> 8) & 0xff; 734 high = (high_low >> 8) & 0xff;
733 735
@@ -744,19 +746,16 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
744 if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { 746 if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
745 IWL_DEBUG_RATE("decrease rate because of low success_ratio\n"); 747 IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
746 scale_action = -1; 748 scale_action = -1;
747 } else if ((low_tpt == IWL_INVALID_VALUE) && 749 } else if ((low_tpt == IWL_INV_TPT) && (high_tpt == IWL_INV_TPT))
748 (high_tpt == IWL_INVALID_VALUE))
749 scale_action = 1; 750 scale_action = 1;
750 else if ((low_tpt != IWL_INVALID_VALUE) && 751 else if ((low_tpt != IWL_INV_TPT) && (high_tpt != IWL_INV_TPT) &&
751 (high_tpt != IWL_INVALID_VALUE) 752 (low_tpt < current_tpt) && (high_tpt < current_tpt)) {
752 && (low_tpt < current_tpt)
753 && (high_tpt < current_tpt)) {
754 IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < " 753 IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < "
755 "current_tpt [%d]\n", 754 "current_tpt [%d]\n",
756 low_tpt, high_tpt, current_tpt); 755 low_tpt, high_tpt, current_tpt);
757 scale_action = 0; 756 scale_action = 0;
758 } else { 757 } else {
759 if (high_tpt != IWL_INVALID_VALUE) { 758 if (high_tpt != IWL_INV_TPT) {
760 if (high_tpt > current_tpt) 759 if (high_tpt > current_tpt)
761 scale_action = 1; 760 scale_action = 1;
762 else { 761 else {
@@ -764,7 +763,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
764 ("decrease rate because of high tpt\n"); 763 ("decrease rate because of high tpt\n");
765 scale_action = -1; 764 scale_action = -1;
766 } 765 }
767 } else if (low_tpt != IWL_INVALID_VALUE) { 766 } else if (low_tpt != IWL_INV_TPT) {
768 if (low_tpt > current_tpt) { 767 if (low_tpt > current_tpt) {
769 IWL_DEBUG_RATE 768 IWL_DEBUG_RATE
770 ("decrease rate because of low tpt\n"); 769 ("decrease rate because of low tpt\n");
@@ -806,16 +805,16 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
806 out: 805 out:
807 806
808 sta->last_txrate_idx = index; 807 sta->last_txrate_idx = index;
809 if (priv->band == IEEE80211_BAND_5GHZ) 808 if (sband->band == IEEE80211_BAND_5GHZ)
810 sta->txrate_idx = sta->last_txrate_idx - IWL_FIRST_OFDM_RATE; 809 sta->txrate_idx = sta->last_txrate_idx - IWL_FIRST_OFDM_RATE;
811 else 810 else
812 sta->txrate_idx = sta->last_txrate_idx; 811 sta->txrate_idx = sta->last_txrate_idx;
813 812
814 sta_info_put(sta); 813 rcu_read_unlock();
815 814
816 IWL_DEBUG_RATE("leave: %d\n", index); 815 IWL_DEBUG_RATE("leave: %d\n", index);
817 816
818 sel->rate = &priv->ieee_rates[index]; 817 sel->rate = &sband->bitrates[sta->txrate_idx];
819} 818}
820 819
821static struct rate_control_ops rs_ops = { 820static struct rate_control_ops rs_ops = {
@@ -843,13 +842,15 @@ int iwl3945_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
843 unsigned long now = jiffies; 842 unsigned long now = jiffies;
844 u32 max_time = 0; 843 u32 max_time = 0;
845 844
845 rcu_read_lock();
846
846 sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); 847 sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
847 if (!sta || !sta->rate_ctrl_priv) { 848 if (!sta || !sta->rate_ctrl_priv) {
848 if (sta) { 849 if (sta)
849 sta_info_put(sta);
850 IWL_DEBUG_RATE("leave - no private rate data!\n"); 850 IWL_DEBUG_RATE("leave - no private rate data!\n");
851 } else 851 else
852 IWL_DEBUG_RATE("leave - no station!\n"); 852 IWL_DEBUG_RATE("leave - no station!\n");
853 rcu_read_unlock();
853 return sprintf(buf, "station %d not found\n", sta_id); 854 return sprintf(buf, "station %d not found\n", sta_id);
854 } 855 }
855 856
@@ -890,7 +891,7 @@ int iwl3945_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
890 i = j; 891 i = j;
891 } 892 }
892 spin_unlock_irqrestore(&rs_sta->lock, flags); 893 spin_unlock_irqrestore(&rs_sta->lock, flags);
893 sta_info_put(sta); 894 rcu_read_unlock();
894 895
895 /* Display the average rate of all samples taken. 896 /* Display the average rate of all samples taken.
896 * 897 *
@@ -927,11 +928,12 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
927 return; 928 return;
928 } 929 }
929 930
931 rcu_read_lock();
932
930 sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); 933 sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
931 if (!sta || !sta->rate_ctrl_priv) { 934 if (!sta || !sta->rate_ctrl_priv) {
932 if (sta)
933 sta_info_put(sta);
934 IWL_DEBUG_RATE("leave - no private rate data!\n"); 935 IWL_DEBUG_RATE("leave - no private rate data!\n");
936 rcu_read_unlock();
935 return; 937 return;
936 } 938 }
937 939
@@ -958,7 +960,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
958 break; 960 break;
959 } 961 }
960 962
961 sta_info_put(sta); 963 rcu_read_unlock();
962 spin_unlock_irqrestore(&rs_sta->lock, flags); 964 spin_unlock_irqrestore(&rs_sta->lock, flags);
963 965
964 rssi = priv->last_rx_rssi; 966 rssi = priv->last_rx_rssi;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
index d5e9220f871d..b082a093ee26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
@@ -36,8 +36,8 @@ struct iwl3945_rate_info {
36 u8 next_rs; /* next rate used in rs algo */ 36 u8 next_rs; /* next rate used in rs algo */
37 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */ 37 u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
38 u8 next_rs_tgg; /* next rate used in TGG rs algo */ 38 u8 next_rs_tgg; /* next rate used in TGG rs algo */
39 u8 table_rs_index; /* index in rate scale table cmd */ 39 u8 table_rs_index; /* index in rate scale table cmd */
40 u8 prev_table_rs; /* prev in rate table cmd */ 40 u8 prev_table_rs; /* prev in rate table cmd */
41}; 41};
42 42
43/* 43/*
@@ -159,7 +159,7 @@ enum {
159 159
160#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) 160#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
161 161
162#define IWL_INVALID_VALUE -1 162#define IWL_INV_TPT -1
163 163
164#define IWL_MIN_RSSI_VAL -100 164#define IWL_MIN_RSSI_VAL -100
165#define IWL_MAX_RSSI_VAL 0 165#define IWL_MAX_RSSI_VAL 0
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 82d282730b75..50a641c0c5b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -39,6 +39,7 @@
39#include <asm/unaligned.h> 39#include <asm/unaligned.h>
40#include <net/mac80211.h> 40#include <net/mac80211.h>
41 41
42#include "iwl-3945-core.h"
42#include "iwl-3945.h" 43#include "iwl-3945.h"
43#include "iwl-helpers.h" 44#include "iwl-helpers.h"
44#include "iwl-3945-rs.h" 45#include "iwl-3945-rs.h"
@@ -183,6 +184,16 @@ void iwl3945_disable_events(struct iwl3945_priv *priv)
183 184
184} 185}
185 186
187static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
188{
189 int idx;
190
191 for (idx = 0; idx < IWL_RATE_COUNT; idx++)
192 if (iwl3945_rates[idx].plcp == plcp)
193 return idx;
194 return -1;
195}
196
186/** 197/**
187 * iwl3945_get_antenna_flags - Get antenna flags for RXON command 198 * iwl3945_get_antenna_flags - Get antenna flags for RXON command
188 * @priv: eeprom and antenna fields are used to determine antenna flags 199 * @priv: eeprom and antenna fields are used to determine antenna flags
@@ -216,14 +227,126 @@ __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
216 return 0; /* "diversity" is default if error */ 227 return 0; /* "diversity" is default if error */
217} 228}
218 229
230#ifdef CONFIG_IWL3945_DEBUG
231#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
232
233static const char *iwl3945_get_tx_fail_reason(u32 status)
234{
235 switch (status & TX_STATUS_MSK) {
236 case TX_STATUS_SUCCESS:
237 return "SUCCESS";
238 TX_STATUS_ENTRY(SHORT_LIMIT);
239 TX_STATUS_ENTRY(LONG_LIMIT);
240 TX_STATUS_ENTRY(FIFO_UNDERRUN);
241 TX_STATUS_ENTRY(MGMNT_ABORT);
242 TX_STATUS_ENTRY(NEXT_FRAG);
243 TX_STATUS_ENTRY(LIFE_EXPIRE);
244 TX_STATUS_ENTRY(DEST_PS);
245 TX_STATUS_ENTRY(ABORTED);
246 TX_STATUS_ENTRY(BT_RETRY);
247 TX_STATUS_ENTRY(STA_INVALID);
248 TX_STATUS_ENTRY(FRAG_DROPPED);
249 TX_STATUS_ENTRY(TID_DISABLE);
250 TX_STATUS_ENTRY(FRAME_FLUSHED);
251 TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
252 TX_STATUS_ENTRY(TX_LOCKED);
253 TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
254 }
255
256 return "UNKNOWN";
257}
258#else
259static inline const char *iwl3945_get_tx_fail_reason(u32 status)
260{
261 return "";
262}
263#endif
264
265
266/**
267 * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
268 *
269 * When FW advances 'R' index, all entries between old and new 'R' index
270 * need to be reclaimed. As result, some free space forms. If there is
271 * enough free space (> low mark), wake the stack that feeds us.
272 */
273static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
274 int txq_id, int index)
275{
276 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
277 struct iwl3945_queue *q = &txq->q;
278 struct iwl3945_tx_info *tx_info;
279
280 BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
281
282 for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
283 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
284
285 tx_info = &txq->txb[txq->q.read_ptr];
286 ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0],
287 &tx_info->status);
288 tx_info->skb[0] = NULL;
289 iwl3945_hw_txq_free_tfd(priv, txq);
290 }
291
292 if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
293 (txq_id != IWL_CMD_QUEUE_NUM) &&
294 priv->mac80211_registered)
295 ieee80211_wake_queue(priv->hw, txq_id);
296}
297
298/**
299 * iwl3945_rx_reply_tx - Handle Tx response
300 */
301static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
302 struct iwl3945_rx_mem_buffer *rxb)
303{
304 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
305 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
306 int txq_id = SEQ_TO_QUEUE(sequence);
307 int index = SEQ_TO_INDEX(sequence);
308 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
309 struct ieee80211_tx_status *tx_status;
310 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
311 u32 status = le32_to_cpu(tx_resp->status);
312 int rate_idx;
313
314 if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
315 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
316 "is out of range [0-%d] %d %d\n", txq_id,
317 index, txq->q.n_bd, txq->q.write_ptr,
318 txq->q.read_ptr);
319 return;
320 }
321
322 tx_status = &(txq->txb[txq->q.read_ptr].status);
323
324 tx_status->retry_count = tx_resp->failure_frame;
325 /* tx_status->rts_retry_count = tx_resp->failure_rts; */
326 tx_status->flags = ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
327 IEEE80211_TX_STATUS_ACK : 0;
328
329 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
330 txq_id, iwl3945_get_tx_fail_reason(status), status,
331 tx_resp->rate, tx_resp->failure_frame);
332
333 rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
334 tx_status->control.tx_rate = &priv->ieee_rates[rate_idx];
335 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
336 iwl3945_tx_queue_reclaim(priv, txq_id, index);
337
338 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
339 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
340}
341
342
343
219/***************************************************************************** 344/*****************************************************************************
220 * 345 *
221 * Intel PRO/Wireless 3945ABG/BG Network Connection 346 * Intel PRO/Wireless 3945ABG/BG Network Connection
222 * 347 *
223 * RX handler implementations 348 * RX handler implementations
224 * 349 *
225 * Used by iwl-base.c
226 *
227 *****************************************************************************/ 350 *****************************************************************************/
228 351
229void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb) 352void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
@@ -238,6 +361,156 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
238 priv->last_statistics_time = jiffies; 361 priv->last_statistics_time = jiffies;
239} 362}
240 363
364/******************************************************************************
365 *
366 * Misc. internal state and helper functions
367 *
368 ******************************************************************************/
369#ifdef CONFIG_IWL3945_DEBUG
370
371/**
372 * iwl3945_report_frame - dump frame to syslog during debug sessions
373 *
374 * You may hack this function to show different aspects of received frames,
375 * including selective frame dumps.
376 * group100 parameter selects whether to show 1 out of 100 good frames.
377 */
378static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
379 struct iwl3945_rx_packet *pkt,
380 struct ieee80211_hdr *header, int group100)
381{
382 u32 to_us;
383 u32 print_summary = 0;
384 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
385 u32 hundred = 0;
386 u32 dataframe = 0;
387 u16 fc;
388 u16 seq_ctl;
389 u16 channel;
390 u16 phy_flags;
391 u16 length;
392 u16 status;
393 u16 bcn_tmr;
394 u32 tsf_low;
395 u64 tsf;
396 u8 rssi;
397 u8 agc;
398 u16 sig_avg;
399 u16 noise_diff;
400 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
401 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
402 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
403 u8 *data = IWL_RX_DATA(pkt);
404
405 /* MAC header */
406 fc = le16_to_cpu(header->frame_control);
407 seq_ctl = le16_to_cpu(header->seq_ctrl);
408
409 /* metadata */
410 channel = le16_to_cpu(rx_hdr->channel);
411 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
412 length = le16_to_cpu(rx_hdr->len);
413
414 /* end-of-frame status and timestamp */
415 status = le32_to_cpu(rx_end->status);
416 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
417 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
418 tsf = le64_to_cpu(rx_end->timestamp);
419
420 /* signal statistics */
421 rssi = rx_stats->rssi;
422 agc = rx_stats->agc;
423 sig_avg = le16_to_cpu(rx_stats->sig_avg);
424 noise_diff = le16_to_cpu(rx_stats->noise_diff);
425
426 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
427
428 /* if data frame is to us and all is good,
429 * (optionally) print summary for only 1 out of every 100 */
430 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
431 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
432 dataframe = 1;
433 if (!group100)
434 print_summary = 1; /* print each frame */
435 else if (priv->framecnt_to_us < 100) {
436 priv->framecnt_to_us++;
437 print_summary = 0;
438 } else {
439 priv->framecnt_to_us = 0;
440 print_summary = 1;
441 hundred = 1;
442 }
443 } else {
444 /* print summary for all other frames */
445 print_summary = 1;
446 }
447
448 if (print_summary) {
449 char *title;
450 u32 rate;
451
452 if (hundred)
453 title = "100Frames";
454 else if (fc & IEEE80211_FCTL_RETRY)
455 title = "Retry";
456 else if (ieee80211_is_assoc_response(fc))
457 title = "AscRsp";
458 else if (ieee80211_is_reassoc_response(fc))
459 title = "RasRsp";
460 else if (ieee80211_is_probe_response(fc)) {
461 title = "PrbRsp";
462 print_dump = 1; /* dump frame contents */
463 } else if (ieee80211_is_beacon(fc)) {
464 title = "Beacon";
465 print_dump = 1; /* dump frame contents */
466 } else if (ieee80211_is_atim(fc))
467 title = "ATIM";
468 else if (ieee80211_is_auth(fc))
469 title = "Auth";
470 else if (ieee80211_is_deauth(fc))
471 title = "DeAuth";
472 else if (ieee80211_is_disassoc(fc))
473 title = "DisAssoc";
474 else
475 title = "Frame";
476
477 rate = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
478 if (rate == -1)
479 rate = 0;
480 else
481 rate = iwl3945_rates[rate].ieee / 2;
482
483 /* print frame summary.
484 * MAC addresses show just the last byte (for brevity),
485 * but you can hack it to show more, if you'd like to. */
486 if (dataframe)
487 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
488 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
489 title, fc, header->addr1[5],
490 length, rssi, channel, rate);
491 else {
492 /* src/dst addresses assume managed mode */
493 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
494 "src=0x%02x, rssi=%u, tim=%lu usec, "
495 "phy=0x%02x, chnl=%d\n",
496 title, fc, header->addr1[5],
497 header->addr3[5], rssi,
498 tsf_low - priv->scan_start_tsf,
499 phy_flags, channel);
500 }
501 }
502 if (print_dump)
503 iwl3945_print_hex_dump(IWL_DL_RX, data, length);
504}
505#else
506static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
507 struct iwl3945_rx_packet *pkt,
508 struct ieee80211_hdr *header, int group100)
509{
510}
511#endif
512
513
241static void iwl3945_add_radiotap(struct iwl3945_priv *priv, 514static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
242 struct sk_buff *skb, 515 struct sk_buff *skb,
243 struct iwl3945_rx_frame_hdr *rx_hdr, 516 struct iwl3945_rx_frame_hdr *rx_hdr,
@@ -376,24 +649,28 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
376static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, 649static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
377 struct iwl3945_rx_mem_buffer *rxb) 650 struct iwl3945_rx_mem_buffer *rxb)
378{ 651{
652 struct ieee80211_hdr *header;
653 struct ieee80211_rx_status rx_status;
379 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; 654 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
380 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); 655 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
381 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); 656 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
382 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); 657 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
383 struct ieee80211_hdr *header; 658 int snr;
384 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg); 659 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg);
385 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff); 660 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
386 struct ieee80211_rx_status stats = {
387 .mactime = le64_to_cpu(rx_end->timestamp),
388 .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)),
389 .band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
390 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ,
391 .antenna = 0,
392 .rate_idx = iwl3945_rate_index_from_plcp(rx_hdr->rate),
393 .flag = 0,
394 };
395 u8 network_packet; 661 u8 network_packet;
396 int snr; 662
663 rx_status.antenna = 0;
664 rx_status.flag = 0;
665 rx_status.mactime = le64_to_cpu(rx_end->timestamp);
666 rx_status.freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel));
667 rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
668 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
669
670 rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
671
672 if (rx_status.band == IEEE80211_BAND_5GHZ)
673 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
397 674
398 if ((unlikely(rx_stats->phy_count > 20))) { 675 if ((unlikely(rx_stats->phy_count > 20))) {
399 IWL_DEBUG_DROP 676 IWL_DEBUG_DROP
@@ -409,12 +686,12 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
409 } 686 }
410 687
411 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { 688 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
412 iwl3945_handle_data_packet(priv, 1, rxb, &stats); 689 iwl3945_handle_data_packet(priv, 1, rxb, &rx_status);
413 return; 690 return;
414 } 691 }
415 692
416 /* Convert 3945's rssi indicator to dBm */ 693 /* Convert 3945's rssi indicator to dBm */
417 stats.ssi = rx_stats->rssi - IWL_RSSI_OFFSET; 694 rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET;
418 695
419 /* Set default noise value to -127 */ 696 /* Set default noise value to -127 */
420 if (priv->last_rx_noise == 0) 697 if (priv->last_rx_noise == 0)
@@ -430,50 +707,47 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
430 * signal-to-noise ratio (SNR) is (sig_avg / noise_diff). 707 * signal-to-noise ratio (SNR) is (sig_avg / noise_diff).
431 * Convert linear SNR to dB SNR, then subtract that from rssi dBm 708 * Convert linear SNR to dB SNR, then subtract that from rssi dBm
432 * to obtain noise level in dBm. 709 * to obtain noise level in dBm.
433 * Calculate stats.signal (quality indicator in %) based on SNR. */ 710 * Calculate rx_status.signal (quality indicator in %) based on SNR. */
434 if (rx_stats_noise_diff) { 711 if (rx_stats_noise_diff) {
435 snr = rx_stats_sig_avg / rx_stats_noise_diff; 712 snr = rx_stats_sig_avg / rx_stats_noise_diff;
436 stats.noise = stats.ssi - iwl3945_calc_db_from_ratio(snr); 713 rx_status.noise = rx_status.ssi -
437 stats.signal = iwl3945_calc_sig_qual(stats.ssi, stats.noise); 714 iwl3945_calc_db_from_ratio(snr);
715 rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi,
716 rx_status.noise);
438 717
439 /* If noise info not available, calculate signal quality indicator (%) 718 /* If noise info not available, calculate signal quality indicator (%)
440 * using just the dBm signal level. */ 719 * using just the dBm signal level. */
441 } else { 720 } else {
442 stats.noise = priv->last_rx_noise; 721 rx_status.noise = priv->last_rx_noise;
443 stats.signal = iwl3945_calc_sig_qual(stats.ssi, 0); 722 rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0);
444 } 723 }
445 724
446 725
447 IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", 726 IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
448 stats.ssi, stats.noise, stats.signal, 727 rx_status.ssi, rx_status.noise, rx_status.signal,
449 rx_stats_sig_avg, rx_stats_noise_diff); 728 rx_stats_sig_avg, rx_stats_noise_diff);
450 729
451 /* can be covered by iwl3945_report_frame() in most cases */
452/* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */
453
454 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); 730 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
455 731
456 network_packet = iwl3945_is_network_packet(priv, header); 732 network_packet = iwl3945_is_network_packet(priv, header);
457 733
458#ifdef CONFIG_IWL3945_DEBUG 734 IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
459 if (iwl3945_debug_level & IWL_DL_STATS && net_ratelimit()) 735 network_packet ? '*' : ' ',
460 IWL_DEBUG_STATS 736 le16_to_cpu(rx_hdr->channel),
461 ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", 737 rx_status.ssi, rx_status.ssi,
462 network_packet ? '*' : ' ', 738 rx_status.ssi, rx_status.rate_idx);
463 le16_to_cpu(rx_hdr->channel),
464 stats.ssi, stats.ssi,
465 stats.ssi, stats.rate_idx);
466 739
740#ifdef CONFIG_IWL3945_DEBUG
467 if (iwl3945_debug_level & (IWL_DL_RX)) 741 if (iwl3945_debug_level & (IWL_DL_RX))
468 /* Set "1" to report good data frames in groups of 100 */ 742 /* Set "1" to report good data frames in groups of 100 */
469 iwl3945_report_frame(priv, pkt, header, 1); 743 iwl3945_dbg_report_frame(priv, pkt, header, 1);
470#endif 744#endif
471 745
472 if (network_packet) { 746 if (network_packet) {
473 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); 747 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
474 priv->last_tsf = le64_to_cpu(rx_end->timestamp); 748 priv->last_tsf = le64_to_cpu(rx_end->timestamp);
475 priv->last_rx_rssi = stats.ssi; 749 priv->last_rx_rssi = rx_status.ssi;
476 priv->last_rx_noise = stats.noise; 750 priv->last_rx_noise = rx_status.noise;
477 } 751 }
478 752
479 switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) { 753 switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
@@ -560,7 +834,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
560 } 834 }
561 } 835 }
562 836
563 iwl3945_handle_data_packet(priv, 0, rxb, &stats); 837 iwl3945_handle_data_packet(priv, 0, rxb, &rx_status);
564 break; 838 break;
565 839
566 case IEEE80211_FTYPE_CTL: 840 case IEEE80211_FTYPE_CTL:
@@ -577,7 +851,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
577 print_mac(mac2, header->addr2), 851 print_mac(mac2, header->addr2),
578 print_mac(mac3, header->addr3)); 852 print_mac(mac3, header->addr3));
579 else 853 else
580 iwl3945_handle_data_packet(priv, 1, rxb, &stats); 854 iwl3945_handle_data_packet(priv, 1, rxb, &rx_status);
581 break; 855 break;
582 } 856 }
583 } 857 }
@@ -993,19 +1267,19 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
993 if (rev_id & PCI_CFG_REV_ID_BIT_RTP) 1267 if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
994 IWL_DEBUG_INFO("RTP type \n"); 1268 IWL_DEBUG_INFO("RTP type \n");
995 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { 1269 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
996 IWL_DEBUG_INFO("ALM-MB type\n"); 1270 IWL_DEBUG_INFO("3945 RADIO-MB type\n");
997 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1271 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
998 CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB); 1272 CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);
999 } else { 1273 } else {
1000 IWL_DEBUG_INFO("ALM-MM type\n"); 1274 IWL_DEBUG_INFO("3945 RADIO-MM type\n");
1001 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1275 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1002 CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM); 1276 CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
1003 } 1277 }
1004 1278
1005 if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) { 1279 if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
1006 IWL_DEBUG_INFO("SKU OP mode is mrc\n"); 1280 IWL_DEBUG_INFO("SKU OP mode is mrc\n");
1007 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1281 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1008 CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC); 1282 CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
1009 } else 1283 } else
1010 IWL_DEBUG_INFO("SKU OP mode is basic\n"); 1284 IWL_DEBUG_INFO("SKU OP mode is basic\n");
1011 1285
@@ -1013,24 +1287,24 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
1013 IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", 1287 IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
1014 priv->eeprom.board_revision); 1288 priv->eeprom.board_revision);
1015 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1289 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1016 CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); 1290 CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
1017 } else { 1291 } else {
1018 IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", 1292 IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
1019 priv->eeprom.board_revision); 1293 priv->eeprom.board_revision);
1020 iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG, 1294 iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
1021 CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); 1295 CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
1022 } 1296 }
1023 1297
1024 if (priv->eeprom.almgor_m_version <= 1) { 1298 if (priv->eeprom.almgor_m_version <= 1) {
1025 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1299 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1026 CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); 1300 CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
1027 IWL_DEBUG_INFO("Card M type A version is 0x%X\n", 1301 IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
1028 priv->eeprom.almgor_m_version); 1302 priv->eeprom.almgor_m_version);
1029 } else { 1303 } else {
1030 IWL_DEBUG_INFO("Card M type B version is 0x%X\n", 1304 IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
1031 priv->eeprom.almgor_m_version); 1305 priv->eeprom.almgor_m_version);
1032 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, 1306 iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1033 CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); 1307 CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
1034 } 1308 }
1035 spin_unlock_irqrestore(&priv->lock, flags); 1309 spin_unlock_irqrestore(&priv->lock, flags);
1036 1310
@@ -2348,6 +2622,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
2348 2622
2349void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) 2623void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
2350{ 2624{
2625 priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
2351 priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; 2626 priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
2352} 2627}
2353 2628
@@ -2362,9 +2637,25 @@ void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
2362 cancel_delayed_work(&priv->thermal_periodic); 2637 cancel_delayed_work(&priv->thermal_periodic);
2363} 2638}
2364 2639
2640static struct iwl_3945_cfg iwl3945_bg_cfg = {
2641 .name = "3945BG",
2642 .fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode",
2643 .sku = IWL_SKU_G,
2644};
2645
2646static struct iwl_3945_cfg iwl3945_abg_cfg = {
2647 .name = "3945ABG",
2648 .fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode",
2649 .sku = IWL_SKU_A|IWL_SKU_G,
2650};
2651
2365struct pci_device_id iwl3945_hw_card_ids[] = { 2652struct pci_device_id iwl3945_hw_card_ids[] = {
2366 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4222)}, 2653 {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)},
2367 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4227)}, 2654 {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)},
2655 {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)},
2656 {IWL_PCI_DEVICE(0x4227, 0x1014, iwl3945_bg_cfg)},
2657 {IWL_PCI_DEVICE(0x4222, PCI_ANY_ID, iwl3945_abg_cfg)},
2658 {IWL_PCI_DEVICE(0x4227, PCI_ANY_ID, iwl3945_abg_cfg)},
2368 {0} 2659 {0}
2369}; 2660};
2370 2661
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index dde389d31637..0ab22d366d93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -40,10 +40,17 @@
40extern struct pci_device_id iwl3945_hw_card_ids[]; 40extern struct pci_device_id iwl3945_hw_card_ids[];
41 41
42#define DRV_NAME "iwl3945" 42#define DRV_NAME "iwl3945"
43#include "iwl-3945-hw.h" 43#include "iwl-csr.h"
44#include "iwl-prph.h" 44#include "iwl-prph.h"
45#include "iwl-3945-hw.h"
45#include "iwl-3945-debug.h" 46#include "iwl-3945-debug.h"
46 47
48/* Change firmware file name, using "-" and incrementing number,
49 * *only* when uCode interface or architecture changes so that it
50 * is not compatible with earlier drivers.
51 * This number will also appear in << 8 position of 1st dword of uCode file */
52#define IWL3945_UCODE_API "-1"
53
47/* Default noise level to report when noise measurement is not available. 54/* Default noise level to report when noise measurement is not available.
48 * This may be because we're: 55 * This may be because we're:
49 * 1) Not associated (4965, no beacon statistics being sent to driver) 56 * 1) Not associated (4965, no beacon statistics being sent to driver)
@@ -109,6 +116,9 @@ struct iwl3945_queue {
109 * space less than this */ 116 * space less than this */
110} __attribute__ ((packed)); 117} __attribute__ ((packed));
111 118
119int iwl3945_queue_space(const struct iwl3945_queue *q);
120int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i);
121
112#define MAX_NUM_OF_TBS (20) 122#define MAX_NUM_OF_TBS (20)
113 123
114/* One for each TFD */ 124/* One for each TFD */
@@ -558,16 +568,6 @@ extern int iwl3945_is_network_packet(struct iwl3945_priv *priv,
558 struct ieee80211_hdr *header); 568 struct ieee80211_hdr *header);
559extern int iwl3945_power_init_handle(struct iwl3945_priv *priv); 569extern int iwl3945_power_init_handle(struct iwl3945_priv *priv);
560extern int iwl3945_eeprom_init(struct iwl3945_priv *priv); 570extern int iwl3945_eeprom_init(struct iwl3945_priv *priv);
561#ifdef CONFIG_IWL3945_DEBUG
562extern void iwl3945_report_frame(struct iwl3945_priv *priv,
563 struct iwl3945_rx_packet *pkt,
564 struct ieee80211_hdr *header, int group100);
565#else
566static inline void iwl3945_report_frame(struct iwl3945_priv *priv,
567 struct iwl3945_rx_packet *pkt,
568 struct ieee80211_hdr *header,
569 int group100) {}
570#endif
571extern void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv, 571extern void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv,
572 struct iwl3945_rx_mem_buffer *rxb, 572 struct iwl3945_rx_mem_buffer *rxb,
573 void *data, short len, 573 void *data, short len,
@@ -691,6 +691,7 @@ struct iwl3945_priv {
691 struct ieee80211_hw *hw; 691 struct ieee80211_hw *hw;
692 struct ieee80211_channel *ieee_channels; 692 struct ieee80211_channel *ieee_channels;
693 struct ieee80211_rate *ieee_rates; 693 struct ieee80211_rate *ieee_rates;
694 struct iwl_3945_cfg *cfg; /* device configuration */
694 695
695 /* temporary frame storage list */ 696 /* temporary frame storage list */
696 struct list_head free_frames; 697 struct list_head free_frames;
@@ -800,7 +801,6 @@ struct iwl3945_priv {
800 struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES]; 801 struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES];
801 802
802 unsigned long status; 803 unsigned long status;
803 u32 config;
804 804
805 int last_rx_rssi; /* From Rx packet statisitics */ 805 int last_rx_rssi; /* From Rx packet statisitics */
806 int last_rx_noise; /* From beacon statistics */ 806 int last_rx_noise; /* From beacon statistics */
@@ -830,7 +830,6 @@ struct iwl3945_priv {
830 int is_open; 830 int is_open;
831 831
832 u8 mac80211_registered; 832 u8 mac80211_registered;
833 int is_abg;
834 833
835 u32 notif_missed_beacons; 834 u32 notif_missed_beacons;
836 835
@@ -950,16 +949,6 @@ static inline int is_channel_ibss(const struct iwl3945_channel_info *ch)
950 return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; 949 return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
951} 950}
952 951
953static inline int iwl3945_rate_index_from_plcp(int plcp)
954{
955 int i;
956
957 for (i = 0; i < IWL_RATE_COUNT; i++)
958 if (iwl3945_rates[i].plcp == plcp)
959 return i;
960 return -1;
961}
962
963extern const struct iwl3945_channel_info *iwl3945_get_channel_info( 952extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
964 const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel); 953 const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel);
965 954
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
index b21ffea325cf..327eabce182c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
@@ -875,26 +875,26 @@ struct iwl4965_rx_frame_hdr {
875 u8 payload[0]; 875 u8 payload[0];
876} __attribute__ ((packed)); 876} __attribute__ ((packed));
877 877
878#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) 878#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0)
879#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) 879#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1)
880 880
881#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) 881#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0)
882#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) 882#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1)
883#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) 883#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2)
884#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) 884#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3)
885#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) 885#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0)
886 886
887#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) 887#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
888#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) 888#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
889#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) 889#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8)
890#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) 890#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8)
891#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) 891#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8)
892 892
893#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) 893#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11)
894#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) 894#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11)
895#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) 895#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11)
896#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) 896#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11)
897#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) 897#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11)
898 898
899struct iwl4965_rx_frame_end { 899struct iwl4965_rx_frame_end {
900 __le32 status; 900 __le32 status;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-debug.h b/drivers/net/wireless/iwlwifi/iwl-4965-debug.h
index 36696bbf170c..baf07c715cf8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-debug.h
@@ -40,15 +40,30 @@ do { if (iwl4965_debug_level & (level)) \
40do { if ((iwl4965_debug_level & (level)) && net_ratelimit()) \ 40do { if ((iwl4965_debug_level & (level)) && net_ratelimit()) \
41 printk(KERN_ERR DRV_NAME": %c %s " fmt, \ 41 printk(KERN_ERR DRV_NAME": %c %s " fmt, \
42 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) 42 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
43
44static inline void iwl4965_print_hex_dump(int level, void *p, u32 len)
45{
46 if (!(iwl4965_debug_level & level))
47 return;
48
49 print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
50 p, len, 1);
51}
43#else 52#else
53
44static inline void IWL_DEBUG(int level, const char *fmt, ...) 54static inline void IWL_DEBUG(int level, const char *fmt, ...)
45{ 55{
46} 56}
47static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) 57static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
48{ 58{
49} 59}
60static inline void iwl4965_print_hex_dump(int level, void *p, u32 len)
61{
62}
50#endif /* CONFIG_IWL4965_DEBUG */ 63#endif /* CONFIG_IWL4965_DEBUG */
51 64
65
66
52/* 67/*
53 * To use the debug system; 68 * To use the debug system;
54 * 69 *
@@ -143,6 +158,7 @@ static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
143 IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) 158 IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
144#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a) 159#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
145#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) 160#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
161#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
146#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) 162#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
147#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) 163#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
148#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) 164#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index cc726215ab93..24413a479a3f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -410,181 +410,6 @@ struct iwl4965_eeprom {
410#define PCI_REG_WUM8 0x0E8 410#define PCI_REG_WUM8 0x0E8
411#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) 411#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
412 412
413/*=== CSR (control and status registers) ===*/
414#define CSR_BASE (0x000)
415
416#define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */
417#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */
418#define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */
419#define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */
420#define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/
421#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */
422#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
423#define CSR_GP_CNTRL (CSR_BASE+0x024)
424
425/*
426 * Hardware revision info
427 * Bit fields:
428 * 31-8: Reserved
429 * 7-4: Type of device: 0x0 = 4965, 0xd = 3945
430 * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D
431 * 1-0: "Dash" value, as in A-1, etc.
432 *
433 * NOTE: Revision step affects calculation of CCK txpower for 4965.
434 */
435#define CSR_HW_REV (CSR_BASE+0x028)
436
437/* EEPROM reads */
438#define CSR_EEPROM_REG (CSR_BASE+0x02c)
439#define CSR_EEPROM_GP (CSR_BASE+0x030)
440#define CSR_GP_UCODE (CSR_BASE+0x044)
441#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
442#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)
443#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
444#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060)
445#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
446
447/*
448 * Indicates hardware rev, to determine CCK backoff for txpower calculation.
449 * Bit fields:
450 * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
451 */
452#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C)
453
454/* Hardware interface configuration bits */
455#define CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R (0x00000010)
456#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00)
457#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
458#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200)
459#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
460
461/* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
462 * acknowledged (reset) by host writing "1" to flagged bits. */
463#define CSR_INT_BIT_FH_RX (1 << 31) /* Rx DMA, cmd responses, FH_INT[17:16] */
464#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
465#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
466#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
467#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
468#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
469#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
470#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
471#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */
472#define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */
473#define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */
474
475#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \
476 CSR_INT_BIT_HW_ERR | \
477 CSR_INT_BIT_FH_TX | \
478 CSR_INT_BIT_SW_ERR | \
479 CSR_INT_BIT_RF_KILL | \
480 CSR_INT_BIT_SW_RX | \
481 CSR_INT_BIT_WAKEUP | \
482 CSR_INT_BIT_ALIVE)
483
484/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
485#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */
486#define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */
487#define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */
488#define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */
489#define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */
490#define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */
491
492#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
493 CSR_FH_INT_BIT_RX_CHNL1 | \
494 CSR_FH_INT_BIT_RX_CHNL0)
495
496#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
497 CSR_FH_INT_BIT_TX_CHNL0)
498
499
500/* RESET */
501#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001)
502#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002)
503#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080)
504#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100)
505#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200)
506
507/* GP (general purpose) CONTROL */
508#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001)
509#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004)
510#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008)
511#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010)
512
513#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001)
514
515#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000)
516#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000)
517#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000)
518
519
520/* EEPROM REG */
521#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
522#define CSR_EEPROM_REG_BIT_CMD (0x00000002)
523
524/* EEPROM GP */
525#define CSR_EEPROM_GP_VALID_MSK (0x00000006)
526#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000)
527#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180)
528
529/* UCODE DRV GP */
530#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001)
531#define CSR_UCODE_SW_BIT_RFKILL (0x00000002)
532#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
533#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
534
535/* GPIO */
536#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
537#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000)
538#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC CSR_GPIO_IN_BIT_AUX_POWER
539
540/* GI Chicken Bits */
541#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
542#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000)
543
544/*=== HBUS (Host-side Bus) ===*/
545#define HBUS_BASE (0x400)
546
547/*
548 * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM
549 * structures, error log, event log, verifying uCode load).
550 * First write to address register, then read from or write to data register
551 * to complete the job. Once the address register is set up, accesses to
552 * data registers auto-increment the address by one dword.
553 * Bit usage for address registers (read or write):
554 * 0-31: memory address within device
555 */
556#define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c)
557#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010)
558#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018)
559#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c)
560
561/*
562 * Registers for accessing device's internal peripheral registers
563 * (e.g. SCD, BSM, etc.). First write to address register,
564 * then read from or write to data register to complete the job.
565 * Bit usage for address registers (read or write):
566 * 0-15: register address (offset) within device
567 * 24-25: (# bytes - 1) to read or write (e.g. 3 for dword)
568 */
569#define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044)
570#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048)
571#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c)
572#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050)
573
574/*
575 * Per-Tx-queue write pointer (index, really!) (3945 and 4965).
576 * Driver sets this to indicate index to next TFD that driver will fill
577 * (1 past latest filled).
578 * Bit usage:
579 * 0-7: queue write index (0-255)
580 * 11-8: queue selector (0-15)
581 */
582#define HBUS_TARG_WRPTR (HBUS_BASE+0x060)
583
584#define HBUS_TARG_MBX_C (HBUS_BASE+0x030)
585
586#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004)
587
588#define TFD_QUEUE_SIZE_MAX (256) 413#define TFD_QUEUE_SIZE_MAX (256)
589 414
590#define IWL_NUM_SCAN_RATES (2) 415#define IWL_NUM_SCAN_RATES (2)
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 48a6a85355ec..25e73864c2a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -570,7 +570,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
570 int index; 570 int index;
571 u32 ant_msk; 571 u32 ant_msk;
572 572
573 index = iwl4965_rate_index_from_plcp(mcs_rate->rate_n_flags); 573 index = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags);
574 574
575 if (index == IWL_RATE_INVALID) { 575 if (index == IWL_RATE_INVALID) {
576 *rate_idx = -1; 576 *rate_idx = -1;
@@ -823,6 +823,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
823 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 823 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
824 struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; 824 struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
825 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 825 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
826 struct ieee80211_hw *hw = local_to_hw(local);
826 struct iwl4965_rate_scale_data *window = NULL; 827 struct iwl4965_rate_scale_data *window = NULL;
827 struct iwl4965_rate_scale_data *search_win = NULL; 828 struct iwl4965_rate_scale_data *search_win = NULL;
828 struct iwl4965_rate tx_mcs; 829 struct iwl4965_rate tx_mcs;
@@ -847,23 +848,22 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
847 if (retries > 15) 848 if (retries > 15)
848 retries = 15; 849 retries = 15;
849 850
851 rcu_read_lock();
850 852
851 sta = sta_info_get(local, hdr->addr1); 853 sta = sta_info_get(local, hdr->addr1);
852 854
853 if (!sta || !sta->rate_ctrl_priv) { 855 if (!sta || !sta->rate_ctrl_priv)
854 if (sta) 856 goto out;
855 sta_info_put(sta); 857
856 return;
857 }
858 858
859 lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; 859 lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
860 860
861 if (!priv->lq_mngr.lq_ready) 861 if (!priv->lq_mngr.lq_ready)
862 return; 862 goto out;
863 863
864 if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && 864 if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
865 !lq_sta->ibss_sta_added) 865 !lq_sta->ibss_sta_added)
866 return; 866 goto out;
867 867
868 table = &lq_sta->lq; 868 table = &lq_sta->lq;
869 active_index = lq_sta->active_tbl; 869 active_index = lq_sta->active_tbl;
@@ -884,17 +884,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
884 search_win = (struct iwl4965_rate_scale_data *) 884 search_win = (struct iwl4965_rate_scale_data *)
885 &(search_tbl->win[0]); 885 &(search_tbl->win[0]);
886 886
887 tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value;
888
889 rs_get_tbl_info_from_mcs(&tx_mcs, priv->band,
890 &tbl_type, &rs_index);
891 if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) {
892 IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n",
893 rs_index, tx_mcs.rate_n_flags);
894 sta_info_put(sta);
895 return;
896 }
897
898 /* 887 /*
899 * Ignore this Tx frame response if its initial rate doesn't match 888 * Ignore this Tx frame response if its initial rate doesn't match
900 * that of latest Link Quality command. There may be stragglers 889 * that of latest Link Quality command. There may be stragglers
@@ -903,14 +892,29 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
903 * to check "search" mode, or a prior "search" mode after we've moved 892 * to check "search" mode, or a prior "search" mode after we've moved
904 * to a new "search" mode (which might become the new "active" mode). 893 * to a new "search" mode (which might become the new "active" mode).
905 */ 894 */
906 if (retries && 895 tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[0].rate_n_flags);
907 (tx_mcs.rate_n_flags != 896 rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index);
908 le32_to_cpu(table->rs_table[0].rate_n_flags))) { 897 if (priv->band == IEEE80211_BAND_5GHZ)
909 IWL_DEBUG_RATE("initial rate does not match 0x%x 0x%x\n", 898 rs_index -= IWL_FIRST_OFDM_RATE;
910 tx_mcs.rate_n_flags, 899
911 le32_to_cpu(table->rs_table[0].rate_n_flags)); 900 if ((tx_resp->control.tx_rate == NULL) ||
912 sta_info_put(sta); 901 (tbl_type.is_SGI ^
913 return; 902 !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) ||
903 (tbl_type.is_fat ^
904 !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) ||
905 (tbl_type.is_dup ^
906 !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) ||
907 (tbl_type.antenna_type ^
908 tx_resp->control.antenna_sel_tx) ||
909 (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^
910 !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) ||
911 (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^
912 !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) ||
913 (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
914 tx_resp->control.tx_rate->bitrate)) {
915 IWL_DEBUG_RATE("initial rate does not match 0x%x\n",
916 tx_mcs.rate_n_flags);
917 goto out;
914 } 918 }
915 919
916 /* Update frame history window with "failure" for each Tx retry. */ 920 /* Update frame history window with "failure" for each Tx retry. */
@@ -959,14 +963,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
959 * if Tx was successful first try, use original rate, 963 * if Tx was successful first try, use original rate,
960 * else look up the rate that was, finally, successful. 964 * else look up the rate that was, finally, successful.
961 */ 965 */
962 if (!tx_resp->retry_count) 966 tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags);
963 tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value; 967 rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index);
964 else
965 tx_mcs.rate_n_flags =
966 le32_to_cpu(table->rs_table[index].rate_n_flags);
967
968 rs_get_tbl_info_from_mcs(&tx_mcs, priv->band,
969 &tbl_type, &rs_index);
970 968
971 /* Update frame history window with "success" if Tx got ACKed ... */ 969 /* Update frame history window with "success" if Tx got ACKed ... */
972 if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) 970 if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
@@ -1025,7 +1023,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
1025 1023
1026 /* See if there's a better rate or modulation mode to try. */ 1024 /* See if there's a better rate or modulation mode to try. */
1027 rs_rate_scale_perform(priv, dev, hdr, sta); 1025 rs_rate_scale_perform(priv, dev, hdr, sta);
1028 sta_info_put(sta); 1026out:
1027 rcu_read_unlock();
1029 return; 1028 return;
1030} 1029}
1031 1030
@@ -1921,7 +1920,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1921 tbl = &(lq_sta->lq_info[active_tbl]); 1920 tbl = &(lq_sta->lq_info[active_tbl]);
1922 1921
1923 /* Revert to "active" rate and throughput info */ 1922 /* Revert to "active" rate and throughput info */
1924 index = iwl4965_rate_index_from_plcp( 1923 index = iwl4965_hwrate_to_plcp_idx(
1925 tbl->current_rate.rate_n_flags); 1924 tbl->current_rate.rate_n_flags);
1926 current_tpt = lq_sta->last_tpt; 1925 current_tpt = lq_sta->last_tpt;
1927 1926
@@ -2077,7 +2076,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
2077 rs_rate_scale_clear_window(&(tbl->win[i])); 2076 rs_rate_scale_clear_window(&(tbl->win[i]));
2078 2077
2079 /* Use new "search" start rate */ 2078 /* Use new "search" start rate */
2080 index = iwl4965_rate_index_from_plcp( 2079 index = iwl4965_hwrate_to_plcp_idx(
2081 tbl->current_rate.rate_n_flags); 2080 tbl->current_rate.rate_n_flags);
2082 2081
2083 IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", 2082 IWL_DEBUG_HT("Switch current mcs: %X index: %d\n",
@@ -2219,6 +2218,8 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
2219 2218
2220 IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); 2219 IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
2221 2220
2221 rcu_read_lock();
2222
2222 sta = sta_info_get(local, hdr->addr1); 2223 sta = sta_info_get(local, hdr->addr1);
2223 2224
2224 /* Send management frames and broadcast/multicast data using lowest 2225 /* Send management frames and broadcast/multicast data using lowest
@@ -2227,9 +2228,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
2227 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || 2228 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
2228 !sta || !sta->rate_ctrl_priv) { 2229 !sta || !sta->rate_ctrl_priv) {
2229 sel->rate = rate_lowest(local, sband, sta); 2230 sel->rate = rate_lowest(local, sband, sta);
2230 if (sta) 2231 goto out;
2231 sta_info_put(sta);
2232 return;
2233 } 2232 }
2234 2233
2235 lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; 2234 lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
@@ -2256,14 +2255,15 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
2256 goto done; 2255 goto done;
2257 } 2256 }
2258 2257
2259 done: 2258done:
2260 if ((i < 0) || (i > IWL_RATE_COUNT)) { 2259 if ((i < 0) || (i > IWL_RATE_COUNT)) {
2261 sel->rate = rate_lowest(local, sband, sta); 2260 sel->rate = rate_lowest(local, sband, sta);
2262 return; 2261 goto out;
2263 } 2262 }
2264 sta_info_put(sta);
2265 2263
2266 sel->rate = &priv->ieee_rates[i]; 2264 sel->rate = &priv->ieee_rates[i];
2265out:
2266 rcu_read_unlock();
2267} 2267}
2268 2268
2269static void *rs_alloc_sta(void *priv, gfp_t gfp) 2269static void *rs_alloc_sta(void *priv, gfp_t gfp)
@@ -2735,13 +2735,15 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
2735 u32 max_time = 0; 2735 u32 max_time = 0;
2736 u8 lq_type, antenna; 2736 u8 lq_type, antenna;
2737 2737
2738 rcu_read_lock();
2739
2738 sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); 2740 sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
2739 if (!sta || !sta->rate_ctrl_priv) { 2741 if (!sta || !sta->rate_ctrl_priv) {
2740 if (sta) { 2742 if (sta)
2741 sta_info_put(sta);
2742 IWL_DEBUG_RATE("leave - no private rate data!\n"); 2743 IWL_DEBUG_RATE("leave - no private rate data!\n");
2743 } else 2744 else
2744 IWL_DEBUG_RATE("leave - no station!\n"); 2745 IWL_DEBUG_RATE("leave - no station!\n");
2746 rcu_read_unlock();
2745 return sprintf(buf, "station %d not found\n", sta_id); 2747 return sprintf(buf, "station %d not found\n", sta_id);
2746 } 2748 }
2747 2749
@@ -2808,7 +2810,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
2808 "active_search %d rate index %d\n", lq_type, antenna, 2810 "active_search %d rate index %d\n", lq_type, antenna,
2809 lq_sta->search_better_tbl, sta->last_txrate_idx); 2811 lq_sta->search_better_tbl, sta->last_txrate_idx);
2810 2812
2811 sta_info_put(sta); 2813 rcu_read_unlock();
2812 return cnt; 2814 return cnt;
2813} 2815}
2814 2816
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
index 13b6c72eeb73..911f21396fd0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
@@ -259,7 +259,7 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
259 return rate; 259 return rate;
260} 260}
261 261
262extern int iwl4965_rate_index_from_plcp(int plcp); 262extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags);
263 263
264/** 264/**
265 * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation 265 * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a9c30bcb65b8..2f01a490c9ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -38,6 +38,7 @@
38#include <linux/etherdevice.h> 38#include <linux/etherdevice.h>
39#include <asm/unaligned.h> 39#include <asm/unaligned.h>
40 40
41#include "iwl-core.h"
41#include "iwl-4965.h" 42#include "iwl-4965.h"
42#include "iwl-helpers.h" 43#include "iwl-helpers.h"
43 44
@@ -122,6 +123,64 @@ static u8 is_single_stream(struct iwl4965_priv *priv)
122 return 0; 123 return 0;
123} 124}
124 125
126int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
127{
128 int idx = 0;
129
130 /* 4965 HT rate format */
131 if (rate_n_flags & RATE_MCS_HT_MSK) {
132 idx = (rate_n_flags & 0xff);
133
134 if (idx >= IWL_RATE_MIMO_6M_PLCP)
135 idx = idx - IWL_RATE_MIMO_6M_PLCP;
136
137 idx += IWL_FIRST_OFDM_RATE;
138 /* skip 9M not supported in ht*/
139 if (idx >= IWL_RATE_9M_INDEX)
140 idx += 1;
141 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
142 return idx;
143
144 /* 4965 legacy rate format, search for match in table */
145 } else {
146 for (idx = 0; idx < ARRAY_SIZE(iwl4965_rates); idx++)
147 if (iwl4965_rates[idx].plcp == (rate_n_flags & 0xFF))
148 return idx;
149 }
150
151 return -1;
152}
153
154/**
155 * translate ucode response to mac80211 tx status control values
156 */
157void iwl4965_hwrate_to_tx_control(struct iwl4965_priv *priv, u32 rate_n_flags,
158 struct ieee80211_tx_control *control)
159{
160 int rate_index;
161
162 control->antenna_sel_tx =
163 ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_A_POS);
164 if (rate_n_flags & RATE_MCS_HT_MSK)
165 control->flags |= IEEE80211_TXCTL_OFDM_HT;
166 if (rate_n_flags & RATE_MCS_GF_MSK)
167 control->flags |= IEEE80211_TXCTL_GREEN_FIELD;
168 if (rate_n_flags & RATE_MCS_FAT_MSK)
169 control->flags |= IEEE80211_TXCTL_40_MHZ_WIDTH;
170 if (rate_n_flags & RATE_MCS_DUP_MSK)
171 control->flags |= IEEE80211_TXCTL_DUP_DATA;
172 if (rate_n_flags & RATE_MCS_SGI_MSK)
173 control->flags |= IEEE80211_TXCTL_SHORT_GI;
174 /* since iwl4965_hwrate_to_plcp_idx is band indifferent, we always use
175 * IEEE80211_BAND_2GHZ band as it contains all the rates */
176 rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
177 if (rate_index == -1)
178 control->tx_rate = NULL;
179 else
180 control->tx_rate =
181 &priv->bands[IEEE80211_BAND_2GHZ].bitrates[rate_index];
182}
183
125/* 184/*
126 * Determine how many receiver/antenna chains to use. 185 * Determine how many receiver/antenna chains to use.
127 * More provides better reception via diversity. Fewer saves power. 186 * More provides better reception via diversity. Fewer saves power.
@@ -546,9 +605,9 @@ int iwl4965_hw_nic_init(struct iwl4965_priv *priv)
546 /* set CSR_HW_CONFIG_REG for uCode use */ 605 /* set CSR_HW_CONFIG_REG for uCode use */
547 606
548 iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG, 607 iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG,
549 CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R | 608 CSR49_HW_IF_CONFIG_REG_BIT_4965_R |
550 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | 609 CSR49_HW_IF_CONFIG_REG_BIT_RADIO_SI |
551 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); 610 CSR49_HW_IF_CONFIG_REG_BIT_MAC_SI);
552 611
553 rc = iwl4965_grab_nic_access(priv); 612 rc = iwl4965_grab_nic_access(priv);
554 if (rc < 0) { 613 if (rc < 0) {
@@ -3523,6 +3582,160 @@ static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *ad
3523 } 3582 }
3524 } 3583 }
3525} 3584}
3585#ifdef CONFIG_IWL4965_DEBUG
3586
3587/**
3588 * iwl4965_dbg_report_frame - dump frame to syslog during debug sessions
3589 *
3590 * You may hack this function to show different aspects of received frames,
3591 * including selective frame dumps.
3592 * group100 parameter selects whether to show 1 out of 100 good frames.
3593 *
3594 * TODO: This was originally written for 3945, need to audit for
3595 * proper operation with 4965.
3596 */
3597static void iwl4965_dbg_report_frame(struct iwl4965_priv *priv,
3598 struct iwl4965_rx_packet *pkt,
3599 struct ieee80211_hdr *header, int group100)
3600{
3601 u32 to_us;
3602 u32 print_summary = 0;
3603 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
3604 u32 hundred = 0;
3605 u32 dataframe = 0;
3606 u16 fc;
3607 u16 seq_ctl;
3608 u16 channel;
3609 u16 phy_flags;
3610 int rate_sym;
3611 u16 length;
3612 u16 status;
3613 u16 bcn_tmr;
3614 u32 tsf_low;
3615 u64 tsf;
3616 u8 rssi;
3617 u8 agc;
3618 u16 sig_avg;
3619 u16 noise_diff;
3620 struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
3621 struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
3622 struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
3623 u8 *data = IWL_RX_DATA(pkt);
3624
3625 if (likely(!(iwl4965_debug_level & IWL_DL_RX)))
3626 return;
3627
3628 /* MAC header */
3629 fc = le16_to_cpu(header->frame_control);
3630 seq_ctl = le16_to_cpu(header->seq_ctrl);
3631
3632 /* metadata */
3633 channel = le16_to_cpu(rx_hdr->channel);
3634 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
3635 rate_sym = rx_hdr->rate;
3636 length = le16_to_cpu(rx_hdr->len);
3637
3638 /* end-of-frame status and timestamp */
3639 status = le32_to_cpu(rx_end->status);
3640 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
3641 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
3642 tsf = le64_to_cpu(rx_end->timestamp);
3643
3644 /* signal statistics */
3645 rssi = rx_stats->rssi;
3646 agc = rx_stats->agc;
3647 sig_avg = le16_to_cpu(rx_stats->sig_avg);
3648 noise_diff = le16_to_cpu(rx_stats->noise_diff);
3649
3650 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
3651
3652 /* if data frame is to us and all is good,
3653 * (optionally) print summary for only 1 out of every 100 */
3654 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
3655 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
3656 dataframe = 1;
3657 if (!group100)
3658 print_summary = 1; /* print each frame */
3659 else if (priv->framecnt_to_us < 100) {
3660 priv->framecnt_to_us++;
3661 print_summary = 0;
3662 } else {
3663 priv->framecnt_to_us = 0;
3664 print_summary = 1;
3665 hundred = 1;
3666 }
3667 } else {
3668 /* print summary for all other frames */
3669 print_summary = 1;
3670 }
3671
3672 if (print_summary) {
3673 char *title;
3674 int rate_idx;
3675 u32 bitrate;
3676
3677 if (hundred)
3678 title = "100Frames";
3679 else if (fc & IEEE80211_FCTL_RETRY)
3680 title = "Retry";
3681 else if (ieee80211_is_assoc_response(fc))
3682 title = "AscRsp";
3683 else if (ieee80211_is_reassoc_response(fc))
3684 title = "RasRsp";
3685 else if (ieee80211_is_probe_response(fc)) {
3686 title = "PrbRsp";
3687 print_dump = 1; /* dump frame contents */
3688 } else if (ieee80211_is_beacon(fc)) {
3689 title = "Beacon";
3690 print_dump = 1; /* dump frame contents */
3691 } else if (ieee80211_is_atim(fc))
3692 title = "ATIM";
3693 else if (ieee80211_is_auth(fc))
3694 title = "Auth";
3695 else if (ieee80211_is_deauth(fc))
3696 title = "DeAuth";
3697 else if (ieee80211_is_disassoc(fc))
3698 title = "DisAssoc";
3699 else
3700 title = "Frame";
3701
3702 rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym);
3703 if (unlikely(rate_idx == -1))
3704 bitrate = 0;
3705 else
3706 bitrate = iwl4965_rates[rate_idx].ieee / 2;
3707
3708 /* print frame summary.
3709 * MAC addresses show just the last byte (for brevity),
3710 * but you can hack it to show more, if you'd like to. */
3711 if (dataframe)
3712 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
3713 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
3714 title, fc, header->addr1[5],
3715 length, rssi, channel, bitrate);
3716 else {
3717 /* src/dst addresses assume managed mode */
3718 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
3719 "src=0x%02x, rssi=%u, tim=%lu usec, "
3720 "phy=0x%02x, chnl=%d\n",
3721 title, fc, header->addr1[5],
3722 header->addr3[5], rssi,
3723 tsf_low - priv->scan_start_tsf,
3724 phy_flags, channel);
3725 }
3726 }
3727 if (print_dump)
3728 iwl4965_print_hex_dump(IWL_DL_RX, data, length);
3729}
3730#else
3731static inline void iwl4965_dbg_report_frame(struct iwl4965_priv *priv,
3732 struct iwl4965_rx_packet *pkt,
3733 struct ieee80211_hdr *header,
3734 int group100)
3735{
3736}
3737#endif
3738
3526 3739
3527#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) 3740#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
3528 3741
@@ -3531,6 +3744,8 @@ static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *ad
3531static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, 3744static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3532 struct iwl4965_rx_mem_buffer *rxb) 3745 struct iwl4965_rx_mem_buffer *rxb)
3533{ 3746{
3747 struct ieee80211_hdr *header;
3748 struct ieee80211_rx_status rx_status;
3534 struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; 3749 struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
3535 /* Use phy data (Rx signal strength, etc.) contained within 3750 /* Use phy data (Rx signal strength, etc.) contained within
3536 * this rx packet for legacy frames, 3751 * this rx packet for legacy frames,
@@ -3541,27 +3756,29 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3541 (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; 3756 (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
3542 __le32 *rx_end; 3757 __le32 *rx_end;
3543 unsigned int len = 0; 3758 unsigned int len = 0;
3544 struct ieee80211_hdr *header;
3545 u16 fc; 3759 u16 fc;
3546 struct ieee80211_rx_status stats = {
3547 .mactime = le64_to_cpu(rx_start->timestamp),
3548 .freq = ieee80211chan2mhz(le16_to_cpu(rx_start->channel)),
3549 .band =
3550 (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
3551 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ,
3552 .antenna = 0,
3553 .rate_idx = iwl4965_rate_index_from_plcp(
3554 le32_to_cpu(rx_start->rate_n_flags)),
3555 .flag = 0,
3556 };
3557 u8 network_packet; 3760 u8 network_packet;
3558 3761
3762 rx_status.mactime = le64_to_cpu(rx_start->timestamp);
3763 rx_status.freq = ieee80211chan2mhz(le16_to_cpu(rx_start->channel));
3764 rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
3765 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
3766 rx_status.rate_idx = iwl4965_hwrate_to_plcp_idx(
3767 le32_to_cpu(rx_start->rate_n_flags));
3768
3769 if (rx_status.band == IEEE80211_BAND_5GHZ)
3770 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
3771
3772 rx_status.antenna = 0;
3773 rx_status.flag = 0;
3774
3559 if ((unlikely(rx_start->cfg_phy_cnt > 20))) { 3775 if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
3560 IWL_DEBUG_DROP 3776 IWL_DEBUG_DROP
3561 ("dsp size out of range [0,20]: " 3777 ("dsp size out of range [0,20]: "
3562 "%d/n", rx_start->cfg_phy_cnt); 3778 "%d/n", rx_start->cfg_phy_cnt);
3563 return; 3779 return;
3564 } 3780 }
3781
3565 if (!include_phy) { 3782 if (!include_phy) {
3566 if (priv->last_phy_res[0]) 3783 if (priv->last_phy_res[0])
3567 rx_start = (struct iwl4965_rx_phy_res *) 3784 rx_start = (struct iwl4965_rx_phy_res *)
@@ -3580,7 +3797,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3580 + rx_start->cfg_phy_cnt); 3797 + rx_start->cfg_phy_cnt);
3581 3798
3582 len = le16_to_cpu(rx_start->byte_count); 3799 len = le16_to_cpu(rx_start->byte_count);
3583 rx_end = (__le32 *) (pkt->u.raw + rx_start->cfg_phy_cnt + 3800 rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
3584 sizeof(struct iwl4965_rx_phy_res) + len); 3801 sizeof(struct iwl4965_rx_phy_res) + len);
3585 } else { 3802 } else {
3586 struct iwl4965_rx_mpdu_res_start *amsdu = 3803 struct iwl4965_rx_mpdu_res_start *amsdu =
@@ -3603,7 +3820,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3603 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); 3820 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
3604 3821
3605 /* Find max signal strength (dBm) among 3 antenna/receiver chains */ 3822 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
3606 stats.ssi = iwl4965_calc_rssi(rx_start); 3823 rx_status.ssi = iwl4965_calc_rssi(rx_start);
3607 3824
3608 /* Meaningful noise values are available only from beacon statistics, 3825 /* Meaningful noise values are available only from beacon statistics,
3609 * which are gathered only when associated, and indicate noise 3826 * which are gathered only when associated, and indicate noise
@@ -3611,32 +3828,29 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3611 * Ignore these noise values while scanning (other channels) */ 3828 * Ignore these noise values while scanning (other channels) */
3612 if (iwl4965_is_associated(priv) && 3829 if (iwl4965_is_associated(priv) &&
3613 !test_bit(STATUS_SCANNING, &priv->status)) { 3830 !test_bit(STATUS_SCANNING, &priv->status)) {
3614 stats.noise = priv->last_rx_noise; 3831 rx_status.noise = priv->last_rx_noise;
3615 stats.signal = iwl4965_calc_sig_qual(stats.ssi, stats.noise); 3832 rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi,
3833 rx_status.noise);
3616 } else { 3834 } else {
3617 stats.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 3835 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
3618 stats.signal = iwl4965_calc_sig_qual(stats.ssi, 0); 3836 rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0);
3619 } 3837 }
3620 3838
3621 /* Reset beacon noise level if not associated. */ 3839 /* Reset beacon noise level if not associated. */
3622 if (!iwl4965_is_associated(priv)) 3840 if (!iwl4965_is_associated(priv))
3623 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 3841 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
3624 3842
3625#ifdef CONFIG_IWL4965_DEBUG 3843 /* Set "1" to report good data frames in groups of 100 */
3626 /* TODO: Parts of iwl4965_report_frame are broken for 4965 */ 3844 /* FIXME: need to optimze the call: */
3627 if (iwl4965_debug_level & (IWL_DL_RX)) 3845 iwl4965_dbg_report_frame(priv, pkt, header, 1);
3628 /* Set "1" to report good data frames in groups of 100 */ 3846
3629 iwl4965_report_frame(priv, pkt, header, 1); 3847 IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
3630 3848 rx_status.ssi, rx_status.noise, rx_status.signal,
3631 if (iwl4965_debug_level & (IWL_DL_RX | IWL_DL_STATS)) 3849 rx_status.mactime);
3632 IWL_DEBUG_RX("Rssi %d, noise %d, qual %d, TSF %lu\n",
3633 stats.ssi, stats.noise, stats.signal,
3634 (long unsigned int)le64_to_cpu(rx_start->timestamp));
3635#endif
3636 3850
3637 network_packet = iwl4965_is_network_packet(priv, header); 3851 network_packet = iwl4965_is_network_packet(priv, header);
3638 if (network_packet) { 3852 if (network_packet) {
3639 priv->last_rx_rssi = stats.ssi; 3853 priv->last_rx_rssi = rx_status.ssi;
3640 priv->last_beacon_time = priv->ucode_beacon_time; 3854 priv->last_beacon_time = priv->ucode_beacon_time;
3641 priv->last_tsf = le64_to_cpu(rx_start->timestamp); 3855 priv->last_tsf = le64_to_cpu(rx_start->timestamp);
3642 } 3856 }
@@ -3739,7 +3953,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3739 return; 3953 return;
3740 } 3954 }
3741 } 3955 }
3742 iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &stats); 3956 iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &rx_status);
3743 break; 3957 break;
3744 3958
3745 case IEEE80211_FTYPE_CTL: 3959 case IEEE80211_FTYPE_CTL:
@@ -3748,7 +3962,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3748 case IEEE80211_STYPE_BACK_REQ: 3962 case IEEE80211_STYPE_BACK_REQ:
3749 IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n"); 3963 IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
3750 iwl4965_handle_data_packet(priv, 0, include_phy, 3964 iwl4965_handle_data_packet(priv, 0, include_phy,
3751 rxb, &stats); 3965 rxb, &rx_status);
3752 break; 3966 break;
3753 default: 3967 default:
3754 break; 3968 break;
@@ -3778,7 +3992,7 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
3778 print_mac(mac3, header->addr3)); 3992 print_mac(mac3, header->addr3));
3779 else 3993 else
3780 iwl4965_handle_data_packet(priv, 1, include_phy, rxb, 3994 iwl4965_handle_data_packet(priv, 1, include_phy, rxb,
3781 &stats); 3995 &rx_status);
3782 break; 3996 break;
3783 } 3997 }
3784 default: 3998 default:
@@ -3900,11 +4114,10 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv,
3900 tx_status->flags |= IEEE80211_TX_STATUS_AMPDU; 4114 tx_status->flags |= IEEE80211_TX_STATUS_AMPDU;
3901 tx_status->ampdu_ack_map = successes; 4115 tx_status->ampdu_ack_map = successes;
3902 tx_status->ampdu_ack_len = agg->frame_count; 4116 tx_status->ampdu_ack_len = agg->frame_count;
3903 /* FIXME Wrong rate 4117 iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags,
3904 tx_status->control.tx_rate = agg->rate_n_flags; 4118 &tx_status->control);
3905 */
3906 4119
3907 IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); 4120 IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
3908 4121
3909 return 0; 4122 return 0;
3910} 4123}
@@ -3925,16 +4138,23 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv,
3925 4138
3926/** 4139/**
3927 * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID 4140 * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID
4141 * priv->lock must be held by the caller
3928 */ 4142 */
3929static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, 4143static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,
3930 u16 ssn_idx, u8 tx_fifo) 4144 u16 ssn_idx, u8 tx_fifo)
3931{ 4145{
4146 int ret = 0;
4147
3932 if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { 4148 if (IWL_BACK_QUEUE_FIRST_ID > txq_id) {
3933 IWL_WARNING("queue number too small: %d, must be > %d\n", 4149 IWL_WARNING("queue number too small: %d, must be > %d\n",
3934 txq_id, IWL_BACK_QUEUE_FIRST_ID); 4150 txq_id, IWL_BACK_QUEUE_FIRST_ID);
3935 return -EINVAL; 4151 return -EINVAL;
3936 } 4152 }
3937 4153
4154 ret = iwl4965_grab_nic_access(priv);
4155 if (ret)
4156 return ret;
4157
3938 iwl4965_tx_queue_stop_scheduler(priv, txq_id); 4158 iwl4965_tx_queue_stop_scheduler(priv, txq_id);
3939 4159
3940 iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); 4160 iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id));
@@ -3948,6 +4168,8 @@ static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,
3948 iwl4965_txq_ctx_deactivate(priv, txq_id); 4168 iwl4965_txq_ctx_deactivate(priv, txq_id);
3949 iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); 4169 iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
3950 4170
4171 iwl4965_release_nic_access(priv);
4172
3951 return 0; 4173 return 0;
3952} 4174}
3953 4175
@@ -4040,12 +4262,12 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv,
4040 "%d, scd_ssn = %d\n", 4262 "%d, scd_ssn = %d\n",
4041 ba_resp->tid, 4263 ba_resp->tid,
4042 ba_resp->seq_ctl, 4264 ba_resp->seq_ctl,
4043 ba_resp->bitmap, 4265 (unsigned long long)ba_resp->bitmap,
4044 ba_resp->scd_flow, 4266 ba_resp->scd_flow,
4045 ba_resp->scd_ssn); 4267 ba_resp->scd_ssn);
4046 IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n", 4268 IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
4047 agg->start_idx, 4269 agg->start_idx,
4048 agg->bitmap); 4270 (unsigned long long)agg->bitmap);
4049 4271
4050 /* Update driver's record of ACK vs. not for each frame in window */ 4272 /* Update driver's record of ACK vs. not for each frame in window */
4051 iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); 4273 iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp);
@@ -4232,7 +4454,7 @@ static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv,
4232 if (!is_channel_valid(ch_info)) 4454 if (!is_channel_valid(ch_info))
4233 return 0; 4455 return 0;
4234 4456
4235 if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_AUTO) 4457 if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)
4236 return 0; 4458 return 0;
4237 4459
4238 if ((ch_info->fat_extension_channel == extension_chan_offset) || 4460 if ((ch_info->fat_extension_channel == extension_chan_offset) ||
@@ -4249,7 +4471,7 @@ static u8 iwl4965_is_fat_tx_allowed(struct iwl4965_priv *priv,
4249 4471
4250 if ((!iwl_ht_conf->is_ht) || 4472 if ((!iwl_ht_conf->is_ht) ||
4251 (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || 4473 (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
4252 (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_AUTO)) 4474 (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE))
4253 return 0; 4475 return 0;
4254 4476
4255 if (sta_ht_inf) { 4477 if (sta_ht_inf) {
@@ -4294,9 +4516,7 @@ void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info)
4294 case IWL_EXT_CHANNEL_OFFSET_BELOW: 4516 case IWL_EXT_CHANNEL_OFFSET_BELOW:
4295 rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; 4517 rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
4296 break; 4518 break;
4297 case IWL_EXT_CHANNEL_OFFSET_AUTO: 4519 case IWL_EXT_CHANNEL_OFFSET_NONE:
4298 rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
4299 break;
4300 default: 4520 default:
4301 rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; 4521 rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
4302 break; 4522 break;
@@ -4419,7 +4639,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
4419 int tx_fifo; 4639 int tx_fifo;
4420 int txq_id; 4640 int txq_id;
4421 int ssn = -1; 4641 int ssn = -1;
4422 int rc = 0; 4642 int ret = 0;
4423 unsigned long flags; 4643 unsigned long flags;
4424 struct iwl4965_tid_data *tid_data; 4644 struct iwl4965_tid_data *tid_data;
4425 DECLARE_MAC_BUF(mac); 4645 DECLARE_MAC_BUF(mac);
@@ -4452,12 +4672,12 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
4452 spin_unlock_irqrestore(&priv->sta_lock, flags); 4672 spin_unlock_irqrestore(&priv->sta_lock, flags);
4453 4673
4454 *start_seq_num = ssn; 4674 *start_seq_num = ssn;
4455 rc = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, 4675 ret = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo,
4456 sta_id, tid, ssn); 4676 sta_id, tid, ssn);
4457 if (rc) 4677 if (ret)
4458 return rc; 4678 return ret;
4459 4679
4460 rc = 0; 4680 ret = 0;
4461 if (tid_data->tfds_in_queue == 0) { 4681 if (tid_data->tfds_in_queue == 0) {
4462 printk(KERN_ERR "HW queue is empty\n"); 4682 printk(KERN_ERR "HW queue is empty\n");
4463 tid_data->agg.state = IWL_AGG_ON; 4683 tid_data->agg.state = IWL_AGG_ON;
@@ -4467,7 +4687,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
4467 tid_data->tfds_in_queue); 4687 tid_data->tfds_in_queue);
4468 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; 4688 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
4469 } 4689 }
4470 return rc; 4690 return ret;
4471} 4691}
4472 4692
4473static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da, 4693static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
@@ -4477,7 +4697,7 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
4477 struct iwl4965_priv *priv = hw->priv; 4697 struct iwl4965_priv *priv = hw->priv;
4478 int tx_fifo_id, txq_id, sta_id, ssn = -1; 4698 int tx_fifo_id, txq_id, sta_id, ssn = -1;
4479 struct iwl4965_tid_data *tid_data; 4699 struct iwl4965_tid_data *tid_data;
4480 int rc, write_ptr, read_ptr; 4700 int ret, write_ptr, read_ptr;
4481 unsigned long flags; 4701 unsigned long flags;
4482 DECLARE_MAC_BUF(mac); 4702 DECLARE_MAC_BUF(mac);
4483 4703
@@ -4517,17 +4737,11 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
4517 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 4737 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
4518 4738
4519 spin_lock_irqsave(&priv->lock, flags); 4739 spin_lock_irqsave(&priv->lock, flags);
4520 rc = iwl4965_grab_nic_access(priv); 4740 ret = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id);
4521 if (rc) {
4522 spin_unlock_irqrestore(&priv->lock, flags);
4523 return rc;
4524 }
4525 rc = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id);
4526 iwl4965_release_nic_access(priv);
4527 spin_unlock_irqrestore(&priv->lock, flags); 4741 spin_unlock_irqrestore(&priv->lock, flags);
4528 4742
4529 if (rc) 4743 if (ret)
4530 return rc; 4744 return ret;
4531 4745
4532 ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid); 4746 ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid);
4533 4747
@@ -4610,9 +4824,15 @@ void iwl4965_hw_cancel_deferred_work(struct iwl4965_priv *priv)
4610 cancel_delayed_work(&priv->init_alive_start); 4824 cancel_delayed_work(&priv->init_alive_start);
4611} 4825}
4612 4826
4827static struct iwl_cfg iwl4965_agn_cfg = {
4828 .name = "4965AGN",
4829 .fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode",
4830 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
4831};
4832
4613struct pci_device_id iwl4965_hw_card_ids[] = { 4833struct pci_device_id iwl4965_hw_card_ids[] = {
4614 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4229)}, 4834 {IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
4615 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4230)}, 4835 {IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
4616 {0} 4836 {0}
4617}; 4837};
4618 4838
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index ce17e4fec838..057fa15d62fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -41,9 +41,17 @@ extern struct pci_device_id iwl4965_hw_card_ids[];
41 41
42#define DRV_NAME "iwl4965" 42#define DRV_NAME "iwl4965"
43#include "iwl-4965-hw.h" 43#include "iwl-4965-hw.h"
44#include "iwl-csr.h"
44#include "iwl-prph.h" 45#include "iwl-prph.h"
45#include "iwl-4965-debug.h" 46#include "iwl-4965-debug.h"
46 47
48/* Change firmware file name, using "-" and incrementing number,
49 * *only* when uCode interface or architecture changes so that it
50 * is not compatible with earlier drivers.
51 * This number will also appear in << 8 position of 1st dword of uCode file */
52#define IWL4965_UCODE_API "-1"
53
54
47/* Default noise level to report when noise measurement is not available. 55/* Default noise level to report when noise measurement is not available.
48 * This may be because we're: 56 * This may be because we're:
49 * 1) Not associated (4965, no beacon statistics being sent to driver) 57 * 1) Not associated (4965, no beacon statistics being sent to driver)
@@ -633,16 +641,6 @@ extern int iwl4965_is_network_packet(struct iwl4965_priv *priv,
633 struct ieee80211_hdr *header); 641 struct ieee80211_hdr *header);
634extern int iwl4965_power_init_handle(struct iwl4965_priv *priv); 642extern int iwl4965_power_init_handle(struct iwl4965_priv *priv);
635extern int iwl4965_eeprom_init(struct iwl4965_priv *priv); 643extern int iwl4965_eeprom_init(struct iwl4965_priv *priv);
636#ifdef CONFIG_IWL4965_DEBUG
637extern void iwl4965_report_frame(struct iwl4965_priv *priv,
638 struct iwl4965_rx_packet *pkt,
639 struct ieee80211_hdr *header, int group100);
640#else
641static inline void iwl4965_report_frame(struct iwl4965_priv *priv,
642 struct iwl4965_rx_packet *pkt,
643 struct ieee80211_hdr *header,
644 int group100) {}
645#endif
646extern void iwl4965_handle_data_packet_monitor(struct iwl4965_priv *priv, 644extern void iwl4965_handle_data_packet_monitor(struct iwl4965_priv *priv,
647 struct iwl4965_rx_mem_buffer *rxb, 645 struct iwl4965_rx_mem_buffer *rxb,
648 void *data, short len, 646 void *data, short len,
@@ -767,6 +765,9 @@ extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv,
767 const struct iwl4965_eeprom_channel *eeprom_ch, 765 const struct iwl4965_eeprom_channel *eeprom_ch,
768 u8 fat_extension_channel); 766 u8 fat_extension_channel);
769extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); 767extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv);
768extern void iwl4965_hwrate_to_tx_control(struct iwl4965_priv *priv,
769 u32 rate_n_flags,
770 struct ieee80211_tx_control *control);
770 771
771#ifdef CONFIG_IWL4965_HT 772#ifdef CONFIG_IWL4965_HT
772void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, 773void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info,
@@ -808,11 +809,10 @@ struct iwl4965_kw {
808#define IWL_OPERATION_MODE_MIXED 2 809#define IWL_OPERATION_MODE_MIXED 2
809#define IWL_OPERATION_MODE_20MHZ 3 810#define IWL_OPERATION_MODE_20MHZ 3
810 811
811#define IWL_EXT_CHANNEL_OFFSET_AUTO 0 812#define IWL_EXT_CHANNEL_OFFSET_NONE 0
812#define IWL_EXT_CHANNEL_OFFSET_ABOVE 1 813#define IWL_EXT_CHANNEL_OFFSET_ABOVE 1
813#define IWL_EXT_CHANNEL_OFFSET_ 2 814#define IWL_EXT_CHANNEL_OFFSET_RESERVE1 2
814#define IWL_EXT_CHANNEL_OFFSET_BELOW 3 815#define IWL_EXT_CHANNEL_OFFSET_BELOW 3
815#define IWL_EXT_CHANNEL_OFFSET_MAX 4
816 816
817#define NRG_NUM_PREV_STAT_L 20 817#define NRG_NUM_PREV_STAT_L 20
818#define NUM_RX_CHAINS (3) 818#define NUM_RX_CHAINS (3)
@@ -974,6 +974,7 @@ struct iwl4965_priv {
974 struct ieee80211_hw *hw; 974 struct ieee80211_hw *hw;
975 struct ieee80211_channel *ieee_channels; 975 struct ieee80211_channel *ieee_channels;
976 struct ieee80211_rate *ieee_rates; 976 struct ieee80211_rate *ieee_rates;
977 struct iwl_cfg *cfg;
977 978
978 /* temporary frame storage list */ 979 /* temporary frame storage list */
979 struct list_head free_frames; 980 struct list_head free_frames;
@@ -1104,7 +1105,6 @@ struct iwl4965_priv {
1104 u32 scd_base_addr; /* scheduler sram base address */ 1105 u32 scd_base_addr; /* scheduler sram base address */
1105 1106
1106 unsigned long status; 1107 unsigned long status;
1107 u32 config;
1108 1108
1109 int last_rx_rssi; /* From Rx packet statisitics */ 1109 int last_rx_rssi; /* From Rx packet statisitics */
1110 int last_rx_noise; /* From beacon statistics */ 1110 int last_rx_noise; /* From beacon statistics */
@@ -1134,7 +1134,6 @@ struct iwl4965_priv {
1134 int is_open; 1134 int is_open;
1135 1135
1136 u8 mac80211_registered; 1136 u8 mac80211_registered;
1137 int is_abg;
1138 1137
1139 u32 notif_missed_beacons; 1138 u32 notif_missed_beacons;
1140 1139
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
new file mode 100644
index 000000000000..675b34b696b4
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -0,0 +1,47 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Tomas Winkler <tomas.winkler@intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *****************************************************************************/
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/version.h>
35
36#include "iwl-4965-debug.h"
37#include "iwl-core.h"
38
39MODULE_DESCRIPTION("iwl core");
40MODULE_VERSION(IWLWIFI_VERSION);
41MODULE_AUTHOR(DRV_COPYRIGHT);
42MODULE_LICENSE("GPL/BSD");
43
44#ifdef CONFIG_IWL4965_DEBUG
45u32 iwl4965_debug_level;
46EXPORT_SYMBOL(iwl4965_debug_level);
47#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
new file mode 100644
index 000000000000..bdd32f891683
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -0,0 +1,84 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Tomas Winkler <tomas.winkler@intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __iwl_core_h__
64#define __iwl_core_h__
65
66#define IWLWIFI_VERSION "1.2.26k"
67#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
68
69#define IWL_PCI_DEVICE(dev, subdev, cfg) \
70 .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
71 .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
72 .driver_data = (kernel_ulong_t)&(cfg)
73
74#define IWL_SKU_G 0x1
75#define IWL_SKU_A 0x2
76#define IWL_SKU_N 0x8
77
78struct iwl_cfg {
79 const char *name;
80 const char *fw_name;
81 unsigned int sku;
82};
83
84#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
new file mode 100644
index 000000000000..7016e5b41c58
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -0,0 +1,259 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63/*=== CSR (control and status registers) ===*/
64#define CSR_BASE (0x000)
65
66#define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */
67#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */
68#define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */
69#define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */
70#define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/
71#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */
72#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
73#define CSR_GP_CNTRL (CSR_BASE+0x024)
74
75/*
76 * Hardware revision info
77 * Bit fields:
78 * 31-8: Reserved
79 * 7-4: Type of device: 0x0 = 4965, 0xd = 3945
80 * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D
81 * 1-0: "Dash" value, as in A-1, etc.
82 *
83 * NOTE: Revision step affects calculation of CCK txpower for 4965.
84 */
85#define CSR_HW_REV (CSR_BASE+0x028)
86
87/* EEPROM reads */
88#define CSR_EEPROM_REG (CSR_BASE+0x02c)
89#define CSR_EEPROM_GP (CSR_BASE+0x030)
90#define CSR_GP_UCODE (CSR_BASE+0x044)
91#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
92#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)
93#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
94#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060)
95#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
96
97/* Analog phase-lock-loop configuration (3945 only)
98 * Set bit 24. */
99#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
100/*
101 * Indicates hardware rev, to determine CCK backoff for txpower calculation.
102 * Bit fields:
103 * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
104 */
105#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C)
106
107/* Bits for CSR_HW_IF_CONFIG_REG */
108#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010)
109#define CSR49_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00)
110#define CSR49_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
111#define CSR49_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200)
112
113#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100)
114#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200)
115#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400)
116#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800)
117#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
118#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
119
120#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
121
122/* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
123 * acknowledged (reset) by host writing "1" to flagged bits. */
124#define CSR_INT_BIT_FH_RX (1 << 31) /* Rx DMA, cmd responses, FH_INT[17:16] */
125#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
126#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
127#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
128#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
129#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
130#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
131#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
132#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */
133#define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */
134#define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */
135
136#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \
137 CSR_INT_BIT_HW_ERR | \
138 CSR_INT_BIT_FH_TX | \
139 CSR_INT_BIT_SW_ERR | \
140 CSR_INT_BIT_RF_KILL | \
141 CSR_INT_BIT_SW_RX | \
142 CSR_INT_BIT_WAKEUP | \
143 CSR_INT_BIT_ALIVE)
144
145/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
146#define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */
147#define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */
148#define CSR39_FH_INT_BIT_RX_CHNL2 (1 << 18) /* Rx channel 2 (3945 only) */
149#define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */
150#define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */
151#define CSR39_FH_INT_BIT_TX_CHNL6 (1 << 6) /* Tx channel 6 (3945 only) */
152#define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */
153#define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */
154
155#define CSR39_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
156 CSR39_FH_INT_BIT_RX_CHNL2 | \
157 CSR_FH_INT_BIT_RX_CHNL1 | \
158 CSR_FH_INT_BIT_RX_CHNL0)
159
160
161#define CSR39_FH_INT_TX_MASK (CSR39_FH_INT_BIT_TX_CHNL6 | \
162 CSR_FH_INT_BIT_TX_CHNL1 | \
163 CSR_FH_INT_BIT_TX_CHNL0)
164
165#define CSR49_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \
166 CSR_FH_INT_BIT_RX_CHNL1 | \
167 CSR_FH_INT_BIT_RX_CHNL0)
168
169#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
170 CSR_FH_INT_BIT_TX_CHNL0)
171
172
173/* RESET */
174#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001)
175#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002)
176#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080)
177#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100)
178#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200)
179
180/* GP (general purpose) CONTROL */
181#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001)
182#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004)
183#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008)
184#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010)
185
186#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001)
187
188#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000)
189#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000)
190#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000)
191
192
193/* EEPROM REG */
194#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
195#define CSR_EEPROM_REG_BIT_CMD (0x00000002)
196
197/* EEPROM GP */
198#define CSR_EEPROM_GP_VALID_MSK (0x00000006)
199#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000)
200#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180)
201
202/* UCODE DRV GP */
203#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001)
204#define CSR_UCODE_SW_BIT_RFKILL (0x00000002)
205#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
206#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
207
208/* GPIO */
209#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
210#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000)
211#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC CSR_GPIO_IN_BIT_AUX_POWER
212
213/* GI Chicken Bits */
214#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
215#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000)
216
217/*=== HBUS (Host-side Bus) ===*/
218#define HBUS_BASE (0x400)
219/*
220 * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM
221 * structures, error log, event log, verifying uCode load).
222 * First write to address register, then read from or write to data register
223 * to complete the job. Once the address register is set up, accesses to
224 * data registers auto-increment the address by one dword.
225 * Bit usage for address registers (read or write):
226 * 0-31: memory address within device
227 */
228#define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c)
229#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010)
230#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018)
231#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c)
232
233/*
234 * Registers for accessing device's internal peripheral registers
235 * (e.g. SCD, BSM, etc.). First write to address register,
236 * then read from or write to data register to complete the job.
237 * Bit usage for address registers (read or write):
238 * 0-15: register address (offset) within device
239 * 24-25: (# bytes - 1) to read or write (e.g. 3 for dword)
240 */
241#define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044)
242#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048)
243#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c)
244#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050)
245
246/*
247 * Per-Tx-queue write pointer (index, really!) (3945 and 4965).
248 * Indicates index to next TFD that driver will fill (1 past latest filled).
249 * Bit usage:
250 * 0-7: queue write index
251 * 11-8: queue selector
252 */
253#define HBUS_TARG_WRPTR (HBUS_BASE+0x060)
254#define HBUS_TARG_MBX_C (HBUS_BASE+0x030)
255
256#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004)
257
258
259
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
new file mode 100644
index 000000000000..0064387dea91
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -0,0 +1,205 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Tomas Winkler <tomas.winkler@intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63
64#include <linux/kernel.h>
65#include <linux/module.h>
66#include <linux/version.h>
67#include <linux/init.h>
68
69#include <net/mac80211.h>
70
71#include "iwl-4965-commands.h"
72#include "iwl-4965.h"
73#include "iwl-core.h"
74#include "iwl-4965-debug.h"
75#include "iwl-eeprom.h"
76#include "iwl-4965-io.h"
77
78/******************************************************************************
79 *
80 * EEPROM related functions
81 *
82******************************************************************************/
83
84int iwlcore_eeprom_verify_signature(struct iwl4965_priv *priv)
85{
86 u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP);
87 if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
88 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
89 return -ENOENT;
90 }
91 return 0;
92}
93EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
94
95/*
96 * The device's EEPROM semaphore prevents conflicts between driver and uCode
97 * when accessing the EEPROM; each access is a series of pulses to/from the
98 * EEPROM chip, not a single event, so even reads could conflict if they
99 * weren't arbitrated by the semaphore.
100 */
101int iwlcore_eeprom_acquire_semaphore(struct iwl4965_priv *priv)
102{
103 u16 count;
104 int ret;
105
106 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
107 /* Request semaphore */
108 iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG,
109 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
110
111 /* See if we got it */
112 ret = iwl4965_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
113 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
114 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
115 EEPROM_SEM_TIMEOUT);
116 if (ret >= 0) {
117 IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
118 count+1);
119 return ret;
120 }
121 }
122
123 return ret;
124}
125EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore);
126
127void iwlcore_eeprom_release_semaphore(struct iwl4965_priv *priv)
128{
129 iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
130 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
131
132}
133EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
134
135
136/**
137 * iwl_eeprom_init - read EEPROM contents
138 *
139 * Load the EEPROM contents from adapter into priv->eeprom
140 *
141 * NOTE: This routine uses the non-debug IO access functions.
142 */
143int iwl_eeprom_init(struct iwl4965_priv *priv)
144{
145 u16 *e = (u16 *)&priv->eeprom;
146 u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP);
147 u32 r;
148 int sz = sizeof(priv->eeprom);
149 int ret;
150 int i;
151 u16 addr;
152
153 /* The EEPROM structure has several padding buffers within it
154 * and when adding new EEPROM maps is subject to programmer errors
155 * which may be very difficult to identify without explicitly
156 * checking the resulting size of the eeprom map. */
157 BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
158
159 if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
160 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
161 return -ENOENT;
162 }
163
164 /* Make sure driver (instead of uCode) is allowed to read EEPROM */
165 ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
166 if (ret < 0) {
167 IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
168 return -ENOENT;
169 }
170
171 /* eeprom is an array of 16bit values */
172 for (addr = 0; addr < sz; addr += sizeof(u16)) {
173 _iwl4965_write32(priv, CSR_EEPROM_REG, addr << 1);
174 _iwl4965_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
175
176 for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
177 i += IWL_EEPROM_ACCESS_DELAY) {
178 r = _iwl4965_read_direct32(priv, CSR_EEPROM_REG);
179 if (r & CSR_EEPROM_REG_READ_VALID_MSK)
180 break;
181 udelay(IWL_EEPROM_ACCESS_DELAY);
182 }
183
184 if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
185 IWL_ERROR("Time out reading EEPROM[%d]", addr);
186 ret = -ETIMEDOUT;
187 goto done;
188 }
189 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
190 }
191 ret = 0;
192
193done:
194 priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
195 return ret;
196}
197EXPORT_SYMBOL(iwl_eeprom_init);
198
199
200void iwl_eeprom_get_mac(const struct iwl4965_priv *priv, u8 *mac)
201{
202 memcpy(mac, priv->eeprom.mac_address, 6);
203}
204EXPORT_SYMBOL(iwl_eeprom_get_mac);
205
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
new file mode 100644
index 000000000000..7827566dcc8b
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -0,0 +1,399 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2008 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Tomas Winkler <tomas.winkler@intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *****************************************************************************/
62
63#ifndef __iwl_eeprom_h__
64#define __iwl_eeprom_h__
65
66struct iwl4965_priv;
67
68/*
69 * EEPROM access time values:
70 *
71 * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
72 * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
73 * CSR_EEPROM_REG_BIT_CMD (0x2).
74 * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
75 * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
76 * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
77 */
78#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
79#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */
80
81#define IWL_EEPROM_SEM_TIMEOUT 10 /* milliseconds */
82#define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
83
84
85/*
86 * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags.
87 *
88 * IBSS and/or AP operation is allowed *only* on those channels with
89 * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because
90 * RADAR detection is not supported by the 4965 driver, but is a
91 * requirement for establishing a new network for legal operation on channels
92 * requiring RADAR detection or restricting ACTIVE scanning.
93 *
94 * NOTE: "WIDE" flag does not indicate anything about "FAT" 40 MHz channels.
95 * It only indicates that 20 MHz channel use is supported; FAT channel
96 * usage is indicated by a separate set of regulatory flags for each
97 * FAT channel pair.
98 *
99 * NOTE: Using a channel inappropriately will result in a uCode error!
100 */
101#define IWL_NUM_TX_CALIB_GROUPS 5
102enum {
103 EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */
104 EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */
105 /* Bit 2 Reserved */
106 EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */
107 EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */
108 EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */
109 EEPROM_CHANNEL_NARROW = (1 << 6), /* 10 MHz channel (not used) */
110 EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */
111};
112
113/* SKU Capabilities */
114#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
115#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
116
117/* *regulatory* channel data format in eeprom, one for each channel.
118 * There are separate entries for FAT (40 MHz) vs. normal (20 MHz) channels. */
119struct iwl4965_eeprom_channel {
120 u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */
121 s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
122} __attribute__ ((packed));
123
124/* 4965 has two radio transmitters (and 3 radio receivers) */
125#define EEPROM_TX_POWER_TX_CHAINS (2)
126
127/* 4965 has room for up to 8 sets of txpower calibration data */
128#define EEPROM_TX_POWER_BANDS (8)
129
130/* 4965 factory calibration measures txpower gain settings for
131 * each of 3 target output levels */
132#define EEPROM_TX_POWER_MEASUREMENTS (3)
133
134#define EEPROM_4965_TX_POWER_VERSION (2)
135
136/* 4965 driver does not work with txpower calibration version < 5.
137 * Look for this in calib_version member of struct iwl4965_eeprom. */
138#define EEPROM_TX_POWER_VERSION_NEW (5)
139
140
141/*
142 * 4965 factory calibration data for one txpower level, on one channel,
143 * measured on one of the 2 tx chains (radio transmitter and associated
144 * antenna). EEPROM contains:
145 *
146 * 1) Temperature (degrees Celsius) of device when measurement was made.
147 *
148 * 2) Gain table index used to achieve the target measurement power.
149 * This refers to the "well-known" gain tables (see iwl-4965-hw.h).
150 *
151 * 3) Actual measured output power, in half-dBm ("34" = 17 dBm).
152 *
153 * 4) RF power amplifier detector level measurement (not used).
154 */
155struct iwl4965_eeprom_calib_measure {
156 u8 temperature; /* Device temperature (Celsius) */
157 u8 gain_idx; /* Index into gain table */
158 u8 actual_pow; /* Measured RF output power, half-dBm */
159 s8 pa_det; /* Power amp detector level (not used) */
160} __attribute__ ((packed));
161
162
163/*
164 * 4965 measurement set for one channel. EEPROM contains:
165 *
166 * 1) Channel number measured
167 *
168 * 2) Measurements for each of 3 power levels for each of 2 radio transmitters
169 * (a.k.a. "tx chains") (6 measurements altogether)
170 */
171struct iwl4965_eeprom_calib_ch_info {
172 u8 ch_num;
173 struct iwl4965_eeprom_calib_measure
174 measurements[EEPROM_TX_POWER_TX_CHAINS]
175 [EEPROM_TX_POWER_MEASUREMENTS];
176} __attribute__ ((packed));
177
178/*
179 * 4965 txpower subband info.
180 *
181 * For each frequency subband, EEPROM contains the following:
182 *
183 * 1) First and last channels within range of the subband. "0" values
184 * indicate that this sample set is not being used.
185 *
186 * 2) Sample measurement sets for 2 channels close to the range endpoints.
187 */
188struct iwl4965_eeprom_calib_subband_info {
189 u8 ch_from; /* channel number of lowest channel in subband */
190 u8 ch_to; /* channel number of highest channel in subband */
191 struct iwl4965_eeprom_calib_ch_info ch1;
192 struct iwl4965_eeprom_calib_ch_info ch2;
193} __attribute__ ((packed));
194
195
196/*
197 * 4965 txpower calibration info. EEPROM contains:
198 *
199 * 1) Factory-measured saturation power levels (maximum levels at which
200 * tx power amplifier can output a signal without too much distortion).
201 * There is one level for 2.4 GHz band and one for 5 GHz band. These
202 * values apply to all channels within each of the bands.
203 *
204 * 2) Factory-measured power supply voltage level. This is assumed to be
205 * constant (i.e. same value applies to all channels/bands) while the
206 * factory measurements are being made.
207 *
208 * 3) Up to 8 sets of factory-measured txpower calibration values.
209 * These are for different frequency ranges, since txpower gain
210 * characteristics of the analog radio circuitry vary with frequency.
211 *
212 * Not all sets need to be filled with data;
213 * struct iwl4965_eeprom_calib_subband_info contains range of channels
214 * (0 if unused) for each set of data.
215 */
216struct iwl4965_eeprom_calib_info {
217 u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */
218 u8 saturation_power52; /* half-dBm */
219 s16 voltage; /* signed */
220 struct iwl4965_eeprom_calib_subband_info
221 band_info[EEPROM_TX_POWER_BANDS];
222} __attribute__ ((packed));
223
224
225
226/*
227 * 4965 EEPROM map
228 */
229struct iwl4965_eeprom {
230 u8 reserved0[16];
231#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */
232 u16 device_id; /* abs.ofs: 16 */
233 u8 reserved1[2];
234#define EEPROM_PMC (2*0x0A) /* 2 bytes */
235 u16 pmc; /* abs.ofs: 20 */
236 u8 reserved2[20];
237#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */
238 u8 mac_address[6]; /* abs.ofs: 42 */
239 u8 reserved3[58];
240#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */
241 u16 board_revision; /* abs.ofs: 106 */
242 u8 reserved4[11];
243#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */
244 u8 board_pba_number[9]; /* abs.ofs: 119 */
245 u8 reserved5[8];
246#define EEPROM_VERSION (2*0x44) /* 2 bytes */
247 u16 version; /* abs.ofs: 136 */
248#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */
249 u8 sku_cap; /* abs.ofs: 138 */
250#define EEPROM_LEDS_MODE (2*0x45+1) /* 1 bytes */
251 u8 leds_mode; /* abs.ofs: 139 */
252#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */
253 u16 oem_mode;
254#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
255 u16 wowlan_mode; /* abs.ofs: 142 */
256#define EEPROM_LEDS_TIME_INTERVAL (2*0x48) /* 2 bytes */
257 u16 leds_time_interval; /* abs.ofs: 144 */
258#define EEPROM_LEDS_OFF_TIME (2*0x49) /* 1 bytes */
259 u8 leds_off_time; /* abs.ofs: 146 */
260#define EEPROM_LEDS_ON_TIME (2*0x49+1) /* 1 bytes */
261 u8 leds_on_time; /* abs.ofs: 147 */
262#define EEPROM_ALMGOR_M_VERSION (2*0x4A) /* 1 bytes */
263 u8 almgor_m_version; /* abs.ofs: 148 */
264#define EEPROM_ANTENNA_SWITCH_TYPE (2*0x4A+1) /* 1 bytes */
265 u8 antenna_switch_type; /* abs.ofs: 149 */
266 u8 reserved6[8];
267#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */
268 u16 board_revision_4965; /* abs.ofs: 158 */
269 u8 reserved7[13];
270#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */
271 u8 board_pba_number_4965[9]; /* abs.ofs: 173 */
272 u8 reserved8[10];
273#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */
274 u8 sku_id[4]; /* abs.ofs: 192 */
275
276/*
277 * Per-channel regulatory data.
278 *
279 * Each channel that *might* be supported by 3945 or 4965 has a fixed location
280 * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
281 * txpower (MSB).
282 *
283 * Entries immediately below are for 20 MHz channel width. FAT (40 MHz)
284 * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
285 *
286 * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
287 */
288#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */
289 u16 band_1_count; /* abs.ofs: 196 */
290#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */
291 struct iwl4965_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
292
293/*
294 * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
295 * 5.0 GHz channels 7, 8, 11, 12, 16
296 * (4915-5080MHz) (none of these is ever supported)
297 */
298#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */
299 u16 band_2_count; /* abs.ofs: 226 */
300#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */
301 struct iwl4965_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
302
303/*
304 * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
305 * (5170-5320MHz)
306 */
307#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */
308 u16 band_3_count; /* abs.ofs: 254 */
309#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */
310 struct iwl4965_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
311
312/*
313 * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
314 * (5500-5700MHz)
315 */
316#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */
317 u16 band_4_count; /* abs.ofs: 280 */
318#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */
319 struct iwl4965_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
320
321/*
322 * 5.7 GHz channels 145, 149, 153, 157, 161, 165
323 * (5725-5825MHz)
324 */
325#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */
326 u16 band_5_count; /* abs.ofs: 304 */
327#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */
328 struct iwl4965_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
329
330 u8 reserved10[2];
331
332
333/*
334 * 2.4 GHz FAT channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
335 *
336 * The channel listed is the center of the lower 20 MHz half of the channel.
337 * The overall center frequency is actually 2 channels (10 MHz) above that,
338 * and the upper half of each FAT channel is centered 4 channels (20 MHz) away
339 * from the lower half; e.g. the upper half of FAT channel 1 is channel 5,
340 * and the overall FAT channel width centers on channel 3.
341 *
342 * NOTE: The RXON command uses 20 MHz channel numbers to specify the
343 * control channel to which to tune. RXON also specifies whether the
344 * control channel is the upper or lower half of a FAT channel.
345 *
346 * NOTE: 4965 does not support FAT channels on 2.4 GHz.
347 */
348#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0) /* 14 bytes */
349 struct iwl4965_eeprom_channel band_24_channels[7]; /* abs.ofs: 320 */
350 u8 reserved11[2];
351
352/*
353 * 5.2 GHz FAT channels 36 (40), 44 (48), 52 (56), 60 (64),
354 * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
355 */
356#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */
357 struct iwl4965_eeprom_channel band_52_channels[11]; /* abs.ofs: 336 */
358 u8 reserved12[6];
359
360/*
361 * 4965 driver requires txpower calibration format version 5 or greater.
362 * Driver does not work with txpower calibration version < 5.
363 * This value is simply a 16-bit number, no major/minor versions here.
364 */
365#define EEPROM_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */
366 u16 calib_version; /* abs.ofs: 364 */
367 u8 reserved13[2];
368 u8 reserved14[96]; /* abs.ofs: 368 */
369
370/*
371 * 4965 Txpower calibration data.
372 */
373#define EEPROM_IWL_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */
374 struct iwl4965_eeprom_calib_info calib_info; /* abs.ofs: 464 */
375
376 u8 reserved16[140]; /* fill out to full 1024 byte block */
377
378
379} __attribute__ ((packed));
380
381#define IWL_EEPROM_IMAGE_SIZE 1024
382
383/* End of EEPROM */
384
385struct iwl_eeprom_ops {
386 int (*verify_signature) (struct iwl4965_priv *priv);
387 int (*acquire_semaphore) (struct iwl4965_priv *priv);
388 void (*release_semaphore) (struct iwl4965_priv *priv);
389};
390
391
392void iwl_eeprom_get_mac(const struct iwl4965_priv *priv, u8 *mac);
393int iwl_eeprom_init(struct iwl4965_priv *priv);
394
395int iwlcore_eeprom_verify_signature(struct iwl4965_priv *priv);
396int iwlcore_eeprom_acquire_semaphore(struct iwl4965_priv *priv);
397void iwlcore_eeprom_release_semaphore(struct iwl4965_priv *priv);
398
399#endif /* __iwl_eeprom_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 8993cca81b40..736b88881b03 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -254,6 +254,26 @@ static inline u8 iwl_get_dma_hi_address(dma_addr_t addr)
254 return sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0; 254 return sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0;
255} 255}
256 256
257/**
258 * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
259 * @index -- current index
260 * @n_bd -- total number of entries in queue (must be power of 2)
261 */
262static inline int iwl_queue_inc_wrap(int index, int n_bd)
263{
264 return ++index & (n_bd - 1);
265}
266
267/**
268 * iwl_queue_dec_wrap - decrement queue index, wrap back to end
269 * @index -- current index
270 * @n_bd -- total number of entries in queue (must be power of 2)
271 */
272static inline int iwl_queue_dec_wrap(int index, int n_bd)
273{
274 return --index & (n_bd - 1);
275}
276
257/* TODO: Move fw_desc functions to iwl-pci.ko */ 277/* TODO: Move fw_desc functions to iwl-pci.ko */
258static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, 278static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
259 struct fw_desc *desc) 279 struct fw_desc *desc)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 0fab832ce8c2..ecf749c2dc0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -46,6 +46,7 @@
46 46
47#include <asm/div64.h> 47#include <asm/div64.h>
48 48
49#include "iwl-3945-core.h"
49#include "iwl-3945.h" 50#include "iwl-3945.h"
50#include "iwl-helpers.h" 51#include "iwl-helpers.h"
51 52
@@ -95,11 +96,6 @@ int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */
95#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" 96#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation"
96#define DRV_VERSION IWLWIFI_VERSION 97#define DRV_VERSION IWLWIFI_VERSION
97 98
98/* Change firmware file name, using "-" and incrementing number,
99 * *only* when uCode interface or architecture changes so that it
100 * is not compatible with earlier drivers.
101 * This number will also appear in << 8 position of 1st dword of uCode file */
102#define IWL3945_UCODE_API "-1"
103 99
104MODULE_DESCRIPTION(DRV_DESCRIPTION); 100MODULE_DESCRIPTION(DRV_DESCRIPTION);
105MODULE_VERSION(DRV_VERSION); 101MODULE_VERSION(DRV_VERSION);
@@ -162,17 +158,6 @@ static const char *iwl3945_escape_essid(const char *essid, u8 essid_len)
162 return escaped; 158 return escaped;
163} 159}
164 160
165static void iwl3945_print_hex_dump(int level, void *p, u32 len)
166{
167#ifdef CONFIG_IWL3945_DEBUG
168 if (!(iwl3945_debug_level & level))
169 return;
170
171 print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
172 p, len, 1);
173#endif
174}
175
176/*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** 161/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
177 * DMA services 162 * DMA services
178 * 163 *
@@ -198,7 +183,7 @@ static void iwl3945_print_hex_dump(int level, void *p, u32 len)
198 * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused. 183 * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused.
199 ***************************************************/ 184 ***************************************************/
200 185
201static int iwl3945_queue_space(const struct iwl3945_queue *q) 186int iwl3945_queue_space(const struct iwl3945_queue *q)
202{ 187{
203 int s = q->read_ptr - q->write_ptr; 188 int s = q->read_ptr - q->write_ptr;
204 189
@@ -214,33 +199,14 @@ static int iwl3945_queue_space(const struct iwl3945_queue *q)
214 return s; 199 return s;
215} 200}
216 201
217/** 202int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i)
218 * iwl3945_queue_inc_wrap - increment queue index, wrap back to beginning
219 * @index -- current index
220 * @n_bd -- total number of entries in queue (must be power of 2)
221 */
222static inline int iwl3945_queue_inc_wrap(int index, int n_bd)
223{
224 return ++index & (n_bd - 1);
225}
226
227/**
228 * iwl3945_queue_dec_wrap - increment queue index, wrap back to end
229 * @index -- current index
230 * @n_bd -- total number of entries in queue (must be power of 2)
231 */
232static inline int iwl3945_queue_dec_wrap(int index, int n_bd)
233{
234 return --index & (n_bd - 1);
235}
236
237static inline int x2_queue_used(const struct iwl3945_queue *q, int i)
238{ 203{
239 return q->write_ptr > q->read_ptr ? 204 return q->write_ptr > q->read_ptr ?
240 (i >= q->read_ptr && i < q->write_ptr) : 205 (i >= q->read_ptr && i < q->write_ptr) :
241 !(i < q->read_ptr && i >= q->write_ptr); 206 !(i < q->read_ptr && i >= q->write_ptr);
242} 207}
243 208
209
244static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge) 210static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
245{ 211{
246 /* This is for scan command, the big buffer at end of command array */ 212 /* This is for scan command, the big buffer at end of command array */
@@ -261,8 +227,8 @@ static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q
261 q->n_window = slots_num; 227 q->n_window = slots_num;
262 q->id = id; 228 q->id = id;
263 229
264 /* count must be power-of-two size, otherwise iwl3945_queue_inc_wrap 230 /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
265 * and iwl3945_queue_dec_wrap are broken. */ 231 * and iwl_queue_dec_wrap are broken. */
266 BUG_ON(!is_power_of_2(count)); 232 BUG_ON(!is_power_of_2(count));
267 233
268 /* slots_num must be power-of-two size, otherwise 234 /* slots_num must be power-of-two size, otherwise
@@ -362,7 +328,7 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
362 txq->need_update = 0; 328 txq->need_update = 0;
363 329
364 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise 330 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
365 * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */ 331 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
366 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); 332 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
367 333
368 /* Initialize queue high/low-water, head/tail indexes */ 334 /* Initialize queue high/low-water, head/tail indexes */
@@ -393,7 +359,7 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t
393 359
394 /* first, empty all BD's */ 360 /* first, empty all BD's */
395 for (; q->write_ptr != q->read_ptr; 361 for (; q->write_ptr != q->read_ptr;
396 q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) 362 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
397 iwl3945_hw_txq_free_tfd(priv, txq); 363 iwl3945_hw_txq_free_tfd(priv, txq);
398 364
399 len = sizeof(struct iwl3945_cmd) * q->n_window; 365 len = sizeof(struct iwl3945_cmd) * q->n_window;
@@ -732,7 +698,7 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c
732 txq->need_update = 1; 698 txq->need_update = 1;
733 699
734 /* Increment and update queue's write index */ 700 /* Increment and update queue's write index */
735 q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); 701 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
736 ret = iwl3945_tx_queue_update_write_ptr(priv, txq); 702 ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
737 703
738 spin_unlock_irqrestore(&priv->hcmd_lock, flags); 704 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
@@ -1630,151 +1596,6 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
1630 return 0; 1596 return 0;
1631} 1597}
1632 1598
1633/******************************************************************************
1634 *
1635 * Misc. internal state and helper functions
1636 *
1637 ******************************************************************************/
1638#ifdef CONFIG_IWL3945_DEBUG
1639
1640/**
1641 * iwl3945_report_frame - dump frame to syslog during debug sessions
1642 *
1643 * You may hack this function to show different aspects of received frames,
1644 * including selective frame dumps.
1645 * group100 parameter selects whether to show 1 out of 100 good frames.
1646 */
1647void iwl3945_report_frame(struct iwl3945_priv *priv,
1648 struct iwl3945_rx_packet *pkt,
1649 struct ieee80211_hdr *header, int group100)
1650{
1651 u32 to_us;
1652 u32 print_summary = 0;
1653 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
1654 u32 hundred = 0;
1655 u32 dataframe = 0;
1656 u16 fc;
1657 u16 seq_ctl;
1658 u16 channel;
1659 u16 phy_flags;
1660 int rate_sym;
1661 u16 length;
1662 u16 status;
1663 u16 bcn_tmr;
1664 u32 tsf_low;
1665 u64 tsf;
1666 u8 rssi;
1667 u8 agc;
1668 u16 sig_avg;
1669 u16 noise_diff;
1670 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
1671 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
1672 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
1673 u8 *data = IWL_RX_DATA(pkt);
1674
1675 /* MAC header */
1676 fc = le16_to_cpu(header->frame_control);
1677 seq_ctl = le16_to_cpu(header->seq_ctrl);
1678
1679 /* metadata */
1680 channel = le16_to_cpu(rx_hdr->channel);
1681 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
1682 rate_sym = rx_hdr->rate;
1683 length = le16_to_cpu(rx_hdr->len);
1684
1685 /* end-of-frame status and timestamp */
1686 status = le32_to_cpu(rx_end->status);
1687 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
1688 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
1689 tsf = le64_to_cpu(rx_end->timestamp);
1690
1691 /* signal statistics */
1692 rssi = rx_stats->rssi;
1693 agc = rx_stats->agc;
1694 sig_avg = le16_to_cpu(rx_stats->sig_avg);
1695 noise_diff = le16_to_cpu(rx_stats->noise_diff);
1696
1697 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
1698
1699 /* if data frame is to us and all is good,
1700 * (optionally) print summary for only 1 out of every 100 */
1701 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
1702 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
1703 dataframe = 1;
1704 if (!group100)
1705 print_summary = 1; /* print each frame */
1706 else if (priv->framecnt_to_us < 100) {
1707 priv->framecnt_to_us++;
1708 print_summary = 0;
1709 } else {
1710 priv->framecnt_to_us = 0;
1711 print_summary = 1;
1712 hundred = 1;
1713 }
1714 } else {
1715 /* print summary for all other frames */
1716 print_summary = 1;
1717 }
1718
1719 if (print_summary) {
1720 char *title;
1721 u32 rate;
1722
1723 if (hundred)
1724 title = "100Frames";
1725 else if (fc & IEEE80211_FCTL_RETRY)
1726 title = "Retry";
1727 else if (ieee80211_is_assoc_response(fc))
1728 title = "AscRsp";
1729 else if (ieee80211_is_reassoc_response(fc))
1730 title = "RasRsp";
1731 else if (ieee80211_is_probe_response(fc)) {
1732 title = "PrbRsp";
1733 print_dump = 1; /* dump frame contents */
1734 } else if (ieee80211_is_beacon(fc)) {
1735 title = "Beacon";
1736 print_dump = 1; /* dump frame contents */
1737 } else if (ieee80211_is_atim(fc))
1738 title = "ATIM";
1739 else if (ieee80211_is_auth(fc))
1740 title = "Auth";
1741 else if (ieee80211_is_deauth(fc))
1742 title = "DeAuth";
1743 else if (ieee80211_is_disassoc(fc))
1744 title = "DisAssoc";
1745 else
1746 title = "Frame";
1747
1748 rate = iwl3945_rate_index_from_plcp(rate_sym);
1749 if (rate == -1)
1750 rate = 0;
1751 else
1752 rate = iwl3945_rates[rate].ieee / 2;
1753
1754 /* print frame summary.
1755 * MAC addresses show just the last byte (for brevity),
1756 * but you can hack it to show more, if you'd like to. */
1757 if (dataframe)
1758 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
1759 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
1760 title, fc, header->addr1[5],
1761 length, rssi, channel, rate);
1762 else {
1763 /* src/dst addresses assume managed mode */
1764 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
1765 "src=0x%02x, rssi=%u, tim=%lu usec, "
1766 "phy=0x%02x, chnl=%d\n",
1767 title, fc, header->addr1[5],
1768 header->addr3[5], rssi,
1769 tsf_low - priv->scan_start_tsf,
1770 phy_flags, channel);
1771 }
1772 }
1773 if (print_dump)
1774 iwl3945_print_hex_dump(IWL_DL_RX, data, length);
1775}
1776#endif
1777
1778static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv) 1599static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
1779{ 1600{
1780 if (priv->hw_setting.shared_virt) 1601 if (priv->hw_setting.shared_virt)
@@ -2242,34 +2063,6 @@ int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *h
2242 return 1; 2063 return 1;
2243} 2064}
2244 2065
2245#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
2246
2247static const char *iwl3945_get_tx_fail_reason(u32 status)
2248{
2249 switch (status & TX_STATUS_MSK) {
2250 case TX_STATUS_SUCCESS:
2251 return "SUCCESS";
2252 TX_STATUS_ENTRY(SHORT_LIMIT);
2253 TX_STATUS_ENTRY(LONG_LIMIT);
2254 TX_STATUS_ENTRY(FIFO_UNDERRUN);
2255 TX_STATUS_ENTRY(MGMNT_ABORT);
2256 TX_STATUS_ENTRY(NEXT_FRAG);
2257 TX_STATUS_ENTRY(LIFE_EXPIRE);
2258 TX_STATUS_ENTRY(DEST_PS);
2259 TX_STATUS_ENTRY(ABORTED);
2260 TX_STATUS_ENTRY(BT_RETRY);
2261 TX_STATUS_ENTRY(STA_INVALID);
2262 TX_STATUS_ENTRY(FRAG_DROPPED);
2263 TX_STATUS_ENTRY(TID_DISABLE);
2264 TX_STATUS_ENTRY(FRAME_FLUSHED);
2265 TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
2266 TX_STATUS_ENTRY(TX_LOCKED);
2267 TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
2268 }
2269
2270 return "UNKNOWN";
2271}
2272
2273/** 2066/**
2274 * iwl3945_scan_cancel - Cancel any currently executing HW scan 2067 * iwl3945_scan_cancel - Cancel any currently executing HW scan
2275 * 2068 *
@@ -2957,7 +2750,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
2957 ieee80211_get_hdrlen(fc)); 2750 ieee80211_get_hdrlen(fc));
2958 2751
2959 /* Tell device the write index *just past* this latest filled TFD */ 2752 /* Tell device the write index *just past* this latest filled TFD */
2960 q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); 2753 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
2961 rc = iwl3945_tx_queue_update_write_ptr(priv, txq); 2754 rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
2962 spin_unlock_irqrestore(&priv->lock, flags); 2755 spin_unlock_irqrestore(&priv->lock, flags);
2963 2756
@@ -3317,125 +3110,6 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
3317} 3110}
3318#endif 3111#endif
3319 3112
3320static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv,
3321 struct iwl3945_tx_info *tx_sta)
3322{
3323
3324 tx_sta->status.ack_signal = 0;
3325 tx_sta->status.excessive_retries = 0;
3326 tx_sta->status.queue_length = 0;
3327 tx_sta->status.queue_number = 0;
3328
3329 if (in_interrupt())
3330 ieee80211_tx_status_irqsafe(priv->hw,
3331 tx_sta->skb[0], &(tx_sta->status));
3332 else
3333 ieee80211_tx_status(priv->hw,
3334 tx_sta->skb[0], &(tx_sta->status));
3335
3336 tx_sta->skb[0] = NULL;
3337}
3338
3339/**
3340 * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
3341 *
3342 * When FW advances 'R' index, all entries between old and new 'R' index
3343 * need to be reclaimed. As result, some free space forms. If there is
3344 * enough free space (> low mark), wake the stack that feeds us.
3345 */
3346static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index)
3347{
3348 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
3349 struct iwl3945_queue *q = &txq->q;
3350 int nfreed = 0;
3351
3352 if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) {
3353 IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
3354 "is out of range [0-%d] %d %d.\n", txq_id,
3355 index, q->n_bd, q->write_ptr, q->read_ptr);
3356 return 0;
3357 }
3358
3359 for (index = iwl3945_queue_inc_wrap(index, q->n_bd);
3360 q->read_ptr != index;
3361 q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) {
3362 if (txq_id != IWL_CMD_QUEUE_NUM) {
3363 iwl3945_txstatus_to_ieee(priv,
3364 &(txq->txb[txq->q.read_ptr]));
3365 iwl3945_hw_txq_free_tfd(priv, txq);
3366 } else if (nfreed > 1) {
3367 IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
3368 q->write_ptr, q->read_ptr);
3369 queue_work(priv->workqueue, &priv->restart);
3370 }
3371 nfreed++;
3372 }
3373
3374 if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
3375 (txq_id != IWL_CMD_QUEUE_NUM) &&
3376 priv->mac80211_registered)
3377 ieee80211_wake_queue(priv->hw, txq_id);
3378
3379
3380 return nfreed;
3381}
3382
3383static int iwl3945_is_tx_success(u32 status)
3384{
3385 return (status & 0xFF) == 0x1;
3386}
3387
3388/******************************************************************************
3389 *
3390 * Generic RX handler implementations
3391 *
3392 ******************************************************************************/
3393/**
3394 * iwl3945_rx_reply_tx - Handle Tx response
3395 */
3396static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
3397 struct iwl3945_rx_mem_buffer *rxb)
3398{
3399 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3400 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
3401 int txq_id = SEQ_TO_QUEUE(sequence);
3402 int index = SEQ_TO_INDEX(sequence);
3403 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
3404 struct ieee80211_tx_status *tx_status;
3405 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
3406 u32 status = le32_to_cpu(tx_resp->status);
3407
3408 if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) {
3409 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
3410 "is out of range [0-%d] %d %d\n", txq_id,
3411 index, txq->q.n_bd, txq->q.write_ptr,
3412 txq->q.read_ptr);
3413 return;
3414 }
3415
3416 tx_status = &(txq->txb[txq->q.read_ptr].status);
3417
3418 tx_status->retry_count = tx_resp->failure_frame;
3419 tx_status->queue_number = status;
3420 tx_status->queue_length = tx_resp->bt_kill_count;
3421 tx_status->queue_length |= tx_resp->failure_rts;
3422
3423 tx_status->flags =
3424 iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
3425
3426 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
3427 txq_id, iwl3945_get_tx_fail_reason(status), status,
3428 tx_resp->rate, tx_resp->failure_frame);
3429
3430 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
3431 if (index != -1)
3432 iwl3945_tx_queue_reclaim(priv, txq_id, index);
3433
3434 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
3435 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
3436}
3437
3438
3439static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv, 3113static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
3440 struct iwl3945_rx_mem_buffer *rxb) 3114 struct iwl3945_rx_mem_buffer *rxb)
3441{ 3115{
@@ -3782,13 +3456,44 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
3782 priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = 3456 priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
3783 iwl3945_rx_scan_complete_notif; 3457 iwl3945_rx_scan_complete_notif;
3784 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; 3458 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
3785 priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
3786 3459
3787 /* Set up hardware specific Rx handlers */ 3460 /* Set up hardware specific Rx handlers */
3788 iwl3945_hw_rx_handler_setup(priv); 3461 iwl3945_hw_rx_handler_setup(priv);
3789} 3462}
3790 3463
3791/** 3464/**
3465 * iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
3466 * When FW advances 'R' index, all entries between old and new 'R' index
3467 * need to be reclaimed.
3468 */
3469static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
3470 int txq_id, int index)
3471{
3472 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
3473 struct iwl3945_queue *q = &txq->q;
3474 int nfreed = 0;
3475
3476 if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
3477 IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
3478 "is out of range [0-%d] %d %d.\n", txq_id,
3479 index, q->n_bd, q->write_ptr, q->read_ptr);
3480 return;
3481 }
3482
3483 for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
3484 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
3485 if (nfreed > 1) {
3486 IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
3487 q->write_ptr, q->read_ptr);
3488 queue_work(priv->workqueue, &priv->restart);
3489 break;
3490 }
3491 nfreed++;
3492 }
3493}
3494
3495
3496/**
3792 * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them 3497 * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
3793 * @rxb: Rx buffer to reclaim 3498 * @rxb: Rx buffer to reclaim
3794 * 3499 *
@@ -3807,12 +3512,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
3807 int cmd_index; 3512 int cmd_index;
3808 struct iwl3945_cmd *cmd; 3513 struct iwl3945_cmd *cmd;
3809 3514
3810 /* If a Tx command is being handled and it isn't in the actual
3811 * command queue then there a command routing bug has been introduced
3812 * in the queue management code. */
3813 if (txq_id != IWL_CMD_QUEUE_NUM)
3814 IWL_ERROR("Error wrong command queue %d command id 0x%X\n",
3815 txq_id, pkt->hdr.cmd);
3816 BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); 3515 BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
3817 3516
3818 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 3517 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
@@ -3826,7 +3525,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
3826 !cmd->meta.u.callback(priv, cmd, rxb->skb)) 3525 !cmd->meta.u.callback(priv, cmd, rxb->skb))
3827 rxb->skb = NULL; 3526 rxb->skb = NULL;
3828 3527
3829 iwl3945_tx_queue_reclaim(priv, txq_id, index); 3528 iwl3945_cmd_queue_reclaim(priv, txq_id, index);
3830 3529
3831 if (!(cmd->meta.flags & CMD_ASYNC)) { 3530 if (!(cmd->meta.flags & CMD_ASYNC)) {
3832 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 3531 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -4506,8 +4205,7 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
4506 4205
4507 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { 4206 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
4508 IWL_ERROR("Start IWL Error Log Dump:\n"); 4207 IWL_ERROR("Start IWL Error Log Dump:\n");
4509 IWL_ERROR("Status: 0x%08lX, Config: %08X count: %d\n", 4208 IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
4510 priv->status, priv->config, count);
4511 } 4209 }
4512 4210
4513 IWL_ERROR("Desc Time asrtPC blink2 " 4211 IWL_ERROR("Desc Time asrtPC blink2 "
@@ -4727,9 +4425,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
4727 * atomic, make sure that inta covers all the interrupts that 4425 * atomic, make sure that inta covers all the interrupts that
4728 * we've discovered, even if FH interrupt came in just after 4426 * we've discovered, even if FH interrupt came in just after
4729 * reading CSR_INT. */ 4427 * reading CSR_INT. */
4730 if (inta_fh & CSR_FH_INT_RX_MASK) 4428 if (inta_fh & CSR39_FH_INT_RX_MASK)
4731 inta |= CSR_INT_BIT_FH_RX; 4429 inta |= CSR_INT_BIT_FH_RX;
4732 if (inta_fh & CSR_FH_INT_TX_MASK) 4430 if (inta_fh & CSR39_FH_INT_TX_MASK)
4733 inta |= CSR_INT_BIT_FH_TX; 4431 inta |= CSR_INT_BIT_FH_TX;
4734 4432
4735 /* Now service all interrupt bits discovered above. */ 4433 /* Now service all interrupt bits discovered above. */
@@ -5119,11 +4817,12 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
5119 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; 4817 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
5120 ch_info->min_power = 0; 4818 ch_info->min_power = 0;
5121 4819
5122 IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x" 4820 IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x"
5123 " %ddBm): Ad-Hoc %ssupported\n", 4821 " %ddBm): Ad-Hoc %ssupported\n",
5124 ch_info->channel, 4822 ch_info->channel,
5125 is_channel_a_band(ch_info) ? 4823 is_channel_a_band(ch_info) ?
5126 "5.2" : "2.4", 4824 "5.2" : "2.4",
4825 CHECK_AND_PRINT(VALID),
5127 CHECK_AND_PRINT(IBSS), 4826 CHECK_AND_PRINT(IBSS),
5128 CHECK_AND_PRINT(ACTIVE), 4827 CHECK_AND_PRINT(ACTIVE),
5129 CHECK_AND_PRINT(RADAR), 4828 CHECK_AND_PRINT(RADAR),
@@ -5333,7 +5032,7 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
5333static int iwl3945_init_geos(struct iwl3945_priv *priv) 5032static int iwl3945_init_geos(struct iwl3945_priv *priv)
5334{ 5033{
5335 struct iwl3945_channel_info *ch; 5034 struct iwl3945_channel_info *ch;
5336 struct ieee80211_supported_band *band; 5035 struct ieee80211_supported_band *sband;
5337 struct ieee80211_channel *channels; 5036 struct ieee80211_channel *channels;
5338 struct ieee80211_channel *geo_ch; 5037 struct ieee80211_channel *geo_ch;
5339 struct ieee80211_rate *rates; 5038 struct ieee80211_rate *rates;
@@ -5351,7 +5050,7 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
5351 if (!channels) 5050 if (!channels)
5352 return -ENOMEM; 5051 return -ENOMEM;
5353 5052
5354 rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), 5053 rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
5355 GFP_KERNEL); 5054 GFP_KERNEL);
5356 if (!rates) { 5055 if (!rates) {
5357 kfree(channels); 5056 kfree(channels);
@@ -5359,38 +5058,38 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
5359 } 5058 }
5360 5059
5361 /* 5.2GHz channels start after the 2.4GHz channels */ 5060 /* 5.2GHz channels start after the 2.4GHz channels */
5362 band = &priv->bands[IEEE80211_BAND_5GHZ]; 5061 sband = &priv->bands[IEEE80211_BAND_5GHZ];
5363 band->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; 5062 sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
5364 band->bitrates = &rates[4]; 5063 /* just OFDM */
5365 band->n_bitrates = 8; /* just OFDM */ 5064 sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
5366 5065 sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
5367 band = &priv->bands[IEEE80211_BAND_2GHZ]; 5066
5368 band->channels = channels; 5067 sband = &priv->bands[IEEE80211_BAND_2GHZ];
5369 band->bitrates = rates; 5068 sband->channels = channels;
5370 band->n_bitrates = 12; /* OFDM & CCK */ 5069 /* OFDM & CCK */
5070 sband->bitrates = rates;
5071 sband->n_bitrates = IWL_RATE_COUNT;
5371 5072
5372 priv->ieee_channels = channels; 5073 priv->ieee_channels = channels;
5373 priv->ieee_rates = rates; 5074 priv->ieee_rates = rates;
5374 5075
5375 iwl3945_init_hw_rates(priv, rates); 5076 iwl3945_init_hw_rates(priv, rates);
5376 5077
5377 for (i = 0, geo_ch = channels; i < priv->channel_count; i++) { 5078 for (i = 0; i < priv->channel_count; i++) {
5378 ch = &priv->channel_info[i]; 5079 ch = &priv->channel_info[i];
5379 5080
5380 if (!is_channel_valid(ch)) { 5081 /* FIXME: might be removed if scan is OK*/
5381 IWL_DEBUG_INFO("Channel %d [%sGHz] is restricted -- " 5082 if (!is_channel_valid(ch))
5382 "skipping.\n",
5383 ch->channel, is_channel_a_band(ch) ?
5384 "5.2" : "2.4");
5385 continue; 5083 continue;
5386 }
5387 5084
5388 if (is_channel_a_band(ch)) 5085 if (is_channel_a_band(ch))
5389 geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; 5086 sband = &priv->bands[IEEE80211_BAND_5GHZ];
5390 else 5087 else
5391 geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; 5088 sband = &priv->bands[IEEE80211_BAND_2GHZ];
5392 5089
5393 geo_ch->center_freq = ieee80211chan2mhz(ch->channel); 5090 geo_ch = &sband->channels[sband->n_channels++];
5091
5092 geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
5394 geo_ch->max_power = ch->max_power_avg; 5093 geo_ch->max_power = ch->max_power_avg;
5395 geo_ch->max_antenna_gain = 0xff; 5094 geo_ch->max_antenna_gain = 0xff;
5396 geo_ch->hw_value = ch->channel; 5095 geo_ch->hw_value = ch->channel;
@@ -5408,16 +5107,28 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
5408 if (ch->max_power_avg > priv->max_channel_txpower_limit) 5107 if (ch->max_power_avg > priv->max_channel_txpower_limit)
5409 priv->max_channel_txpower_limit = 5108 priv->max_channel_txpower_limit =
5410 ch->max_power_avg; 5109 ch->max_power_avg;
5411 } else 5110 } else {
5412 geo_ch->flags |= IEEE80211_CHAN_DISABLED; 5111 geo_ch->flags |= IEEE80211_CHAN_DISABLED;
5112 }
5113
5114 /* Save flags for reg domain usage */
5115 geo_ch->orig_flags = geo_ch->flags;
5116
5117 IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
5118 ch->channel, geo_ch->center_freq,
5119 is_channel_a_band(ch) ? "5.2" : "2.4",
5120 geo_ch->flags & IEEE80211_CHAN_DISABLED ?
5121 "restricted" : "valid",
5122 geo_ch->flags);
5413 } 5123 }
5414 5124
5415 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { 5125 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
5126 priv->cfg->sku & IWL_SKU_A) {
5416 printk(KERN_INFO DRV_NAME 5127 printk(KERN_INFO DRV_NAME
5417 ": Incorrectly detected BG card as ABG. Please send " 5128 ": Incorrectly detected BG card as ABG. Please send "
5418 "your PCI ID 0x%04X:0x%04X to maintainer.\n", 5129 "your PCI ID 0x%04X:0x%04X to maintainer.\n",
5419 priv->pci_dev->device, priv->pci_dev->subsystem_device); 5130 priv->pci_dev->device, priv->pci_dev->subsystem_device);
5420 priv->is_abg = 0; 5131 priv->cfg->sku &= ~IWL_SKU_A;
5421 } 5132 }
5422 5133
5423 printk(KERN_INFO DRV_NAME 5134 printk(KERN_INFO DRV_NAME
@@ -5764,7 +5475,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
5764 int ret = 0; 5475 int ret = 0;
5765 const struct firmware *ucode_raw; 5476 const struct firmware *ucode_raw;
5766 /* firmware file name contains uCode/driver compatibility version */ 5477 /* firmware file name contains uCode/driver compatibility version */
5767 const char *name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode"; 5478 const char *name = priv->cfg->fw_name;
5768 u8 *src; 5479 u8 *src;
5769 size_t len; 5480 size_t len;
5770 u32 ver, inst_size, data_size, init_size, init_data_size, boot_size; 5481 u32 ver, inst_size, data_size, init_size, init_data_size, boot_size;
@@ -7152,6 +6863,12 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
7152 if (conf == NULL) 6863 if (conf == NULL)
7153 return -EIO; 6864 return -EIO;
7154 6865
6866 if (priv->vif != vif) {
6867 IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
6868 mutex_unlock(&priv->mutex);
6869 return 0;
6870 }
6871
7155 /* XXX: this MUST use conf->mac_addr */ 6872 /* XXX: this MUST use conf->mac_addr */
7156 6873
7157 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && 6874 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
@@ -7176,17 +6893,6 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
7176 if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && 6893 if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
7177 !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { 6894 !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
7178 */ 6895 */
7179 if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
7180 IWL_DEBUG_MAC80211("leave - scanning\n");
7181 mutex_unlock(&priv->mutex);
7182 return 0;
7183 }
7184
7185 if (priv->vif != vif) {
7186 IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
7187 mutex_unlock(&priv->mutex);
7188 return 0;
7189 }
7190 6896
7191 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { 6897 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
7192 if (!conf->bssid) { 6898 if (!conf->bssid) {
@@ -7884,31 +7590,6 @@ static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
7884 show_measurement, store_measurement); 7590 show_measurement, store_measurement);
7885#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */ 7591#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
7886 7592
7887static ssize_t show_rate(struct device *d,
7888 struct device_attribute *attr, char *buf)
7889{
7890 struct iwl3945_priv *priv = dev_get_drvdata(d);
7891 unsigned long flags;
7892 int i;
7893
7894 spin_lock_irqsave(&priv->sta_lock, flags);
7895 if (priv->iw_mode == IEEE80211_IF_TYPE_STA)
7896 i = priv->stations[IWL_AP_ID].current_rate.s.rate;
7897 else
7898 i = priv->stations[IWL_STA_ID].current_rate.s.rate;
7899 spin_unlock_irqrestore(&priv->sta_lock, flags);
7900
7901 i = iwl3945_rate_index_from_plcp(i);
7902 if (i == -1)
7903 return sprintf(buf, "0\n");
7904
7905 return sprintf(buf, "%d%s\n",
7906 (iwl3945_rates[i].ieee >> 1),
7907 (iwl3945_rates[i].ieee & 0x1) ? ".5" : "");
7908}
7909
7910static DEVICE_ATTR(rate, S_IRUSR, show_rate, NULL);
7911
7912static ssize_t store_retry_rate(struct device *d, 7593static ssize_t store_retry_rate(struct device *d,
7913 struct device_attribute *attr, 7594 struct device_attribute *attr,
7914 const char *buf, size_t count) 7595 const char *buf, size_t count)
@@ -8199,7 +7880,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
8199 &dev_attr_measurement.attr, 7880 &dev_attr_measurement.attr,
8200#endif 7881#endif
8201 &dev_attr_power_level.attr, 7882 &dev_attr_power_level.attr,
8202 &dev_attr_rate.attr,
8203 &dev_attr_retry_rate.attr, 7883 &dev_attr_retry_rate.attr,
8204 &dev_attr_rf_kill.attr, 7884 &dev_attr_rf_kill.attr,
8205 &dev_attr_rs_window.attr, 7885 &dev_attr_rs_window.attr,
@@ -8238,9 +7918,9 @@ static struct ieee80211_ops iwl3945_hw_ops = {
8238static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 7918static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
8239{ 7919{
8240 int err = 0; 7920 int err = 0;
8241 u32 pci_id;
8242 struct iwl3945_priv *priv; 7921 struct iwl3945_priv *priv;
8243 struct ieee80211_hw *hw; 7922 struct ieee80211_hw *hw;
7923 struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
8244 int i; 7924 int i;
8245 DECLARE_MAC_BUF(mac); 7925 DECLARE_MAC_BUF(mac);
8246 7926
@@ -8276,6 +7956,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8276 priv->hw = hw; 7956 priv->hw = hw;
8277 7957
8278 priv->pci_dev = pdev; 7958 priv->pci_dev = pdev;
7959 priv->cfg = cfg;
8279 7960
8280 /* Select antenna (may be helpful if only one antenna is connected) */ 7961 /* Select antenna (may be helpful if only one antenna is connected) */
8281 priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna; 7962 priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
@@ -8365,32 +8046,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8365 8046
8366 priv->iw_mode = IEEE80211_IF_TYPE_STA; 8047 priv->iw_mode = IEEE80211_IF_TYPE_STA;
8367 8048
8368 pci_id =
8369 (priv->pci_dev->device << 16) | priv->pci_dev->subsystem_device;
8370
8371 switch (pci_id) {
8372 case 0x42221005: /* 0x4222 0x8086 0x1005 is BG SKU */
8373 case 0x42221034: /* 0x4222 0x8086 0x1034 is BG SKU */
8374 case 0x42271014: /* 0x4227 0x8086 0x1014 is BG SKU */
8375 case 0x42221044: /* 0x4222 0x8086 0x1044 is BG SKU */
8376 priv->is_abg = 0;
8377 break;
8378
8379 /*
8380 * Rest are assumed ABG SKU -- if this is not the
8381 * case then the card will get the wrong 'Detected'
8382 * line in the kernel log however the code that
8383 * initializes the GEO table will detect no A-band
8384 * channels and remove the is_abg mask.
8385 */
8386 default:
8387 priv->is_abg = 1;
8388 break;
8389 }
8390
8391 printk(KERN_INFO DRV_NAME 8049 printk(KERN_INFO DRV_NAME
8392 ": Detected Intel PRO/Wireless 3945%sBG Network Connection\n", 8050 ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
8393 priv->is_abg ? "A" : "");
8394 8051
8395 /* Device-specific setup */ 8052 /* Device-specific setup */
8396 if (iwl3945_hw_set_hw_setting(priv)) { 8053 if (iwl3945_hw_set_hw_setting(priv)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 20d012d4f37e..28c64c39ef02 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -45,13 +45,10 @@
45 45
46#include <asm/div64.h> 46#include <asm/div64.h>
47 47
48#include "iwl-core.h"
48#include "iwl-4965.h" 49#include "iwl-4965.h"
49#include "iwl-helpers.h" 50#include "iwl-helpers.h"
50 51
51#ifdef CONFIG_IWL4965_DEBUG
52u32 iwl4965_debug_level;
53#endif
54
55static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv, 52static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv,
56 struct iwl4965_tx_queue *txq); 53 struct iwl4965_tx_queue *txq);
57 54
@@ -90,15 +87,8 @@ int iwl4965_param_amsdu_size_8K; /* def: enable 8K amsdu size */
90#define VS 87#define VS
91#endif 88#endif
92 89
93#define IWLWIFI_VERSION "1.2.26k" VD VS 90#define DRV_VERSION IWLWIFI_VERSION VD VS
94#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation"
95#define DRV_VERSION IWLWIFI_VERSION
96 91
97/* Change firmware file name, using "-" and incrementing number,
98 * *only* when uCode interface or architecture changes so that it
99 * is not compatible with earlier drivers.
100 * This number will also appear in << 8 position of 1st dword of uCode file */
101#define IWL4965_UCODE_API "-1"
102 92
103MODULE_DESCRIPTION(DRV_DESCRIPTION); 93MODULE_DESCRIPTION(DRV_DESCRIPTION);
104MODULE_VERSION(DRV_VERSION); 94MODULE_VERSION(DRV_VERSION);
@@ -161,17 +151,6 @@ static const char *iwl4965_escape_essid(const char *essid, u8 essid_len)
161 return escaped; 151 return escaped;
162} 152}
163 153
164static void iwl4965_print_hex_dump(int level, void *p, u32 len)
165{
166#ifdef CONFIG_IWL4965_DEBUG
167 if (!(iwl4965_debug_level & level))
168 return;
169
170 print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
171 p, len, 1);
172#endif
173}
174
175/*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** 154/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
176 * DMA services 155 * DMA services
177 * 156 *
@@ -215,25 +194,6 @@ int iwl4965_queue_space(const struct iwl4965_queue *q)
215 return s; 194 return s;
216} 195}
217 196
218/**
219 * iwl4965_queue_inc_wrap - increment queue index, wrap back to beginning
220 * @index -- current index
221 * @n_bd -- total number of entries in queue (must be power of 2)
222 */
223static inline int iwl4965_queue_inc_wrap(int index, int n_bd)
224{
225 return ++index & (n_bd - 1);
226}
227
228/**
229 * iwl4965_queue_dec_wrap - decrement queue index, wrap back to end
230 * @index -- current index
231 * @n_bd -- total number of entries in queue (must be power of 2)
232 */
233static inline int iwl4965_queue_dec_wrap(int index, int n_bd)
234{
235 return --index & (n_bd - 1);
236}
237 197
238static inline int x2_queue_used(const struct iwl4965_queue *q, int i) 198static inline int x2_queue_used(const struct iwl4965_queue *q, int i)
239{ 199{
@@ -262,8 +222,8 @@ static int iwl4965_queue_init(struct iwl4965_priv *priv, struct iwl4965_queue *q
262 q->n_window = slots_num; 222 q->n_window = slots_num;
263 q->id = id; 223 q->id = id;
264 224
265 /* count must be power-of-two size, otherwise iwl4965_queue_inc_wrap 225 /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
266 * and iwl4965_queue_dec_wrap are broken. */ 226 * and iwl_queue_dec_wrap are broken. */
267 BUG_ON(!is_power_of_2(count)); 227 BUG_ON(!is_power_of_2(count));
268 228
269 /* slots_num must be power-of-two size, otherwise 229 /* slots_num must be power-of-two size, otherwise
@@ -363,7 +323,7 @@ int iwl4965_tx_queue_init(struct iwl4965_priv *priv,
363 txq->need_update = 0; 323 txq->need_update = 0;
364 324
365 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise 325 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
366 * iwl4965_queue_inc_wrap and iwl4965_queue_dec_wrap are broken. */ 326 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
367 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); 327 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
368 328
369 /* Initialize queue's high/low-water marks, and head/tail indexes */ 329 /* Initialize queue's high/low-water marks, and head/tail indexes */
@@ -394,7 +354,7 @@ void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *t
394 354
395 /* first, empty all BD's */ 355 /* first, empty all BD's */
396 for (; q->write_ptr != q->read_ptr; 356 for (; q->write_ptr != q->read_ptr;
397 q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd)) 357 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
398 iwl4965_hw_txq_free_tfd(priv, txq); 358 iwl4965_hw_txq_free_tfd(priv, txq);
399 359
400 len = sizeof(struct iwl4965_cmd) * q->n_window; 360 len = sizeof(struct iwl4965_cmd) * q->n_window;
@@ -735,7 +695,7 @@ static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_c
735 ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0); 695 ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0);
736 696
737 /* Increment and update queue's write index */ 697 /* Increment and update queue's write index */
738 q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); 698 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
739 iwl4965_tx_queue_update_write_ptr(priv, txq); 699 iwl4965_tx_queue_update_write_ptr(priv, txq);
740 700
741 spin_unlock_irqrestore(&priv->hcmd_lock, flags); 701 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
@@ -1551,34 +1511,6 @@ unsigned int iwl4965_fill_beacon_frame(struct iwl4965_priv *priv,
1551 return priv->ibss_beacon->len; 1511 return priv->ibss_beacon->len;
1552} 1512}
1553 1513
1554int iwl4965_rate_index_from_plcp(int plcp)
1555{
1556 int i = 0;
1557
1558 /* 4965 HT rate format */
1559 if (plcp & RATE_MCS_HT_MSK) {
1560 i = (plcp & 0xff);
1561
1562 if (i >= IWL_RATE_MIMO_6M_PLCP)
1563 i = i - IWL_RATE_MIMO_6M_PLCP;
1564
1565 i += IWL_FIRST_OFDM_RATE;
1566 /* skip 9M not supported in ht*/
1567 if (i >= IWL_RATE_9M_INDEX)
1568 i += 1;
1569 if ((i >= IWL_FIRST_OFDM_RATE) &&
1570 (i <= IWL_LAST_OFDM_RATE))
1571 return i;
1572
1573 /* 4965 legacy rate format, search for match in table */
1574 } else {
1575 for (i = 0; i < ARRAY_SIZE(iwl4965_rates); i++)
1576 if (iwl4965_rates[i].plcp == (plcp &0xFF))
1577 return i;
1578 }
1579 return -1;
1580}
1581
1582static u8 iwl4965_rate_get_lowest_plcp(int rate_mask) 1514static u8 iwl4965_rate_get_lowest_plcp(int rate_mask)
1583{ 1515{
1584 u8 i; 1516 u8 i;
@@ -1712,148 +1644,6 @@ done:
1712 * Misc. internal state and helper functions 1644 * Misc. internal state and helper functions
1713 * 1645 *
1714 ******************************************************************************/ 1646 ******************************************************************************/
1715#ifdef CONFIG_IWL4965_DEBUG
1716
1717/**
1718 * iwl4965_report_frame - dump frame to syslog during debug sessions
1719 *
1720 * You may hack this function to show different aspects of received frames,
1721 * including selective frame dumps.
1722 * group100 parameter selects whether to show 1 out of 100 good frames.
1723 *
1724 * TODO: This was originally written for 3945, need to audit for
1725 * proper operation with 4965.
1726 */
1727void iwl4965_report_frame(struct iwl4965_priv *priv,
1728 struct iwl4965_rx_packet *pkt,
1729 struct ieee80211_hdr *header, int group100)
1730{
1731 u32 to_us;
1732 u32 print_summary = 0;
1733 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
1734 u32 hundred = 0;
1735 u32 dataframe = 0;
1736 u16 fc;
1737 u16 seq_ctl;
1738 u16 channel;
1739 u16 phy_flags;
1740 int rate_sym;
1741 u16 length;
1742 u16 status;
1743 u16 bcn_tmr;
1744 u32 tsf_low;
1745 u64 tsf;
1746 u8 rssi;
1747 u8 agc;
1748 u16 sig_avg;
1749 u16 noise_diff;
1750 struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
1751 struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
1752 struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
1753 u8 *data = IWL_RX_DATA(pkt);
1754
1755 /* MAC header */
1756 fc = le16_to_cpu(header->frame_control);
1757 seq_ctl = le16_to_cpu(header->seq_ctrl);
1758
1759 /* metadata */
1760 channel = le16_to_cpu(rx_hdr->channel);
1761 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
1762 rate_sym = rx_hdr->rate;
1763 length = le16_to_cpu(rx_hdr->len);
1764
1765 /* end-of-frame status and timestamp */
1766 status = le32_to_cpu(rx_end->status);
1767 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
1768 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
1769 tsf = le64_to_cpu(rx_end->timestamp);
1770
1771 /* signal statistics */
1772 rssi = rx_stats->rssi;
1773 agc = rx_stats->agc;
1774 sig_avg = le16_to_cpu(rx_stats->sig_avg);
1775 noise_diff = le16_to_cpu(rx_stats->noise_diff);
1776
1777 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
1778
1779 /* if data frame is to us and all is good,
1780 * (optionally) print summary for only 1 out of every 100 */
1781 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
1782 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
1783 dataframe = 1;
1784 if (!group100)
1785 print_summary = 1; /* print each frame */
1786 else if (priv->framecnt_to_us < 100) {
1787 priv->framecnt_to_us++;
1788 print_summary = 0;
1789 } else {
1790 priv->framecnt_to_us = 0;
1791 print_summary = 1;
1792 hundred = 1;
1793 }
1794 } else {
1795 /* print summary for all other frames */
1796 print_summary = 1;
1797 }
1798
1799 if (print_summary) {
1800 char *title;
1801 u32 rate;
1802
1803 if (hundred)
1804 title = "100Frames";
1805 else if (fc & IEEE80211_FCTL_RETRY)
1806 title = "Retry";
1807 else if (ieee80211_is_assoc_response(fc))
1808 title = "AscRsp";
1809 else if (ieee80211_is_reassoc_response(fc))
1810 title = "RasRsp";
1811 else if (ieee80211_is_probe_response(fc)) {
1812 title = "PrbRsp";
1813 print_dump = 1; /* dump frame contents */
1814 } else if (ieee80211_is_beacon(fc)) {
1815 title = "Beacon";
1816 print_dump = 1; /* dump frame contents */
1817 } else if (ieee80211_is_atim(fc))
1818 title = "ATIM";
1819 else if (ieee80211_is_auth(fc))
1820 title = "Auth";
1821 else if (ieee80211_is_deauth(fc))
1822 title = "DeAuth";
1823 else if (ieee80211_is_disassoc(fc))
1824 title = "DisAssoc";
1825 else
1826 title = "Frame";
1827
1828 rate = iwl4965_rate_index_from_plcp(rate_sym);
1829 if (rate == -1)
1830 rate = 0;
1831 else
1832 rate = iwl4965_rates[rate].ieee / 2;
1833
1834 /* print frame summary.
1835 * MAC addresses show just the last byte (for brevity),
1836 * but you can hack it to show more, if you'd like to. */
1837 if (dataframe)
1838 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
1839 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
1840 title, fc, header->addr1[5],
1841 length, rssi, channel, rate);
1842 else {
1843 /* src/dst addresses assume managed mode */
1844 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
1845 "src=0x%02x, rssi=%u, tim=%lu usec, "
1846 "phy=0x%02x, chnl=%d\n",
1847 title, fc, header->addr1[5],
1848 header->addr3[5], rssi,
1849 tsf_low - priv->scan_start_tsf,
1850 phy_flags, channel);
1851 }
1852 }
1853 if (print_dump)
1854 iwl4965_print_hex_dump(IWL_DL_RX, data, length);
1855}
1856#endif
1857 1647
1858static void iwl4965_unset_hw_setting(struct iwl4965_priv *priv) 1648static void iwl4965_unset_hw_setting(struct iwl4965_priv *priv)
1859{ 1649{
@@ -3088,7 +2878,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
3088 iwl4965_tx_queue_update_wr_ptr(priv, txq, len); 2878 iwl4965_tx_queue_update_wr_ptr(priv, txq, len);
3089 2879
3090 /* Tell device the write index *just past* this latest filled TFD */ 2880 /* Tell device the write index *just past* this latest filled TFD */
3091 q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); 2881 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
3092 rc = iwl4965_tx_queue_update_write_ptr(priv, txq); 2882 rc = iwl4965_tx_queue_update_write_ptr(priv, txq);
3093 spin_unlock_irqrestore(&priv->lock, flags); 2883 spin_unlock_irqrestore(&priv->lock, flags);
3094 2884
@@ -3482,9 +3272,9 @@ int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index)
3482 return 0; 3272 return 0;
3483 } 3273 }
3484 3274
3485 for (index = iwl4965_queue_inc_wrap(index, q->n_bd); 3275 for (index = iwl_queue_inc_wrap(index, q->n_bd);
3486 q->read_ptr != index; 3276 q->read_ptr != index;
3487 q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd)) { 3277 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
3488 if (txq_id != IWL_CMD_QUEUE_NUM) { 3278 if (txq_id != IWL_CMD_QUEUE_NUM) {
3489 iwl4965_txstatus_to_ieee(priv, 3279 iwl4965_txstatus_to_ieee(priv,
3490 &(txq->txb[txq->q.read_ptr])); 3280 &(txq->txb[txq->q.read_ptr]));
@@ -3591,9 +3381,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv,
3591 tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU; 3381 tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU;
3592 tx_status->flags = iwl4965_is_tx_success(status)? 3382 tx_status->flags = iwl4965_is_tx_success(status)?
3593 IEEE80211_TX_STATUS_ACK : 0; 3383 IEEE80211_TX_STATUS_ACK : 0;
3594 /* FIXME Wrong Rate 3384 iwl4965_hwrate_to_tx_control(priv,
3595 tx_status->control.tx_rate = 3385 le32_to_cpu(tx_resp->rate_n_flags),
3596 iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); */ 3386 &tx_status->control);
3597 /* FIXME: code repetition end */ 3387 /* FIXME: code repetition end */
3598 3388
3599 IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", 3389 IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
@@ -3729,7 +3519,7 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv,
3729 3519
3730 if (txq->q.read_ptr != (scd_ssn & 0xff)) { 3520 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
3731 int freed; 3521 int freed;
3732 index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); 3522 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
3733 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " 3523 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
3734 "%d index %d\n", scd_ssn , index); 3524 "%d index %d\n", scd_ssn , index);
3735 freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); 3525 freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
@@ -3750,9 +3540,10 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv,
3750 tx_status->queue_number = status; 3540 tx_status->queue_number = status;
3751 tx_status->queue_length = tx_resp->bt_kill_count; 3541 tx_status->queue_length = tx_resp->bt_kill_count;
3752 tx_status->queue_length |= tx_resp->failure_rts; 3542 tx_status->queue_length |= tx_resp->failure_rts;
3753
3754 tx_status->flags = 3543 tx_status->flags =
3755 iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; 3544 iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
3545 iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
3546 &tx_status->control);
3756 3547
3757 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " 3548 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
3758 "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), 3549 "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status),
@@ -4886,8 +4677,7 @@ static void iwl4965_dump_nic_error_log(struct iwl4965_priv *priv)
4886 4677
4887 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { 4678 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
4888 IWL_ERROR("Start IWL Error Log Dump:\n"); 4679 IWL_ERROR("Start IWL Error Log Dump:\n");
4889 IWL_ERROR("Status: 0x%08lX, Config: %08X count: %d\n", 4680 IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
4890 priv->status, priv->config, count);
4891 } 4681 }
4892 4682
4893 desc = iwl4965_read_targ_mem(priv, base + 1 * sizeof(u32)); 4683 desc = iwl4965_read_targ_mem(priv, base + 1 * sizeof(u32));
@@ -5099,9 +4889,9 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
5099 * atomic, make sure that inta covers all the interrupts that 4889 * atomic, make sure that inta covers all the interrupts that
5100 * we've discovered, even if FH interrupt came in just after 4890 * we've discovered, even if FH interrupt came in just after
5101 * reading CSR_INT. */ 4891 * reading CSR_INT. */
5102 if (inta_fh & CSR_FH_INT_RX_MASK) 4892 if (inta_fh & CSR49_FH_INT_RX_MASK)
5103 inta |= CSR_INT_BIT_FH_RX; 4893 inta |= CSR_INT_BIT_FH_RX;
5104 if (inta_fh & CSR_FH_INT_TX_MASK) 4894 if (inta_fh & CSR49_FH_INT_TX_MASK)
5105 inta |= CSR_INT_BIT_FH_TX; 4895 inta |= CSR_INT_BIT_FH_TX;
5106 4896
5107 /* Now service all interrupt bits discovered above. */ 4897 /* Now service all interrupt bits discovered above. */
@@ -5502,11 +5292,12 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
5502 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; 5292 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
5503 ch_info->min_power = 0; 5293 ch_info->min_power = 0;
5504 5294
5505 IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x" 5295 IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x"
5506 " %ddBm): Ad-Hoc %ssupported\n", 5296 " %ddBm): Ad-Hoc %ssupported\n",
5507 ch_info->channel, 5297 ch_info->channel,
5508 is_channel_a_band(ch_info) ? 5298 is_channel_a_band(ch_info) ?
5509 "5.2" : "2.4", 5299 "5.2" : "2.4",
5300 CHECK_AND_PRINT(VALID),
5510 CHECK_AND_PRINT(IBSS), 5301 CHECK_AND_PRINT(IBSS),
5511 CHECK_AND_PRINT(ACTIVE), 5302 CHECK_AND_PRINT(ACTIVE),
5512 CHECK_AND_PRINT(RADAR), 5303 CHECK_AND_PRINT(RADAR),
@@ -5749,7 +5540,7 @@ static void iwl4965_init_hw_rates(struct iwl4965_priv *priv,
5749static int iwl4965_init_geos(struct iwl4965_priv *priv) 5540static int iwl4965_init_geos(struct iwl4965_priv *priv)
5750{ 5541{
5751 struct iwl4965_channel_info *ch; 5542 struct iwl4965_channel_info *ch;
5752 struct ieee80211_supported_band *band; 5543 struct ieee80211_supported_band *sband;
5753 struct ieee80211_channel *channels; 5544 struct ieee80211_channel *channels;
5754 struct ieee80211_channel *geo_ch; 5545 struct ieee80211_channel *geo_ch;
5755 struct ieee80211_rate *rates; 5546 struct ieee80211_rate *rates;
@@ -5767,7 +5558,7 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
5767 if (!channels) 5558 if (!channels)
5768 return -ENOMEM; 5559 return -ENOMEM;
5769 5560
5770 rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), 5561 rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
5771 GFP_KERNEL); 5562 GFP_KERNEL);
5772 if (!rates) { 5563 if (!rates) {
5773 kfree(channels); 5564 kfree(channels);
@@ -5775,42 +5566,42 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
5775 } 5566 }
5776 5567
5777 /* 5.2GHz channels start after the 2.4GHz channels */ 5568 /* 5.2GHz channels start after the 2.4GHz channels */
5778 band = &priv->bands[IEEE80211_BAND_5GHZ]; 5569 sband = &priv->bands[IEEE80211_BAND_5GHZ];
5779 band->channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; 5570 sband->channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)];
5780 band->bitrates = &rates[4]; 5571 /* just OFDM */
5781 band->n_bitrates = 8; /* just OFDM */ 5572 sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
5573 sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
5782 5574
5783 iwl4965_init_ht_hw_capab(&band->ht_info, IEEE80211_BAND_5GHZ); 5575 iwl4965_init_ht_hw_capab(&sband->ht_info, IEEE80211_BAND_5GHZ);
5784 5576
5785 band = &priv->bands[IEEE80211_BAND_2GHZ]; 5577 sband = &priv->bands[IEEE80211_BAND_2GHZ];
5786 band->channels = channels; 5578 sband->channels = channels;
5787 band->bitrates = rates; 5579 /* OFDM & CCK */
5788 band->n_bitrates = 12; /* OFDM & CCK */ 5580 sband->bitrates = rates;
5581 sband->n_bitrates = IWL_RATE_COUNT;
5789 5582
5790 iwl4965_init_ht_hw_capab(&band->ht_info, IEEE80211_BAND_2GHZ); 5583 iwl4965_init_ht_hw_capab(&sband->ht_info, IEEE80211_BAND_2GHZ);
5791 5584
5792 priv->ieee_channels = channels; 5585 priv->ieee_channels = channels;
5793 priv->ieee_rates = rates; 5586 priv->ieee_rates = rates;
5794 5587
5795 iwl4965_init_hw_rates(priv, rates); 5588 iwl4965_init_hw_rates(priv, rates);
5796 5589
5797 for (i = 0, geo_ch = channels; i < priv->channel_count; i++) { 5590 for (i = 0; i < priv->channel_count; i++) {
5798 ch = &priv->channel_info[i]; 5591 ch = &priv->channel_info[i];
5799 5592
5800 if (!is_channel_valid(ch)) { 5593 /* FIXME: might be removed if scan is OK */
5801 IWL_DEBUG_INFO("Channel %d [%sGHz] is restricted -- " 5594 if (!is_channel_valid(ch))
5802 "skipping.\n",
5803 ch->channel, is_channel_a_band(ch) ?
5804 "5.2" : "2.4");
5805 continue; 5595 continue;
5806 }
5807 5596
5808 if (is_channel_a_band(ch)) { 5597 if (is_channel_a_band(ch))
5809 geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; 5598 sband = &priv->bands[IEEE80211_BAND_5GHZ];
5810 } else 5599 else
5811 geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; 5600 sband = &priv->bands[IEEE80211_BAND_2GHZ];
5601
5602 geo_ch = &sband->channels[sband->n_channels++];
5812 5603
5813 geo_ch->center_freq = ieee80211chan2mhz(ch->channel); 5604 geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
5814 geo_ch->max_power = ch->max_power_avg; 5605 geo_ch->max_power = ch->max_power_avg;
5815 geo_ch->max_antenna_gain = 0xff; 5606 geo_ch->max_antenna_gain = 0xff;
5816 geo_ch->hw_value = ch->channel; 5607 geo_ch->hw_value = ch->channel;
@@ -5828,16 +5619,28 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
5828 if (ch->max_power_avg > priv->max_channel_txpower_limit) 5619 if (ch->max_power_avg > priv->max_channel_txpower_limit)
5829 priv->max_channel_txpower_limit = 5620 priv->max_channel_txpower_limit =
5830 ch->max_power_avg; 5621 ch->max_power_avg;
5831 } else 5622 } else {
5832 geo_ch->flags |= IEEE80211_CHAN_DISABLED; 5623 geo_ch->flags |= IEEE80211_CHAN_DISABLED;
5624 }
5625
5626 /* Save flags for reg domain usage */
5627 geo_ch->orig_flags = geo_ch->flags;
5628
5629 IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
5630 ch->channel, geo_ch->center_freq,
5631 is_channel_a_band(ch) ? "5.2" : "2.4",
5632 geo_ch->flags & IEEE80211_CHAN_DISABLED ?
5633 "restricted" : "valid",
5634 geo_ch->flags);
5833 } 5635 }
5834 5636
5835 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { 5637 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
5638 priv->cfg->sku & IWL_SKU_A) {
5836 printk(KERN_INFO DRV_NAME 5639 printk(KERN_INFO DRV_NAME
5837 ": Incorrectly detected BG card as ABG. Please send " 5640 ": Incorrectly detected BG card as ABG. Please send "
5838 "your PCI ID 0x%04X:0x%04X to maintainer.\n", 5641 "your PCI ID 0x%04X:0x%04X to maintainer.\n",
5839 priv->pci_dev->device, priv->pci_dev->subsystem_device); 5642 priv->pci_dev->device, priv->pci_dev->subsystem_device);
5840 priv->is_abg = 0; 5643 priv->cfg->sku &= ~IWL_SKU_A;
5841 } 5644 }
5842 5645
5843 printk(KERN_INFO DRV_NAME 5646 printk(KERN_INFO DRV_NAME
@@ -6186,7 +5989,7 @@ static int iwl4965_read_ucode(struct iwl4965_priv *priv)
6186 struct iwl4965_ucode *ucode; 5989 struct iwl4965_ucode *ucode;
6187 int ret; 5990 int ret;
6188 const struct firmware *ucode_raw; 5991 const struct firmware *ucode_raw;
6189 const char *name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode"; 5992 const char *name = priv->cfg->fw_name;
6190 u8 *src; 5993 u8 *src;
6191 size_t len; 5994 size_t len;
6192 u32 ver, inst_size, data_size, init_size, init_data_size, boot_size; 5995 u32 ver, inst_size, data_size, init_size, init_data_size, boot_size;
@@ -7596,6 +7399,12 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
7596 if (conf == NULL) 7399 if (conf == NULL)
7597 return -EIO; 7400 return -EIO;
7598 7401
7402 if (priv->vif != vif) {
7403 IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
7404 mutex_unlock(&priv->mutex);
7405 return 0;
7406 }
7407
7599 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && 7408 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
7600 (!conf->beacon || !conf->ssid_len)) { 7409 (!conf->beacon || !conf->ssid_len)) {
7601 IWL_DEBUG_MAC80211 7410 IWL_DEBUG_MAC80211
@@ -7618,17 +7427,6 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
7618 if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && 7427 if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
7619 !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { 7428 !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
7620 */ 7429 */
7621 if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
7622 IWL_DEBUG_MAC80211("leave - scanning\n");
7623 mutex_unlock(&priv->mutex);
7624 return 0;
7625 }
7626
7627 if (priv->vif != vif) {
7628 IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
7629 mutex_unlock(&priv->mutex);
7630 return 0;
7631 }
7632 7430
7633 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { 7431 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
7634 if (!conf->bssid) { 7432 if (!conf->bssid) {
@@ -8127,15 +7925,21 @@ static void iwl4965_ht_info_fill(struct ieee80211_conf *conf,
8127 iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); 7925 iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
8128 iwl_conf->max_amsdu_size = 7926 iwl_conf->max_amsdu_size =
8129 !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); 7927 !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
7928
8130 iwl_conf->supported_chan_width = 7929 iwl_conf->supported_chan_width =
8131 !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); 7930 !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
7931 iwl_conf->extension_chan_offset =
7932 ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
7933 /* If no above or below channel supplied disable FAT channel */
7934 if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
7935 iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
7936 iwl_conf->supported_chan_width = 0;
7937
8132 iwl_conf->tx_mimo_ps_mode = 7938 iwl_conf->tx_mimo_ps_mode =
8133 (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); 7939 (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
8134 memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); 7940 memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
8135 7941
8136 iwl_conf->control_channel = ht_bss_conf->primary_channel; 7942 iwl_conf->control_channel = ht_bss_conf->primary_channel;
8137 iwl_conf->extension_chan_offset =
8138 ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
8139 iwl_conf->tx_chan_width = 7943 iwl_conf->tx_chan_width =
8140 !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); 7944 !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
8141 iwl_conf->ht_protection = 7945 iwl_conf->ht_protection =
@@ -8776,6 +8580,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8776 int err = 0; 8580 int err = 0;
8777 struct iwl4965_priv *priv; 8581 struct iwl4965_priv *priv;
8778 struct ieee80211_hw *hw; 8582 struct ieee80211_hw *hw;
8583 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
8779 int i; 8584 int i;
8780 DECLARE_MAC_BUF(mac); 8585 DECLARE_MAC_BUF(mac);
8781 8586
@@ -8809,6 +8614,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8809 IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); 8614 IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
8810 priv = hw->priv; 8615 priv = hw->priv;
8811 priv->hw = hw; 8616 priv->hw = hw;
8617 priv->cfg = cfg;
8812 8618
8813 priv->pci_dev = pdev; 8619 priv->pci_dev = pdev;
8814 priv->antenna = (enum iwl4965_antenna)iwl4965_param_antenna; 8620 priv->antenna = (enum iwl4965_antenna)iwl4965_param_antenna;
@@ -8911,8 +8717,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8911 /* Choose which receivers/antennas to use */ 8717 /* Choose which receivers/antennas to use */
8912 iwl4965_set_rxon_chain(priv); 8718 iwl4965_set_rxon_chain(priv);
8913 8719
8720
8914 printk(KERN_INFO DRV_NAME 8721 printk(KERN_INFO DRV_NAME
8915 ": Detected Intel Wireless WiFi Link 4965AGN\n"); 8722 ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
8916 8723
8917 /* Device-specific setup */ 8724 /* Device-specific setup */
8918 if (iwl4965_hw_set_hw_setting(priv)) { 8725 if (iwl4965_hw_set_hw_setting(priv)) {
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 75f6191e718d..7fe37bedf313 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -349,11 +349,7 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
349 349
350 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 350 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
351 clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); 351 clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
352 ret = lbs_prepare_and_send_command(priv, 352 ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
353 CMD_802_11_KEY_MATERIAL,
354 CMD_ACT_SET,
355 CMD_OPTION_WAITFORRSP,
356 0, assoc_req);
357 assoc_req->flags = flags; 353 assoc_req->flags = flags;
358 } 354 }
359 355
@@ -363,11 +359,7 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
363 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { 359 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
364 clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); 360 clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
365 361
366 ret = lbs_prepare_and_send_command(priv, 362 ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
367 CMD_802_11_KEY_MATERIAL,
368 CMD_ACT_SET,
369 CMD_OPTION_WAITFORRSP,
370 0, assoc_req);
371 assoc_req->flags = flags; 363 assoc_req->flags = flags;
372 } 364 }
373 365
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 3f9074df91e4..445c6dc09786 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -338,75 +338,103 @@ int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
338 return ret; 338 return ret;
339} 339}
340 340
341static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, 341static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam,
342 struct enc_key * pkey) 342 struct enc_key *key)
343{ 343{
344 lbs_deb_enter(LBS_DEB_CMD); 344 lbs_deb_enter(LBS_DEB_CMD);
345 345
346 if (pkey->flags & KEY_INFO_WPA_ENABLED) { 346 if (key->flags & KEY_INFO_WPA_ENABLED)
347 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); 347 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
348 } 348 if (key->flags & KEY_INFO_WPA_UNICAST)
349 if (pkey->flags & KEY_INFO_WPA_UNICAST) { 349 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
350 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); 350 if (key->flags & KEY_INFO_WPA_MCAST)
351 } 351 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
352 if (pkey->flags & KEY_INFO_WPA_MCAST) { 352
353 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); 353 keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
354 } 354 keyparam->keytypeid = cpu_to_le16(key->type);
355 keyparam->keylen = cpu_to_le16(key->len);
356 memcpy(keyparam->key, key->key, key->len);
355 357
356 pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); 358 /* Length field doesn't include the {type,length} header */
357 pkeyparamset->keytypeid = cpu_to_le16(pkey->type); 359 keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4);
358 pkeyparamset->keylen = cpu_to_le16(pkey->len);
359 memcpy(pkeyparamset->key, pkey->key, pkey->len);
360 pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid)
361 + sizeof(pkeyparamset->keyinfo)
362 + sizeof(pkeyparamset->keylen)
363 + sizeof(pkeyparamset->key));
364 lbs_deb_leave(LBS_DEB_CMD); 360 lbs_deb_leave(LBS_DEB_CMD);
365} 361}
366 362
367static int lbs_cmd_802_11_key_material(struct lbs_private *priv, 363int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
368 struct cmd_ds_command *cmd, 364 struct assoc_request *assoc)
369 u16 cmd_action,
370 u32 cmd_oid, void *pdata_buf)
371{ 365{
372 struct cmd_ds_802_11_key_material *pkeymaterial = 366 struct cmd_ds_802_11_key_material cmd;
373 &cmd->params.keymaterial;
374 struct assoc_request * assoc_req = pdata_buf;
375 int ret = 0; 367 int ret = 0;
376 int index = 0; 368 int index = 0;
377 369
378 lbs_deb_enter(LBS_DEB_CMD); 370 lbs_deb_enter(LBS_DEB_CMD);
379 371
380 cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL); 372 cmd.action = cpu_to_le16(cmd_action);
381 pkeymaterial->action = cpu_to_le16(cmd_action); 373 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
382 374
383 if (cmd_action == CMD_ACT_GET) { 375 if (cmd_action == CMD_ACT_GET) {
384 cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); 376 cmd.hdr.size = cpu_to_le16(S_DS_GEN + 2);
385 ret = 0; 377 } else {
386 goto done; 378 memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet));
387 }
388 379
389 memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet)); 380 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) {
381 set_one_wpa_key(&cmd.keyParamSet[index],
382 &assoc->wpa_unicast_key);
383 index++;
384 }
390 385
391 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { 386 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) {
392 set_one_wpa_key(&pkeymaterial->keyParamSet[index], 387 set_one_wpa_key(&cmd.keyParamSet[index],
393 &assoc_req->wpa_unicast_key); 388 &assoc->wpa_mcast_key);
394 index++; 389 index++;
395 } 390 }
396 391
397 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { 392 /* The common header and as many keys as we included */
398 set_one_wpa_key(&pkeymaterial->keyParamSet[index], 393 cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd),
399 &assoc_req->wpa_mcast_key); 394 keyParamSet[index]));
400 index++;
401 } 395 }
396 ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
397 /* Copy the returned key to driver private data */
398 if (!ret && cmd_action == CMD_ACT_GET) {
399 void *buf_ptr = cmd.keyParamSet;
400 void *resp_end = &(&cmd)[1];
401
402 while (buf_ptr < resp_end) {
403 struct MrvlIEtype_keyParamSet *keyparam = buf_ptr;
404 struct enc_key *key;
405 uint16_t param_set_len = le16_to_cpu(keyparam->length);
406 uint16_t key_len = le16_to_cpu(keyparam->keylen);
407 uint16_t key_flags = le16_to_cpu(keyparam->keyinfo);
408 uint16_t key_type = le16_to_cpu(keyparam->keytypeid);
409 void *end;
410
411 end = (void *)keyparam + sizeof(keyparam->type)
412 + sizeof(keyparam->length) + param_set_len;
413
414 /* Make sure we don't access past the end of the IEs */
415 if (end > resp_end)
416 break;
402 417
403 cmd->size = cpu_to_le16( S_DS_GEN 418 if (key_flags & KEY_INFO_WPA_UNICAST)
404 + sizeof (pkeymaterial->action) 419 key = &priv->wpa_unicast_key;
405 + (index * sizeof(struct MrvlIEtype_keyParamSet))); 420 else if (key_flags & KEY_INFO_WPA_MCAST)
421 key = &priv->wpa_mcast_key;
422 else
423 break;
406 424
407 ret = 0; 425 /* Copy returned key into driver */
426 memset(key, 0, sizeof(struct enc_key));
427 if (key_len > sizeof(key->key))
428 break;
429 key->type = key_type;
430 key->flags = key_flags;
431 key->len = key_len;
432 memcpy(key->key, keyparam->key, key->len);
433
434 buf_ptr = end + 1;
435 }
436 }
408 437
409done:
410 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 438 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
411 return ret; 439 return ret;
412} 440}
@@ -1354,10 +1382,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1354 ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action); 1382 ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
1355 break; 1383 break;
1356 1384
1357 case CMD_802_11_SCAN:
1358 ret = lbs_cmd_80211_scan(priv, cmdptr, pdata_buf);
1359 break;
1360
1361 case CMD_MAC_CONTROL: 1385 case CMD_MAC_CONTROL:
1362 ret = lbs_cmd_mac_control(priv, cmdptr); 1386 ret = lbs_cmd_mac_control(priv, cmdptr);
1363 break; 1387 break;
@@ -1435,11 +1459,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1435 ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr); 1459 ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
1436 break; 1460 break;
1437 1461
1438 case CMD_802_11_KEY_MATERIAL:
1439 ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action,
1440 cmd_oid, pdata_buf);
1441 break;
1442
1443 case CMD_802_11_PAIRWISE_TSC: 1462 case CMD_802_11_PAIRWISE_TSC:
1444 break; 1463 break;
1445 case CMD_802_11_GROUP_TSC: 1464 case CMD_802_11_GROUP_TSC:
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index b9ab85cc7913..d250e6bc0609 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -57,5 +57,7 @@ int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
57 struct assoc_request *assoc); 57 struct assoc_request *assoc);
58int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, 58int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
59 uint16_t *enable); 59 uint16_t *enable);
60int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
61 struct assoc_request *assoc);
60 62
61#endif /* _LBS_CMD_H */ 63#endif /* _LBS_CMD_H */
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 5d90b83f28eb..15e4ebdcd477 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -204,61 +204,6 @@ static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv,
204 return 0; 204 return 0;
205} 205}
206 206
207static int lbs_ret_802_11_key_material(struct lbs_private *priv,
208 struct cmd_ds_command *resp)
209{
210 struct cmd_ds_802_11_key_material *pkeymaterial =
211 &resp->params.keymaterial;
212 u16 action = le16_to_cpu(pkeymaterial->action);
213
214 lbs_deb_enter(LBS_DEB_CMD);
215
216 /* Copy the returned key to driver private data */
217 if (action == CMD_ACT_GET) {
218 u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet;
219 u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size));
220
221 while (buf_ptr < resp_end) {
222 struct MrvlIEtype_keyParamSet * pkeyparamset =
223 (struct MrvlIEtype_keyParamSet *) buf_ptr;
224 struct enc_key * pkey;
225 u16 param_set_len = le16_to_cpu(pkeyparamset->length);
226 u16 key_len = le16_to_cpu(pkeyparamset->keylen);
227 u16 key_flags = le16_to_cpu(pkeyparamset->keyinfo);
228 u16 key_type = le16_to_cpu(pkeyparamset->keytypeid);
229 u8 * end;
230
231 end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type)
232 + sizeof (pkeyparamset->length)
233 + param_set_len;
234 /* Make sure we don't access past the end of the IEs */
235 if (end > resp_end)
236 break;
237
238 if (key_flags & KEY_INFO_WPA_UNICAST)
239 pkey = &priv->wpa_unicast_key;
240 else if (key_flags & KEY_INFO_WPA_MCAST)
241 pkey = &priv->wpa_mcast_key;
242 else
243 break;
244
245 /* Copy returned key into driver */
246 memset(pkey, 0, sizeof(struct enc_key));
247 if (key_len > sizeof(pkey->key))
248 break;
249 pkey->type = key_type;
250 pkey->flags = key_flags;
251 pkey->len = key_len;
252 memcpy(pkey->key, pkeyparamset->key, pkey->len);
253
254 buf_ptr = end + 1;
255 }
256 }
257
258 lbs_deb_enter(LBS_DEB_CMD);
259 return 0;
260}
261
262static int lbs_ret_802_11_mac_address(struct lbs_private *priv, 207static int lbs_ret_802_11_mac_address(struct lbs_private *priv,
263 struct cmd_ds_command *resp) 208 struct cmd_ds_command *resp)
264{ 209{
@@ -407,10 +352,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
407 ret = lbs_ret_reg_access(priv, respcmd, resp); 352 ret = lbs_ret_reg_access(priv, respcmd, resp);
408 break; 353 break;
409 354
410 case CMD_RET(CMD_802_11_SCAN):
411 ret = lbs_ret_80211_scan(priv, resp);
412 break;
413
414 case CMD_RET(CMD_802_11_GET_LOG): 355 case CMD_RET(CMD_802_11_GET_LOG):
415 ret = lbs_ret_get_log(priv, resp); 356 ret = lbs_ret_get_log(priv, resp);
416 break; 357 break;
@@ -475,10 +416,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
475 ret = lbs_ret_80211_ad_hoc_stop(priv, resp); 416 ret = lbs_ret_80211_ad_hoc_stop(priv, resp);
476 break; 417 break;
477 418
478 case CMD_RET(CMD_802_11_KEY_MATERIAL):
479 ret = lbs_ret_802_11_key_material(priv, resp);
480 break;
481
482 case CMD_RET(CMD_802_11_EEPROM_ACCESS): 419 case CMD_RET(CMD_802_11_EEPROM_ACCESS):
483 ret = lbs_ret_802_11_eeprom_access(priv, resp); 420 ret = lbs_ret_802_11_eeprom_access(priv, resp);
484 break; 421 break;
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index d35b015b6657..56bc1aa2bb00 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -174,9 +174,11 @@ struct cmd_ds_802_11_subscribe_event {
174 * Define data structure for CMD_802_11_SCAN 174 * Define data structure for CMD_802_11_SCAN
175 */ 175 */
176struct cmd_ds_802_11_scan { 176struct cmd_ds_802_11_scan {
177 u8 bsstype; 177 struct cmd_header hdr;
178 u8 bssid[ETH_ALEN]; 178
179 u8 tlvbuffer[1]; 179 uint8_t bsstype;
180 uint8_t bssid[ETH_ALEN];
181 uint8_t tlvbuffer[0];
180#if 0 182#if 0
181 mrvlietypes_ssidparamset_t ssidParamSet; 183 mrvlietypes_ssidparamset_t ssidParamSet;
182 mrvlietypes_chanlistparamset_t ChanListParamSet; 184 mrvlietypes_chanlistparamset_t ChanListParamSet;
@@ -185,9 +187,11 @@ struct cmd_ds_802_11_scan {
185}; 187};
186 188
187struct cmd_ds_802_11_scan_rsp { 189struct cmd_ds_802_11_scan_rsp {
190 struct cmd_header hdr;
191
188 __le16 bssdescriptsize; 192 __le16 bssdescriptsize;
189 u8 nr_sets; 193 uint8_t nr_sets;
190 u8 bssdesc_and_tlvbuffer[1]; 194 uint8_t bssdesc_and_tlvbuffer[0];
191}; 195};
192 196
193struct cmd_ds_802_11_get_log { 197struct cmd_ds_802_11_get_log {
@@ -572,6 +576,8 @@ struct cmd_ds_host_sleep {
572} __attribute__ ((packed)); 576} __attribute__ ((packed));
573 577
574struct cmd_ds_802_11_key_material { 578struct cmd_ds_802_11_key_material {
579 struct cmd_header hdr;
580
575 __le16 action; 581 __le16 action;
576 struct MrvlIEtype_keyParamSet keyParamSet[2]; 582 struct MrvlIEtype_keyParamSet keyParamSet[2];
577} __attribute__ ((packed)); 583} __attribute__ ((packed));
@@ -689,8 +695,6 @@ struct cmd_ds_command {
689 /* command Body */ 695 /* command Body */
690 union { 696 union {
691 struct cmd_ds_802_11_ps_mode psmode; 697 struct cmd_ds_802_11_ps_mode psmode;
692 struct cmd_ds_802_11_scan scan;
693 struct cmd_ds_802_11_scan_rsp scanresp;
694 struct cmd_ds_mac_control macctrl; 698 struct cmd_ds_mac_control macctrl;
695 struct cmd_ds_802_11_associate associate; 699 struct cmd_ds_802_11_associate associate;
696 struct cmd_ds_802_11_deauthenticate deauth; 700 struct cmd_ds_802_11_deauthenticate deauth;
@@ -712,7 +716,6 @@ struct cmd_ds_command {
712 struct cmd_ds_802_11_rssi_rsp rssirsp; 716 struct cmd_ds_802_11_rssi_rsp rssirsp;
713 struct cmd_ds_802_11_disassociate dassociate; 717 struct cmd_ds_802_11_disassociate dassociate;
714 struct cmd_ds_802_11_mac_address macadd; 718 struct cmd_ds_802_11_mac_address macadd;
715 struct cmd_ds_802_11_key_material keymaterial;
716 struct cmd_ds_mac_reg_access macreg; 719 struct cmd_ds_mac_reg_access macreg;
717 struct cmd_ds_bbp_reg_access bbpreg; 720 struct cmd_ds_bbp_reg_access bbpreg;
718 struct cmd_ds_rf_reg_access rfreg; 721 struct cmd_ds_rf_reg_access rfreg;
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 7d4f3afa8cc5..99f11a56d84e 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -20,6 +20,7 @@
20#include "dev.h" 20#include "dev.h"
21#include "scan.h" 21#include "scan.h"
22#include "join.h" 22#include "join.h"
23#include "cmd.h"
23 24
24//! Approximate amount of data needed to pass a scan result back to iwlist 25//! Approximate amount of data needed to pass a scan result back to iwlist
25#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \ 26#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN \
@@ -39,10 +40,9 @@
39//! Memory needed to store a max number/size SSID TLV for a firmware scan 40//! Memory needed to store a max number/size SSID TLV for a firmware scan
40#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset)) 41#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset))
41 42
42//! Maximum memory needed for a lbs_scan_cmd_config with all TLVs at max 43//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max
43#define MAX_SCAN_CFG_ALLOC (sizeof(struct lbs_scan_cmd_config) \ 44#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \
44 + CHAN_TLV_MAX_SIZE \ 45 + CHAN_TLV_MAX_SIZE + SSID_TLV_MAX_SIZE)
45 + SSID_TLV_MAX_SIZE)
46 46
47//! The maximum number of channels the firmware can scan per command 47//! The maximum number of channels the firmware can scan per command
48#define MRVDRV_MAX_CHANNELS_PER_SCAN 14 48#define MRVDRV_MAX_CHANNELS_PER_SCAN 14
@@ -61,11 +61,8 @@
61//! Scan time specified in the channel TLV for each channel for active scans 61//! Scan time specified in the channel TLV for each channel for active scans
62#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100 62#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
63 63
64static const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 64static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
65static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 65 struct cmd_header *resp);
66
67
68
69 66
70/*********************************************************************/ 67/*********************************************************************/
71/* */ 68/* */
@@ -90,7 +87,7 @@ static void lbs_unset_basic_rate_flags(u8 *rates, size_t len)
90} 87}
91 88
92 89
93static inline void clear_bss_descriptor (struct bss_descriptor * bss) 90static inline void clear_bss_descriptor(struct bss_descriptor *bss)
94{ 91{
95 /* Don't blow away ->list, just BSS data */ 92 /* Don't blow away ->list, just BSS data */
96 memset(bss, 0, offsetof(struct bss_descriptor, list)); 93 memset(bss, 0, offsetof(struct bss_descriptor, list));
@@ -104,7 +101,8 @@ static inline void clear_bss_descriptor (struct bss_descriptor * bss)
104 * 101 *
105 * @return 0: ssid is same, otherwise is different 102 * @return 0: ssid is same, otherwise is different
106 */ 103 */
107int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) 104int lbs_ssid_cmp(uint8_t *ssid1, uint8_t ssid1_len, uint8_t *ssid2,
105 uint8_t ssid2_len)
108{ 106{
109 if (ssid1_len != ssid2_len) 107 if (ssid1_len != ssid2_len)
110 return -1; 108 return -1;
@@ -113,73 +111,66 @@ int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
113} 111}
114 112
115static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, 113static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
116 struct bss_descriptor * match_bss) 114 struct bss_descriptor *match_bss)
117{ 115{
118 if ( !secinfo->wep_enabled 116 if (!secinfo->wep_enabled && !secinfo->WPAenabled
119 && !secinfo->WPAenabled
120 && !secinfo->WPA2enabled 117 && !secinfo->WPA2enabled
121 && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC 118 && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC
122 && match_bss->rsn_ie[0] != MFIE_TYPE_RSN 119 && match_bss->rsn_ie[0] != MFIE_TYPE_RSN
123 && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { 120 && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
124 return 1; 121 return 1;
125 } 122 else
126 return 0; 123 return 0;
127} 124}
128 125
129static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, 126static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
130 struct bss_descriptor * match_bss) 127 struct bss_descriptor *match_bss)
131{ 128{
132 if ( secinfo->wep_enabled 129 if (secinfo->wep_enabled && !secinfo->WPAenabled
133 && !secinfo->WPAenabled 130 && !secinfo->WPA2enabled
134 && !secinfo->WPA2enabled 131 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
135 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
136 return 1; 132 return 1;
137 } 133 else
138 return 0; 134 return 0;
139} 135}
140 136
141static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, 137static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
142 struct bss_descriptor * match_bss) 138 struct bss_descriptor *match_bss)
143{ 139{
144 if ( !secinfo->wep_enabled 140 if (!secinfo->wep_enabled && secinfo->WPAenabled
145 && secinfo->WPAenabled 141 && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC)
146 && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC) 142 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
147 /* privacy bit may NOT be set in some APs like LinkSys WRT54G 143 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
148 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { 144 )
149 */
150 ) {
151 return 1; 145 return 1;
152 } 146 else
153 return 0; 147 return 0;
154} 148}
155 149
156static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo, 150static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
157 struct bss_descriptor * match_bss) 151 struct bss_descriptor *match_bss)
158{ 152{
159 if ( !secinfo->wep_enabled 153 if (!secinfo->wep_enabled && secinfo->WPA2enabled
160 && secinfo->WPA2enabled 154 && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN)
161 && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN) 155 /* privacy bit may NOT be set in some APs like LinkSys WRT54G
162 /* privacy bit may NOT be set in some APs like LinkSys WRT54G 156 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
163 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) { 157 )
164 */
165 ) {
166 return 1; 158 return 1;
167 } 159 else
168 return 0; 160 return 0;
169} 161}
170 162
171static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, 163static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
172 struct bss_descriptor * match_bss) 164 struct bss_descriptor *match_bss)
173{ 165{
174 if ( !secinfo->wep_enabled 166 if (!secinfo->wep_enabled && !secinfo->WPAenabled
175 && !secinfo->WPAenabled 167 && !secinfo->WPA2enabled
176 && !secinfo->WPA2enabled 168 && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC)
177 && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC) 169 && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN)
178 && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN) 170 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
179 && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
180 return 1; 171 return 1;
181 } 172 else
182 return 0; 173 return 0;
183} 174}
184 175
185static inline int is_same_network(struct bss_descriptor *src, 176static inline int is_same_network(struct bss_descriptor *src,
@@ -214,7 +205,7 @@ static inline int is_same_network(struct bss_descriptor *src,
214 * @return Index in scantable, or error code if negative 205 * @return Index in scantable, or error code if negative
215 */ 206 */
216static int is_network_compatible(struct lbs_private *priv, 207static int is_network_compatible(struct lbs_private *priv,
217 struct bss_descriptor * bss, u8 mode) 208 struct bss_descriptor *bss, uint8_t mode)
218{ 209{
219 int matched = 0; 210 int matched = 0;
220 211
@@ -228,43 +219,39 @@ static int is_network_compatible(struct lbs_private *priv,
228 } else if ((matched = match_bss_static_wep(&priv->secinfo, bss))) { 219 } else if ((matched = match_bss_static_wep(&priv->secinfo, bss))) {
229 goto done; 220 goto done;
230 } else if ((matched = match_bss_wpa(&priv->secinfo, bss))) { 221 } else if ((matched = match_bss_wpa(&priv->secinfo, bss))) {
231 lbs_deb_scan( 222 lbs_deb_scan("is_network_compatible() WPA: wpa_ie 0x%x "
232 "is_network_compatible() WPA: wpa_ie 0x%x " 223 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
233 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " 224 "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
234 "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], 225 priv->secinfo.wep_enabled ? "e" : "d",
235 priv->secinfo.wep_enabled ? "e" : "d", 226 priv->secinfo.WPAenabled ? "e" : "d",
236 priv->secinfo.WPAenabled ? "e" : "d", 227 priv->secinfo.WPA2enabled ? "e" : "d",
237 priv->secinfo.WPA2enabled ? "e" : "d", 228 (bss->capability & WLAN_CAPABILITY_PRIVACY));
238 (bss->capability & WLAN_CAPABILITY_PRIVACY));
239 goto done; 229 goto done;
240 } else if ((matched = match_bss_wpa2(&priv->secinfo, bss))) { 230 } else if ((matched = match_bss_wpa2(&priv->secinfo, bss))) {
241 lbs_deb_scan( 231 lbs_deb_scan("is_network_compatible() WPA2: wpa_ie 0x%x "
242 "is_network_compatible() WPA2: wpa_ie 0x%x " 232 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
243 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s " 233 "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
244 "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0], 234 priv->secinfo.wep_enabled ? "e" : "d",
245 priv->secinfo.wep_enabled ? "e" : "d", 235 priv->secinfo.WPAenabled ? "e" : "d",
246 priv->secinfo.WPAenabled ? "e" : "d", 236 priv->secinfo.WPA2enabled ? "e" : "d",
247 priv->secinfo.WPA2enabled ? "e" : "d", 237 (bss->capability & WLAN_CAPABILITY_PRIVACY));
248 (bss->capability & WLAN_CAPABILITY_PRIVACY));
249 goto done; 238 goto done;
250 } else if ((matched = match_bss_dynamic_wep(&priv->secinfo, bss))) { 239 } else if ((matched = match_bss_dynamic_wep(&priv->secinfo, bss))) {
251 lbs_deb_scan( 240 lbs_deb_scan("is_network_compatible() dynamic WEP: "
252 "is_network_compatible() dynamic WEP: " 241 "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n",
253 "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n", 242 bss->wpa_ie[0], bss->rsn_ie[0],
254 bss->wpa_ie[0], bss->rsn_ie[0], 243 (bss->capability & WLAN_CAPABILITY_PRIVACY));
255 (bss->capability & WLAN_CAPABILITY_PRIVACY));
256 goto done; 244 goto done;
257 } 245 }
258 246
259 /* bss security settings don't match those configured on card */ 247 /* bss security settings don't match those configured on card */
260 lbs_deb_scan( 248 lbs_deb_scan("is_network_compatible() FAILED: wpa_ie 0x%x "
261 "is_network_compatible() FAILED: wpa_ie 0x%x " 249 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n",
262 "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n", 250 bss->wpa_ie[0], bss->rsn_ie[0],
263 bss->wpa_ie[0], bss->rsn_ie[0], 251 priv->secinfo.wep_enabled ? "e" : "d",
264 priv->secinfo.wep_enabled ? "e" : "d", 252 priv->secinfo.WPAenabled ? "e" : "d",
265 priv->secinfo.WPAenabled ? "e" : "d", 253 priv->secinfo.WPA2enabled ? "e" : "d",
266 priv->secinfo.WPA2enabled ? "e" : "d", 254 (bss->capability & WLAN_CAPABILITY_PRIVACY));
267 (bss->capability & WLAN_CAPABILITY_PRIVACY));
268 255
269done: 256done:
270 lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched); 257 lbs_deb_leave_args(LBS_DEB_SCAN, "matched: %d", matched);
@@ -311,16 +298,15 @@ void lbs_scan_worker(struct work_struct *work)
311 * @return void 298 * @return void
312 */ 299 */
313static int lbs_scan_create_channel_list(struct lbs_private *priv, 300static int lbs_scan_create_channel_list(struct lbs_private *priv,
314 struct chanscanparamset * scanchanlist, 301 struct chanscanparamset *scanchanlist,
315 u8 filteredscan) 302 uint8_t filteredscan)
316{ 303{
317
318 struct region_channel *scanregion; 304 struct region_channel *scanregion;
319 struct chan_freq_power *cfp; 305 struct chan_freq_power *cfp;
320 int rgnidx; 306 int rgnidx;
321 int chanidx; 307 int chanidx;
322 int nextchan; 308 int nextchan;
323 u8 scantype; 309 uint8_t scantype;
324 310
325 chanidx = 0; 311 chanidx = 0;
326 312
@@ -331,9 +317,8 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
331 scantype = CMD_SCAN_TYPE_ACTIVE; 317 scantype = CMD_SCAN_TYPE_ACTIVE;
332 318
333 for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) { 319 for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) {
334 if (priv->enable11d && 320 if (priv->enable11d && (priv->connect_status != LBS_CONNECTED)
335 (priv->connect_status != LBS_CONNECTED) && 321 && (priv->mesh_connect_status != LBS_CONNECTED)) {
336 (priv->mesh_connect_status != LBS_CONNECTED)) {
337 /* Scan all the supported chan for the first scan */ 322 /* Scan all the supported chan for the first scan */
338 if (!priv->universal_channel[rgnidx].valid) 323 if (!priv->universal_channel[rgnidx].valid)
339 continue; 324 continue;
@@ -348,45 +333,30 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
348 scanregion = &priv->region_channel[rgnidx]; 333 scanregion = &priv->region_channel[rgnidx];
349 } 334 }
350 335
351 for (nextchan = 0; 336 for (nextchan = 0; nextchan < scanregion->nrcfp; nextchan++, chanidx++) {
352 nextchan < scanregion->nrcfp; nextchan++, chanidx++) { 337 struct chanscanparamset *chan = &scanchanlist[chanidx];
353 338
354 cfp = scanregion->CFP + nextchan; 339 cfp = scanregion->CFP + nextchan;
355 340
356 if (priv->enable11d) { 341 if (priv->enable11d)
357 scantype = 342 scantype = lbs_get_scan_type_11d(cfp->channel,
358 lbs_get_scan_type_11d(cfp->channel, 343 &priv->parsed_region_chan);
359 &priv->
360 parsed_region_chan);
361 }
362 344
363 switch (scanregion->band) { 345 if (scanregion->band == BAND_B || scanregion->band == BAND_G)
364 case BAND_B: 346 chan->radiotype = CMD_SCAN_RADIO_TYPE_BG;
365 case BAND_G:
366 default:
367 scanchanlist[chanidx].radiotype =
368 CMD_SCAN_RADIO_TYPE_BG;
369 break;
370 }
371 347
372 if (scantype == CMD_SCAN_TYPE_PASSIVE) { 348 if (scantype == CMD_SCAN_TYPE_PASSIVE) {
373 scanchanlist[chanidx].maxscantime = 349 chan->maxscantime = cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME);
374 cpu_to_le16(MRVDRV_PASSIVE_SCAN_CHAN_TIME); 350 chan->chanscanmode.passivescan = 1;
375 scanchanlist[chanidx].chanscanmode.passivescan =
376 1;
377 } else { 351 } else {
378 scanchanlist[chanidx].maxscantime = 352 chan->maxscantime = cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME);
379 cpu_to_le16(MRVDRV_ACTIVE_SCAN_CHAN_TIME); 353 chan->chanscanmode.passivescan = 0;
380 scanchanlist[chanidx].chanscanmode.passivescan =
381 0;
382 } 354 }
383 355
384 scanchanlist[chanidx].channumber = cfp->channel; 356 chan->channumber = cfp->channel;
385 357
386 if (filteredscan) { 358 if (filteredscan)
387 scanchanlist[chanidx].chanscanmode. 359 chan->chanscanmode.disablechanfilt = 1;
388 disablechanfilt = 1;
389 }
390 } 360 }
391 } 361 }
392 return chanidx; 362 return chanidx;
@@ -400,11 +370,11 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
400 * length 06 00 370 * length 06 00
401 * ssid 4d 4e 54 45 53 54 371 * ssid 4d 4e 54 45 53 54
402 */ 372 */
403static int lbs_scan_add_ssid_tlv(u8 *tlv, 373static int lbs_scan_add_ssid_tlv(uint8_t *tlv,
404 const struct lbs_ioctl_user_scan_cfg *user_cfg) 374 const struct lbs_ioctl_user_scan_cfg *user_cfg)
405{ 375{
406 struct mrvlietypes_ssidparamset *ssid_tlv = 376 struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv;
407 (struct mrvlietypes_ssidparamset *)tlv; 377
408 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); 378 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
409 ssid_tlv->header.len = cpu_to_le16(user_cfg->ssid_len); 379 ssid_tlv->header.len = cpu_to_le16(user_cfg->ssid_len);
410 memcpy(ssid_tlv->ssid, user_cfg->ssid, user_cfg->ssid_len); 380 memcpy(ssid_tlv->ssid, user_cfg->ssid, user_cfg->ssid_len);
@@ -437,13 +407,12 @@ static int lbs_scan_add_ssid_tlv(u8 *tlv,
437 * channel 13 00 0d 00 00 00 64 00 407 * channel 13 00 0d 00 00 00 64 00
438 * 408 *
439 */ 409 */
440static int lbs_scan_add_chanlist_tlv(u8 *tlv, 410static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
441 struct chanscanparamset *chan_list, 411 struct chanscanparamset *chan_list,
442 int chan_count) 412 int chan_count)
443{ 413{
444 size_t size = sizeof(struct chanscanparamset) * chan_count; 414 size_t size = sizeof(struct chanscanparamset) *chan_count;
445 struct mrvlietypes_chanlistparamset *chan_tlv = 415 struct mrvlietypes_chanlistparamset *chan_tlv = (void *)tlv;
446 (struct mrvlietypes_chanlistparamset *) tlv;
447 416
448 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); 417 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
449 memcpy(chan_tlv->chanscanparam, chan_list, size); 418 memcpy(chan_tlv->chanscanparam, chan_list, size);
@@ -462,11 +431,10 @@ static int lbs_scan_add_chanlist_tlv(u8 *tlv,
462 * The rates are in lbs_bg_rates[], but for the 802.11b 431 * The rates are in lbs_bg_rates[], but for the 802.11b
463 * rates the high bit isn't set. 432 * rates the high bit isn't set.
464 */ 433 */
465static int lbs_scan_add_rates_tlv(u8 *tlv) 434static int lbs_scan_add_rates_tlv(uint8_t *tlv)
466{ 435{
467 int i; 436 int i;
468 struct mrvlietypes_ratesparamset *rate_tlv = 437 struct mrvlietypes_ratesparamset *rate_tlv = (void *)tlv;
469 (struct mrvlietypes_ratesparamset *) tlv;
470 438
471 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); 439 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
472 tlv += sizeof(rate_tlv->header); 440 tlv += sizeof(rate_tlv->header);
@@ -492,24 +460,22 @@ static int lbs_scan_add_rates_tlv(u8 *tlv)
492 * Generate the CMD_802_11_SCAN command with the proper tlv 460 * Generate the CMD_802_11_SCAN command with the proper tlv
493 * for a bunch of channels. 461 * for a bunch of channels.
494 */ 462 */
495static int lbs_do_scan(struct lbs_private *priv, 463static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype,
496 u8 bsstype, 464 struct chanscanparamset *chan_list, int chan_count,
497 struct chanscanparamset *chan_list, 465 const struct lbs_ioctl_user_scan_cfg *user_cfg)
498 int chan_count,
499 const struct lbs_ioctl_user_scan_cfg *user_cfg)
500{ 466{
501 int ret = -ENOMEM; 467 int ret = -ENOMEM;
502 struct lbs_scan_cmd_config *scan_cmd; 468 struct cmd_ds_802_11_scan *scan_cmd;
503 u8 *tlv; /* pointer into our current, growing TLV storage area */ 469 uint8_t *tlv; /* pointer into our current, growing TLV storage area */
504 470
505 lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, " 471 lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, chan_count %d",
506 "chan_count %d", 472 bsstype, chan_list[0].channumber, chan_count);
507 bsstype, chan_list[0].channumber, chan_count);
508 473
509 /* create the fixed part for scan command */ 474 /* create the fixed part for scan command */
510 scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL); 475 scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
511 if (scan_cmd == NULL) 476 if (scan_cmd == NULL)
512 goto out; 477 goto out;
478
513 tlv = scan_cmd->tlvbuffer; 479 tlv = scan_cmd->tlvbuffer;
514 if (user_cfg) 480 if (user_cfg)
515 memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN); 481 memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN);
@@ -523,13 +489,16 @@ static int lbs_do_scan(struct lbs_private *priv,
523 tlv += lbs_scan_add_rates_tlv(tlv); 489 tlv += lbs_scan_add_rates_tlv(tlv);
524 490
525 /* This is the final data we are about to send */ 491 /* This is the final data we are about to send */
526 scan_cmd->tlvbufferlen = tlv - scan_cmd->tlvbuffer; 492 scan_cmd->hdr.size = cpu_to_le16(tlv - (uint8_t *)scan_cmd);
527 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, 1+6); 493 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
494 sizeof(*scan_cmd));
528 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer, 495 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
529 scan_cmd->tlvbufferlen); 496 tlv - scan_cmd->tlvbuffer);
497
498 ret = __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
499 le16_to_cpu(scan_cmd->hdr.size),
500 lbs_ret_80211_scan, 0);
530 501
531 ret = lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, 0,
532 CMD_OPTION_WAITFORRSP, 0, scan_cmd);
533out: 502out:
534 kfree(scan_cmd); 503 kfree(scan_cmd);
535 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); 504 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
@@ -553,14 +522,14 @@ out:
553 * @return 0 or < 0 if error 522 * @return 0 or < 0 if error
554 */ 523 */
555int lbs_scan_networks(struct lbs_private *priv, 524int lbs_scan_networks(struct lbs_private *priv,
556 const struct lbs_ioctl_user_scan_cfg *user_cfg, 525 const struct lbs_ioctl_user_scan_cfg *user_cfg,
557 int full_scan) 526 int full_scan)
558{ 527{
559 int ret = -ENOMEM; 528 int ret = -ENOMEM;
560 struct chanscanparamset *chan_list; 529 struct chanscanparamset *chan_list;
561 struct chanscanparamset *curr_chans; 530 struct chanscanparamset *curr_chans;
562 int chan_count; 531 int chan_count;
563 u8 bsstype = CMD_BSS_TYPE_ANY; 532 uint8_t bsstype = CMD_BSS_TYPE_ANY;
564 int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD; 533 int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD;
565 int filteredscan = 0; 534 int filteredscan = 0;
566 union iwreq_data wrqu; 535 union iwreq_data wrqu;
@@ -570,8 +539,7 @@ int lbs_scan_networks(struct lbs_private *priv,
570 DECLARE_MAC_BUF(mac); 539 DECLARE_MAC_BUF(mac);
571#endif 540#endif
572 541
573 lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", 542 lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan);
574 full_scan);
575 543
576 /* Cancel any partial outstanding partial scans if this scan 544 /* Cancel any partial outstanding partial scans if this scan
577 * is a full scan. 545 * is a full scan.
@@ -583,26 +551,24 @@ int lbs_scan_networks(struct lbs_private *priv,
583 if (user_cfg) { 551 if (user_cfg) {
584 if (user_cfg->bsstype) 552 if (user_cfg->bsstype)
585 bsstype = user_cfg->bsstype; 553 bsstype = user_cfg->bsstype;
586 if (compare_ether_addr(user_cfg->bssid, &zeromac[0]) != 0) { 554 if (!is_zero_ether_addr(user_cfg->bssid)) {
587 numchannels = MRVDRV_MAX_CHANNELS_PER_SCAN; 555 numchannels = MRVDRV_MAX_CHANNELS_PER_SCAN;
588 filteredscan = 1; 556 filteredscan = 1;
589 } 557 }
590 } 558 }
591 lbs_deb_scan("numchannels %d, bsstype %d, " 559 lbs_deb_scan("numchannels %d, bsstype %d, filteredscan %d\n",
592 "filteredscan %d\n", 560 numchannels, bsstype, filteredscan);
593 numchannels, bsstype, filteredscan);
594 561
595 /* Create list of channels to scan */ 562 /* Create list of channels to scan */
596 chan_list = kzalloc(sizeof(struct chanscanparamset) * 563 chan_list = kzalloc(sizeof(struct chanscanparamset) *
597 LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); 564 LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
598 if (!chan_list) { 565 if (!chan_list) {
599 lbs_pr_alert("SCAN: chan_list empty\n"); 566 lbs_pr_alert("SCAN: chan_list empty\n");
600 goto out; 567 goto out;
601 } 568 }
602 569
603 /* We want to scan all channels */ 570 /* We want to scan all channels */
604 chan_count = lbs_scan_create_channel_list(priv, chan_list, 571 chan_count = lbs_scan_create_channel_list(priv, chan_list, filteredscan);
605 filteredscan);
606 572
607 netif_stop_queue(priv->dev); 573 netif_stop_queue(priv->dev);
608 netif_carrier_off(priv->dev); 574 netif_carrier_off(priv->dev);
@@ -629,9 +595,9 @@ int lbs_scan_networks(struct lbs_private *priv,
629 while (chan_count) { 595 while (chan_count) {
630 int to_scan = min(numchannels, chan_count); 596 int to_scan = min(numchannels, chan_count);
631 lbs_deb_scan("scanning %d of %d channels\n", 597 lbs_deb_scan("scanning %d of %d channels\n",
632 to_scan, chan_count); 598 to_scan, chan_count);
633 ret = lbs_do_scan(priv, bsstype, curr_chans, 599 ret = lbs_do_scan(priv, bsstype, curr_chans,
634 to_scan, user_cfg); 600 to_scan, user_cfg);
635 if (ret) { 601 if (ret) {
636 lbs_pr_err("SCAN_CMD failed\n"); 602 lbs_pr_err("SCAN_CMD failed\n");
637 goto out2; 603 goto out2;
@@ -640,8 +606,7 @@ int lbs_scan_networks(struct lbs_private *priv,
640 chan_count -= to_scan; 606 chan_count -= to_scan;
641 607
642 /* somehow schedule the next part of the scan */ 608 /* somehow schedule the next part of the scan */
643 if (chan_count && 609 if (chan_count && !full_scan &&
644 !full_scan &&
645 !priv->surpriseremoved) { 610 !priv->surpriseremoved) {
646 /* -1 marks just that we're currently scanning */ 611 /* -1 marks just that we're currently scanning */
647 if (priv->scan_channel < 0) 612 if (priv->scan_channel < 0)
@@ -650,7 +615,7 @@ int lbs_scan_networks(struct lbs_private *priv,
650 priv->scan_channel += to_scan; 615 priv->scan_channel += to_scan;
651 cancel_delayed_work(&priv->scan_work); 616 cancel_delayed_work(&priv->scan_work);
652 queue_delayed_work(priv->work_thread, &priv->scan_work, 617 queue_delayed_work(priv->work_thread, &priv->scan_work,
653 msecs_to_jiffies(300)); 618 msecs_to_jiffies(300));
654 /* skip over GIWSCAN event */ 619 /* skip over GIWSCAN event */
655 goto out; 620 goto out;
656 } 621 }
@@ -665,8 +630,8 @@ int lbs_scan_networks(struct lbs_private *priv,
665 lbs_deb_scan("scan table:\n"); 630 lbs_deb_scan("scan table:\n");
666 list_for_each_entry(iter, &priv->network_list, list) 631 list_for_each_entry(iter, &priv->network_list, list)
667 lbs_deb_scan("%02d: BSSID %s, RSSI %d, SSID '%s'\n", 632 lbs_deb_scan("%02d: BSSID %s, RSSI %d, SSID '%s'\n",
668 i++, print_mac(mac, iter->bssid), (s32) iter->rssi, 633 i++, print_mac(mac, iter->bssid), (int)iter->rssi,
669 escape_essid(iter->ssid, iter->ssid_len)); 634 escape_essid(iter->ssid, iter->ssid_len));
670 mutex_unlock(&priv->lock); 635 mutex_unlock(&priv->lock);
671#endif 636#endif
672 637
@@ -711,7 +676,7 @@ out:
711 * @return 0 or -1 676 * @return 0 or -1
712 */ 677 */
713static int lbs_process_bss(struct bss_descriptor *bss, 678static int lbs_process_bss(struct bss_descriptor *bss,
714 u8 ** pbeaconinfo, int *bytesleft) 679 uint8_t **pbeaconinfo, int *bytesleft)
715{ 680{
716 struct ieeetypes_fhparamset *pFH; 681 struct ieeetypes_fhparamset *pFH;
717 struct ieeetypes_dsparamset *pDS; 682 struct ieeetypes_dsparamset *pDS;
@@ -719,9 +684,9 @@ static int lbs_process_bss(struct bss_descriptor *bss,
719 struct ieeetypes_ibssparamset *pibss; 684 struct ieeetypes_ibssparamset *pibss;
720 DECLARE_MAC_BUF(mac); 685 DECLARE_MAC_BUF(mac);
721 struct ieeetypes_countryinfoset *pcountryinfo; 686 struct ieeetypes_countryinfoset *pcountryinfo;
722 u8 *pos, *end, *p; 687 uint8_t *pos, *end, *p;
723 u8 n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; 688 uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
724 u16 beaconsize = 0; 689 uint16_t beaconsize = 0;
725 int ret; 690 int ret;
726 691
727 lbs_deb_enter(LBS_DEB_SCAN); 692 lbs_deb_enter(LBS_DEB_SCAN);
@@ -793,12 +758,11 @@ static int lbs_process_bss(struct bss_descriptor *bss,
793 758
794 /* process variable IE */ 759 /* process variable IE */
795 while (pos <= end - 2) { 760 while (pos <= end - 2) {
796 struct ieee80211_info_element * elem = 761 struct ieee80211_info_element * elem = (void *)pos;
797 (struct ieee80211_info_element *) pos;
798 762
799 if (pos + elem->len > end) { 763 if (pos + elem->len > end) {
800 lbs_deb_scan("process_bss: error in processing IE, " 764 lbs_deb_scan("process_bss: error in processing IE, "
801 "bytes left < IE length\n"); 765 "bytes left < IE length\n");
802 break; 766 break;
803 } 767 }
804 768
@@ -812,7 +776,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
812 break; 776 break;
813 777
814 case MFIE_TYPE_RATES: 778 case MFIE_TYPE_RATES:
815 n_basic_rates = min_t(u8, MAX_RATES, elem->len); 779 n_basic_rates = min_t(uint8_t, MAX_RATES, elem->len);
816 memcpy(bss->rates, elem->data, n_basic_rates); 780 memcpy(bss->rates, elem->data, n_basic_rates);
817 got_basic_rates = 1; 781 got_basic_rates = 1;
818 lbs_deb_scan("got RATES IE\n"); 782 lbs_deb_scan("got RATES IE\n");
@@ -853,19 +817,16 @@ static int lbs_process_bss(struct bss_descriptor *bss,
853 lbs_deb_scan("got COUNTRY IE\n"); 817 lbs_deb_scan("got COUNTRY IE\n");
854 if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) 818 if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
855 || pcountryinfo->len > 254) { 819 || pcountryinfo->len > 254) {
856 lbs_deb_scan("process_bss: 11D- Err " 820 lbs_deb_scan("process_bss: 11D- Err CountryInfo len %d, min %zd, max 254\n",
857 "CountryInfo len %d, min %zd, max 254\n", 821 pcountryinfo->len, sizeof(pcountryinfo->countrycode));
858 pcountryinfo->len,
859 sizeof(pcountryinfo->countrycode));
860 ret = -1; 822 ret = -1;
861 goto done; 823 goto done;
862 } 824 }
863 825
864 memcpy(&bss->countryinfo, 826 memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2);
865 pcountryinfo, pcountryinfo->len + 2);
866 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo", 827 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
867 (u8 *) pcountryinfo, 828 (uint8_t *) pcountryinfo,
868 (u32) (pcountryinfo->len + 2)); 829 (int) (pcountryinfo->len + 2));
869 break; 830 break;
870 831
871 case MFIE_TYPE_RATES_EX: 832 case MFIE_TYPE_RATES_EX:
@@ -889,26 +850,19 @@ static int lbs_process_bss(struct bss_descriptor *bss,
889 850
890 case MFIE_TYPE_GENERIC: 851 case MFIE_TYPE_GENERIC:
891 if (elem->len >= 4 && 852 if (elem->len >= 4 &&
892 elem->data[0] == 0x00 && 853 elem->data[0] == 0x00 && elem->data[1] == 0x50 &&
893 elem->data[1] == 0x50 && 854 elem->data[2] == 0xf2 && elem->data[3] == 0x01) {
894 elem->data[2] == 0xf2 && 855 bss->wpa_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
895 elem->data[3] == 0x01) {
896 bss->wpa_ie_len = min(elem->len + 2,
897 MAX_WPA_IE_LEN);
898 memcpy(bss->wpa_ie, elem, bss->wpa_ie_len); 856 memcpy(bss->wpa_ie, elem, bss->wpa_ie_len);
899 lbs_deb_scan("got WPA IE\n"); 857 lbs_deb_scan("got WPA IE\n");
900 lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, 858 lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, elem->len);
901 elem->len);
902 } else if (elem->len >= MARVELL_MESH_IE_LENGTH && 859 } else if (elem->len >= MARVELL_MESH_IE_LENGTH &&
903 elem->data[0] == 0x00 && 860 elem->data[0] == 0x00 && elem->data[1] == 0x50 &&
904 elem->data[1] == 0x50 && 861 elem->data[2] == 0x43 && elem->data[3] == 0x04) {
905 elem->data[2] == 0x43 &&
906 elem->data[3] == 0x04) {
907 lbs_deb_scan("got mesh IE\n"); 862 lbs_deb_scan("got mesh IE\n");
908 bss->mesh = 1; 863 bss->mesh = 1;
909 } else { 864 } else {
910 lbs_deb_scan("got generiec IE: " 865 lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n",
911 "%02x:%02x:%02x:%02x, len %d\n",
912 elem->data[0], elem->data[1], 866 elem->data[0], elem->data[1],
913 elem->data[2], elem->data[3], 867 elem->data[2], elem->data[3],
914 elem->len); 868 elem->len);
@@ -920,12 +874,12 @@ static int lbs_process_bss(struct bss_descriptor *bss,
920 bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN); 874 bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
921 memcpy(bss->rsn_ie, elem, bss->rsn_ie_len); 875 memcpy(bss->rsn_ie, elem, bss->rsn_ie_len);
922 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE", 876 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE",
923 bss->rsn_ie, elem->len); 877 bss->rsn_ie, elem->len);
924 break; 878 break;
925 879
926 default: 880 default:
927 lbs_deb_scan("got IE 0x%04x, len %d\n", 881 lbs_deb_scan("got IE 0x%04x, len %d\n",
928 elem->id, elem->len); 882 elem->id, elem->len);
929 break; 883 break;
930 } 884 }
931 885
@@ -955,18 +909,17 @@ done:
955 * @return index in BSSID list, or error return code (< 0) 909 * @return index in BSSID list, or error return code (< 0)
956 */ 910 */
957struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv, 911struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv,
958 u8 * bssid, u8 mode) 912 uint8_t *bssid, uint8_t mode)
959{ 913{
960 struct bss_descriptor * iter_bss; 914 struct bss_descriptor *iter_bss;
961 struct bss_descriptor * found_bss = NULL; 915 struct bss_descriptor *found_bss = NULL;
962 916
963 lbs_deb_enter(LBS_DEB_SCAN); 917 lbs_deb_enter(LBS_DEB_SCAN);
964 918
965 if (!bssid) 919 if (!bssid)
966 goto out; 920 goto out;
967 921
968 lbs_deb_hex(LBS_DEB_SCAN, "looking for", 922 lbs_deb_hex(LBS_DEB_SCAN, "looking for", bssid, ETH_ALEN);
969 bssid, ETH_ALEN);
970 923
971 /* Look through the scan table for a compatible match. The loop will 924 /* Look through the scan table for a compatible match. The loop will
972 * continue past a matched bssid that is not compatible in case there 925 * continue past a matched bssid that is not compatible in case there
@@ -1008,10 +961,11 @@ out:
1008 * @return index in BSSID list 961 * @return index in BSSID list
1009 */ 962 */
1010struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv, 963struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv,
1011 u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode, 964 uint8_t *ssid, uint8_t ssid_len,
1012 int channel) 965 uint8_t *bssid, uint8_t mode,
966 int channel)
1013{ 967{
1014 u8 bestrssi = 0; 968 uint8_t bestrssi = 0;
1015 struct bss_descriptor * iter_bss = NULL; 969 struct bss_descriptor * iter_bss = NULL;
1016 struct bss_descriptor * found_bss = NULL; 970 struct bss_descriptor * found_bss = NULL;
1017 struct bss_descriptor * tmp_oldest = NULL; 971 struct bss_descriptor * tmp_oldest = NULL;
@@ -1026,7 +980,7 @@ struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv,
1026 tmp_oldest = iter_bss; 980 tmp_oldest = iter_bss;
1027 981
1028 if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len, 982 if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
1029 ssid, ssid_len) != 0) 983 ssid, ssid_len) != 0)
1030 continue; /* ssid doesn't match */ 984 continue; /* ssid doesn't match */
1031 if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0) 985 if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0)
1032 continue; /* bssid doesn't match */ 986 continue; /* bssid doesn't match */
@@ -1076,13 +1030,12 @@ out:
1076 * 1030 *
1077 * @return index in BSSID list 1031 * @return index in BSSID list
1078 */ 1032 */
1079static struct bss_descriptor *lbs_find_best_ssid_in_list( 1033static struct bss_descriptor *lbs_find_best_ssid_in_list(struct lbs_private *priv,
1080 struct lbs_private *priv, 1034 uint8_t mode)
1081 u8 mode)
1082{ 1035{
1083 u8 bestrssi = 0; 1036 uint8_t bestrssi = 0;
1084 struct bss_descriptor * iter_bss; 1037 struct bss_descriptor *iter_bss;
1085 struct bss_descriptor * best_bss = NULL; 1038 struct bss_descriptor *best_bss = NULL;
1086 1039
1087 lbs_deb_enter(LBS_DEB_SCAN); 1040 lbs_deb_enter(LBS_DEB_SCAN);
1088 1041
@@ -1124,11 +1077,12 @@ static struct bss_descriptor *lbs_find_best_ssid_in_list(
1124 * 1077 *
1125 * @return 0--success, otherwise--fail 1078 * @return 0--success, otherwise--fail
1126 */ 1079 */
1127int lbs_find_best_network_ssid(struct lbs_private *priv, 1080int lbs_find_best_network_ssid(struct lbs_private *priv, uint8_t *out_ssid,
1128 u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode) 1081 uint8_t *out_ssid_len, uint8_t preferred_mode,
1082 uint8_t *out_mode)
1129{ 1083{
1130 int ret = -1; 1084 int ret = -1;
1131 struct bss_descriptor * found; 1085 struct bss_descriptor *found;
1132 1086
1133 lbs_deb_enter(LBS_DEB_SCAN); 1087 lbs_deb_enter(LBS_DEB_SCAN);
1134 1088
@@ -1163,14 +1117,14 @@ out:
1163 * 1117 *
1164 * @return 0-success, otherwise fail 1118 * @return 0-success, otherwise fail
1165 */ 1119 */
1166int lbs_send_specific_ssid_scan(struct lbs_private *priv, 1120int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid,
1167 u8 *ssid, u8 ssid_len, u8 clear_ssid) 1121 uint8_t ssid_len, uint8_t clear_ssid)
1168{ 1122{
1169 struct lbs_ioctl_user_scan_cfg scancfg; 1123 struct lbs_ioctl_user_scan_cfg scancfg;
1170 int ret = 0; 1124 int ret = 0;
1171 1125
1172 lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d", 1126 lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d",
1173 escape_essid(ssid, ssid_len), clear_ssid); 1127 escape_essid(ssid, ssid_len), clear_ssid);
1174 1128
1175 if (!ssid_len) 1129 if (!ssid_len)
1176 goto out; 1130 goto out;
@@ -1204,17 +1158,17 @@ out:
1204#define MAX_CUSTOM_LEN 64 1158#define MAX_CUSTOM_LEN 64
1205 1159
1206static inline char *lbs_translate_scan(struct lbs_private *priv, 1160static inline char *lbs_translate_scan(struct lbs_private *priv,
1207 char *start, char *stop, 1161 char *start, char *stop,
1208 struct bss_descriptor *bss) 1162 struct bss_descriptor *bss)
1209{ 1163{
1210 struct chan_freq_power *cfp; 1164 struct chan_freq_power *cfp;
1211 char *current_val; /* For rates */ 1165 char *current_val; /* For rates */
1212 struct iw_event iwe; /* Temporary buffer */ 1166 struct iw_event iwe; /* Temporary buffer */
1213 int j; 1167 int j;
1214#define PERFECT_RSSI ((u8)50) 1168#define PERFECT_RSSI ((uint8_t)50)
1215#define WORST_RSSI ((u8)0) 1169#define WORST_RSSI ((uint8_t)0)
1216#define RSSI_DIFF ((u8)(PERFECT_RSSI - WORST_RSSI)) 1170#define RSSI_DIFF ((uint8_t)(PERFECT_RSSI - WORST_RSSI))
1217 u8 rssi; 1171 uint8_t rssi;
1218 1172
1219 lbs_deb_enter(LBS_DEB_SCAN); 1173 lbs_deb_enter(LBS_DEB_SCAN);
1220 1174
@@ -1234,7 +1188,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
1234 /* SSID */ 1188 /* SSID */
1235 iwe.cmd = SIOCGIWESSID; 1189 iwe.cmd = SIOCGIWESSID;
1236 iwe.u.data.flags = 1; 1190 iwe.u.data.flags = 1;
1237 iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE); 1191 iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
1238 start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); 1192 start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
1239 1193
1240 /* Mode */ 1194 /* Mode */
@@ -1255,28 +1209,26 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
1255 1209
1256 rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE; 1210 rssi = iwe.u.qual.level - MRVDRV_NF_DEFAULT_SCAN_VALUE;
1257 iwe.u.qual.qual = 1211 iwe.u.qual.qual =
1258 (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) * 1212 (100 * RSSI_DIFF * RSSI_DIFF - (PERFECT_RSSI - rssi) *
1259 (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) / 1213 (15 * (RSSI_DIFF) + 62 * (PERFECT_RSSI - rssi))) /
1260 (RSSI_DIFF * RSSI_DIFF); 1214 (RSSI_DIFF * RSSI_DIFF);
1261 if (iwe.u.qual.qual > 100) 1215 if (iwe.u.qual.qual > 100)
1262 iwe.u.qual.qual = 100; 1216 iwe.u.qual.qual = 100;
1263 1217
1264 if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) { 1218 if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
1265 iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE; 1219 iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
1266 } else { 1220 } else {
1267 iwe.u.qual.noise = 1221 iwe.u.qual.noise = CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
1268 CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
1269 } 1222 }
1270 1223
1271 /* Locally created ad-hoc BSSs won't have beacons if this is the 1224 /* Locally created ad-hoc BSSs won't have beacons if this is the
1272 * only station in the adhoc network; so get signal strength 1225 * only station in the adhoc network; so get signal strength
1273 * from receive statistics. 1226 * from receive statistics.
1274 */ 1227 */
1275 if ((priv->mode == IW_MODE_ADHOC) 1228 if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate
1276 && priv->adhoccreate
1277 && !lbs_ssid_cmp(priv->curbssparams.ssid, 1229 && !lbs_ssid_cmp(priv->curbssparams.ssid,
1278 priv->curbssparams.ssid_len, 1230 priv->curbssparams.ssid_len,
1279 bss->ssid, bss->ssid_len)) { 1231 bss->ssid, bss->ssid_len)) {
1280 int snr, nf; 1232 int snr, nf;
1281 snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; 1233 snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
1282 nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; 1234 nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
@@ -1307,14 +1259,13 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
1307 current_val = iwe_stream_add_value(start, current_val, 1259 current_val = iwe_stream_add_value(start, current_val,
1308 stop, &iwe, IW_EV_PARAM_LEN); 1260 stop, &iwe, IW_EV_PARAM_LEN);
1309 } 1261 }
1310 if ((bss->mode == IW_MODE_ADHOC) 1262 if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
1311 && !lbs_ssid_cmp(priv->curbssparams.ssid, 1263 && !lbs_ssid_cmp(priv->curbssparams.ssid,
1312 priv->curbssparams.ssid_len, 1264 priv->curbssparams.ssid_len,
1313 bss->ssid, bss->ssid_len) 1265 bss->ssid, bss->ssid_len)) {
1314 && priv->adhoccreate) {
1315 iwe.u.bitrate.value = 22 * 500000; 1266 iwe.u.bitrate.value = 22 * 500000;
1316 current_val = iwe_stream_add_value(start, current_val, 1267 current_val = iwe_stream_add_value(start, current_val,
1317 stop, &iwe, IW_EV_PARAM_LEN); 1268 stop, &iwe, IW_EV_PARAM_LEN);
1318 } 1269 }
1319 /* Check if we added any event */ 1270 /* Check if we added any event */
1320 if((current_val - start) > IW_EV_LCP_LEN) 1271 if((current_val - start) > IW_EV_LCP_LEN)
@@ -1343,8 +1294,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
1343 char *p = custom; 1294 char *p = custom;
1344 1295
1345 iwe.cmd = IWEVCUSTOM; 1296 iwe.cmd = IWEVCUSTOM;
1346 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), 1297 p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
1347 "mesh-type: olpc");
1348 iwe.u.data.length = p - custom; 1298 iwe.u.data.length = p - custom;
1349 if (iwe.u.data.length) 1299 if (iwe.u.data.length)
1350 start = iwe_stream_add_point(start, stop, &iwe, custom); 1300 start = iwe_stream_add_point(start, stop, &iwe, custom);
@@ -1367,7 +1317,7 @@ out:
1367 * @return 0 --success, otherwise fail 1317 * @return 0 --success, otherwise fail
1368 */ 1318 */
1369int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, 1319int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
1370 struct iw_param *wrqu, char *extra) 1320 struct iw_param *wrqu, char *extra)
1371{ 1321{
1372 struct lbs_private *priv = dev->priv; 1322 struct lbs_private *priv = dev->priv;
1373 1323
@@ -1391,7 +1341,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
1391 1341
1392 if (!delayed_work_pending(&priv->scan_work)) 1342 if (!delayed_work_pending(&priv->scan_work))
1393 queue_delayed_work(priv->work_thread, &priv->scan_work, 1343 queue_delayed_work(priv->work_thread, &priv->scan_work,
1394 msecs_to_jiffies(50)); 1344 msecs_to_jiffies(50));
1395 /* set marker that currently a scan is taking place */ 1345 /* set marker that currently a scan is taking place */
1396 priv->scan_channel = -1; 1346 priv->scan_channel = -1;
1397 1347
@@ -1414,15 +1364,15 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
1414 * @return 0 --success, otherwise fail 1364 * @return 0 --success, otherwise fail
1415 */ 1365 */
1416int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, 1366int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
1417 struct iw_point *dwrq, char *extra) 1367 struct iw_point *dwrq, char *extra)
1418{ 1368{
1419#define SCAN_ITEM_SIZE 128 1369#define SCAN_ITEM_SIZE 128
1420 struct lbs_private *priv = dev->priv; 1370 struct lbs_private *priv = dev->priv;
1421 int err = 0; 1371 int err = 0;
1422 char *ev = extra; 1372 char *ev = extra;
1423 char *stop = ev + dwrq->length; 1373 char *stop = ev + dwrq->length;
1424 struct bss_descriptor * iter_bss; 1374 struct bss_descriptor *iter_bss;
1425 struct bss_descriptor * safe; 1375 struct bss_descriptor *safe;
1426 1376
1427 lbs_deb_enter(LBS_DEB_SCAN); 1377 lbs_deb_enter(LBS_DEB_SCAN);
1428 1378
@@ -1431,14 +1381,13 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
1431 return -EAGAIN; 1381 return -EAGAIN;
1432 1382
1433 /* Update RSSI if current BSS is a locally created ad-hoc BSS */ 1383 /* Update RSSI if current BSS is a locally created ad-hoc BSS */
1434 if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) { 1384 if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate)
1435 lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, 1385 lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
1436 CMD_OPTION_WAITFORRSP, 0, NULL); 1386 CMD_OPTION_WAITFORRSP, 0, NULL);
1437 }
1438 1387
1439 mutex_lock(&priv->lock); 1388 mutex_lock(&priv->lock);
1440 list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) { 1389 list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
1441 char * next_ev; 1390 char *next_ev;
1442 unsigned long stale_time; 1391 unsigned long stale_time;
1443 1392
1444 if (stop - ev < SCAN_ITEM_SIZE) { 1393 if (stop - ev < SCAN_ITEM_SIZE) {
@@ -1453,8 +1402,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
1453 /* Prune old an old scan result */ 1402 /* Prune old an old scan result */
1454 stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE; 1403 stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
1455 if (time_after(jiffies, stale_time)) { 1404 if (time_after(jiffies, stale_time)) {
1456 list_move_tail (&iter_bss->list, 1405 list_move_tail(&iter_bss->list, &priv->network_free_list);
1457 &priv->network_free_list);
1458 clear_bss_descriptor(iter_bss); 1406 clear_bss_descriptor(iter_bss);
1459 continue; 1407 continue;
1460 } 1408 }
@@ -1485,44 +1433,6 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
1485 1433
1486 1434
1487/** 1435/**
1488 * @brief Prepare a scan command to be sent to the firmware
1489 *
1490 * Called via lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, ...)
1491 * from cmd.c
1492 *
1493 * Sends a fixed length data part (specifying the BSS type and BSSID filters)
1494 * as well as a variable number/length of TLVs to the firmware.
1495 *
1496 * @param priv A pointer to struct lbs_private structure
1497 * @param cmd A pointer to cmd_ds_command structure to be sent to
1498 * firmware with the cmd_DS_801_11_SCAN structure
1499 * @param pdata_buf Void pointer cast of a lbs_scan_cmd_config struct used
1500 * to set the fields/TLVs for the command sent to firmware
1501 *
1502 * @return 0 or -1
1503 */
1504int lbs_cmd_80211_scan(struct lbs_private *priv,
1505 struct cmd_ds_command *cmd, void *pdata_buf)
1506{
1507 struct cmd_ds_802_11_scan *pscan = &cmd->params.scan;
1508 struct lbs_scan_cmd_config *pscancfg = pdata_buf;
1509
1510 lbs_deb_enter(LBS_DEB_SCAN);
1511
1512 /* Set fixed field variables in scan command */
1513 pscan->bsstype = pscancfg->bsstype;
1514 memcpy(pscan->bssid, pscancfg->bssid, ETH_ALEN);
1515 memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
1516
1517 /* size is equal to the sizeof(fixed portions) + the TLV len + header */
1518 cmd->size = cpu_to_le16(sizeof(pscan->bsstype) + ETH_ALEN
1519 + pscancfg->tlvbufferlen + S_DS_GEN);
1520
1521 lbs_deb_leave(LBS_DEB_SCAN);
1522 return 0;
1523}
1524
1525/**
1526 * @brief This function handles the command response of scan 1436 * @brief This function handles the command response of scan
1527 * 1437 *
1528 * Called from handle_cmd_response() in cmdrespc. 1438 * Called from handle_cmd_response() in cmdrespc.
@@ -1548,13 +1458,14 @@ int lbs_cmd_80211_scan(struct lbs_private *priv,
1548 * 1458 *
1549 * @return 0 or -1 1459 * @return 0 or -1
1550 */ 1460 */
1551int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp) 1461static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
1462 struct cmd_header *resp)
1552{ 1463{
1553 struct cmd_ds_802_11_scan_rsp *pscan; 1464 struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
1554 struct bss_descriptor * iter_bss; 1465 struct bss_descriptor *iter_bss;
1555 struct bss_descriptor * safe; 1466 struct bss_descriptor *safe;
1556 u8 *pbssinfo; 1467 uint8_t *bssinfo;
1557 u16 scanrespsize; 1468 uint16_t scanrespsize;
1558 int bytesleft; 1469 int bytesleft;
1559 int idx; 1470 int idx;
1560 int tlvbufsize; 1471 int tlvbufsize;
@@ -1571,48 +1482,45 @@ int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp)
1571 clear_bss_descriptor(iter_bss); 1482 clear_bss_descriptor(iter_bss);
1572 } 1483 }
1573 1484
1574 pscan = &resp->params.scanresp; 1485 if (scanresp->nr_sets > MAX_NETWORK_COUNT) {
1575 1486 lbs_deb_scan("SCAN_RESP: too many scan results (%d, max %d)\n",
1576 if (pscan->nr_sets > MAX_NETWORK_COUNT) { 1487 scanresp->nr_sets, MAX_NETWORK_COUNT);
1577 lbs_deb_scan(
1578 "SCAN_RESP: too many scan results (%d, max %d)!!\n",
1579 pscan->nr_sets, MAX_NETWORK_COUNT);
1580 ret = -1; 1488 ret = -1;
1581 goto done; 1489 goto done;
1582 } 1490 }
1583 1491
1584 bytesleft = le16_to_cpu(pscan->bssdescriptsize); 1492 bytesleft = le16_to_cpu(scanresp->bssdescriptsize);
1585 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); 1493 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
1586 1494
1587 scanrespsize = le16_to_cpu(resp->size); 1495 scanrespsize = le16_to_cpu(resp->size);
1588 lbs_deb_scan("SCAN_RESP: scan results %d\n", pscan->nr_sets); 1496 lbs_deb_scan("SCAN_RESP: scan results %d\n", scanresp->nr_sets);
1589 1497
1590 pbssinfo = pscan->bssdesc_and_tlvbuffer; 1498 bssinfo = scanresp->bssdesc_and_tlvbuffer;
1591 1499
1592 /* The size of the TLV buffer is equal to the entire command response 1500 /* The size of the TLV buffer is equal to the entire command response
1593 * size (scanrespsize) minus the fixed fields (sizeof()'s), the 1501 * size (scanrespsize) minus the fixed fields (sizeof()'s), the
1594 * BSS Descriptions (bssdescriptsize as bytesLef) and the command 1502 * BSS Descriptions (bssdescriptsize as bytesLef) and the command
1595 * response header (S_DS_GEN) 1503 * response header (S_DS_GEN)
1596 */ 1504 */
1597 tlvbufsize = scanrespsize - (bytesleft + sizeof(pscan->bssdescriptsize) 1505 tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize)
1598 + sizeof(pscan->nr_sets) 1506 + sizeof(scanresp->nr_sets)
1599 + S_DS_GEN); 1507 + S_DS_GEN);
1600 1508
1601 /* 1509 /*
1602 * Process each scan response returned (pscan->nr_sets). Save 1510 * Process each scan response returned (scanresp->nr_sets). Save
1603 * the information in the newbssentry and then insert into the 1511 * the information in the newbssentry and then insert into the
1604 * driver scan table either as an update to an existing entry 1512 * driver scan table either as an update to an existing entry
1605 * or as an addition at the end of the table 1513 * or as an addition at the end of the table
1606 */ 1514 */
1607 for (idx = 0; idx < pscan->nr_sets && bytesleft; idx++) { 1515 for (idx = 0; idx < scanresp->nr_sets && bytesleft; idx++) {
1608 struct bss_descriptor new; 1516 struct bss_descriptor new;
1609 struct bss_descriptor * found = NULL; 1517 struct bss_descriptor *found = NULL;
1610 struct bss_descriptor * oldest = NULL; 1518 struct bss_descriptor *oldest = NULL;
1611 DECLARE_MAC_BUF(mac); 1519 DECLARE_MAC_BUF(mac);
1612 1520
1613 /* Process the data fields and IEs returned for this BSS */ 1521 /* Process the data fields and IEs returned for this BSS */
1614 memset(&new, 0, sizeof (struct bss_descriptor)); 1522 memset(&new, 0, sizeof (struct bss_descriptor));
1615 if (lbs_process_bss(&new, &pbssinfo, &bytesleft) != 0) { 1523 if (lbs_process_bss(&new, &bssinfo, &bytesleft) != 0) {
1616 /* error parsing the scan response, skipped */ 1524 /* error parsing the scan response, skipped */
1617 lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n"); 1525 lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n");
1618 continue; 1526 continue;
@@ -1647,8 +1555,7 @@ int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp)
1647 continue; 1555 continue;
1648 } 1556 }
1649 1557
1650 lbs_deb_scan("SCAN_RESP: BSSID %s\n", 1558 lbs_deb_scan("SCAN_RESP: BSSID %s\n", print_mac(mac, new.bssid));
1651 print_mac(mac, new.bssid));
1652 1559
1653 /* Copy the locally created newbssentry to the scan table */ 1560 /* Copy the locally created newbssentry to the scan table */
1654 memcpy(found, &new, offsetof(struct bss_descriptor, list)); 1561 memcpy(found, &new, offsetof(struct bss_descriptor, list));
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
index 319f70dde350..10d1196acf78 100644
--- a/drivers/net/wireless/libertas/scan.h
+++ b/drivers/net/wireless/libertas/scan.h
@@ -17,57 +17,16 @@
17 */ 17 */
18#define LBS_IOCTL_USER_SCAN_CHAN_MAX 50 18#define LBS_IOCTL_USER_SCAN_CHAN_MAX 50
19 19
20//! Infrastructure BSS scan type in lbs_scan_cmd_config 20//! Infrastructure BSS scan type in cmd_ds_802_11_scan
21#define LBS_SCAN_BSS_TYPE_BSS 1 21#define LBS_SCAN_BSS_TYPE_BSS 1
22 22
23//! Adhoc BSS scan type in lbs_scan_cmd_config 23//! Adhoc BSS scan type in cmd_ds_802_11_scan
24#define LBS_SCAN_BSS_TYPE_IBSS 2 24#define LBS_SCAN_BSS_TYPE_IBSS 2
25 25
26//! Adhoc or Infrastructure BSS scan type in lbs_scan_cmd_config, no filter 26//! Adhoc or Infrastructure BSS scan type in cmd_ds_802_11_scan, no filter
27#define LBS_SCAN_BSS_TYPE_ANY 3 27#define LBS_SCAN_BSS_TYPE_ANY 3
28 28
29/** 29/**
30 * @brief Structure used internally in the wlan driver to configure a scan.
31 *
32 * Sent to the command processing module to configure the firmware
33 * scan command prepared by lbs_cmd_80211_scan.
34 *
35 * @sa lbs_scan_networks
36 *
37 */
38struct lbs_scan_cmd_config {
39 /**
40 * @brief BSS type to be sent in the firmware command
41 *
42 * Field can be used to restrict the types of networks returned in the
43 * scan. valid settings are:
44 *
45 * - LBS_SCAN_BSS_TYPE_BSS (infrastructure)
46 * - LBS_SCAN_BSS_TYPE_IBSS (adhoc)
47 * - LBS_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure)
48 */
49 u8 bsstype;
50
51 /**
52 * @brief Specific BSSID used to filter scan results in the firmware
53 */
54 u8 bssid[ETH_ALEN];
55
56 /**
57 * @brief length of TLVs sent in command starting at tlvBuffer
58 */
59 int tlvbufferlen;
60
61 /**
62 * @brief SSID TLV(s) and ChanList TLVs to be sent in the firmware command
63 *
64 * @sa TLV_TYPE_CHANLIST, mrvlietypes_chanlistparamset_t
65 * @sa TLV_TYPE_SSID, mrvlietypes_ssidparamset_t
66 */
67 u8 tlvbuffer[1]; //!< SSID TLV(s) and ChanList TLVs are stored here
68};
69
70/**
71 * @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg 30 * @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg
72 * 31 *
73 * Multiple instances of this structure are included in the IOCTL command 32 * Multiple instances of this structure are included in the IOCTL command
@@ -179,13 +138,6 @@ int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid,
179int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, 138int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
180 u8 ssid_len, u8 clear_ssid); 139 u8 ssid_len, u8 clear_ssid);
181 140
182int lbs_cmd_80211_scan(struct lbs_private *priv,
183 struct cmd_ds_command *cmd,
184 void *pdata_buf);
185
186int lbs_ret_80211_scan(struct lbs_private *priv,
187 struct cmd_ds_command *resp);
188
189int lbs_scan_networks(struct lbs_private *priv, 141int lbs_scan_networks(struct lbs_private *priv,
190 const struct lbs_ioctl_user_scan_cfg *puserscanin, 142 const struct lbs_ioctl_user_scan_cfg *puserscanin,
191 int full_scan); 143 int full_scan);
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index f0d57958b34b..4031be420862 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -239,4 +239,17 @@ struct mrvlietypes_ledgpio {
239 struct led_pin ledpin[1]; 239 struct led_pin ledpin[1];
240} __attribute__ ((packed)); 240} __attribute__ ((packed));
241 241
242struct led_bhv {
243 uint8_t firmwarestate;
244 uint8_t led;
245 uint8_t ledstate;
246 uint8_t ledarg;
247} __attribute__ ((packed));
248
249
250struct mrvlietypes_ledbhv {
251 struct mrvlietypesheader header;
252 struct led_bhv ledbhv[1];
253} __attribute__ ((packed));
254
242#endif 255#endif
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index db96adf90ae2..0acb5c345734 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -809,6 +809,7 @@ static int hw_init_hmac(struct zd_chip *chip)
809 { CR_AFTER_PNP, 0x1 }, 809 { CR_AFTER_PNP, 0x1 },
810 { CR_WEP_PROTECT, 0x114 }, 810 { CR_WEP_PROTECT, 0x114 },
811 { CR_IFS_VALUE, IFS_VALUE_DEFAULT }, 811 { CR_IFS_VALUE, IFS_VALUE_DEFAULT },
812 { CR_CAM_MODE, MODE_AP_WDS},
812 }; 813 };
813 814
814 ZD_ASSERT(mutex_is_locked(&chip->mutex)); 815 ZD_ASSERT(mutex_is_locked(&chip->mutex));
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 5b6e3a3751ba..f8c061a9b6ec 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -489,6 +489,7 @@ enum {
489 489
490#define CR_RX_OFFSET CTL_REG(0x065c) 490#define CR_RX_OFFSET CTL_REG(0x065c)
491 491
492#define CR_BCN_LENGTH CTL_REG(0x0664)
492#define CR_PHY_DELAY CTL_REG(0x066C) 493#define CR_PHY_DELAY CTL_REG(0x066C)
493#define CR_BCN_FIFO CTL_REG(0x0670) 494#define CR_BCN_FIFO CTL_REG(0x0670)
494#define CR_SNIFFER_ON CTL_REG(0x0674) 495#define CR_SNIFFER_ON CTL_REG(0x0674)
@@ -545,6 +546,8 @@ enum {
545#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ 546#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \
546 RX_FILTER_CFEND | RX_FILTER_CFACK) 547 RX_FILTER_CFEND | RX_FILTER_CFACK)
547 548
549#define BCN_MODE_IBSS 0x2000000
550
548/* Monitor mode sets filter to 0xfffff */ 551/* Monitor mode sets filter to 0xfffff */
549 552
550#define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690) 553#define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690)
@@ -578,6 +581,11 @@ enum {
578 581
579/* CAM: Continuous Access Mode (power management) */ 582/* CAM: Continuous Access Mode (power management) */
580#define CR_CAM_MODE CTL_REG(0x0700) 583#define CR_CAM_MODE CTL_REG(0x0700)
584#define MODE_IBSS 0x0
585#define MODE_AP 0x1
586#define MODE_STA 0x2
587#define MODE_AP_WDS 0x3
588
581#define CR_CAM_ROLL_TB_LOW CTL_REG(0x0704) 589#define CR_CAM_ROLL_TB_LOW CTL_REG(0x0704)
582#define CR_CAM_ROLL_TB_HIGH CTL_REG(0x0708) 590#define CR_CAM_ROLL_TB_HIGH CTL_REG(0x0708)
583#define CR_CAM_ADDRESS CTL_REG(0x070C) 591#define CR_CAM_ADDRESS CTL_REG(0x070C)
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index f90f03f676de..69c45ca99051 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -475,6 +475,46 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
475 /* FIXME: Management frame? */ 475 /* FIXME: Management frame? */
476} 476}
477 477
478void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
479{
480 struct zd_mac *mac = zd_hw_mac(hw);
481 u32 tmp, j = 0;
482 /* 4 more bytes for tail CRC */
483 u32 full_len = beacon->len + 4;
484 zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
485 zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
486 while (tmp & 0x2) {
487 zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
488 if ((++j % 100) == 0) {
489 printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
490 if (j >= 500) {
491 printk(KERN_ERR "Giving up beacon config.\n");
492 return;
493 }
494 }
495 msleep(1);
496 }
497
498 zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
499 if (zd_chip_is_zd1211b(&mac->chip))
500 zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
501
502 for (j = 0 ; j < beacon->len; j++)
503 zd_iowrite32(&mac->chip, CR_BCN_FIFO,
504 *((u8 *)(beacon->data + j)));
505
506 for (j = 0; j < 4; j++)
507 zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
508
509 zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
510 /* 802.11b/g 2.4G CCK 1Mb
511 * 802.11a, not yet implemented, uses different values (see GPL vendor
512 * driver)
513 */
514 zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
515 (full_len << 19));
516}
517
478static int fill_ctrlset(struct zd_mac *mac, 518static int fill_ctrlset(struct zd_mac *mac,
479 struct sk_buff *skb, 519 struct sk_buff *skb,
480 struct ieee80211_tx_control *control) 520 struct ieee80211_tx_control *control)
@@ -709,6 +749,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
709 749
710 switch (conf->type) { 750 switch (conf->type) {
711 case IEEE80211_IF_TYPE_MNTR: 751 case IEEE80211_IF_TYPE_MNTR:
752 case IEEE80211_IF_TYPE_MESH_POINT:
712 case IEEE80211_IF_TYPE_STA: 753 case IEEE80211_IF_TYPE_STA:
713 mac->type = conf->type; 754 mac->type = conf->type;
714 break; 755 break;
@@ -738,15 +779,43 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
738 struct ieee80211_if_conf *conf) 779 struct ieee80211_if_conf *conf)
739{ 780{
740 struct zd_mac *mac = zd_hw_mac(hw); 781 struct zd_mac *mac = zd_hw_mac(hw);
782 int associated;
783
784 if (mac->type == IEEE80211_IF_TYPE_MESH_POINT) {
785 associated = true;
786 if (conf->beacon) {
787 zd_mac_config_beacon(hw, conf->beacon);
788 kfree_skb(conf->beacon);
789 zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
790 hw->conf.beacon_int);
791 }
792 } else
793 associated = is_valid_ether_addr(conf->bssid);
741 794
742 spin_lock_irq(&mac->lock); 795 spin_lock_irq(&mac->lock);
743 mac->associated = is_valid_ether_addr(conf->bssid); 796 mac->associated = associated;
744 spin_unlock_irq(&mac->lock); 797 spin_unlock_irq(&mac->lock);
745 798
746 /* TODO: do hardware bssid filtering */ 799 /* TODO: do hardware bssid filtering */
747 return 0; 800 return 0;
748} 801}
749 802
803void zd_process_intr(struct work_struct *work)
804{
805 u16 int_status;
806 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
807
808 int_status = le16_to_cpu(*(u16 *)(mac->intr_buffer+4));
809 if (int_status & INT_CFG_NEXT_BCN) {
810 if (net_ratelimit())
811 dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
812 } else
813 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
814
815 zd_chip_enable_hwint(&mac->chip);
816}
817
818
750static void set_multicast_hash_handler(struct work_struct *work) 819static void set_multicast_hash_handler(struct work_struct *work)
751{ 820{
752 struct zd_mac *mac = 821 struct zd_mac *mac =
@@ -912,7 +981,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
912 981
913 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; 982 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
914 983
915 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS; 984 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
985 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
916 hw->max_rssi = 100; 986 hw->max_rssi = 100;
917 hw->max_signal = 100; 987 hw->max_signal = 100;
918 988
@@ -926,6 +996,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
926 INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); 996 INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
927 INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); 997 INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
928 INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler); 998 INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
999 INIT_WORK(&mac->process_intr, zd_process_intr);
929 1000
930 SET_IEEE80211_DEV(hw, &intf->dev); 1001 SET_IEEE80211_DEV(hw, &intf->dev);
931 return hw; 1002 return hw;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 67dea9739c8f..71170244d2c9 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -172,12 +172,15 @@ struct zd_tx_skb_control_block {
172struct zd_mac { 172struct zd_mac {
173 struct zd_chip chip; 173 struct zd_chip chip;
174 spinlock_t lock; 174 spinlock_t lock;
175 spinlock_t intr_lock;
175 struct ieee80211_hw *hw; 176 struct ieee80211_hw *hw;
176 struct housekeeping housekeeping; 177 struct housekeeping housekeeping;
177 struct work_struct set_multicast_hash_work; 178 struct work_struct set_multicast_hash_work;
178 struct work_struct set_rts_cts_work; 179 struct work_struct set_rts_cts_work;
179 struct work_struct set_rx_filter_work; 180 struct work_struct set_rx_filter_work;
181 struct work_struct process_intr;
180 struct zd_mc_hash multicast_hash; 182 struct zd_mc_hash multicast_hash;
183 u8 intr_buffer[USB_MAX_EP_INT_BUFFER];
181 u8 regdomain; 184 u8 regdomain;
182 u8 default_regdomain; 185 u8 default_regdomain;
183 int type; 186 int type;
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 7942b15acfe7..e34675c2f8fc 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -97,6 +97,7 @@ MODULE_DEVICE_TABLE(usb, usb_ids);
97#define FW_ZD1211B_PREFIX "zd1211/zd1211b_" 97#define FW_ZD1211B_PREFIX "zd1211/zd1211b_"
98 98
99/* USB device initialization */ 99/* USB device initialization */
100static void int_urb_complete(struct urb *urb);
100 101
101static int request_fw_file( 102static int request_fw_file(
102 const struct firmware **fw, const char *name, struct device *device) 103 const struct firmware **fw, const char *name, struct device *device)
@@ -336,11 +337,18 @@ static inline void handle_regs_int(struct urb *urb)
336 struct zd_usb *usb = urb->context; 337 struct zd_usb *usb = urb->context;
337 struct zd_usb_interrupt *intr = &usb->intr; 338 struct zd_usb_interrupt *intr = &usb->intr;
338 int len; 339 int len;
340 u16 int_num;
339 341
340 ZD_ASSERT(in_interrupt()); 342 ZD_ASSERT(in_interrupt());
341 spin_lock(&intr->lock); 343 spin_lock(&intr->lock);
342 344
343 if (intr->read_regs_enabled) { 345 int_num = le16_to_cpu(*(u16 *)(urb->transfer_buffer+2));
346 if (int_num == CR_INTERRUPT) {
347 struct zd_mac *mac = zd_hw_mac(zd_usb_to_hw(urb->context));
348 memcpy(&mac->intr_buffer, urb->transfer_buffer,
349 USB_MAX_EP_INT_BUFFER);
350 schedule_work(&mac->process_intr);
351 } else if (intr->read_regs_enabled) {
344 intr->read_regs.length = len = urb->actual_length; 352 intr->read_regs.length = len = urb->actual_length;
345 353
346 if (len > sizeof(intr->read_regs.buffer)) 354 if (len > sizeof(intr->read_regs.buffer))
@@ -351,7 +359,6 @@ static inline void handle_regs_int(struct urb *urb)
351 goto out; 359 goto out;
352 } 360 }
353 361
354 dev_dbg_f(urb_dev(urb), "regs interrupt ignored\n");
355out: 362out:
356 spin_unlock(&intr->lock); 363 spin_unlock(&intr->lock);
357} 364}