diff options
Diffstat (limited to 'drivers/net')
163 files changed, 14157 insertions, 16038 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index e4f9f747de88..fe819a785714 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -151,6 +151,12 @@ config LIBERTAS_SDIO | |||
151 | ---help--- | 151 | ---help--- |
152 | A driver for Marvell Libertas 8385 and 8686 SDIO devices. | 152 | A driver for Marvell Libertas 8385 and 8686 SDIO devices. |
153 | 153 | ||
154 | config LIBERTAS_SPI | ||
155 | tristate "Marvell Libertas 8686 SPI 802.11b/g cards" | ||
156 | depends on LIBERTAS && SPI && GENERIC_GPIO | ||
157 | ---help--- | ||
158 | A driver for Marvell Libertas 8686 SPI devices. | ||
159 | |||
154 | config LIBERTAS_DEBUG | 160 | config LIBERTAS_DEBUG |
155 | bool "Enable full debugging output in the Libertas module." | 161 | bool "Enable full debugging output in the Libertas module." |
156 | depends on LIBERTAS | 162 | depends on LIBERTAS |
@@ -188,127 +194,6 @@ config AIRO | |||
188 | 194 | ||
189 | The driver can be compiled as a module and will be named "airo". | 195 | The driver can be compiled as a module and will be named "airo". |
190 | 196 | ||
191 | config HERMES | ||
192 | tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)" | ||
193 | depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211 | ||
194 | select WIRELESS_EXT | ||
195 | select FW_LOADER | ||
196 | select CRYPTO | ||
197 | select CRYPTO_MICHAEL_MIC | ||
198 | ---help--- | ||
199 | A driver for 802.11b wireless cards based on the "Hermes" or | ||
200 | Intersil HFA384x (Prism 2) MAC controller. This includes the vast | ||
201 | majority of the PCMCIA 802.11b cards (which are nearly all rebadges) | ||
202 | - except for the Cisco/Aironet cards. Cards supported include the | ||
203 | Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco, | ||
204 | Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya, | ||
205 | IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear | ||
206 | MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel | ||
207 | IPW2011, and Symbol Spectrum24 High Rate amongst others. | ||
208 | |||
209 | This option includes the guts of the driver, but in order to | ||
210 | actually use a card you will also need to enable support for PCMCIA | ||
211 | Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below. | ||
212 | |||
213 | You will also very likely also need the Wireless Tools in order to | ||
214 | configure your card and that /etc/pcmcia/wireless.opts works : | ||
215 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> | ||
216 | |||
217 | config HERMES_CACHE_FW_ON_INIT | ||
218 | bool "Cache Hermes firmware on driver initialisation" | ||
219 | depends on HERMES | ||
220 | default y | ||
221 | ---help--- | ||
222 | Say Y to cache any firmware required by the Hermes drivers | ||
223 | on startup. The firmware will remain cached until the | ||
224 | driver is unloaded. The cache uses 64K of RAM. | ||
225 | |||
226 | Otherwise load the firmware from userspace as required. In | ||
227 | this case the driver should be unloaded and restarted | ||
228 | whenever the firmware is changed. | ||
229 | |||
230 | If you are not sure, say Y. | ||
231 | |||
232 | config APPLE_AIRPORT | ||
233 | tristate "Apple Airport support (built-in)" | ||
234 | depends on PPC_PMAC && HERMES | ||
235 | help | ||
236 | Say Y here to support the Airport 802.11b wireless Ethernet hardware | ||
237 | built into the Macintosh iBook and other recent PowerPC-based | ||
238 | Macintosh machines. This is essentially a Lucent Orinoco card with | ||
239 | a non-standard interface. | ||
240 | |||
241 | This driver does not support the Airport Extreme (802.11b/g). Use | ||
242 | the BCM43xx driver for Airport Extreme cards. | ||
243 | |||
244 | config PLX_HERMES | ||
245 | tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)" | ||
246 | depends on PCI && HERMES | ||
247 | help | ||
248 | Enable support for PCMCIA cards supported by the "Hermes" (aka | ||
249 | orinoco) driver when used in PLX9052 based PCI adaptors. These | ||
250 | adaptors are not a full PCMCIA controller but act as a more limited | ||
251 | PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that | ||
252 | 802.11b PCMCIA cards can be used in desktop machines. The Netgear | ||
253 | MA301 is such an adaptor. | ||
254 | |||
255 | config TMD_HERMES | ||
256 | tristate "Hermes in TMD7160 based PCI adaptor support" | ||
257 | depends on PCI && HERMES | ||
258 | help | ||
259 | Enable support for PCMCIA cards supported by the "Hermes" (aka | ||
260 | orinoco) driver when used in TMD7160 based PCI adaptors. These | ||
261 | adaptors are not a full PCMCIA controller but act as a more limited | ||
262 | PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that | ||
263 | 802.11b PCMCIA cards can be used in desktop machines. | ||
264 | |||
265 | config NORTEL_HERMES | ||
266 | tristate "Nortel emobility PCI adaptor support" | ||
267 | depends on PCI && HERMES | ||
268 | help | ||
269 | Enable support for PCMCIA cards supported by the "Hermes" (aka | ||
270 | orinoco) driver when used in Nortel emobility PCI adaptors. These | ||
271 | adaptors are not full PCMCIA controllers, but act as a more limited | ||
272 | PCI <-> PCMCIA bridge. | ||
273 | |||
274 | config PCI_HERMES | ||
275 | tristate "Prism 2.5 PCI 802.11b adaptor support" | ||
276 | depends on PCI && HERMES | ||
277 | help | ||
278 | Enable support for PCI and mini-PCI 802.11b wireless NICs based on | ||
279 | the Prism 2.5 chipset. These are true PCI cards, not the 802.11b | ||
280 | PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also | ||
281 | common. Some of the built-in wireless adaptors in laptops are of | ||
282 | this variety. | ||
283 | |||
284 | config PCMCIA_HERMES | ||
285 | tristate "Hermes PCMCIA card support" | ||
286 | depends on PCMCIA && HERMES | ||
287 | ---help--- | ||
288 | A driver for "Hermes" chipset based PCMCIA wireless adaptors, such | ||
289 | as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/ | ||
290 | EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and | ||
291 | others). It should also be usable on various Prism II based cards | ||
292 | such as the Linksys, D-Link and Farallon Skyline. It should also | ||
293 | work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN. | ||
294 | |||
295 | You will very likely need the Wireless Tools in order to | ||
296 | configure your card and that /etc/pcmcia/wireless.opts works: | ||
297 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. | ||
298 | |||
299 | config PCMCIA_SPECTRUM | ||
300 | tristate "Symbol Spectrum24 Trilogy PCMCIA card support" | ||
301 | depends on PCMCIA && HERMES | ||
302 | ---help--- | ||
303 | |||
304 | This is a driver for 802.11b cards using RAM-loadable Symbol | ||
305 | firmware, such as Symbol Wireless Networker LA4100, CompactFlash | ||
306 | cards by Socket Communications and Intel PRO/Wireless 2011B. | ||
307 | |||
308 | This driver requires firmware download on startup. Utilities | ||
309 | for downloading Symbol firmware are available at | ||
310 | <http://sourceforge.net/projects/orinoco/> | ||
311 | |||
312 | config ATMEL | 197 | config ATMEL |
313 | tristate "Atmel at76c50x chipset 802.11b support" | 198 | tristate "Atmel at76c50x chipset 802.11b support" |
314 | depends on (PCI || PCMCIA) && WLAN_80211 | 199 | depends on (PCI || PCMCIA) && WLAN_80211 |
@@ -590,5 +475,6 @@ source "drivers/net/wireless/b43/Kconfig" | |||
590 | source "drivers/net/wireless/b43legacy/Kconfig" | 475 | source "drivers/net/wireless/b43legacy/Kconfig" |
591 | source "drivers/net/wireless/zd1211rw/Kconfig" | 476 | source "drivers/net/wireless/zd1211rw/Kconfig" |
592 | source "drivers/net/wireless/rt2x00/Kconfig" | 477 | source "drivers/net/wireless/rt2x00/Kconfig" |
478 | source "drivers/net/wireless/orinoco/Kconfig" | ||
593 | 479 | ||
594 | endmenu | 480 | endmenu |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index fc4322ca669f..acda45838e98 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -496,39 +496,41 @@ typedef struct { | |||
496 | * so all rid access should use the read/writeXXXRid routines. | 496 | * so all rid access should use the read/writeXXXRid routines. |
497 | */ | 497 | */ |
498 | 498 | ||
499 | /* This is redundant for x86 archs, but it seems necessary for ARM */ | ||
500 | #pragma pack(1) | ||
501 | |||
502 | /* This structure came from an email sent to me from an engineer at | 499 | /* This structure came from an email sent to me from an engineer at |
503 | aironet for inclusion into this driver */ | 500 | aironet for inclusion into this driver */ |
504 | typedef struct { | 501 | typedef struct WepKeyRid WepKeyRid; |
502 | struct WepKeyRid { | ||
505 | __le16 len; | 503 | __le16 len; |
506 | __le16 kindex; | 504 | __le16 kindex; |
507 | u8 mac[ETH_ALEN]; | 505 | u8 mac[ETH_ALEN]; |
508 | __le16 klen; | 506 | __le16 klen; |
509 | u8 key[16]; | 507 | u8 key[16]; |
510 | } WepKeyRid; | 508 | } __attribute__ ((packed)); |
511 | 509 | ||
512 | /* These structures are from the Aironet's PC4500 Developers Manual */ | 510 | /* These structures are from the Aironet's PC4500 Developers Manual */ |
513 | typedef struct { | 511 | typedef struct Ssid Ssid; |
512 | struct Ssid { | ||
514 | __le16 len; | 513 | __le16 len; |
515 | u8 ssid[32]; | 514 | u8 ssid[32]; |
516 | } Ssid; | 515 | } __attribute__ ((packed)); |
517 | 516 | ||
518 | typedef struct { | 517 | typedef struct SsidRid SsidRid; |
518 | struct SsidRid { | ||
519 | __le16 len; | 519 | __le16 len; |
520 | Ssid ssids[3]; | 520 | Ssid ssids[3]; |
521 | } SsidRid; | 521 | } __attribute__ ((packed)); |
522 | 522 | ||
523 | typedef struct { | 523 | typedef struct ModulationRid ModulationRid; |
524 | struct ModulationRid { | ||
524 | __le16 len; | 525 | __le16 len; |
525 | __le16 modulation; | 526 | __le16 modulation; |
526 | #define MOD_DEFAULT cpu_to_le16(0) | 527 | #define MOD_DEFAULT cpu_to_le16(0) |
527 | #define MOD_CCK cpu_to_le16(1) | 528 | #define MOD_CCK cpu_to_le16(1) |
528 | #define MOD_MOK cpu_to_le16(2) | 529 | #define MOD_MOK cpu_to_le16(2) |
529 | } ModulationRid; | 530 | } __attribute__ ((packed)); |
530 | 531 | ||
531 | typedef struct { | 532 | typedef struct ConfigRid ConfigRid; |
533 | struct ConfigRid { | ||
532 | __le16 len; /* sizeof(ConfigRid) */ | 534 | __le16 len; /* sizeof(ConfigRid) */ |
533 | __le16 opmode; /* operating mode */ | 535 | __le16 opmode; /* operating mode */ |
534 | #define MODE_STA_IBSS cpu_to_le16(0) | 536 | #define MODE_STA_IBSS cpu_to_le16(0) |
@@ -649,9 +651,10 @@ typedef struct { | |||
649 | #define MAGIC_STAY_IN_CAM (1<<10) | 651 | #define MAGIC_STAY_IN_CAM (1<<10) |
650 | u8 magicControl; | 652 | u8 magicControl; |
651 | __le16 autoWake; | 653 | __le16 autoWake; |
652 | } ConfigRid; | 654 | } __attribute__ ((packed)); |
653 | 655 | ||
654 | typedef struct { | 656 | typedef struct StatusRid StatusRid; |
657 | struct StatusRid { | ||
655 | __le16 len; | 658 | __le16 len; |
656 | u8 mac[ETH_ALEN]; | 659 | u8 mac[ETH_ALEN]; |
657 | __le16 mode; | 660 | __le16 mode; |
@@ -707,21 +710,23 @@ typedef struct { | |||
707 | #define STAT_LEAPFAILED 91 | 710 | #define STAT_LEAPFAILED 91 |
708 | #define STAT_LEAPTIMEDOUT 92 | 711 | #define STAT_LEAPTIMEDOUT 92 |
709 | #define STAT_LEAPCOMPLETE 93 | 712 | #define STAT_LEAPCOMPLETE 93 |
710 | } StatusRid; | 713 | } __attribute__ ((packed)); |
711 | 714 | ||
712 | typedef struct { | 715 | typedef struct StatsRid StatsRid; |
716 | struct StatsRid { | ||
713 | __le16 len; | 717 | __le16 len; |
714 | __le16 spacer; | 718 | __le16 spacer; |
715 | __le32 vals[100]; | 719 | __le32 vals[100]; |
716 | } StatsRid; | 720 | } __attribute__ ((packed)); |
717 | |||
718 | 721 | ||
719 | typedef struct { | 722 | typedef struct APListRid APListRid; |
723 | struct APListRid { | ||
720 | __le16 len; | 724 | __le16 len; |
721 | u8 ap[4][ETH_ALEN]; | 725 | u8 ap[4][ETH_ALEN]; |
722 | } APListRid; | 726 | } __attribute__ ((packed)); |
723 | 727 | ||
724 | typedef struct { | 728 | typedef struct CapabilityRid CapabilityRid; |
729 | struct CapabilityRid { | ||
725 | __le16 len; | 730 | __le16 len; |
726 | char oui[3]; | 731 | char oui[3]; |
727 | char zero; | 732 | char zero; |
@@ -748,17 +753,18 @@ typedef struct { | |||
748 | __le16 bootBlockVer; | 753 | __le16 bootBlockVer; |
749 | __le16 requiredHard; | 754 | __le16 requiredHard; |
750 | __le16 extSoftCap; | 755 | __le16 extSoftCap; |
751 | } CapabilityRid; | 756 | } __attribute__ ((packed)); |
752 | |||
753 | 757 | ||
754 | /* Only present on firmware >= 5.30.17 */ | 758 | /* Only present on firmware >= 5.30.17 */ |
755 | typedef struct { | 759 | typedef struct BSSListRidExtra BSSListRidExtra; |
760 | struct BSSListRidExtra { | ||
756 | __le16 unknown[4]; | 761 | __le16 unknown[4]; |
757 | u8 fixed[12]; /* WLAN management frame */ | 762 | u8 fixed[12]; /* WLAN management frame */ |
758 | u8 iep[624]; | 763 | u8 iep[624]; |
759 | } BSSListRidExtra; | 764 | } __attribute__ ((packed)); |
760 | 765 | ||
761 | typedef struct { | 766 | typedef struct BSSListRid BSSListRid; |
767 | struct BSSListRid { | ||
762 | __le16 len; | 768 | __le16 len; |
763 | __le16 index; /* First is 0 and 0xffff means end of list */ | 769 | __le16 index; /* First is 0 and 0xffff means end of list */ |
764 | #define RADIO_FH 1 /* Frequency hopping radio type */ | 770 | #define RADIO_FH 1 /* Frequency hopping radio type */ |
@@ -789,33 +795,37 @@ typedef struct { | |||
789 | 795 | ||
790 | /* Only present on firmware >= 5.30.17 */ | 796 | /* Only present on firmware >= 5.30.17 */ |
791 | BSSListRidExtra extra; | 797 | BSSListRidExtra extra; |
792 | } BSSListRid; | 798 | } __attribute__ ((packed)); |
793 | 799 | ||
794 | typedef struct { | 800 | typedef struct { |
795 | BSSListRid bss; | 801 | BSSListRid bss; |
796 | struct list_head list; | 802 | struct list_head list; |
797 | } BSSListElement; | 803 | } BSSListElement; |
798 | 804 | ||
799 | typedef struct { | 805 | typedef struct tdsRssiEntry tdsRssiEntry; |
806 | struct tdsRssiEntry { | ||
800 | u8 rssipct; | 807 | u8 rssipct; |
801 | u8 rssidBm; | 808 | u8 rssidBm; |
802 | } tdsRssiEntry; | 809 | } __attribute__ ((packed)); |
803 | 810 | ||
804 | typedef struct { | 811 | typedef struct tdsRssiRid tdsRssiRid; |
812 | struct tdsRssiRid { | ||
805 | u16 len; | 813 | u16 len; |
806 | tdsRssiEntry x[256]; | 814 | tdsRssiEntry x[256]; |
807 | } tdsRssiRid; | 815 | } __attribute__ ((packed)); |
808 | 816 | ||
809 | typedef struct { | 817 | typedef struct MICRid MICRid; |
810 | u16 len; | 818 | struct MICRid { |
811 | u16 state; | 819 | __le16 len; |
812 | u16 multicastValid; | 820 | __le16 state; |
821 | __le16 multicastValid; | ||
813 | u8 multicast[16]; | 822 | u8 multicast[16]; |
814 | u16 unicastValid; | 823 | __le16 unicastValid; |
815 | u8 unicast[16]; | 824 | u8 unicast[16]; |
816 | } MICRid; | 825 | } __attribute__ ((packed)); |
817 | 826 | ||
818 | typedef struct { | 827 | typedef struct MICBuffer MICBuffer; |
828 | struct MICBuffer { | ||
819 | __be16 typelen; | 829 | __be16 typelen; |
820 | 830 | ||
821 | union { | 831 | union { |
@@ -830,15 +840,13 @@ typedef struct { | |||
830 | } u; | 840 | } u; |
831 | __be32 mic; | 841 | __be32 mic; |
832 | __be32 seq; | 842 | __be32 seq; |
833 | } MICBuffer; | 843 | } __attribute__ ((packed)); |
834 | 844 | ||
835 | typedef struct { | 845 | typedef struct { |
836 | u8 da[ETH_ALEN]; | 846 | u8 da[ETH_ALEN]; |
837 | u8 sa[ETH_ALEN]; | 847 | u8 sa[ETH_ALEN]; |
838 | } etherHead; | 848 | } etherHead; |
839 | 849 | ||
840 | #pragma pack() | ||
841 | |||
842 | #define TXCTL_TXOK (1<<1) /* report if tx is ok */ | 850 | #define TXCTL_TXOK (1<<1) /* report if tx is ok */ |
843 | #define TXCTL_TXEX (1<<2) /* report if tx fails */ | 851 | #define TXCTL_TXEX (1<<2) /* report if tx fails */ |
844 | #define TXCTL_802_3 (0<<3) /* 802.3 packet */ | 852 | #define TXCTL_802_3 (0<<3) /* 802.3 packet */ |
@@ -981,6 +989,14 @@ typedef struct { | |||
981 | dma_addr_t host_addr; | 989 | dma_addr_t host_addr; |
982 | } TxFid; | 990 | } TxFid; |
983 | 991 | ||
992 | struct rx_hdr { | ||
993 | __le16 status, len; | ||
994 | u8 rssi[2]; | ||
995 | u8 rate; | ||
996 | u8 freq; | ||
997 | __le16 tmp[4]; | ||
998 | } __attribute__ ((packed)); | ||
999 | |||
984 | typedef struct { | 1000 | typedef struct { |
985 | unsigned int ctl: 15; | 1001 | unsigned int ctl: 15; |
986 | unsigned int rdy: 1; | 1002 | unsigned int rdy: 1; |
@@ -1070,10 +1086,6 @@ static WifiCtlHdr wifictlhdr8023 = { | |||
1070 | } | 1086 | } |
1071 | }; | 1087 | }; |
1072 | 1088 | ||
1073 | // Frequency list (map channels to frequencies) | ||
1074 | static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
1075 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; | ||
1076 | |||
1077 | // A few details needed for WEP (Wireless Equivalent Privacy) | 1089 | // A few details needed for WEP (Wireless Equivalent Privacy) |
1078 | #define MAX_KEY_SIZE 13 // 128 (?) bits | 1090 | #define MAX_KEY_SIZE 13 // 128 (?) bits |
1079 | #define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP | 1091 | #define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP |
@@ -1082,12 +1094,6 @@ typedef struct wep_key_t { | |||
1082 | u8 key[16]; /* 40-bit and 104-bit keys */ | 1094 | u8 key[16]; /* 40-bit and 104-bit keys */ |
1083 | } wep_key_t; | 1095 | } wep_key_t; |
1084 | 1096 | ||
1085 | /* Backward compatibility */ | ||
1086 | #ifndef IW_ENCODE_NOKEY | ||
1087 | #define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ | ||
1088 | #define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN) | ||
1089 | #endif /* IW_ENCODE_NOKEY */ | ||
1090 | |||
1091 | /* List of Wireless Handlers (new API) */ | 1097 | /* List of Wireless Handlers (new API) */ |
1092 | static const struct iw_handler_def airo_handler_def; | 1098 | static const struct iw_handler_def airo_handler_def; |
1093 | 1099 | ||
@@ -1229,6 +1235,9 @@ struct airo_info { | |||
1229 | #define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE | 1235 | #define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE |
1230 | char proc_name[IFNAMSIZ]; | 1236 | char proc_name[IFNAMSIZ]; |
1231 | 1237 | ||
1238 | int wep_capable; | ||
1239 | int max_wep_idx; | ||
1240 | |||
1232 | /* WPA-related stuff */ | 1241 | /* WPA-related stuff */ |
1233 | unsigned int bssListFirst; | 1242 | unsigned int bssListFirst; |
1234 | unsigned int bssListNext; | 1243 | unsigned int bssListNext; |
@@ -1287,6 +1296,29 @@ static void emmh32_update(emmh32_context *context, u8 *pOctets, int len); | |||
1287 | static void emmh32_final(emmh32_context *context, u8 digest[4]); | 1296 | static void emmh32_final(emmh32_context *context, u8 digest[4]); |
1288 | static int flashpchar(struct airo_info *ai,int byte,int dwelltime); | 1297 | static int flashpchar(struct airo_info *ai,int byte,int dwelltime); |
1289 | 1298 | ||
1299 | static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len, | ||
1300 | struct crypto_cipher *tfm) | ||
1301 | { | ||
1302 | /* If the current MIC context is valid and its key is the same as | ||
1303 | * the MIC register, there's nothing to do. | ||
1304 | */ | ||
1305 | if (cur->valid && (memcmp(cur->key, key, key_len) == 0)) | ||
1306 | return; | ||
1307 | |||
1308 | /* Age current mic Context */ | ||
1309 | memcpy(old, cur, sizeof(*cur)); | ||
1310 | |||
1311 | /* Initialize new context */ | ||
1312 | memcpy(cur->key, key, key_len); | ||
1313 | cur->window = 33; /* Window always points to the middle */ | ||
1314 | cur->rx = 0; /* Rx Sequence numbers */ | ||
1315 | cur->tx = 0; /* Tx sequence numbers */ | ||
1316 | cur->valid = 1; /* Key is now valid */ | ||
1317 | |||
1318 | /* Give key to mic seed */ | ||
1319 | emmh32_setseed(&cur->seed, key, key_len, tfm); | ||
1320 | } | ||
1321 | |||
1290 | /* micinit - Initialize mic seed */ | 1322 | /* micinit - Initialize mic seed */ |
1291 | 1323 | ||
1292 | static void micinit(struct airo_info *ai) | 1324 | static void micinit(struct airo_info *ai) |
@@ -1297,49 +1329,26 @@ static void micinit(struct airo_info *ai) | |||
1297 | PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); | 1329 | PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); |
1298 | up(&ai->sem); | 1330 | up(&ai->sem); |
1299 | 1331 | ||
1300 | ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0; | 1332 | ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0; |
1301 | 1333 | if (!ai->micstats.enabled) { | |
1302 | if (ai->micstats.enabled) { | 1334 | /* So next time we have a valid key and mic is enabled, we will |
1303 | /* Key must be valid and different */ | 1335 | * update the sequence number if the key is the same as before. |
1304 | if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid || | 1336 | */ |
1305 | (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast, | ||
1306 | sizeof(ai->mod[0].mCtx.key)) != 0))) { | ||
1307 | /* Age current mic Context */ | ||
1308 | memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx)); | ||
1309 | /* Initialize new context */ | ||
1310 | memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast)); | ||
1311 | ai->mod[0].mCtx.window = 33; //Window always points to the middle | ||
1312 | ai->mod[0].mCtx.rx = 0; //Rx Sequence numbers | ||
1313 | ai->mod[0].mCtx.tx = 0; //Tx sequence numbers | ||
1314 | ai->mod[0].mCtx.valid = 1; //Key is now valid | ||
1315 | |||
1316 | /* Give key to mic seed */ | ||
1317 | emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm); | ||
1318 | } | ||
1319 | |||
1320 | /* Key must be valid and different */ | ||
1321 | if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid || | ||
1322 | (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast, | ||
1323 | sizeof(ai->mod[0].uCtx.key)) != 0))) { | ||
1324 | /* Age current mic Context */ | ||
1325 | memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx)); | ||
1326 | /* Initialize new context */ | ||
1327 | memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast)); | ||
1328 | |||
1329 | ai->mod[0].uCtx.window = 33; //Window always points to the middle | ||
1330 | ai->mod[0].uCtx.rx = 0; //Rx Sequence numbers | ||
1331 | ai->mod[0].uCtx.tx = 0; //Tx sequence numbers | ||
1332 | ai->mod[0].uCtx.valid = 1; //Key is now valid | ||
1333 | |||
1334 | //Give key to mic seed | ||
1335 | emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm); | ||
1336 | } | ||
1337 | } else { | ||
1338 | /* So next time we have a valid key and mic is enabled, we will update | ||
1339 | * the sequence number if the key is the same as before. | ||
1340 | */ | ||
1341 | ai->mod[0].uCtx.valid = 0; | 1337 | ai->mod[0].uCtx.valid = 0; |
1342 | ai->mod[0].mCtx.valid = 0; | 1338 | ai->mod[0].mCtx.valid = 0; |
1339 | return; | ||
1340 | } | ||
1341 | |||
1342 | if (mic_rid.multicastValid) { | ||
1343 | age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx, | ||
1344 | mic_rid.multicast, sizeof(mic_rid.multicast), | ||
1345 | ai->tfm); | ||
1346 | } | ||
1347 | |||
1348 | if (mic_rid.unicastValid) { | ||
1349 | age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx, | ||
1350 | mic_rid.unicast, sizeof(mic_rid.unicast), | ||
1351 | ai->tfm); | ||
1343 | } | 1352 | } |
1344 | } | 1353 | } |
1345 | 1354 | ||
@@ -2730,28 +2739,6 @@ static void airo_networks_initialize(struct airo_info *ai) | |||
2730 | &ai->network_free_list); | 2739 | &ai->network_free_list); |
2731 | } | 2740 | } |
2732 | 2741 | ||
2733 | static int airo_test_wpa_capable(struct airo_info *ai) | ||
2734 | { | ||
2735 | int status; | ||
2736 | CapabilityRid cap_rid; | ||
2737 | |||
2738 | status = readCapabilityRid(ai, &cap_rid, 1); | ||
2739 | if (status != SUCCESS) return 0; | ||
2740 | |||
2741 | /* Only firmware versions 5.30.17 or better can do WPA */ | ||
2742 | if (le16_to_cpu(cap_rid.softVer) > 0x530 | ||
2743 | || (le16_to_cpu(cap_rid.softVer) == 0x530 | ||
2744 | && le16_to_cpu(cap_rid.softSubVer) >= 17)) { | ||
2745 | airo_print_info("", "WPA is supported."); | ||
2746 | return 1; | ||
2747 | } | ||
2748 | |||
2749 | /* No WPA support */ | ||
2750 | airo_print_info("", "WPA unsupported (only firmware versions 5.30.17" | ||
2751 | " and greater support WPA. Detected %s)", cap_rid.prodVer); | ||
2752 | return 0; | ||
2753 | } | ||
2754 | |||
2755 | static struct net_device *_init_airo_card( unsigned short irq, int port, | 2742 | static struct net_device *_init_airo_card( unsigned short irq, int port, |
2756 | int is_pcmcia, struct pci_dev *pci, | 2743 | int is_pcmcia, struct pci_dev *pci, |
2757 | struct device *dmdev ) | 2744 | struct device *dmdev ) |
@@ -2759,6 +2746,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2759 | struct net_device *dev; | 2746 | struct net_device *dev; |
2760 | struct airo_info *ai; | 2747 | struct airo_info *ai; |
2761 | int i, rc; | 2748 | int i, rc; |
2749 | CapabilityRid cap_rid; | ||
2762 | 2750 | ||
2763 | /* Create the network device object. */ | 2751 | /* Create the network device object. */ |
2764 | dev = alloc_netdev(sizeof(*ai), "", ether_setup); | 2752 | dev = alloc_netdev(sizeof(*ai), "", ether_setup); |
@@ -2828,7 +2816,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2828 | } | 2816 | } |
2829 | 2817 | ||
2830 | if (probe) { | 2818 | if (probe) { |
2831 | if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) { | 2819 | if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) { |
2832 | airo_print_err(dev->name, "MAC could not be enabled" ); | 2820 | airo_print_err(dev->name, "MAC could not be enabled" ); |
2833 | rc = -EIO; | 2821 | rc = -EIO; |
2834 | goto err_out_map; | 2822 | goto err_out_map; |
@@ -2838,28 +2826,50 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2838 | set_bit(FLAG_FLASHING, &ai->flags); | 2826 | set_bit(FLAG_FLASHING, &ai->flags); |
2839 | } | 2827 | } |
2840 | 2828 | ||
2829 | strcpy(dev->name, "eth%d"); | ||
2830 | rc = register_netdev(dev); | ||
2831 | if (rc) { | ||
2832 | airo_print_err(dev->name, "Couldn't register_netdev"); | ||
2833 | goto err_out_map; | ||
2834 | } | ||
2835 | ai->wifidev = init_wifidev(ai, dev); | ||
2836 | if (!ai->wifidev) | ||
2837 | goto err_out_reg; | ||
2838 | |||
2839 | rc = readCapabilityRid(ai, &cap_rid, 1); | ||
2840 | if (rc != SUCCESS) { | ||
2841 | rc = -EIO; | ||
2842 | goto err_out_wifi; | ||
2843 | } | ||
2844 | /* WEP capability discovery */ | ||
2845 | ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0; | ||
2846 | ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0; | ||
2847 | |||
2848 | airo_print_info(dev->name, "Firmware version %x.%x.%02x", | ||
2849 | ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF), | ||
2850 | (le16_to_cpu(cap_rid.softVer) & 0xFF), | ||
2851 | le16_to_cpu(cap_rid.softSubVer)); | ||
2852 | |||
2841 | /* Test for WPA support */ | 2853 | /* Test for WPA support */ |
2842 | if (airo_test_wpa_capable(ai)) { | 2854 | /* Only firmware versions 5.30.17 or better can do WPA */ |
2855 | if (le16_to_cpu(cap_rid.softVer) > 0x530 | ||
2856 | || (le16_to_cpu(cap_rid.softVer) == 0x530 | ||
2857 | && le16_to_cpu(cap_rid.softSubVer) >= 17)) { | ||
2858 | airo_print_info(ai->dev->name, "WPA supported."); | ||
2859 | |||
2843 | set_bit(FLAG_WPA_CAPABLE, &ai->flags); | 2860 | set_bit(FLAG_WPA_CAPABLE, &ai->flags); |
2844 | ai->bssListFirst = RID_WPA_BSSLISTFIRST; | 2861 | ai->bssListFirst = RID_WPA_BSSLISTFIRST; |
2845 | ai->bssListNext = RID_WPA_BSSLISTNEXT; | 2862 | ai->bssListNext = RID_WPA_BSSLISTNEXT; |
2846 | ai->bssListRidLen = sizeof(BSSListRid); | 2863 | ai->bssListRidLen = sizeof(BSSListRid); |
2847 | } else { | 2864 | } else { |
2865 | airo_print_info(ai->dev->name, "WPA unsupported with firmware " | ||
2866 | "versions older than 5.30.17."); | ||
2867 | |||
2848 | ai->bssListFirst = RID_BSSLISTFIRST; | 2868 | ai->bssListFirst = RID_BSSLISTFIRST; |
2849 | ai->bssListNext = RID_BSSLISTNEXT; | 2869 | ai->bssListNext = RID_BSSLISTNEXT; |
2850 | ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra); | 2870 | ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra); |
2851 | } | 2871 | } |
2852 | 2872 | ||
2853 | strcpy(dev->name, "eth%d"); | ||
2854 | rc = register_netdev(dev); | ||
2855 | if (rc) { | ||
2856 | airo_print_err(dev->name, "Couldn't register_netdev"); | ||
2857 | goto err_out_map; | ||
2858 | } | ||
2859 | ai->wifidev = init_wifidev(ai, dev); | ||
2860 | if (!ai->wifidev) | ||
2861 | goto err_out_reg; | ||
2862 | |||
2863 | set_bit(FLAG_REGISTERED,&ai->flags); | 2873 | set_bit(FLAG_REGISTERED,&ai->flags); |
2864 | airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr); | 2874 | airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr); |
2865 | 2875 | ||
@@ -3127,314 +3137,354 @@ static int header_len(__le16 ctl) | |||
3127 | return 24; | 3137 | return 24; |
3128 | } | 3138 | } |
3129 | 3139 | ||
3130 | static irqreturn_t airo_interrupt(int irq, void *dev_id) | 3140 | static void airo_handle_cisco_mic(struct airo_info *ai) |
3131 | { | 3141 | { |
3132 | struct net_device *dev = dev_id; | 3142 | if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) { |
3143 | set_bit(JOB_MIC, &ai->jobs); | ||
3144 | wake_up_interruptible(&ai->thr_wait); | ||
3145 | } | ||
3146 | } | ||
3147 | |||
3148 | /* Airo Status codes */ | ||
3149 | #define STAT_NOBEACON 0x8000 /* Loss of sync - missed beacons */ | ||
3150 | #define STAT_MAXRETRIES 0x8001 /* Loss of sync - max retries */ | ||
3151 | #define STAT_MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/ | ||
3152 | #define STAT_FORCELOSS 0x8003 /* Loss of sync - host request */ | ||
3153 | #define STAT_TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */ | ||
3154 | #define STAT_DEAUTH 0x8100 /* low byte is 802.11 reason code */ | ||
3155 | #define STAT_DISASSOC 0x8200 /* low byte is 802.11 reason code */ | ||
3156 | #define STAT_ASSOC_FAIL 0x8400 /* low byte is 802.11 reason code */ | ||
3157 | #define STAT_AUTH_FAIL 0x0300 /* low byte is 802.11 reason code */ | ||
3158 | #define STAT_ASSOC 0x0400 /* Associated */ | ||
3159 | #define STAT_REASSOC 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */ | ||
3160 | |||
3161 | static void airo_print_status(const char *devname, u16 status) | ||
3162 | { | ||
3163 | u8 reason = status & 0xFF; | ||
3164 | |||
3165 | switch (status) { | ||
3166 | case STAT_NOBEACON: | ||
3167 | airo_print_dbg(devname, "link lost (missed beacons)"); | ||
3168 | break; | ||
3169 | case STAT_MAXRETRIES: | ||
3170 | case STAT_MAXARL: | ||
3171 | airo_print_dbg(devname, "link lost (max retries)"); | ||
3172 | break; | ||
3173 | case STAT_FORCELOSS: | ||
3174 | airo_print_dbg(devname, "link lost (local choice)"); | ||
3175 | break; | ||
3176 | case STAT_TSFSYNC: | ||
3177 | airo_print_dbg(devname, "link lost (TSF sync lost)"); | ||
3178 | break; | ||
3179 | case STAT_DEAUTH: | ||
3180 | airo_print_dbg(devname, "deauthenticated (reason: %d)", reason); | ||
3181 | break; | ||
3182 | case STAT_DISASSOC: | ||
3183 | airo_print_dbg(devname, "disassociated (reason: %d)", reason); | ||
3184 | break; | ||
3185 | case STAT_ASSOC_FAIL: | ||
3186 | airo_print_dbg(devname, "association failed (reason: %d)", | ||
3187 | reason); | ||
3188 | break; | ||
3189 | case STAT_AUTH_FAIL: | ||
3190 | airo_print_dbg(devname, "authentication failed (reason: %d)", | ||
3191 | reason); | ||
3192 | break; | ||
3193 | default: | ||
3194 | break; | ||
3195 | } | ||
3196 | } | ||
3197 | |||
3198 | static void airo_handle_link(struct airo_info *ai) | ||
3199 | { | ||
3200 | union iwreq_data wrqu; | ||
3201 | int scan_forceloss = 0; | ||
3133 | u16 status; | 3202 | u16 status; |
3134 | u16 fid; | ||
3135 | struct airo_info *apriv = dev->ml_priv; | ||
3136 | u16 savedInterrupts = 0; | ||
3137 | int handled = 0; | ||
3138 | 3203 | ||
3139 | if (!netif_device_present(dev)) | 3204 | /* Get new status and acknowledge the link change */ |
3140 | return IRQ_NONE; | 3205 | status = le16_to_cpu(IN4500(ai, LINKSTAT)); |
3206 | OUT4500(ai, EVACK, EV_LINK); | ||
3141 | 3207 | ||
3142 | for (;;) { | 3208 | if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0)) |
3143 | status = IN4500( apriv, EVSTAT ); | 3209 | scan_forceloss = 1; |
3144 | if ( !(status & STATUS_INTS) || status == 0xffff ) break; | ||
3145 | 3210 | ||
3146 | handled = 1; | 3211 | airo_print_status(ai->dev->name, status); |
3147 | 3212 | ||
3148 | if ( status & EV_AWAKE ) { | 3213 | if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) { |
3149 | OUT4500( apriv, EVACK, EV_AWAKE ); | 3214 | if (auto_wep) |
3150 | OUT4500( apriv, EVACK, EV_AWAKE ); | 3215 | ai->expires = 0; |
3151 | } | 3216 | if (ai->list_bss_task) |
3217 | wake_up_process(ai->list_bss_task); | ||
3218 | set_bit(FLAG_UPDATE_UNI, &ai->flags); | ||
3219 | set_bit(FLAG_UPDATE_MULTI, &ai->flags); | ||
3152 | 3220 | ||
3153 | if (!savedInterrupts) { | 3221 | if (down_trylock(&ai->sem) != 0) { |
3154 | savedInterrupts = IN4500( apriv, EVINTEN ); | 3222 | set_bit(JOB_EVENT, &ai->jobs); |
3155 | OUT4500( apriv, EVINTEN, 0 ); | 3223 | wake_up_interruptible(&ai->thr_wait); |
3224 | } else | ||
3225 | airo_send_event(ai->dev); | ||
3226 | } else if (!scan_forceloss) { | ||
3227 | if (auto_wep && !ai->expires) { | ||
3228 | ai->expires = RUN_AT(3*HZ); | ||
3229 | wake_up_interruptible(&ai->thr_wait); | ||
3156 | } | 3230 | } |
3157 | 3231 | ||
3158 | if ( status & EV_MIC ) { | 3232 | /* Send event to user space */ |
3159 | OUT4500( apriv, EVACK, EV_MIC ); | 3233 | memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); |
3160 | if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { | 3234 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |
3161 | set_bit(JOB_MIC, &apriv->jobs); | 3235 | wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL); |
3162 | wake_up_interruptible(&apriv->thr_wait); | 3236 | } |
3163 | } | 3237 | } |
3164 | } | ||
3165 | if ( status & EV_LINK ) { | ||
3166 | union iwreq_data wrqu; | ||
3167 | int scan_forceloss = 0; | ||
3168 | /* The link status has changed, if you want to put a | ||
3169 | monitor hook in, do it here. (Remember that | ||
3170 | interrupts are still disabled!) | ||
3171 | */ | ||
3172 | u16 newStatus = IN4500(apriv, LINKSTAT); | ||
3173 | OUT4500( apriv, EVACK, EV_LINK); | ||
3174 | /* Here is what newStatus means: */ | ||
3175 | #define NOBEACON 0x8000 /* Loss of sync - missed beacons */ | ||
3176 | #define MAXRETRIES 0x8001 /* Loss of sync - max retries */ | ||
3177 | #define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/ | ||
3178 | #define FORCELOSS 0x8003 /* Loss of sync - host request */ | ||
3179 | #define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */ | ||
3180 | #define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */ | ||
3181 | #define DISASS 0x8200 /* Disassociation (low byte is reason code) */ | ||
3182 | #define ASSFAIL 0x8400 /* Association failure (low byte is reason | ||
3183 | code) */ | ||
3184 | #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason | ||
3185 | code) */ | ||
3186 | #define ASSOCIATED 0x0400 /* Associated */ | ||
3187 | #define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */ | ||
3188 | #define RC_RESERVED 0 /* Reserved return code */ | ||
3189 | #define RC_NOREASON 1 /* Unspecified reason */ | ||
3190 | #define RC_AUTHINV 2 /* Previous authentication invalid */ | ||
3191 | #define RC_DEAUTH 3 /* Deauthenticated because sending station is | ||
3192 | leaving */ | ||
3193 | #define RC_NOACT 4 /* Disassociated due to inactivity */ | ||
3194 | #define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle | ||
3195 | all currently associated stations */ | ||
3196 | #define RC_BADCLASS2 6 /* Class 2 frame received from | ||
3197 | non-Authenticated station */ | ||
3198 | #define RC_BADCLASS3 7 /* Class 3 frame received from | ||
3199 | non-Associated station */ | ||
3200 | #define RC_STATLEAVE 8 /* Disassociated because sending station is | ||
3201 | leaving BSS */ | ||
3202 | #define RC_NOAUTH 9 /* Station requesting (Re)Association is not | ||
3203 | Authenticated with the responding station */ | ||
3204 | if (newStatus == FORCELOSS && apriv->scan_timeout > 0) | ||
3205 | scan_forceloss = 1; | ||
3206 | if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) { | ||
3207 | if (auto_wep) | ||
3208 | apriv->expires = 0; | ||
3209 | if (apriv->list_bss_task) | ||
3210 | wake_up_process(apriv->list_bss_task); | ||
3211 | set_bit(FLAG_UPDATE_UNI, &apriv->flags); | ||
3212 | set_bit(FLAG_UPDATE_MULTI, &apriv->flags); | ||
3213 | |||
3214 | if (down_trylock(&apriv->sem) != 0) { | ||
3215 | set_bit(JOB_EVENT, &apriv->jobs); | ||
3216 | wake_up_interruptible(&apriv->thr_wait); | ||
3217 | } else | ||
3218 | airo_send_event(dev); | ||
3219 | } else if (!scan_forceloss) { | ||
3220 | if (auto_wep && !apriv->expires) { | ||
3221 | apriv->expires = RUN_AT(3*HZ); | ||
3222 | wake_up_interruptible(&apriv->thr_wait); | ||
3223 | } | ||
3224 | 3238 | ||
3225 | /* Send event to user space */ | 3239 | static void airo_handle_rx(struct airo_info *ai) |
3226 | memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); | 3240 | { |
3227 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 3241 | struct sk_buff *skb = NULL; |
3228 | wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL); | 3242 | __le16 fc, v, *buffer, tmpbuf[4]; |
3229 | } | 3243 | u16 len, hdrlen = 0, gap, fid; |
3230 | } | 3244 | struct rx_hdr hdr; |
3245 | int success = 0; | ||
3231 | 3246 | ||
3232 | /* Check to see if there is something to receive */ | 3247 | if (test_bit(FLAG_MPI, &ai->flags)) { |
3233 | if ( status & EV_RX ) { | 3248 | if (test_bit(FLAG_802_11, &ai->flags)) |
3234 | struct sk_buff *skb = NULL; | 3249 | mpi_receive_802_11(ai); |
3235 | __le16 fc, v; | 3250 | else |
3236 | u16 len, hdrlen = 0; | 3251 | mpi_receive_802_3(ai); |
3237 | #pragma pack(1) | 3252 | OUT4500(ai, EVACK, EV_RX); |
3238 | struct { | 3253 | return; |
3239 | __le16 status, len; | 3254 | } |
3240 | u8 rssi[2]; | ||
3241 | u8 rate; | ||
3242 | u8 freq; | ||
3243 | __le16 tmp[4]; | ||
3244 | } hdr; | ||
3245 | #pragma pack() | ||
3246 | u16 gap; | ||
3247 | __le16 tmpbuf[4]; | ||
3248 | __le16 *buffer; | ||
3249 | |||
3250 | if (test_bit(FLAG_MPI,&apriv->flags)) { | ||
3251 | if (test_bit(FLAG_802_11, &apriv->flags)) | ||
3252 | mpi_receive_802_11(apriv); | ||
3253 | else | ||
3254 | mpi_receive_802_3(apriv); | ||
3255 | OUT4500(apriv, EVACK, EV_RX); | ||
3256 | goto exitrx; | ||
3257 | } | ||
3258 | 3255 | ||
3259 | fid = IN4500( apriv, RXFID ); | 3256 | fid = IN4500(ai, RXFID); |
3260 | |||
3261 | /* Get the packet length */ | ||
3262 | if (test_bit(FLAG_802_11, &apriv->flags)) { | ||
3263 | bap_setup (apriv, fid, 4, BAP0); | ||
3264 | bap_read (apriv, (__le16*)&hdr, sizeof(hdr), BAP0); | ||
3265 | /* Bad CRC. Ignore packet */ | ||
3266 | if (le16_to_cpu(hdr.status) & 2) | ||
3267 | hdr.len = 0; | ||
3268 | if (apriv->wifidev == NULL) | ||
3269 | hdr.len = 0; | ||
3270 | } else { | ||
3271 | bap_setup (apriv, fid, 0x36, BAP0); | ||
3272 | bap_read (apriv, &hdr.len, 2, BAP0); | ||
3273 | } | ||
3274 | len = le16_to_cpu(hdr.len); | ||
3275 | 3257 | ||
3276 | if (len > AIRO_DEF_MTU) { | 3258 | /* Get the packet length */ |
3277 | airo_print_err(apriv->dev->name, "Bad size %d", len); | 3259 | if (test_bit(FLAG_802_11, &ai->flags)) { |
3278 | goto badrx; | 3260 | bap_setup (ai, fid, 4, BAP0); |
3279 | } | 3261 | bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0); |
3280 | if (len == 0) | 3262 | /* Bad CRC. Ignore packet */ |
3281 | goto badrx; | 3263 | if (le16_to_cpu(hdr.status) & 2) |
3264 | hdr.len = 0; | ||
3265 | if (ai->wifidev == NULL) | ||
3266 | hdr.len = 0; | ||
3267 | } else { | ||
3268 | bap_setup(ai, fid, 0x36, BAP0); | ||
3269 | bap_read(ai, &hdr.len, 2, BAP0); | ||
3270 | } | ||
3271 | len = le16_to_cpu(hdr.len); | ||
3282 | 3272 | ||
3283 | if (test_bit(FLAG_802_11, &apriv->flags)) { | 3273 | if (len > AIRO_DEF_MTU) { |
3284 | bap_read (apriv, &fc, sizeof(fc), BAP0); | 3274 | airo_print_err(ai->dev->name, "Bad size %d", len); |
3285 | hdrlen = header_len(fc); | 3275 | goto done; |
3286 | } else | 3276 | } |
3287 | hdrlen = ETH_ALEN * 2; | 3277 | if (len == 0) |
3278 | goto done; | ||
3288 | 3279 | ||
3289 | skb = dev_alloc_skb( len + hdrlen + 2 + 2 ); | 3280 | if (test_bit(FLAG_802_11, &ai->flags)) { |
3290 | if ( !skb ) { | 3281 | bap_read(ai, &fc, sizeof (fc), BAP0); |
3291 | dev->stats.rx_dropped++; | 3282 | hdrlen = header_len(fc); |
3292 | goto badrx; | 3283 | } else |
3293 | } | 3284 | hdrlen = ETH_ALEN * 2; |
3294 | skb_reserve(skb, 2); /* This way the IP header is aligned */ | 3285 | |
3295 | buffer = (__le16*)skb_put (skb, len + hdrlen); | 3286 | skb = dev_alloc_skb(len + hdrlen + 2 + 2); |
3296 | if (test_bit(FLAG_802_11, &apriv->flags)) { | 3287 | if (!skb) { |
3297 | buffer[0] = fc; | 3288 | ai->dev->stats.rx_dropped++; |
3298 | bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); | 3289 | goto done; |
3299 | if (hdrlen == 24) | 3290 | } |
3300 | bap_read (apriv, tmpbuf, 6, BAP0); | 3291 | |
3301 | 3292 | skb_reserve(skb, 2); /* This way the IP header is aligned */ | |
3302 | bap_read (apriv, &v, sizeof(v), BAP0); | 3293 | buffer = (__le16 *) skb_put(skb, len + hdrlen); |
3303 | gap = le16_to_cpu(v); | 3294 | if (test_bit(FLAG_802_11, &ai->flags)) { |
3304 | if (gap) { | 3295 | buffer[0] = fc; |
3305 | if (gap <= 8) { | 3296 | bap_read(ai, buffer + 1, hdrlen - 2, BAP0); |
3306 | bap_read (apriv, tmpbuf, gap, BAP0); | 3297 | if (hdrlen == 24) |
3307 | } else { | 3298 | bap_read(ai, tmpbuf, 6, BAP0); |
3308 | airo_print_err(apriv->dev->name, "gaplen too " | 3299 | |
3309 | "big. Problems will follow..."); | 3300 | bap_read(ai, &v, sizeof(v), BAP0); |
3310 | } | 3301 | gap = le16_to_cpu(v); |
3311 | } | 3302 | if (gap) { |
3312 | bap_read (apriv, buffer + hdrlen/2, len, BAP0); | 3303 | if (gap <= 8) { |
3304 | bap_read(ai, tmpbuf, gap, BAP0); | ||
3313 | } else { | 3305 | } else { |
3314 | MICBuffer micbuf; | 3306 | airo_print_err(ai->dev->name, "gaplen too " |
3315 | bap_read (apriv, buffer, ETH_ALEN*2, BAP0); | 3307 | "big. Problems will follow..."); |
3316 | if (apriv->micstats.enabled) { | 3308 | } |
3317 | bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0); | 3309 | } |
3318 | if (ntohs(micbuf.typelen) > 0x05DC) | 3310 | bap_read(ai, buffer + hdrlen/2, len, BAP0); |
3319 | bap_setup (apriv, fid, 0x44, BAP0); | 3311 | } else { |
3320 | else { | 3312 | MICBuffer micbuf; |
3321 | if (len <= sizeof(micbuf)) | 3313 | |
3322 | goto badmic; | 3314 | bap_read(ai, buffer, ETH_ALEN * 2, BAP0); |
3323 | 3315 | if (ai->micstats.enabled) { | |
3324 | len -= sizeof(micbuf); | 3316 | bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0); |
3325 | skb_trim (skb, len + hdrlen); | 3317 | if (ntohs(micbuf.typelen) > 0x05DC) |
3326 | } | 3318 | bap_setup(ai, fid, 0x44, BAP0); |
3327 | } | 3319 | else { |
3328 | bap_read(apriv,buffer+ETH_ALEN,len,BAP0); | 3320 | if (len <= sizeof (micbuf)) { |
3329 | if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) { | 3321 | dev_kfree_skb_irq(skb); |
3330 | badmic: | 3322 | goto done; |
3331 | dev_kfree_skb_irq (skb); | ||
3332 | badrx: | ||
3333 | OUT4500( apriv, EVACK, EV_RX); | ||
3334 | goto exitrx; | ||
3335 | } | 3323 | } |
3324 | |||
3325 | len -= sizeof(micbuf); | ||
3326 | skb_trim(skb, len + hdrlen); | ||
3336 | } | 3327 | } |
3328 | } | ||
3329 | |||
3330 | bap_read(ai, buffer + ETH_ALEN, len, BAP0); | ||
3331 | if (decapsulate(ai, &micbuf, (etherHead*) buffer, len)) | ||
3332 | dev_kfree_skb_irq (skb); | ||
3333 | else | ||
3334 | success = 1; | ||
3335 | } | ||
3336 | |||
3337 | #ifdef WIRELESS_SPY | 3337 | #ifdef WIRELESS_SPY |
3338 | if (apriv->spy_data.spy_number > 0) { | 3338 | if (success && (ai->spy_data.spy_number > 0)) { |
3339 | char *sa; | 3339 | char *sa; |
3340 | struct iw_quality wstats; | 3340 | struct iw_quality wstats; |
3341 | /* Prepare spy data : addr + qual */ | 3341 | |
3342 | if (!test_bit(FLAG_802_11, &apriv->flags)) { | 3342 | /* Prepare spy data : addr + qual */ |
3343 | sa = (char*)buffer + 6; | 3343 | if (!test_bit(FLAG_802_11, &ai->flags)) { |
3344 | bap_setup (apriv, fid, 8, BAP0); | 3344 | sa = (char *) buffer + 6; |
3345 | bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0); | 3345 | bap_setup(ai, fid, 8, BAP0); |
3346 | } else | 3346 | bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0); |
3347 | sa = (char*)buffer + 10; | 3347 | } else |
3348 | wstats.qual = hdr.rssi[0]; | 3348 | sa = (char *) buffer + 10; |
3349 | if (apriv->rssi) | 3349 | wstats.qual = hdr.rssi[0]; |
3350 | wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; | 3350 | if (ai->rssi) |
3351 | else | 3351 | wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm; |
3352 | wstats.level = (hdr.rssi[1] + 321) / 2; | 3352 | else |
3353 | wstats.noise = apriv->wstats.qual.noise; | 3353 | wstats.level = (hdr.rssi[1] + 321) / 2; |
3354 | wstats.updated = IW_QUAL_LEVEL_UPDATED | 3354 | wstats.noise = ai->wstats.qual.noise; |
3355 | | IW_QUAL_QUAL_UPDATED | 3355 | wstats.updated = IW_QUAL_LEVEL_UPDATED |
3356 | | IW_QUAL_DBM; | 3356 | | IW_QUAL_QUAL_UPDATED |
3357 | /* Update spy records */ | 3357 | | IW_QUAL_DBM; |
3358 | wireless_spy_update(dev, sa, &wstats); | 3358 | /* Update spy records */ |
3359 | } | 3359 | wireless_spy_update(ai->dev, sa, &wstats); |
3360 | } | ||
3360 | #endif /* WIRELESS_SPY */ | 3361 | #endif /* WIRELESS_SPY */ |
3361 | OUT4500( apriv, EVACK, EV_RX); | ||
3362 | 3362 | ||
3363 | if (test_bit(FLAG_802_11, &apriv->flags)) { | 3363 | done: |
3364 | skb_reset_mac_header(skb); | 3364 | OUT4500(ai, EVACK, EV_RX); |
3365 | skb->pkt_type = PACKET_OTHERHOST; | 3365 | |
3366 | skb->dev = apriv->wifidev; | 3366 | if (success) { |
3367 | skb->protocol = htons(ETH_P_802_2); | 3367 | if (test_bit(FLAG_802_11, &ai->flags)) { |
3368 | } else | 3368 | skb_reset_mac_header(skb); |
3369 | skb->protocol = eth_type_trans(skb,dev); | 3369 | skb->pkt_type = PACKET_OTHERHOST; |
3370 | skb->ip_summed = CHECKSUM_NONE; | 3370 | skb->dev = ai->wifidev; |
3371 | skb->protocol = htons(ETH_P_802_2); | ||
3372 | } else | ||
3373 | skb->protocol = eth_type_trans(skb, ai->dev); | ||
3374 | skb->ip_summed = CHECKSUM_NONE; | ||
3375 | |||
3376 | netif_rx(skb); | ||
3377 | } | ||
3378 | } | ||
3379 | |||
3380 | static void airo_handle_tx(struct airo_info *ai, u16 status) | ||
3381 | { | ||
3382 | int i, len = 0, index = -1; | ||
3383 | u16 fid; | ||
3371 | 3384 | ||
3372 | netif_rx( skb ); | 3385 | if (test_bit(FLAG_MPI, &ai->flags)) { |
3386 | unsigned long flags; | ||
3387 | |||
3388 | if (status & EV_TXEXC) | ||
3389 | get_tx_error(ai, -1); | ||
3390 | |||
3391 | spin_lock_irqsave(&ai->aux_lock, flags); | ||
3392 | if (!skb_queue_empty(&ai->txq)) { | ||
3393 | spin_unlock_irqrestore(&ai->aux_lock,flags); | ||
3394 | mpi_send_packet(ai->dev); | ||
3395 | } else { | ||
3396 | clear_bit(FLAG_PENDING_XMIT, &ai->flags); | ||
3397 | spin_unlock_irqrestore(&ai->aux_lock,flags); | ||
3398 | netif_wake_queue(ai->dev); | ||
3373 | } | 3399 | } |
3374 | exitrx: | 3400 | OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC)); |
3401 | return; | ||
3402 | } | ||
3375 | 3403 | ||
3376 | /* Check to see if a packet has been transmitted */ | 3404 | fid = IN4500(ai, TXCOMPLFID); |
3377 | if ( status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) { | ||
3378 | int i; | ||
3379 | int len = 0; | ||
3380 | int index = -1; | ||
3381 | |||
3382 | if (test_bit(FLAG_MPI,&apriv->flags)) { | ||
3383 | unsigned long flags; | ||
3384 | |||
3385 | if (status & EV_TXEXC) | ||
3386 | get_tx_error(apriv, -1); | ||
3387 | spin_lock_irqsave(&apriv->aux_lock, flags); | ||
3388 | if (!skb_queue_empty(&apriv->txq)) { | ||
3389 | spin_unlock_irqrestore(&apriv->aux_lock,flags); | ||
3390 | mpi_send_packet (dev); | ||
3391 | } else { | ||
3392 | clear_bit(FLAG_PENDING_XMIT, &apriv->flags); | ||
3393 | spin_unlock_irqrestore(&apriv->aux_lock,flags); | ||
3394 | netif_wake_queue (dev); | ||
3395 | } | ||
3396 | OUT4500( apriv, EVACK, | ||
3397 | status & (EV_TX|EV_TXCPY|EV_TXEXC)); | ||
3398 | goto exittx; | ||
3399 | } | ||
3400 | 3405 | ||
3401 | fid = IN4500(apriv, TXCOMPLFID); | 3406 | for(i = 0; i < MAX_FIDS; i++) { |
3407 | if ((ai->fids[i] & 0xffff) == fid) { | ||
3408 | len = ai->fids[i] >> 16; | ||
3409 | index = i; | ||
3410 | } | ||
3411 | } | ||
3402 | 3412 | ||
3403 | for( i = 0; i < MAX_FIDS; i++ ) { | 3413 | if (index != -1) { |
3404 | if ( ( apriv->fids[i] & 0xffff ) == fid ) { | 3414 | if (status & EV_TXEXC) |
3405 | len = apriv->fids[i] >> 16; | 3415 | get_tx_error(ai, index); |
3406 | index = i; | 3416 | |
3407 | } | 3417 | OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC)); |
3408 | } | 3418 | |
3409 | if (index != -1) { | 3419 | /* Set up to be used again */ |
3410 | if (status & EV_TXEXC) | 3420 | ai->fids[index] &= 0xffff; |
3411 | get_tx_error(apriv, index); | 3421 | if (index < MAX_FIDS / 2) { |
3412 | OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC)); | 3422 | if (!test_bit(FLAG_PENDING_XMIT, &ai->flags)) |
3413 | /* Set up to be used again */ | 3423 | netif_wake_queue(ai->dev); |
3414 | apriv->fids[index] &= 0xffff; | 3424 | } else { |
3415 | if (index < MAX_FIDS / 2) { | 3425 | if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags)) |
3416 | if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags)) | 3426 | netif_wake_queue(ai->wifidev); |
3417 | netif_wake_queue(dev); | 3427 | } |
3418 | } else { | 3428 | } else { |
3419 | if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags)) | 3429 | OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC)); |
3420 | netif_wake_queue(apriv->wifidev); | 3430 | airo_print_err(ai->dev->name, "Unallocated FID was used to xmit"); |
3421 | } | 3431 | } |
3422 | } else { | 3432 | } |
3423 | OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC)); | 3433 | |
3424 | airo_print_err(apriv->dev->name, "Unallocated FID was " | 3434 | static irqreturn_t airo_interrupt(int irq, void *dev_id) |
3425 | "used to xmit" ); | 3435 | { |
3426 | } | 3436 | struct net_device *dev = dev_id; |
3437 | u16 status, savedInterrupts = 0; | ||
3438 | struct airo_info *ai = dev->ml_priv; | ||
3439 | int handled = 0; | ||
3440 | |||
3441 | if (!netif_device_present(dev)) | ||
3442 | return IRQ_NONE; | ||
3443 | |||
3444 | for (;;) { | ||
3445 | status = IN4500(ai, EVSTAT); | ||
3446 | if (!(status & STATUS_INTS) || (status == 0xffff)) | ||
3447 | break; | ||
3448 | |||
3449 | handled = 1; | ||
3450 | |||
3451 | if (status & EV_AWAKE) { | ||
3452 | OUT4500(ai, EVACK, EV_AWAKE); | ||
3453 | OUT4500(ai, EVACK, EV_AWAKE); | ||
3454 | } | ||
3455 | |||
3456 | if (!savedInterrupts) { | ||
3457 | savedInterrupts = IN4500(ai, EVINTEN); | ||
3458 | OUT4500(ai, EVINTEN, 0); | ||
3459 | } | ||
3460 | |||
3461 | if (status & EV_MIC) { | ||
3462 | OUT4500(ai, EVACK, EV_MIC); | ||
3463 | airo_handle_cisco_mic(ai); | ||
3427 | } | 3464 | } |
3428 | exittx: | 3465 | |
3429 | if ( status & ~STATUS_INTS & ~IGNORE_INTS ) | 3466 | if (status & EV_LINK) { |
3430 | airo_print_warn(apriv->dev->name, "Got weird status %x", | 3467 | /* Link status changed */ |
3468 | airo_handle_link(ai); | ||
3469 | } | ||
3470 | |||
3471 | /* Check to see if there is something to receive */ | ||
3472 | if (status & EV_RX) | ||
3473 | airo_handle_rx(ai); | ||
3474 | |||
3475 | /* Check to see if a packet has been transmitted */ | ||
3476 | if (status & (EV_TX | EV_TXCPY | EV_TXEXC)) | ||
3477 | airo_handle_tx(ai, status); | ||
3478 | |||
3479 | if ( status & ~STATUS_INTS & ~IGNORE_INTS ) { | ||
3480 | airo_print_warn(ai->dev->name, "Got weird status %x", | ||
3431 | status & ~STATUS_INTS & ~IGNORE_INTS ); | 3481 | status & ~STATUS_INTS & ~IGNORE_INTS ); |
3482 | } | ||
3432 | } | 3483 | } |
3433 | 3484 | ||
3434 | if (savedInterrupts) | 3485 | if (savedInterrupts) |
3435 | OUT4500( apriv, EVINTEN, savedInterrupts ); | 3486 | OUT4500(ai, EVINTEN, savedInterrupts); |
3436 | 3487 | ||
3437 | /* done.. */ | ||
3438 | return IRQ_RETVAL(handled); | 3488 | return IRQ_RETVAL(handled); |
3439 | } | 3489 | } |
3440 | 3490 | ||
@@ -3613,18 +3663,10 @@ static void mpi_receive_802_11(struct airo_info *ai) | |||
3613 | struct sk_buff *skb = NULL; | 3663 | struct sk_buff *skb = NULL; |
3614 | u16 len, hdrlen = 0; | 3664 | u16 len, hdrlen = 0; |
3615 | __le16 fc; | 3665 | __le16 fc; |
3616 | #pragma pack(1) | 3666 | struct rx_hdr hdr; |
3617 | struct { | ||
3618 | __le16 status, len; | ||
3619 | u8 rssi[2]; | ||
3620 | u8 rate; | ||
3621 | u8 freq; | ||
3622 | __le16 tmp[4]; | ||
3623 | } hdr; | ||
3624 | #pragma pack() | ||
3625 | u16 gap; | 3667 | u16 gap; |
3626 | u16 *buffer; | 3668 | u16 *buffer; |
3627 | char *ptr = ai->rxfids[0].virtual_host_addr+4; | 3669 | char *ptr = ai->rxfids[0].virtual_host_addr + 4; |
3628 | 3670 | ||
3629 | memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd)); | 3671 | memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd)); |
3630 | memcpy ((char *)&hdr, ptr, sizeof(hdr)); | 3672 | memcpy ((char *)&hdr, ptr, sizeof(hdr)); |
@@ -3691,6 +3733,7 @@ static void mpi_receive_802_11(struct airo_info *ai) | |||
3691 | skb->protocol = htons(ETH_P_802_2); | 3733 | skb->protocol = htons(ETH_P_802_2); |
3692 | skb->ip_summed = CHECKSUM_NONE; | 3734 | skb->ip_summed = CHECKSUM_NONE; |
3693 | netif_rx( skb ); | 3735 | netif_rx( skb ); |
3736 | |||
3694 | badrx: | 3737 | badrx: |
3695 | if (rxd.valid == 0) { | 3738 | if (rxd.valid == 0) { |
3696 | rxd.valid = 1; | 3739 | rxd.valid = 1; |
@@ -5131,55 +5174,98 @@ static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data, | |||
5131 | return rc; | 5174 | return rc; |
5132 | } | 5175 | } |
5133 | 5176 | ||
5134 | /* Returns the length of the key at the index. If index == 0xffff | 5177 | /* Returns the WEP key at the specified index, or -1 if that key does |
5135 | * the index of the transmit key is returned. If the key doesn't exist, | 5178 | * not exist. The buffer is assumed to be at least 16 bytes in length. |
5136 | * -1 will be returned. | ||
5137 | */ | 5179 | */ |
5138 | static int get_wep_key(struct airo_info *ai, u16 index) { | 5180 | static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen) |
5181 | { | ||
5139 | WepKeyRid wkr; | 5182 | WepKeyRid wkr; |
5140 | int rc; | 5183 | int rc; |
5141 | __le16 lastindex; | 5184 | __le16 lastindex; |
5142 | 5185 | ||
5143 | rc = readWepKeyRid(ai, &wkr, 1, 1); | 5186 | rc = readWepKeyRid(ai, &wkr, 1, 1); |
5144 | if (rc == SUCCESS) do { | 5187 | if (rc != SUCCESS) |
5188 | return -1; | ||
5189 | do { | ||
5145 | lastindex = wkr.kindex; | 5190 | lastindex = wkr.kindex; |
5146 | if (wkr.kindex == cpu_to_le16(index)) { | 5191 | if (le16_to_cpu(wkr.kindex) == index) { |
5147 | if (index == 0xffff) { | 5192 | int klen = min_t(int, buflen, le16_to_cpu(wkr.klen)); |
5148 | return wkr.mac[0]; | 5193 | memcpy(buf, wkr.key, klen); |
5149 | } | 5194 | return klen; |
5150 | return le16_to_cpu(wkr.klen); | ||
5151 | } | 5195 | } |
5152 | readWepKeyRid(ai, &wkr, 0, 1); | 5196 | rc = readWepKeyRid(ai, &wkr, 0, 1); |
5197 | if (rc != SUCCESS) | ||
5198 | return -1; | ||
5153 | } while (lastindex != wkr.kindex); | 5199 | } while (lastindex != wkr.kindex); |
5154 | return -1; | 5200 | return -1; |
5155 | } | 5201 | } |
5156 | 5202 | ||
5157 | static int set_wep_key(struct airo_info *ai, u16 index, | 5203 | static int get_wep_tx_idx(struct airo_info *ai) |
5158 | const char *key, u16 keylen, int perm, int lock ) | 5204 | { |
5205 | WepKeyRid wkr; | ||
5206 | int rc; | ||
5207 | __le16 lastindex; | ||
5208 | |||
5209 | rc = readWepKeyRid(ai, &wkr, 1, 1); | ||
5210 | if (rc != SUCCESS) | ||
5211 | return -1; | ||
5212 | do { | ||
5213 | lastindex = wkr.kindex; | ||
5214 | if (wkr.kindex == cpu_to_le16(0xffff)) | ||
5215 | return wkr.mac[0]; | ||
5216 | rc = readWepKeyRid(ai, &wkr, 0, 1); | ||
5217 | if (rc != SUCCESS) | ||
5218 | return -1; | ||
5219 | } while (lastindex != wkr.kindex); | ||
5220 | return -1; | ||
5221 | } | ||
5222 | |||
5223 | static int set_wep_key(struct airo_info *ai, u16 index, const char *key, | ||
5224 | u16 keylen, int perm, int lock) | ||
5159 | { | 5225 | { |
5160 | static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; | 5226 | static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; |
5161 | WepKeyRid wkr; | 5227 | WepKeyRid wkr; |
5228 | int rc; | ||
5162 | 5229 | ||
5163 | memset(&wkr, 0, sizeof(wkr)); | ||
5164 | if (keylen == 0) { | 5230 | if (keylen == 0) { |
5165 | // We are selecting which key to use | 5231 | airo_print_err(ai->dev->name, "%s: key length to set was zero", |
5166 | wkr.len = cpu_to_le16(sizeof(wkr)); | 5232 | __func__); |
5167 | wkr.kindex = cpu_to_le16(0xffff); | 5233 | return -1; |
5168 | wkr.mac[0] = (char)index; | ||
5169 | if (perm) ai->defindex = (char)index; | ||
5170 | } else { | ||
5171 | // We are actually setting the key | ||
5172 | wkr.len = cpu_to_le16(sizeof(wkr)); | ||
5173 | wkr.kindex = cpu_to_le16(index); | ||
5174 | wkr.klen = cpu_to_le16(keylen); | ||
5175 | memcpy( wkr.key, key, keylen ); | ||
5176 | memcpy( wkr.mac, macaddr, ETH_ALEN ); | ||
5177 | } | 5234 | } |
5178 | 5235 | ||
5236 | memset(&wkr, 0, sizeof(wkr)); | ||
5237 | wkr.len = cpu_to_le16(sizeof(wkr)); | ||
5238 | wkr.kindex = cpu_to_le16(index); | ||
5239 | wkr.klen = cpu_to_le16(keylen); | ||
5240 | memcpy(wkr.key, key, keylen); | ||
5241 | memcpy(wkr.mac, macaddr, ETH_ALEN); | ||
5242 | |||
5179 | if (perm) disable_MAC(ai, lock); | 5243 | if (perm) disable_MAC(ai, lock); |
5180 | writeWepKeyRid(ai, &wkr, perm, lock); | 5244 | rc = writeWepKeyRid(ai, &wkr, perm, lock); |
5181 | if (perm) enable_MAC(ai, lock); | 5245 | if (perm) enable_MAC(ai, lock); |
5182 | return 0; | 5246 | return rc; |
5247 | } | ||
5248 | |||
5249 | static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock) | ||
5250 | { | ||
5251 | WepKeyRid wkr; | ||
5252 | int rc; | ||
5253 | |||
5254 | memset(&wkr, 0, sizeof(wkr)); | ||
5255 | wkr.len = cpu_to_le16(sizeof(wkr)); | ||
5256 | wkr.kindex = cpu_to_le16(0xffff); | ||
5257 | wkr.mac[0] = (char)index; | ||
5258 | |||
5259 | if (perm) { | ||
5260 | ai->defindex = (char)index; | ||
5261 | disable_MAC(ai, lock); | ||
5262 | } | ||
5263 | |||
5264 | rc = writeWepKeyRid(ai, &wkr, perm, lock); | ||
5265 | |||
5266 | if (perm) | ||
5267 | enable_MAC(ai, lock); | ||
5268 | return rc; | ||
5183 | } | 5269 | } |
5184 | 5270 | ||
5185 | static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { | 5271 | static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { |
@@ -5187,7 +5273,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { | |||
5187 | struct proc_dir_entry *dp = PDE(inode); | 5273 | struct proc_dir_entry *dp = PDE(inode); |
5188 | struct net_device *dev = dp->data; | 5274 | struct net_device *dev = dp->data; |
5189 | struct airo_info *ai = dev->ml_priv; | 5275 | struct airo_info *ai = dev->ml_priv; |
5190 | int i; | 5276 | int i, rc; |
5191 | char key[16]; | 5277 | char key[16]; |
5192 | u16 index = 0; | 5278 | u16 index = 0; |
5193 | int j = 0; | 5279 | int j = 0; |
@@ -5201,7 +5287,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { | |||
5201 | (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) { | 5287 | (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) { |
5202 | index = data->wbuffer[0] - '0'; | 5288 | index = data->wbuffer[0] - '0'; |
5203 | if (data->wbuffer[1] == '\n') { | 5289 | if (data->wbuffer[1] == '\n') { |
5204 | set_wep_key(ai, index, NULL, 0, 1, 1); | 5290 | rc = set_wep_tx_idx(ai, index, 1, 1); |
5291 | if (rc < 0) { | ||
5292 | airo_print_err(ai->dev->name, "failed to set " | ||
5293 | "WEP transmit index to %d: %d.", | ||
5294 | index, rc); | ||
5295 | } | ||
5205 | return; | 5296 | return; |
5206 | } | 5297 | } |
5207 | j = 2; | 5298 | j = 2; |
@@ -5220,7 +5311,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) { | |||
5220 | break; | 5311 | break; |
5221 | } | 5312 | } |
5222 | } | 5313 | } |
5223 | set_wep_key(ai, index, key, i/3, 1, 1); | 5314 | |
5315 | rc = set_wep_key(ai, index, key, i/3, 1, 1); | ||
5316 | if (rc < 0) { | ||
5317 | airo_print_err(ai->dev->name, "failed to set WEP key at index " | ||
5318 | "%d: %d.", index, rc); | ||
5319 | } | ||
5224 | } | 5320 | } |
5225 | 5321 | ||
5226 | static int proc_wepkey_open( struct inode *inode, struct file *file ) | 5322 | static int proc_wepkey_open( struct inode *inode, struct file *file ) |
@@ -5451,13 +5547,13 @@ static void timer_func( struct net_device *dev ) { | |||
5451 | break; | 5547 | break; |
5452 | case AUTH_SHAREDKEY: | 5548 | case AUTH_SHAREDKEY: |
5453 | if (apriv->keyindex < auto_wep) { | 5549 | if (apriv->keyindex < auto_wep) { |
5454 | set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0); | 5550 | set_wep_tx_idx(apriv, apriv->keyindex, 0, 0); |
5455 | apriv->config.authType = AUTH_SHAREDKEY; | 5551 | apriv->config.authType = AUTH_SHAREDKEY; |
5456 | apriv->keyindex++; | 5552 | apriv->keyindex++; |
5457 | } else { | 5553 | } else { |
5458 | /* Drop to ENCRYPT */ | 5554 | /* Drop to ENCRYPT */ |
5459 | apriv->keyindex = 0; | 5555 | apriv->keyindex = 0; |
5460 | set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0); | 5556 | set_wep_tx_idx(apriv, apriv->defindex, 0, 0); |
5461 | apriv->config.authType = AUTH_ENCRYPT; | 5557 | apriv->config.authType = AUTH_ENCRYPT; |
5462 | } | 5558 | } |
5463 | break; | 5559 | break; |
@@ -5725,16 +5821,12 @@ static int airo_set_freq(struct net_device *dev, | |||
5725 | int rc = -EINPROGRESS; /* Call commit handler */ | 5821 | int rc = -EINPROGRESS; /* Call commit handler */ |
5726 | 5822 | ||
5727 | /* If setting by frequency, convert to a channel */ | 5823 | /* If setting by frequency, convert to a channel */ |
5728 | if((fwrq->e == 1) && | 5824 | if(fwrq->e == 1) { |
5729 | (fwrq->m >= (int) 2.412e8) && | ||
5730 | (fwrq->m <= (int) 2.487e8)) { | ||
5731 | int f = fwrq->m / 100000; | 5825 | int f = fwrq->m / 100000; |
5732 | int c = 0; | 5826 | |
5733 | while((c < 14) && (f != frequency_list[c])) | ||
5734 | c++; | ||
5735 | /* Hack to fall through... */ | 5827 | /* Hack to fall through... */ |
5736 | fwrq->e = 0; | 5828 | fwrq->e = 0; |
5737 | fwrq->m = c + 1; | 5829 | fwrq->m = ieee80211_freq_to_dsss_chan(f); |
5738 | } | 5830 | } |
5739 | /* Setting by channel number */ | 5831 | /* Setting by channel number */ |
5740 | if((fwrq->m > 1000) || (fwrq->e > 0)) | 5832 | if((fwrq->m > 1000) || (fwrq->e > 0)) |
@@ -5778,7 +5870,7 @@ static int airo_get_freq(struct net_device *dev, | |||
5778 | 5870 | ||
5779 | ch = le16_to_cpu(status_rid.channel); | 5871 | ch = le16_to_cpu(status_rid.channel); |
5780 | if((ch > 0) && (ch < 15)) { | 5872 | if((ch > 0) && (ch < 15)) { |
5781 | fwrq->m = frequency_list[ch - 1] * 100000; | 5873 | fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000; |
5782 | fwrq->e = 1; | 5874 | fwrq->e = 1; |
5783 | } else { | 5875 | } else { |
5784 | fwrq->m = ch; | 5876 | fwrq->m = ch; |
@@ -6234,11 +6326,9 @@ static int airo_get_mode(struct net_device *dev, | |||
6234 | return 0; | 6326 | return 0; |
6235 | } | 6327 | } |
6236 | 6328 | ||
6237 | static inline int valid_index(CapabilityRid *p, int index) | 6329 | static inline int valid_index(struct airo_info *ai, int index) |
6238 | { | 6330 | { |
6239 | if (index < 0) | 6331 | return (index >= 0) && (index <= ai->max_wep_idx); |
6240 | return 0; | ||
6241 | return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1); | ||
6242 | } | 6332 | } |
6243 | 6333 | ||
6244 | /*------------------------------------------------------------------*/ | 6334 | /*------------------------------------------------------------------*/ |
@@ -6251,16 +6341,13 @@ static int airo_set_encode(struct net_device *dev, | |||
6251 | char *extra) | 6341 | char *extra) |
6252 | { | 6342 | { |
6253 | struct airo_info *local = dev->ml_priv; | 6343 | struct airo_info *local = dev->ml_priv; |
6254 | CapabilityRid cap_rid; /* Card capability info */ | 6344 | int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1); |
6255 | int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 ); | ||
6256 | __le16 currentAuthType = local->config.authType; | 6345 | __le16 currentAuthType = local->config.authType; |
6346 | int rc = 0; | ||
6257 | 6347 | ||
6258 | /* Is WEP supported ? */ | 6348 | if (!local->wep_capable) |
6259 | readCapabilityRid(local, &cap_rid, 1); | ||
6260 | /* Older firmware doesn't support this... | ||
6261 | if(!(cap_rid.softCap & cpu_to_le16(2))) { | ||
6262 | return -EOPNOTSUPP; | 6349 | return -EOPNOTSUPP; |
6263 | } */ | 6350 | |
6264 | readConfigRid(local, 1); | 6351 | readConfigRid(local, 1); |
6265 | 6352 | ||
6266 | /* Basic checking: do we have a key to set ? | 6353 | /* Basic checking: do we have a key to set ? |
@@ -6272,14 +6359,21 @@ static int airo_set_encode(struct net_device *dev, | |||
6272 | if (dwrq->length > 0) { | 6359 | if (dwrq->length > 0) { |
6273 | wep_key_t key; | 6360 | wep_key_t key; |
6274 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; | 6361 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; |
6275 | int current_index = get_wep_key(local, 0xffff); | 6362 | int current_index; |
6363 | |||
6276 | /* Check the size of the key */ | 6364 | /* Check the size of the key */ |
6277 | if (dwrq->length > MAX_KEY_SIZE) { | 6365 | if (dwrq->length > MAX_KEY_SIZE) { |
6278 | return -EINVAL; | 6366 | return -EINVAL; |
6279 | } | 6367 | } |
6368 | |||
6369 | current_index = get_wep_tx_idx(local); | ||
6370 | if (current_index < 0) | ||
6371 | current_index = 0; | ||
6372 | |||
6280 | /* Check the index (none -> use current) */ | 6373 | /* Check the index (none -> use current) */ |
6281 | if (!valid_index(&cap_rid, index)) | 6374 | if (!valid_index(local, index)) |
6282 | index = current_index; | 6375 | index = current_index; |
6376 | |||
6283 | /* Set the length */ | 6377 | /* Set the length */ |
6284 | if (dwrq->length > MIN_KEY_SIZE) | 6378 | if (dwrq->length > MIN_KEY_SIZE) |
6285 | key.len = MAX_KEY_SIZE; | 6379 | key.len = MAX_KEY_SIZE; |
@@ -6296,7 +6390,13 @@ static int airo_set_encode(struct net_device *dev, | |||
6296 | /* Copy the key in the driver */ | 6390 | /* Copy the key in the driver */ |
6297 | memcpy(key.key, extra, dwrq->length); | 6391 | memcpy(key.key, extra, dwrq->length); |
6298 | /* Send the key to the card */ | 6392 | /* Send the key to the card */ |
6299 | set_wep_key(local, index, key.key, key.len, perm, 1); | 6393 | rc = set_wep_key(local, index, key.key, key.len, perm, 1); |
6394 | if (rc < 0) { | ||
6395 | airo_print_err(local->dev->name, "failed to set" | ||
6396 | " WEP key at index %d: %d.", | ||
6397 | index, rc); | ||
6398 | return rc; | ||
6399 | } | ||
6300 | } | 6400 | } |
6301 | /* WE specify that if a valid key is set, encryption | 6401 | /* WE specify that if a valid key is set, encryption |
6302 | * should be enabled (user may turn it off later) | 6402 | * should be enabled (user may turn it off later) |
@@ -6308,12 +6408,19 @@ static int airo_set_encode(struct net_device *dev, | |||
6308 | } else { | 6408 | } else { |
6309 | /* Do we want to just set the transmit key index ? */ | 6409 | /* Do we want to just set the transmit key index ? */ |
6310 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; | 6410 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; |
6311 | if (valid_index(&cap_rid, index)) { | 6411 | if (valid_index(local, index)) { |
6312 | set_wep_key(local, index, NULL, 0, perm, 1); | 6412 | rc = set_wep_tx_idx(local, index, perm, 1); |
6313 | } else | 6413 | if (rc < 0) { |
6414 | airo_print_err(local->dev->name, "failed to set" | ||
6415 | " WEP transmit index to %d: %d.", | ||
6416 | index, rc); | ||
6417 | return rc; | ||
6418 | } | ||
6419 | } else { | ||
6314 | /* Don't complain if only change the mode */ | 6420 | /* Don't complain if only change the mode */ |
6315 | if (!(dwrq->flags & IW_ENCODE_MODE)) | 6421 | if (!(dwrq->flags & IW_ENCODE_MODE)) |
6316 | return -EINVAL; | 6422 | return -EINVAL; |
6423 | } | ||
6317 | } | 6424 | } |
6318 | /* Read the flags */ | 6425 | /* Read the flags */ |
6319 | if(dwrq->flags & IW_ENCODE_DISABLED) | 6426 | if(dwrq->flags & IW_ENCODE_DISABLED) |
@@ -6339,14 +6446,13 @@ static int airo_get_encode(struct net_device *dev, | |||
6339 | { | 6446 | { |
6340 | struct airo_info *local = dev->ml_priv; | 6447 | struct airo_info *local = dev->ml_priv; |
6341 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; | 6448 | int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; |
6342 | CapabilityRid cap_rid; /* Card capability info */ | 6449 | u8 buf[16]; |
6343 | 6450 | ||
6344 | /* Is it supported ? */ | 6451 | if (!local->wep_capable) |
6345 | readCapabilityRid(local, &cap_rid, 1); | ||
6346 | if(!(cap_rid.softCap & cpu_to_le16(2))) { | ||
6347 | return -EOPNOTSUPP; | 6452 | return -EOPNOTSUPP; |
6348 | } | 6453 | |
6349 | readConfigRid(local, 1); | 6454 | readConfigRid(local, 1); |
6455 | |||
6350 | /* Check encryption mode */ | 6456 | /* Check encryption mode */ |
6351 | switch(local->config.authType) { | 6457 | switch(local->config.authType) { |
6352 | case AUTH_ENCRYPT: | 6458 | case AUTH_ENCRYPT: |
@@ -6365,14 +6471,17 @@ static int airo_get_encode(struct net_device *dev, | |||
6365 | memset(extra, 0, 16); | 6471 | memset(extra, 0, 16); |
6366 | 6472 | ||
6367 | /* Which key do we want ? -1 -> tx index */ | 6473 | /* Which key do we want ? -1 -> tx index */ |
6368 | if (!valid_index(&cap_rid, index)) | 6474 | if (!valid_index(local, index)) { |
6369 | index = get_wep_key(local, 0xffff); | 6475 | index = get_wep_tx_idx(local); |
6476 | if (index < 0) | ||
6477 | index = 0; | ||
6478 | } | ||
6370 | dwrq->flags |= index + 1; | 6479 | dwrq->flags |= index + 1; |
6480 | |||
6371 | /* Copy the key to the user buffer */ | 6481 | /* Copy the key to the user buffer */ |
6372 | dwrq->length = get_wep_key(local, index); | 6482 | dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf)); |
6373 | if (dwrq->length > 16) { | 6483 | memcpy(extra, buf, dwrq->length); |
6374 | dwrq->length=0; | 6484 | |
6375 | } | ||
6376 | return 0; | 6485 | return 0; |
6377 | } | 6486 | } |
6378 | 6487 | ||
@@ -6388,28 +6497,27 @@ static int airo_set_encodeext(struct net_device *dev, | |||
6388 | struct airo_info *local = dev->ml_priv; | 6497 | struct airo_info *local = dev->ml_priv; |
6389 | struct iw_point *encoding = &wrqu->encoding; | 6498 | struct iw_point *encoding = &wrqu->encoding; |
6390 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 6499 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
6391 | CapabilityRid cap_rid; /* Card capability info */ | ||
6392 | int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 ); | 6500 | int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 ); |
6393 | __le16 currentAuthType = local->config.authType; | 6501 | __le16 currentAuthType = local->config.authType; |
6394 | int idx, key_len, alg = ext->alg, set_key = 1; | 6502 | int idx, key_len, alg = ext->alg, set_key = 1, rc; |
6395 | wep_key_t key; | 6503 | wep_key_t key; |
6396 | 6504 | ||
6397 | /* Is WEP supported ? */ | 6505 | if (!local->wep_capable) |
6398 | readCapabilityRid(local, &cap_rid, 1); | ||
6399 | /* Older firmware doesn't support this... | ||
6400 | if(!(cap_rid.softCap & cpu_to_le16(2))) { | ||
6401 | return -EOPNOTSUPP; | 6506 | return -EOPNOTSUPP; |
6402 | } */ | 6507 | |
6403 | readConfigRid(local, 1); | 6508 | readConfigRid(local, 1); |
6404 | 6509 | ||
6405 | /* Determine and validate the key index */ | 6510 | /* Determine and validate the key index */ |
6406 | idx = encoding->flags & IW_ENCODE_INDEX; | 6511 | idx = encoding->flags & IW_ENCODE_INDEX; |
6407 | if (idx) { | 6512 | if (idx) { |
6408 | if (!valid_index(&cap_rid, idx - 1)) | 6513 | if (!valid_index(local, idx - 1)) |
6409 | return -EINVAL; | 6514 | return -EINVAL; |
6410 | idx--; | 6515 | idx--; |
6411 | } else | 6516 | } else { |
6412 | idx = get_wep_key(local, 0xffff); | 6517 | idx = get_wep_tx_idx(local); |
6518 | if (idx < 0) | ||
6519 | idx = 0; | ||
6520 | } | ||
6413 | 6521 | ||
6414 | if (encoding->flags & IW_ENCODE_DISABLED) | 6522 | if (encoding->flags & IW_ENCODE_DISABLED) |
6415 | alg = IW_ENCODE_ALG_NONE; | 6523 | alg = IW_ENCODE_ALG_NONE; |
@@ -6418,7 +6526,13 @@ static int airo_set_encodeext(struct net_device *dev, | |||
6418 | /* Only set transmit key index here, actual | 6526 | /* Only set transmit key index here, actual |
6419 | * key is set below if needed. | 6527 | * key is set below if needed. |
6420 | */ | 6528 | */ |
6421 | set_wep_key(local, idx, NULL, 0, perm, 1); | 6529 | rc = set_wep_tx_idx(local, idx, perm, 1); |
6530 | if (rc < 0) { | ||
6531 | airo_print_err(local->dev->name, "failed to set " | ||
6532 | "WEP transmit index to %d: %d.", | ||
6533 | idx, rc); | ||
6534 | return rc; | ||
6535 | } | ||
6422 | set_key = ext->key_len > 0 ? 1 : 0; | 6536 | set_key = ext->key_len > 0 ? 1 : 0; |
6423 | } | 6537 | } |
6424 | 6538 | ||
@@ -6444,7 +6558,12 @@ static int airo_set_encodeext(struct net_device *dev, | |||
6444 | return -EINVAL; | 6558 | return -EINVAL; |
6445 | } | 6559 | } |
6446 | /* Send the key to the card */ | 6560 | /* Send the key to the card */ |
6447 | set_wep_key(local, idx, key.key, key.len, perm, 1); | 6561 | rc = set_wep_key(local, idx, key.key, key.len, perm, 1); |
6562 | if (rc < 0) { | ||
6563 | airo_print_err(local->dev->name, "failed to set WEP key" | ||
6564 | " at index %d: %d.", idx, rc); | ||
6565 | return rc; | ||
6566 | } | ||
6448 | } | 6567 | } |
6449 | 6568 | ||
6450 | /* Read the flags */ | 6569 | /* Read the flags */ |
@@ -6474,14 +6593,12 @@ static int airo_get_encodeext(struct net_device *dev, | |||
6474 | struct airo_info *local = dev->ml_priv; | 6593 | struct airo_info *local = dev->ml_priv; |
6475 | struct iw_point *encoding = &wrqu->encoding; | 6594 | struct iw_point *encoding = &wrqu->encoding; |
6476 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 6595 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
6477 | CapabilityRid cap_rid; /* Card capability info */ | ||
6478 | int idx, max_key_len; | 6596 | int idx, max_key_len; |
6597 | u8 buf[16]; | ||
6479 | 6598 | ||
6480 | /* Is it supported ? */ | 6599 | if (!local->wep_capable) |
6481 | readCapabilityRid(local, &cap_rid, 1); | ||
6482 | if(!(cap_rid.softCap & cpu_to_le16(2))) { | ||
6483 | return -EOPNOTSUPP; | 6600 | return -EOPNOTSUPP; |
6484 | } | 6601 | |
6485 | readConfigRid(local, 1); | 6602 | readConfigRid(local, 1); |
6486 | 6603 | ||
6487 | max_key_len = encoding->length - sizeof(*ext); | 6604 | max_key_len = encoding->length - sizeof(*ext); |
@@ -6490,11 +6607,14 @@ static int airo_get_encodeext(struct net_device *dev, | |||
6490 | 6607 | ||
6491 | idx = encoding->flags & IW_ENCODE_INDEX; | 6608 | idx = encoding->flags & IW_ENCODE_INDEX; |
6492 | if (idx) { | 6609 | if (idx) { |
6493 | if (!valid_index(&cap_rid, idx - 1)) | 6610 | if (!valid_index(local, idx - 1)) |
6494 | return -EINVAL; | 6611 | return -EINVAL; |
6495 | idx--; | 6612 | idx--; |
6496 | } else | 6613 | } else { |
6497 | idx = get_wep_key(local, 0xffff); | 6614 | idx = get_wep_tx_idx(local); |
6615 | if (idx < 0) | ||
6616 | idx = 0; | ||
6617 | } | ||
6498 | 6618 | ||
6499 | encoding->flags = idx + 1; | 6619 | encoding->flags = idx + 1; |
6500 | memset(ext, 0, sizeof(*ext)); | 6620 | memset(ext, 0, sizeof(*ext)); |
@@ -6517,10 +6637,8 @@ static int airo_get_encodeext(struct net_device *dev, | |||
6517 | memset(extra, 0, 16); | 6637 | memset(extra, 0, 16); |
6518 | 6638 | ||
6519 | /* Copy the key to the user buffer */ | 6639 | /* Copy the key to the user buffer */ |
6520 | ext->key_len = get_wep_key(local, idx); | 6640 | ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf)); |
6521 | if (ext->key_len > 16) { | 6641 | memcpy(extra, buf, ext->key_len); |
6522 | ext->key_len=0; | ||
6523 | } | ||
6524 | 6642 | ||
6525 | return 0; | 6643 | return 0; |
6526 | } | 6644 | } |
@@ -6795,8 +6913,8 @@ static int airo_get_range(struct net_device *dev, | |||
6795 | k = 0; | 6913 | k = 0; |
6796 | for(i = 0; i < 14; i++) { | 6914 | for(i = 0; i < 14; i++) { |
6797 | range->freq[k].i = i + 1; /* List index */ | 6915 | range->freq[k].i = i + 1; /* List index */ |
6798 | range->freq[k].m = frequency_list[i] * 100000; | 6916 | range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000; |
6799 | range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ | 6917 | range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */ |
6800 | } | 6918 | } |
6801 | range->num_frequency = k; | 6919 | range->num_frequency = k; |
6802 | 6920 | ||
@@ -7189,10 +7307,7 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7189 | /* Add frequency */ | 7307 | /* Add frequency */ |
7190 | iwe.cmd = SIOCGIWFREQ; | 7308 | iwe.cmd = SIOCGIWFREQ; |
7191 | iwe.u.freq.m = le16_to_cpu(bss->dsChannel); | 7309 | iwe.u.freq.m = le16_to_cpu(bss->dsChannel); |
7192 | /* iwe.u.freq.m containt the channel (starting 1), our | 7310 | iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000; |
7193 | * frequency_list array start at index 0... | ||
7194 | */ | ||
7195 | iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000; | ||
7196 | iwe.u.freq.e = 1; | 7311 | iwe.u.freq.e = 1; |
7197 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, | 7312 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
7198 | &iwe, IW_EV_FREQ_LEN); | 7313 | &iwe, IW_EV_FREQ_LEN); |
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 183ffc8e62ca..0eda785fe62f 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -1206,6 +1206,7 @@ extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); | |||
1206 | /* Beacon control functions */ | 1206 | /* Beacon control functions */ |
1207 | extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); | 1207 | extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); |
1208 | extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); | 1208 | extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); |
1209 | extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); | ||
1209 | extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); | 1210 | extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); |
1210 | extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); | 1211 | extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); |
1211 | #if 0 | 1212 | #if 0 |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index a533ed60bb4d..bd2c580d1f19 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -232,13 +232,14 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
232 | int mc_count, struct dev_mc_list *mclist); | 232 | int mc_count, struct dev_mc_list *mclist); |
233 | static int ath5k_set_key(struct ieee80211_hw *hw, | 233 | static int ath5k_set_key(struct ieee80211_hw *hw, |
234 | enum set_key_cmd cmd, | 234 | enum set_key_cmd cmd, |
235 | const u8 *local_addr, const u8 *addr, | 235 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
236 | struct ieee80211_key_conf *key); | 236 | struct ieee80211_key_conf *key); |
237 | static int ath5k_get_stats(struct ieee80211_hw *hw, | 237 | static int ath5k_get_stats(struct ieee80211_hw *hw, |
238 | struct ieee80211_low_level_stats *stats); | 238 | struct ieee80211_low_level_stats *stats); |
239 | static int ath5k_get_tx_stats(struct ieee80211_hw *hw, | 239 | static int ath5k_get_tx_stats(struct ieee80211_hw *hw, |
240 | struct ieee80211_tx_queue_stats *stats); | 240 | struct ieee80211_tx_queue_stats *stats); |
241 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | 241 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); |
242 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); | ||
242 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | 243 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); |
243 | static int ath5k_beacon_update(struct ath5k_softc *sc, | 244 | static int ath5k_beacon_update(struct ath5k_softc *sc, |
244 | struct sk_buff *skb); | 245 | struct sk_buff *skb); |
@@ -261,6 +262,7 @@ static struct ieee80211_ops ath5k_hw_ops = { | |||
261 | .conf_tx = NULL, | 262 | .conf_tx = NULL, |
262 | .get_tx_stats = ath5k_get_tx_stats, | 263 | .get_tx_stats = ath5k_get_tx_stats, |
263 | .get_tsf = ath5k_get_tsf, | 264 | .get_tsf = ath5k_get_tsf, |
265 | .set_tsf = ath5k_set_tsf, | ||
264 | .reset_tsf = ath5k_reset_tsf, | 266 | .reset_tsf = ath5k_reset_tsf, |
265 | .bss_info_changed = ath5k_bss_info_changed, | 267 | .bss_info_changed = ath5k_bss_info_changed, |
266 | }; | 268 | }; |
@@ -347,9 +349,9 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) | |||
347 | } | 349 | } |
348 | 350 | ||
349 | /* Interrupt handling */ | 351 | /* Interrupt handling */ |
350 | static int ath5k_init(struct ath5k_softc *sc, bool is_resume); | 352 | static int ath5k_init(struct ath5k_softc *sc); |
351 | static int ath5k_stop_locked(struct ath5k_softc *sc); | 353 | static int ath5k_stop_locked(struct ath5k_softc *sc); |
352 | static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend); | 354 | static int ath5k_stop_hw(struct ath5k_softc *sc); |
353 | static irqreturn_t ath5k_intr(int irq, void *dev_id); | 355 | static irqreturn_t ath5k_intr(int irq, void *dev_id); |
354 | static void ath5k_tasklet_reset(unsigned long data); | 356 | static void ath5k_tasklet_reset(unsigned long data); |
355 | 357 | ||
@@ -653,8 +655,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
653 | 655 | ||
654 | ath5k_led_off(sc); | 656 | ath5k_led_off(sc); |
655 | 657 | ||
656 | ath5k_stop_hw(sc, true); | ||
657 | |||
658 | free_irq(pdev->irq, sc); | 658 | free_irq(pdev->irq, sc); |
659 | pci_save_state(pdev); | 659 | pci_save_state(pdev); |
660 | pci_disable_device(pdev); | 660 | pci_disable_device(pdev); |
@@ -689,14 +689,9 @@ ath5k_pci_resume(struct pci_dev *pdev) | |||
689 | goto err_no_irq; | 689 | goto err_no_irq; |
690 | } | 690 | } |
691 | 691 | ||
692 | err = ath5k_init(sc, true); | ||
693 | if (err) | ||
694 | goto err_irq; | ||
695 | ath5k_led_enable(sc); | 692 | ath5k_led_enable(sc); |
696 | |||
697 | return 0; | 693 | return 0; |
698 | err_irq: | 694 | |
699 | free_irq(pdev->irq, sc); | ||
700 | err_no_irq: | 695 | err_no_irq: |
701 | pci_disable_device(pdev); | 696 | pci_disable_device(pdev); |
702 | return err; | 697 | return err; |
@@ -1098,6 +1093,42 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) | |||
1098 | * Buffers setup * | 1093 | * Buffers setup * |
1099 | \***************/ | 1094 | \***************/ |
1100 | 1095 | ||
1096 | static | ||
1097 | struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) | ||
1098 | { | ||
1099 | struct sk_buff *skb; | ||
1100 | unsigned int off; | ||
1101 | |||
1102 | /* | ||
1103 | * Allocate buffer with headroom_needed space for the | ||
1104 | * fake physical layer header at the start. | ||
1105 | */ | ||
1106 | skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1); | ||
1107 | |||
1108 | if (!skb) { | ||
1109 | ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", | ||
1110 | sc->rxbufsize + sc->cachelsz - 1); | ||
1111 | return NULL; | ||
1112 | } | ||
1113 | /* | ||
1114 | * Cache-line-align. This is important (for the | ||
1115 | * 5210 at least) as not doing so causes bogus data | ||
1116 | * in rx'd frames. | ||
1117 | */ | ||
1118 | off = ((unsigned long)skb->data) % sc->cachelsz; | ||
1119 | if (off != 0) | ||
1120 | skb_reserve(skb, sc->cachelsz - off); | ||
1121 | |||
1122 | *skb_addr = pci_map_single(sc->pdev, | ||
1123 | skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); | ||
1124 | if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { | ||
1125 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); | ||
1126 | dev_kfree_skb(skb); | ||
1127 | return NULL; | ||
1128 | } | ||
1129 | return skb; | ||
1130 | } | ||
1131 | |||
1101 | static int | 1132 | static int |
1102 | ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | 1133 | ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) |
1103 | { | 1134 | { |
@@ -1105,37 +1136,11 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1105 | struct sk_buff *skb = bf->skb; | 1136 | struct sk_buff *skb = bf->skb; |
1106 | struct ath5k_desc *ds; | 1137 | struct ath5k_desc *ds; |
1107 | 1138 | ||
1108 | if (likely(skb == NULL)) { | 1139 | if (!skb) { |
1109 | unsigned int off; | 1140 | skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr); |
1110 | 1141 | if (!skb) | |
1111 | /* | ||
1112 | * Allocate buffer with headroom_needed space for the | ||
1113 | * fake physical layer header at the start. | ||
1114 | */ | ||
1115 | skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1); | ||
1116 | if (unlikely(skb == NULL)) { | ||
1117 | ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", | ||
1118 | sc->rxbufsize + sc->cachelsz - 1); | ||
1119 | return -ENOMEM; | 1142 | return -ENOMEM; |
1120 | } | ||
1121 | /* | ||
1122 | * Cache-line-align. This is important (for the | ||
1123 | * 5210 at least) as not doing so causes bogus data | ||
1124 | * in rx'd frames. | ||
1125 | */ | ||
1126 | off = ((unsigned long)skb->data) % sc->cachelsz; | ||
1127 | if (off != 0) | ||
1128 | skb_reserve(skb, sc->cachelsz - off); | ||
1129 | |||
1130 | bf->skb = skb; | 1143 | bf->skb = skb; |
1131 | bf->skbaddr = pci_map_single(sc->pdev, | ||
1132 | skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); | ||
1133 | if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) { | ||
1134 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); | ||
1135 | dev_kfree_skb(skb); | ||
1136 | bf->skb = NULL; | ||
1137 | return -ENOMEM; | ||
1138 | } | ||
1139 | } | 1144 | } |
1140 | 1145 | ||
1141 | /* | 1146 | /* |
@@ -1178,6 +1183,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1178 | struct ieee80211_rate *rate; | 1183 | struct ieee80211_rate *rate; |
1179 | unsigned int mrr_rate[3], mrr_tries[3]; | 1184 | unsigned int mrr_rate[3], mrr_tries[3]; |
1180 | int i, ret; | 1185 | int i, ret; |
1186 | u16 hw_rate; | ||
1187 | u16 cts_rate = 0; | ||
1188 | u16 duration = 0; | ||
1189 | u8 rc_flags; | ||
1181 | 1190 | ||
1182 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; | 1191 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; |
1183 | 1192 | ||
@@ -1185,11 +1194,30 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1185 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, | 1194 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, |
1186 | PCI_DMA_TODEVICE); | 1195 | PCI_DMA_TODEVICE); |
1187 | 1196 | ||
1197 | rate = ieee80211_get_tx_rate(sc->hw, info); | ||
1198 | |||
1188 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | 1199 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) |
1189 | flags |= AR5K_TXDESC_NOACK; | 1200 | flags |= AR5K_TXDESC_NOACK; |
1190 | 1201 | ||
1202 | rc_flags = info->control.rates[0].flags; | ||
1203 | hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? | ||
1204 | rate->hw_value_short : rate->hw_value; | ||
1205 | |||
1191 | pktlen = skb->len; | 1206 | pktlen = skb->len; |
1192 | 1207 | ||
1208 | if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { | ||
1209 | flags |= AR5K_TXDESC_RTSENA; | ||
1210 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; | ||
1211 | duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, | ||
1212 | sc->vif, pktlen, info)); | ||
1213 | } | ||
1214 | if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | ||
1215 | flags |= AR5K_TXDESC_CTSENA; | ||
1216 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; | ||
1217 | duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, | ||
1218 | sc->vif, pktlen, info)); | ||
1219 | } | ||
1220 | |||
1193 | if (info->control.hw_key) { | 1221 | if (info->control.hw_key) { |
1194 | keyidx = info->control.hw_key->hw_key_idx; | 1222 | keyidx = info->control.hw_key->hw_key_idx; |
1195 | pktlen += info->control.hw_key->icv_len; | 1223 | pktlen += info->control.hw_key->icv_len; |
@@ -1197,8 +1225,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1197 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1225 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1198 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1226 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, |
1199 | (sc->power_level * 2), | 1227 | (sc->power_level * 2), |
1200 | ieee80211_get_tx_rate(sc->hw, info)->hw_value, | 1228 | hw_rate, |
1201 | info->control.rates[0].count, keyidx, 0, flags, 0, 0); | 1229 | info->control.rates[0].count, keyidx, 0, flags, |
1230 | cts_rate, duration); | ||
1202 | if (ret) | 1231 | if (ret) |
1203 | goto err_unmap; | 1232 | goto err_unmap; |
1204 | 1233 | ||
@@ -1664,7 +1693,8 @@ ath5k_tasklet_rx(unsigned long data) | |||
1664 | { | 1693 | { |
1665 | struct ieee80211_rx_status rxs = {}; | 1694 | struct ieee80211_rx_status rxs = {}; |
1666 | struct ath5k_rx_status rs = {}; | 1695 | struct ath5k_rx_status rs = {}; |
1667 | struct sk_buff *skb; | 1696 | struct sk_buff *skb, *next_skb; |
1697 | dma_addr_t next_skb_addr; | ||
1668 | struct ath5k_softc *sc = (void *)data; | 1698 | struct ath5k_softc *sc = (void *)data; |
1669 | struct ath5k_buf *bf, *bf_last; | 1699 | struct ath5k_buf *bf, *bf_last; |
1670 | struct ath5k_desc *ds; | 1700 | struct ath5k_desc *ds; |
@@ -1749,10 +1779,17 @@ ath5k_tasklet_rx(unsigned long data) | |||
1749 | goto next; | 1779 | goto next; |
1750 | } | 1780 | } |
1751 | accept: | 1781 | accept: |
1782 | next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); | ||
1783 | |||
1784 | /* | ||
1785 | * If we can't replace bf->skb with a new skb under memory | ||
1786 | * pressure, just skip this packet | ||
1787 | */ | ||
1788 | if (!next_skb) | ||
1789 | goto next; | ||
1790 | |||
1752 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, | 1791 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, |
1753 | PCI_DMA_FROMDEVICE); | 1792 | PCI_DMA_FROMDEVICE); |
1754 | bf->skb = NULL; | ||
1755 | |||
1756 | skb_put(skb, rs.rs_datalen); | 1793 | skb_put(skb, rs.rs_datalen); |
1757 | 1794 | ||
1758 | /* The MAC header is padded to have 32-bit boundary if the | 1795 | /* The MAC header is padded to have 32-bit boundary if the |
@@ -1825,6 +1862,9 @@ accept: | |||
1825 | ath5k_check_ibss_tsf(sc, skb, &rxs); | 1862 | ath5k_check_ibss_tsf(sc, skb, &rxs); |
1826 | 1863 | ||
1827 | __ieee80211_rx(sc->hw, skb, &rxs); | 1864 | __ieee80211_rx(sc->hw, skb, &rxs); |
1865 | |||
1866 | bf->skb = next_skb; | ||
1867 | bf->skbaddr = next_skb_addr; | ||
1828 | next: | 1868 | next: |
1829 | list_move_tail(&bf->list, &sc->rxbuf); | 1869 | list_move_tail(&bf->list, &sc->rxbuf); |
1830 | } while (ath5k_rxbuf_setup(sc, bf) == 0); | 1870 | } while (ath5k_rxbuf_setup(sc, bf) == 0); |
@@ -2207,18 +2247,13 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
2207 | \********************/ | 2247 | \********************/ |
2208 | 2248 | ||
2209 | static int | 2249 | static int |
2210 | ath5k_init(struct ath5k_softc *sc, bool is_resume) | 2250 | ath5k_init(struct ath5k_softc *sc) |
2211 | { | 2251 | { |
2212 | struct ath5k_hw *ah = sc->ah; | 2252 | struct ath5k_hw *ah = sc->ah; |
2213 | int ret, i; | 2253 | int ret, i; |
2214 | 2254 | ||
2215 | mutex_lock(&sc->lock); | 2255 | mutex_lock(&sc->lock); |
2216 | 2256 | ||
2217 | if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status)) | ||
2218 | goto out_ok; | ||
2219 | |||
2220 | __clear_bit(ATH_STAT_STARTED, sc->status); | ||
2221 | |||
2222 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); | 2257 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); |
2223 | 2258 | ||
2224 | /* | 2259 | /* |
@@ -2250,15 +2285,12 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume) | |||
2250 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) | 2285 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) |
2251 | ath5k_hw_reset_key(ah, i); | 2286 | ath5k_hw_reset_key(ah, i); |
2252 | 2287 | ||
2253 | __set_bit(ATH_STAT_STARTED, sc->status); | ||
2254 | |||
2255 | /* Set ack to be sent at low bit-rates */ | 2288 | /* Set ack to be sent at low bit-rates */ |
2256 | ath5k_hw_set_ack_bitrate_high(ah, false); | 2289 | ath5k_hw_set_ack_bitrate_high(ah, false); |
2257 | 2290 | ||
2258 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + | 2291 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + |
2259 | msecs_to_jiffies(ath5k_calinterval * 1000))); | 2292 | msecs_to_jiffies(ath5k_calinterval * 1000))); |
2260 | 2293 | ||
2261 | out_ok: | ||
2262 | ret = 0; | 2294 | ret = 0; |
2263 | done: | 2295 | done: |
2264 | mmiowb(); | 2296 | mmiowb(); |
@@ -2313,7 +2345,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) | |||
2313 | * stop is preempted). | 2345 | * stop is preempted). |
2314 | */ | 2346 | */ |
2315 | static int | 2347 | static int |
2316 | ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend) | 2348 | ath5k_stop_hw(struct ath5k_softc *sc) |
2317 | { | 2349 | { |
2318 | int ret; | 2350 | int ret; |
2319 | 2351 | ||
@@ -2344,8 +2376,6 @@ ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend) | |||
2344 | } | 2376 | } |
2345 | } | 2377 | } |
2346 | ath5k_txbuf_free(sc, sc->bbuf); | 2378 | ath5k_txbuf_free(sc, sc->bbuf); |
2347 | if (!is_suspend) | ||
2348 | __clear_bit(ATH_STAT_STARTED, sc->status); | ||
2349 | 2379 | ||
2350 | mmiowb(); | 2380 | mmiowb(); |
2351 | mutex_unlock(&sc->lock); | 2381 | mutex_unlock(&sc->lock); |
@@ -2598,6 +2628,17 @@ ath5k_init_leds(struct ath5k_softc *sc) | |||
2598 | sc->led_pin = 1; | 2628 | sc->led_pin = 1; |
2599 | sc->led_on = 1; /* active high */ | 2629 | sc->led_on = 1; /* active high */ |
2600 | } | 2630 | } |
2631 | /* | ||
2632 | * Pin 3 on Foxconn chips used in Acer Aspire One (0x105b:e008) and | ||
2633 | * in emachines notebooks with AMBIT subsystem. | ||
2634 | */ | ||
2635 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_FOXCONN || | ||
2636 | pdev->subsystem_vendor == PCI_VENDOR_ID_AMBIT) { | ||
2637 | __set_bit(ATH_STAT_LEDSOFT, sc->status); | ||
2638 | sc->led_pin = 3; | ||
2639 | sc->led_on = 0; /* active low */ | ||
2640 | } | ||
2641 | |||
2601 | if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) | 2642 | if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) |
2602 | goto out; | 2643 | goto out; |
2603 | 2644 | ||
@@ -2745,12 +2786,12 @@ ath5k_reset_wake(struct ath5k_softc *sc) | |||
2745 | 2786 | ||
2746 | static int ath5k_start(struct ieee80211_hw *hw) | 2787 | static int ath5k_start(struct ieee80211_hw *hw) |
2747 | { | 2788 | { |
2748 | return ath5k_init(hw->priv, false); | 2789 | return ath5k_init(hw->priv); |
2749 | } | 2790 | } |
2750 | 2791 | ||
2751 | static void ath5k_stop(struct ieee80211_hw *hw) | 2792 | static void ath5k_stop(struct ieee80211_hw *hw) |
2752 | { | 2793 | { |
2753 | ath5k_stop_hw(hw->priv, false); | 2794 | ath5k_stop_hw(hw->priv); |
2754 | } | 2795 | } |
2755 | 2796 | ||
2756 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 2797 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
@@ -2999,8 +3040,8 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
2999 | 3040 | ||
3000 | static int | 3041 | static int |
3001 | ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 3042 | ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
3002 | const u8 *local_addr, const u8 *addr, | 3043 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
3003 | struct ieee80211_key_conf *key) | 3044 | struct ieee80211_key_conf *key) |
3004 | { | 3045 | { |
3005 | struct ath5k_softc *sc = hw->priv; | 3046 | struct ath5k_softc *sc = hw->priv; |
3006 | int ret = 0; | 3047 | int ret = 0; |
@@ -3023,7 +3064,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3023 | 3064 | ||
3024 | switch (cmd) { | 3065 | switch (cmd) { |
3025 | case SET_KEY: | 3066 | case SET_KEY: |
3026 | ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr); | 3067 | ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, |
3068 | sta ? sta->addr : NULL); | ||
3027 | if (ret) { | 3069 | if (ret) { |
3028 | ATH5K_ERR(sc, "can't set the key\n"); | 3070 | ATH5K_ERR(sc, "can't set the key\n"); |
3029 | goto unlock; | 3071 | goto unlock; |
@@ -3083,6 +3125,14 @@ ath5k_get_tsf(struct ieee80211_hw *hw) | |||
3083 | } | 3125 | } |
3084 | 3126 | ||
3085 | static void | 3127 | static void |
3128 | ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | ||
3129 | { | ||
3130 | struct ath5k_softc *sc = hw->priv; | ||
3131 | |||
3132 | ath5k_hw_set_tsf64(sc->ah, tsf); | ||
3133 | } | ||
3134 | |||
3135 | static void | ||
3086 | ath5k_reset_tsf(struct ieee80211_hw *hw) | 3136 | ath5k_reset_tsf(struct ieee80211_hw *hw) |
3087 | { | 3137 | { |
3088 | struct ath5k_softc *sc = hw->priv; | 3138 | struct ath5k_softc *sc = hw->priv; |
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index facc60ddada2..c0fb8b5c42fe 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
@@ -148,8 +148,7 @@ struct ath5k_softc { | |||
148 | u8 bssidmask[ETH_ALEN]; | 148 | u8 bssidmask[ETH_ALEN]; |
149 | 149 | ||
150 | unsigned int led_pin, /* GPIO pin for driving LED */ | 150 | unsigned int led_pin, /* GPIO pin for driving LED */ |
151 | led_on, /* pin setting for LED on */ | 151 | led_on; /* pin setting for LED on */ |
152 | led_off; /* off time for current blink */ | ||
153 | 152 | ||
154 | struct tasklet_struct restq; /* reset tasklet */ | 153 | struct tasklet_struct restq; /* reset tasklet */ |
155 | 154 | ||
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c index 150f5ed204a0..367a6c7d3cc7 100644 --- a/drivers/net/wireless/ath5k/caps.c +++ b/drivers/net/wireless/ath5k/caps.c | |||
@@ -85,7 +85,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
85 | /* Enable 802.11b if a 2GHz capable radio (2111/5112) is | 85 | /* Enable 802.11b if a 2GHz capable radio (2111/5112) is |
86 | * connected */ | 86 | * connected */ |
87 | if (AR5K_EEPROM_HDR_11B(ee_header) || | 87 | if (AR5K_EEPROM_HDR_11B(ee_header) || |
88 | AR5K_EEPROM_HDR_11G(ee_header)) { | 88 | (AR5K_EEPROM_HDR_11G(ee_header) && |
89 | ah->ah_version != AR5K_AR5211)) { | ||
89 | /* 2312 */ | 90 | /* 2312 */ |
90 | ah->ah_capabilities.cap_range.range_2ghz_min = 2412; | 91 | ah->ah_capabilities.cap_range.range_2ghz_min = 2412; |
91 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | 92 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; |
@@ -94,7 +95,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
94 | __set_bit(AR5K_MODE_11B, | 95 | __set_bit(AR5K_MODE_11B, |
95 | ah->ah_capabilities.cap_mode); | 96 | ah->ah_capabilities.cap_mode); |
96 | 97 | ||
97 | if (AR5K_EEPROM_HDR_11G(ee_header)) | 98 | if (AR5K_EEPROM_HDR_11G(ee_header) && |
99 | ah->ah_version != AR5K_AR5211) | ||
98 | __set_bit(AR5K_MODE_11G, | 100 | __set_bit(AR5K_MODE_11G, |
99 | ah->ah_capabilities.cap_mode); | 101 | ah->ah_capabilities.cap_mode); |
100 | } | 102 | } |
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index d281b6e38629..413ed689cd5f 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c | |||
@@ -193,43 +193,6 @@ static const struct file_operations fops_registers = { | |||
193 | }; | 193 | }; |
194 | 194 | ||
195 | 195 | ||
196 | /* debugfs: TSF */ | ||
197 | |||
198 | static ssize_t read_file_tsf(struct file *file, char __user *user_buf, | ||
199 | size_t count, loff_t *ppos) | ||
200 | { | ||
201 | struct ath5k_softc *sc = file->private_data; | ||
202 | char buf[100]; | ||
203 | snprintf(buf, sizeof(buf), "0x%016llx\n", | ||
204 | (unsigned long long)ath5k_hw_get_tsf64(sc->ah)); | ||
205 | return simple_read_from_buffer(user_buf, count, ppos, buf, 19); | ||
206 | } | ||
207 | |||
208 | static ssize_t write_file_tsf(struct file *file, | ||
209 | const char __user *userbuf, | ||
210 | size_t count, loff_t *ppos) | ||
211 | { | ||
212 | struct ath5k_softc *sc = file->private_data; | ||
213 | char buf[20]; | ||
214 | |||
215 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
216 | return -EFAULT; | ||
217 | |||
218 | if (strncmp(buf, "reset", 5) == 0) { | ||
219 | ath5k_hw_reset_tsf(sc->ah); | ||
220 | printk(KERN_INFO "debugfs reset TSF\n"); | ||
221 | } | ||
222 | return count; | ||
223 | } | ||
224 | |||
225 | static const struct file_operations fops_tsf = { | ||
226 | .read = read_file_tsf, | ||
227 | .write = write_file_tsf, | ||
228 | .open = ath5k_debugfs_open, | ||
229 | .owner = THIS_MODULE, | ||
230 | }; | ||
231 | |||
232 | |||
233 | /* debugfs: beacons */ | 196 | /* debugfs: beacons */ |
234 | 197 | ||
235 | static ssize_t read_file_beacon(struct file *file, char __user *user_buf, | 198 | static ssize_t read_file_beacon(struct file *file, char __user *user_buf, |
@@ -423,9 +386,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc) | |||
423 | sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO, | 386 | sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO, |
424 | sc->debug.debugfs_phydir, sc, &fops_registers); | 387 | sc->debug.debugfs_phydir, sc, &fops_registers); |
425 | 388 | ||
426 | sc->debug.debugfs_tsf = debugfs_create_file("tsf", S_IWUSR | S_IRUGO, | ||
427 | sc->debug.debugfs_phydir, sc, &fops_tsf); | ||
428 | |||
429 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO, | 389 | sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO, |
430 | sc->debug.debugfs_phydir, sc, &fops_beacon); | 390 | sc->debug.debugfs_phydir, sc, &fops_beacon); |
431 | 391 | ||
@@ -444,7 +404,6 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) | |||
444 | { | 404 | { |
445 | debugfs_remove(sc->debug.debugfs_debug); | 405 | debugfs_remove(sc->debug.debugfs_debug); |
446 | debugfs_remove(sc->debug.debugfs_registers); | 406 | debugfs_remove(sc->debug.debugfs_registers); |
447 | debugfs_remove(sc->debug.debugfs_tsf); | ||
448 | debugfs_remove(sc->debug.debugfs_beacon); | 407 | debugfs_remove(sc->debug.debugfs_beacon); |
449 | debugfs_remove(sc->debug.debugfs_reset); | 408 | debugfs_remove(sc->debug.debugfs_reset); |
450 | debugfs_remove(sc->debug.debugfs_phydir); | 409 | debugfs_remove(sc->debug.debugfs_phydir); |
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h index ffc529393306..66f69f04e55e 100644 --- a/drivers/net/wireless/ath5k/debug.h +++ b/drivers/net/wireless/ath5k/debug.h | |||
@@ -72,7 +72,6 @@ struct ath5k_dbg_info { | |||
72 | struct dentry *debugfs_phydir; | 72 | struct dentry *debugfs_phydir; |
73 | struct dentry *debugfs_debug; | 73 | struct dentry *debugfs_debug; |
74 | struct dentry *debugfs_registers; | 74 | struct dentry *debugfs_registers; |
75 | struct dentry *debugfs_tsf; | ||
76 | struct dentry *debugfs_beacon; | 75 | struct dentry *debugfs_beacon; |
77 | struct dentry *debugfs_reset; | 76 | struct dentry *debugfs_reset; |
78 | }; | 77 | }; |
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c index 1cb7edfae625..b4ec539c464b 100644 --- a/drivers/net/wireless/ath5k/eeprom.c +++ b/drivers/net/wireless/ath5k/eeprom.c | |||
@@ -137,6 +137,18 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | |||
137 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | 137 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { |
138 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); | 138 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); |
139 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); | 139 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); |
140 | |||
141 | /* XXX: Don't know which versions include these two */ | ||
142 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2); | ||
143 | |||
144 | if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) | ||
145 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3); | ||
146 | |||
147 | if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) { | ||
148 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4); | ||
149 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5); | ||
150 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6); | ||
151 | } | ||
140 | } | 152 | } |
141 | 153 | ||
142 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { | 154 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { |
@@ -213,7 +225,8 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, | |||
213 | } | 225 | } |
214 | 226 | ||
215 | /* | 227 | /* |
216 | * Read supported modes from eeprom | 228 | * Read supported modes and some mode-specific calibration data |
229 | * from eeprom | ||
217 | */ | 230 | */ |
218 | static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | 231 | static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, |
219 | unsigned int mode) | 232 | unsigned int mode) |
@@ -315,6 +328,9 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
315 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0) | 328 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0) |
316 | goto done; | 329 | goto done; |
317 | 330 | ||
331 | /* Note: >= v5 have bg freq piers on another location | ||
332 | * so these freq piers are ignored for >= v5 (should be 0xff | ||
333 | * anyway) */ | ||
318 | switch(mode) { | 334 | switch(mode) { |
319 | case AR5K_EEPROM_MODE_11A: | 335 | case AR5K_EEPROM_MODE_11A: |
320 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1) | 336 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1) |
@@ -442,7 +458,7 @@ ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah, | |||
442 | return 0; | 458 | return 0; |
443 | } | 459 | } |
444 | 460 | ||
445 | 461 | /* Read mode-specific data (except power calibration data) */ | |
446 | static int | 462 | static int |
447 | ath5k_eeprom_init_modes(struct ath5k_hw *ah) | 463 | ath5k_eeprom_init_modes(struct ath5k_hw *ah) |
448 | { | 464 | { |
@@ -488,6 +504,16 @@ ath5k_eeprom_init_modes(struct ath5k_hw *ah) | |||
488 | return 0; | 504 | return 0; |
489 | } | 505 | } |
490 | 506 | ||
507 | /* Used to match PCDAC steps with power values on RF5111 chips | ||
508 | * (eeprom versions < 4). For RF5111 we have 10 pre-defined PCDAC | ||
509 | * steps that match with the power values we read from eeprom. On | ||
510 | * older eeprom versions (< 3.2) these steps are equaly spaced at | ||
511 | * 10% of the pcdac curve -until the curve reaches it's maximum- | ||
512 | * (10 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) | ||
513 | * these 10 steps are spaced in a different way. This function returns | ||
514 | * the pcdac steps based on eeprom version and curve min/max so that we | ||
515 | * can have pcdac/pwr points. | ||
516 | */ | ||
491 | static inline void | 517 | static inline void |
492 | ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) | 518 | ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) |
493 | { | 519 | { |
@@ -507,37 +533,48 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) | |||
507 | *vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100; | 533 | *vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100; |
508 | } | 534 | } |
509 | 535 | ||
536 | /* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff | ||
537 | * frequency mask) */ | ||
510 | static inline int | 538 | static inline int |
511 | ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, | 539 | ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, |
512 | struct ath5k_chan_pcal_info *pc, u8 *count) | 540 | struct ath5k_chan_pcal_info *pc, unsigned int mode) |
513 | { | 541 | { |
542 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
514 | int o = *offset; | 543 | int o = *offset; |
515 | int i = 0; | 544 | int i = 0; |
516 | u8 f1, f2; | 545 | u8 freq1, freq2; |
517 | int ret; | 546 | int ret; |
518 | u16 val; | 547 | u16 val; |
519 | 548 | ||
520 | while(i < max) { | 549 | while(i < max) { |
521 | AR5K_EEPROM_READ(o++, val); | 550 | AR5K_EEPROM_READ(o++, val); |
522 | 551 | ||
523 | f1 = (val >> 8) & 0xff; | 552 | freq1 = (val >> 8) & 0xff; |
524 | f2 = val & 0xff; | 553 | freq2 = val & 0xff; |
525 | 554 | ||
526 | if (f1) | 555 | if (freq1) { |
527 | pc[i++].freq = f1; | 556 | pc[i++].freq = ath5k_eeprom_bin2freq(ee, |
557 | freq1, mode); | ||
558 | ee->ee_n_piers[mode]++; | ||
559 | } | ||
528 | 560 | ||
529 | if (f2) | 561 | if (freq2) { |
530 | pc[i++].freq = f2; | 562 | pc[i++].freq = ath5k_eeprom_bin2freq(ee, |
563 | freq2, mode); | ||
564 | ee->ee_n_piers[mode]++; | ||
565 | } | ||
531 | 566 | ||
532 | if (!f1 || !f2) | 567 | if (!freq1 || !freq2) |
533 | break; | 568 | break; |
534 | } | 569 | } |
570 | |||
571 | /* return new offset */ | ||
535 | *offset = o; | 572 | *offset = o; |
536 | *count = i; | ||
537 | 573 | ||
538 | return 0; | 574 | return 0; |
539 | } | 575 | } |
540 | 576 | ||
577 | /* Read frequency piers for 802.11a */ | ||
541 | static int | 578 | static int |
542 | ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) | 579 | ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) |
543 | { | 580 | { |
@@ -550,7 +587,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) | |||
550 | if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { | 587 | if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { |
551 | ath5k_eeprom_read_freq_list(ah, &offset, | 588 | ath5k_eeprom_read_freq_list(ah, &offset, |
552 | AR5K_EEPROM_N_5GHZ_CHAN, pcal, | 589 | AR5K_EEPROM_N_5GHZ_CHAN, pcal, |
553 | &ee->ee_n_piers[AR5K_EEPROM_MODE_11A]); | 590 | AR5K_EEPROM_MODE_11A); |
554 | } else { | 591 | } else { |
555 | mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version); | 592 | mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version); |
556 | 593 | ||
@@ -577,23 +614,25 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) | |||
577 | 614 | ||
578 | AR5K_EEPROM_READ(offset++, val); | 615 | AR5K_EEPROM_READ(offset++, val); |
579 | pcal[9].freq |= (val >> 10) & 0x3f; | 616 | pcal[9].freq |= (val >> 10) & 0x3f; |
617 | |||
618 | /* Fixed number of piers */ | ||
580 | ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10; | 619 | ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10; |
581 | } | ||
582 | 620 | ||
583 | for(i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i += 1) { | 621 | for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) { |
584 | pcal[i].freq = ath5k_eeprom_bin2freq(ee, | 622 | pcal[i].freq = ath5k_eeprom_bin2freq(ee, |
585 | pcal[i].freq, AR5K_EEPROM_MODE_11A); | 623 | pcal[i].freq, AR5K_EEPROM_MODE_11A); |
624 | } | ||
586 | } | 625 | } |
587 | 626 | ||
588 | return 0; | 627 | return 0; |
589 | } | 628 | } |
590 | 629 | ||
630 | /* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */ | ||
591 | static inline int | 631 | static inline int |
592 | ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) | 632 | ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) |
593 | { | 633 | { |
594 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 634 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
595 | struct ath5k_chan_pcal_info *pcal; | 635 | struct ath5k_chan_pcal_info *pcal; |
596 | int i; | ||
597 | 636 | ||
598 | switch(mode) { | 637 | switch(mode) { |
599 | case AR5K_EEPROM_MODE_11B: | 638 | case AR5K_EEPROM_MODE_11B: |
@@ -608,23 +647,25 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) | |||
608 | 647 | ||
609 | ath5k_eeprom_read_freq_list(ah, &offset, | 648 | ath5k_eeprom_read_freq_list(ah, &offset, |
610 | AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal, | 649 | AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal, |
611 | &ee->ee_n_piers[mode]); | 650 | mode); |
612 | for(i = 0; i < AR5K_EEPROM_N_2GHZ_CHAN_2413; i += 1) { | ||
613 | pcal[i].freq = ath5k_eeprom_bin2freq(ee, | ||
614 | pcal[i].freq, mode); | ||
615 | } | ||
616 | 651 | ||
617 | return 0; | 652 | return 0; |
618 | } | 653 | } |
619 | 654 | ||
620 | 655 | /* Read power calibration for RF5111 chips | |
656 | * For RF5111 we have an XPD -eXternal Power Detector- curve | ||
657 | * for each calibrated channel. Each curve has PCDAC steps on | ||
658 | * x axis and power on y axis and looks like a logarithmic | ||
659 | * function. To recreate the curve and pass the power values | ||
660 | * on the pcdac table, we read 10 points here and interpolate later. | ||
661 | */ | ||
621 | static int | 662 | static int |
622 | ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) | 663 | ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) |
623 | { | 664 | { |
624 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 665 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
625 | struct ath5k_chan_pcal_info *pcal; | 666 | struct ath5k_chan_pcal_info *pcal; |
626 | int offset, ret; | 667 | int offset, ret; |
627 | int i, j; | 668 | int i; |
628 | u16 val; | 669 | u16 val; |
629 | 670 | ||
630 | offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); | 671 | offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); |
@@ -704,16 +745,22 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) | |||
704 | 745 | ||
705 | ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min, | 746 | ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min, |
706 | cdata->pcdac_max, cdata->pcdac); | 747 | cdata->pcdac_max, cdata->pcdac); |
707 | |||
708 | for (j = 0; j < AR5K_EEPROM_N_PCDAC; j++) { | ||
709 | cdata->pwr[j] = (u16) | ||
710 | (AR5K_EEPROM_POWER_STEP * cdata->pwr[j]); | ||
711 | } | ||
712 | } | 748 | } |
713 | 749 | ||
714 | return 0; | 750 | return 0; |
715 | } | 751 | } |
716 | 752 | ||
753 | /* Read power calibration for RF5112 chips | ||
754 | * For RF5112 we have 4 XPD -eXternal Power Detector- curves | ||
755 | * for each calibrated channel on 0, -6, -12 and -18dbm but we only | ||
756 | * use the higher (3) and the lower (0) curves. Each curve has PCDAC | ||
757 | * steps on x axis and power on y axis and looks like a linear | ||
758 | * function. To recreate the curve and pass the power values | ||
759 | * on the pcdac table, we read 4 points for xpd 0 and 3 points | ||
760 | * for xpd 3 here and interpolate later. | ||
761 | * | ||
762 | * Note: Many vendors just use xpd 0 so xpd 3 is zeroed. | ||
763 | */ | ||
717 | static int | 764 | static int |
718 | ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) | 765 | ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) |
719 | { | 766 | { |
@@ -790,7 +837,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) | |||
790 | 837 | ||
791 | /* PCDAC steps | 838 | /* PCDAC steps |
792 | * corresponding to the above power | 839 | * corresponding to the above power |
793 | * measurements (static) */ | 840 | * measurements (fixed) */ |
794 | chan_pcal_info->pcdac_x3[0] = 20; | 841 | chan_pcal_info->pcdac_x3[0] = 20; |
795 | chan_pcal_info->pcdac_x3[1] = 35; | 842 | chan_pcal_info->pcdac_x3[1] = 35; |
796 | chan_pcal_info->pcdac_x3[2] = 63; | 843 | chan_pcal_info->pcdac_x3[2] = 63; |
@@ -814,6 +861,13 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) | |||
814 | return 0; | 861 | return 0; |
815 | } | 862 | } |
816 | 863 | ||
864 | /* For RF2413 power calibration data doesn't start on a fixed location and | ||
865 | * if a mode is not supported, it's section is missing -not zeroed-. | ||
866 | * So we need to calculate the starting offset for each section by using | ||
867 | * these two functions */ | ||
868 | |||
869 | /* Return the size of each section based on the mode and the number of pd | ||
870 | * gains available (maximum 4). */ | ||
817 | static inline unsigned int | 871 | static inline unsigned int |
818 | ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) | 872 | ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) |
819 | { | 873 | { |
@@ -826,6 +880,8 @@ ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) | |||
826 | return sz; | 880 | return sz; |
827 | } | 881 | } |
828 | 882 | ||
883 | /* Return the starting offset for a section based on the modes supported | ||
884 | * and each section's size. */ | ||
829 | static unsigned int | 885 | static unsigned int |
830 | ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) | 886 | ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) |
831 | { | 887 | { |
@@ -834,11 +890,13 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) | |||
834 | switch(mode) { | 890 | switch(mode) { |
835 | case AR5K_EEPROM_MODE_11G: | 891 | case AR5K_EEPROM_MODE_11G: |
836 | if (AR5K_EEPROM_HDR_11B(ee->ee_header)) | 892 | if (AR5K_EEPROM_HDR_11B(ee->ee_header)) |
837 | offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + 2; | 893 | offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + |
894 | AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; | ||
838 | /* fall through */ | 895 | /* fall through */ |
839 | case AR5K_EEPROM_MODE_11B: | 896 | case AR5K_EEPROM_MODE_11B: |
840 | if (AR5K_EEPROM_HDR_11A(ee->ee_header)) | 897 | if (AR5K_EEPROM_HDR_11A(ee->ee_header)) |
841 | offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + 5; | 898 | offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + |
899 | AR5K_EEPROM_N_5GHZ_CHAN / 2; | ||
842 | /* fall through */ | 900 | /* fall through */ |
843 | case AR5K_EEPROM_MODE_11A: | 901 | case AR5K_EEPROM_MODE_11A: |
844 | break; | 902 | break; |
@@ -849,6 +907,17 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) | |||
849 | return offset; | 907 | return offset; |
850 | } | 908 | } |
851 | 909 | ||
910 | /* Read power calibration for RF2413 chips | ||
911 | * For RF2413 we have a PDDAC table (Power Detector) instead | ||
912 | * of a PCDAC and 4 pd gain curves for each calibrated channel. | ||
913 | * Each curve has PDDAC steps on x axis and power on y axis and | ||
914 | * looks like an exponential function. To recreate the curves | ||
915 | * we read here the points and interpolate later. Note that | ||
916 | * in most cases only higher and lower curves are used (like | ||
917 | * RF5112) but vendors have the oportunity to include all 4 | ||
918 | * curves on eeprom. The final curve (higher power) has an extra | ||
919 | * point for better accuracy like RF5112. | ||
920 | */ | ||
852 | static int | 921 | static int |
853 | ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) | 922 | ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) |
854 | { | 923 | { |
@@ -868,6 +937,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) | |||
868 | ee->ee_pd_gains[mode] = pd_gains; | 937 | ee->ee_pd_gains[mode] = pd_gains; |
869 | 938 | ||
870 | offset = ath5k_cal_data_offset_2413(ee, mode); | 939 | offset = ath5k_cal_data_offset_2413(ee, mode); |
940 | ee->ee_n_piers[mode] = 0; | ||
871 | switch (mode) { | 941 | switch (mode) { |
872 | case AR5K_EEPROM_MODE_11A: | 942 | case AR5K_EEPROM_MODE_11A: |
873 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | 943 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) |
@@ -1163,6 +1233,20 @@ static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned | |||
1163 | return 0; | 1233 | return 0; |
1164 | } | 1234 | } |
1165 | 1235 | ||
1236 | /* | ||
1237 | * Read per channel calibration info from EEPROM | ||
1238 | * | ||
1239 | * This info is used to calibrate the baseband power table. Imagine | ||
1240 | * that for each channel there is a power curve that's hw specific | ||
1241 | * (depends on amplifier etc) and we try to "correct" this curve using | ||
1242 | * offests we pass on to phy chip (baseband -> before amplifier) so that | ||
1243 | * it can use accurate power values when setting tx power (takes amplifier's | ||
1244 | * performance on each channel into account). | ||
1245 | * | ||
1246 | * EEPROM provides us with the offsets for some pre-calibrated channels | ||
1247 | * and we have to interpolate to create the full table for these channels and | ||
1248 | * also the table for any channel. | ||
1249 | */ | ||
1166 | static int | 1250 | static int |
1167 | ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) | 1251 | ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) |
1168 | { | 1252 | { |
@@ -1193,7 +1277,7 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) | |||
1193 | return 0; | 1277 | return 0; |
1194 | } | 1278 | } |
1195 | 1279 | ||
1196 | /* Read conformance test limits */ | 1280 | /* Read conformance test limits used for regulatory control */ |
1197 | static int | 1281 | static int |
1198 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) | 1282 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) |
1199 | { | 1283 | { |
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath5k/gpio.c index b77205adc180..64a27e73d02e 100644 --- a/drivers/net/wireless/ath5k/gpio.c +++ b/drivers/net/wireless/ath5k/gpio.c | |||
@@ -83,7 +83,7 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) | |||
83 | int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) | 83 | int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) |
84 | { | 84 | { |
85 | ATH5K_TRACE(ah->ah_sc); | 85 | ATH5K_TRACE(ah->ah_sc); |
86 | if (gpio > AR5K_NUM_GPIO) | 86 | if (gpio >= AR5K_NUM_GPIO) |
87 | return -EINVAL; | 87 | return -EINVAL; |
88 | 88 | ||
89 | ath5k_hw_reg_write(ah, | 89 | ath5k_hw_reg_write(ah, |
@@ -99,7 +99,7 @@ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) | |||
99 | int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) | 99 | int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) |
100 | { | 100 | { |
101 | ATH5K_TRACE(ah->ah_sc); | 101 | ATH5K_TRACE(ah->ah_sc); |
102 | if (gpio > AR5K_NUM_GPIO) | 102 | if (gpio >= AR5K_NUM_GPIO) |
103 | return -EINVAL; | 103 | return -EINVAL; |
104 | 104 | ||
105 | ath5k_hw_reg_write(ah, | 105 | ath5k_hw_reg_write(ah, |
@@ -115,7 +115,7 @@ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) | |||
115 | u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) | 115 | u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) |
116 | { | 116 | { |
117 | ATH5K_TRACE(ah->ah_sc); | 117 | ATH5K_TRACE(ah->ah_sc); |
118 | if (gpio > AR5K_NUM_GPIO) | 118 | if (gpio >= AR5K_NUM_GPIO) |
119 | return 0xffffffff; | 119 | return 0xffffffff; |
120 | 120 | ||
121 | /* GPIO input magic */ | 121 | /* GPIO input magic */ |
@@ -131,7 +131,7 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) | |||
131 | u32 data; | 131 | u32 data; |
132 | ATH5K_TRACE(ah->ah_sc); | 132 | ATH5K_TRACE(ah->ah_sc); |
133 | 133 | ||
134 | if (gpio > AR5K_NUM_GPIO) | 134 | if (gpio >= AR5K_NUM_GPIO) |
135 | return -EINVAL; | 135 | return -EINVAL; |
136 | 136 | ||
137 | /* GPIO output magic */ | 137 | /* GPIO output magic */ |
@@ -154,7 +154,7 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, | |||
154 | u32 data; | 154 | u32 data; |
155 | 155 | ||
156 | ATH5K_TRACE(ah->ah_sc); | 156 | ATH5K_TRACE(ah->ah_sc); |
157 | if (gpio > AR5K_NUM_GPIO) | 157 | if (gpio >= AR5K_NUM_GPIO) |
158 | return; | 158 | return; |
159 | 159 | ||
160 | /* | 160 | /* |
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c index 75eb9f43c741..f8a4a6960270 100644 --- a/drivers/net/wireless/ath5k/pcu.c +++ b/drivers/net/wireless/ath5k/pcu.c | |||
@@ -646,6 +646,23 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) | |||
646 | } | 646 | } |
647 | 647 | ||
648 | /** | 648 | /** |
649 | * ath5k_hw_set_tsf64 - Set a new 64bit TSF | ||
650 | * | ||
651 | * @ah: The &struct ath5k_hw | ||
652 | * @tsf64: The new 64bit TSF | ||
653 | * | ||
654 | * Sets the new TSF | ||
655 | */ | ||
656 | void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64) | ||
657 | { | ||
658 | ATH5K_TRACE(ah->ah_sc); | ||
659 | |||
660 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_TSF_L32); | ||
661 | ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32); | ||
662 | ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32); | ||
663 | } | ||
664 | |||
665 | /** | ||
649 | * ath5k_hw_reset_tsf - Force a TSF reset | 666 | * ath5k_hw_reset_tsf - Force a TSF reset |
650 | * | 667 | * |
651 | * @ah: The &struct ath5k_hw | 668 | * @ah: The &struct ath5k_hw |
@@ -1026,6 +1043,9 @@ int ath5k_keycache_type(const struct ieee80211_key_conf *key) | |||
1026 | return AR5K_KEYTABLE_TYPE_40; | 1043 | return AR5K_KEYTABLE_TYPE_40; |
1027 | else if (key->keylen == LEN_WEP104) | 1044 | else if (key->keylen == LEN_WEP104) |
1028 | return AR5K_KEYTABLE_TYPE_104; | 1045 | return AR5K_KEYTABLE_TYPE_104; |
1046 | return -EINVAL; | ||
1047 | default: | ||
1048 | return -EINVAL; | ||
1029 | } | 1049 | } |
1030 | return -EINVAL; | 1050 | return -EINVAL; |
1031 | } | 1051 | } |
@@ -1041,7 +1061,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | |||
1041 | __le32 key_v[5] = {}; | 1061 | __le32 key_v[5] = {}; |
1042 | __le32 key0 = 0, key1 = 0; | 1062 | __le32 key0 = 0, key1 = 0; |
1043 | __le32 *rxmic, *txmic; | 1063 | __le32 *rxmic, *txmic; |
1044 | u32 keytype; | 1064 | int keytype; |
1045 | u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; | 1065 | u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; |
1046 | bool is_tkip; | 1066 | bool is_tkip; |
1047 | const u8 *key_ptr; | 1067 | const u8 *key_ptr; |
@@ -1139,7 +1159,7 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) | |||
1139 | 1159 | ||
1140 | /* MAC may be NULL if it's a broadcast key. In this case no need to | 1160 | /* MAC may be NULL if it's a broadcast key. In this case no need to |
1141 | * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ | 1161 | * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ |
1142 | if (unlikely(mac == NULL)) { | 1162 | if (!mac) { |
1143 | low_id = 0xffffffff; | 1163 | low_id = 0xffffffff; |
1144 | high_id = 0xffff | AR5K_KEYTABLE_VALID; | 1164 | high_id = 0xffff | AR5K_KEYTABLE_VALID; |
1145 | } else { | 1165 | } else { |
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c index 1b7bc50ea8eb..5094c394a4b2 100644 --- a/drivers/net/wireless/ath5k/qcu.c +++ b/drivers/net/wireless/ath5k/qcu.c | |||
@@ -148,6 +148,7 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, | |||
148 | */ | 148 | */ |
149 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) | 149 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) |
150 | { | 150 | { |
151 | u32 pending; | ||
151 | ATH5K_TRACE(ah->ah_sc); | 152 | ATH5K_TRACE(ah->ah_sc); |
152 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | 153 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); |
153 | 154 | ||
@@ -159,7 +160,15 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) | |||
159 | if (ah->ah_version == AR5K_AR5210) | 160 | if (ah->ah_version == AR5K_AR5210) |
160 | return false; | 161 | return false; |
161 | 162 | ||
162 | return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT; | 163 | pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT); |
164 | |||
165 | /* It's possible to have no frames pending even if TXE | ||
166 | * is set. To indicate that q has not stopped return | ||
167 | * true */ | ||
168 | if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) | ||
169 | return true; | ||
170 | |||
171 | return pending; | ||
163 | } | 172 | } |
164 | 173 | ||
165 | /* | 174 | /* |
@@ -324,8 +333,18 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
324 | /* | 333 | /* |
325 | * Set misc registers | 334 | * Set misc registers |
326 | */ | 335 | */ |
327 | ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY, | 336 | /* Enable DCU early termination for this queue */ |
328 | AR5K_QUEUE_MISC(queue)); | 337 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), |
338 | AR5K_QCU_MISC_DCU_EARLY); | ||
339 | |||
340 | /* Enable DCU to wait for next fragment from QCU */ | ||
341 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), | ||
342 | AR5K_DCU_MISC_FRAG_WAIT); | ||
343 | |||
344 | /* On Maui and Spirit use the global seqnum on DCU */ | ||
345 | if (ah->ah_mac_version < AR5K_SREV_AR5211) | ||
346 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), | ||
347 | AR5K_DCU_MISC_SEQNUM_CTL); | ||
329 | 348 | ||
330 | if (tq->tqi_cbr_period) { | 349 | if (tq->tqi_cbr_period) { |
331 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, | 350 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, |
@@ -341,7 +360,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
341 | AR5K_QCU_MISC_CBR_THRES_ENABLE); | 360 | AR5K_QCU_MISC_CBR_THRES_ENABLE); |
342 | } | 361 | } |
343 | 362 | ||
344 | if (tq->tqi_ready_time) | 363 | if (tq->tqi_ready_time && |
364 | (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB)) | ||
345 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, | 365 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, |
346 | AR5K_QCU_RDYTIMECFG_INTVAL) | | 366 | AR5K_QCU_RDYTIMECFG_INTVAL) | |
347 | AR5K_QCU_RDYTIMECFG_ENABLE, | 367 | AR5K_QCU_RDYTIMECFG_ENABLE, |
@@ -383,13 +403,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
383 | AR5K_DCU_MISC_ARBLOCK_CTL_S) | | 403 | AR5K_DCU_MISC_ARBLOCK_CTL_S) | |
384 | AR5K_DCU_MISC_POST_FR_BKOFF_DIS | | 404 | AR5K_DCU_MISC_POST_FR_BKOFF_DIS | |
385 | AR5K_DCU_MISC_BCN_ENABLE); | 405 | AR5K_DCU_MISC_BCN_ENABLE); |
386 | |||
387 | ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - | ||
388 | (AR5K_TUNE_SW_BEACON_RESP - | ||
389 | AR5K_TUNE_DMA_BEACON_RESP) - | ||
390 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | | ||
391 | AR5K_QCU_RDYTIMECFG_ENABLE, | ||
392 | AR5K_QUEUE_RDYTIMECFG(queue)); | ||
393 | break; | 406 | break; |
394 | 407 | ||
395 | case AR5K_TX_QUEUE_CAB: | 408 | case AR5K_TX_QUEUE_CAB: |
@@ -398,6 +411,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
398 | AR5K_QCU_MISC_CBREXP_DIS | | 411 | AR5K_QCU_MISC_CBREXP_DIS | |
399 | AR5K_QCU_MISC_CBREXP_BCN_DIS); | 412 | AR5K_QCU_MISC_CBREXP_BCN_DIS); |
400 | 413 | ||
414 | ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - | ||
415 | (AR5K_TUNE_SW_BEACON_RESP - | ||
416 | AR5K_TUNE_DMA_BEACON_RESP) - | ||
417 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | | ||
418 | AR5K_QCU_RDYTIMECFG_ENABLE, | ||
419 | AR5K_QUEUE_RDYTIMECFG(queue)); | ||
420 | |||
401 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), | 421 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), |
402 | (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << | 422 | (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << |
403 | AR5K_DCU_MISC_ARBLOCK_CTL_S)); | 423 | AR5K_DCU_MISC_ARBLOCK_CTL_S)); |
@@ -413,6 +433,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
413 | break; | 433 | break; |
414 | } | 434 | } |
415 | 435 | ||
436 | /* TODO: Handle frame compression */ | ||
437 | |||
416 | /* | 438 | /* |
417 | * Enable interrupts for this tx queue | 439 | * Enable interrupts for this tx queue |
418 | * in the secondary interrupt mask registers | 440 | * in the secondary interrupt mask registers |
@@ -483,6 +505,9 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
483 | * by setting AR5K_TXNOFRM to zero */ | 505 | * by setting AR5K_TXNOFRM to zero */ |
484 | if (ah->ah_txq_imr_nofrm == 0) | 506 | if (ah->ah_txq_imr_nofrm == 0) |
485 | ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); | 507 | ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); |
508 | |||
509 | /* Set QCU mask for this DCU to save power */ | ||
510 | AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue); | ||
486 | } | 511 | } |
487 | 512 | ||
488 | return 0; | 513 | return 0; |
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile index 1209d14613ac..00629587b790 100644 --- a/drivers/net/wireless/ath9k/Makefile +++ b/drivers/net/wireless/ath9k/Makefile | |||
@@ -11,6 +11,8 @@ ath9k-y += hw.o \ | |||
11 | xmit.o \ | 11 | xmit.o \ |
12 | rc.o | 12 | rc.o |
13 | 13 | ||
14 | ath9k-$(CONFIG_PCI) += pci.o | ||
15 | ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o | ||
14 | ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o | 16 | ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o |
15 | 17 | ||
16 | obj-$(CONFIG_ATH9K) += ath9k.o | 18 | obj-$(CONFIG_ATH9K) += ath9k.o |
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c new file mode 100644 index 000000000000..7f2c3a09bcac --- /dev/null +++ b/drivers/net/wireless/ath9k/ahb.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Atheros Communications Inc. | ||
3 | * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
4 | * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> | ||
5 | * | ||
6 | * Permission to use, copy, modify, and/or distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | */ | ||
18 | |||
19 | #include <linux/nl80211.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/ath9k_platform.h> | ||
22 | #include "core.h" | ||
23 | #include "reg.h" | ||
24 | #include "hw.h" | ||
25 | |||
26 | /* return bus cachesize in 4B word units */ | ||
27 | static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz) | ||
28 | { | ||
29 | *csz = L1_CACHE_BYTES >> 2; | ||
30 | } | ||
31 | |||
32 | static void ath_ahb_cleanup(struct ath_softc *sc) | ||
33 | { | ||
34 | iounmap(sc->mem); | ||
35 | } | ||
36 | |||
37 | static bool ath_ahb_eeprom_read(struct ath_hal *ah, u32 off, u16 *data) | ||
38 | { | ||
39 | struct ath_softc *sc = ah->ah_sc; | ||
40 | struct platform_device *pdev = to_platform_device(sc->dev); | ||
41 | struct ath9k_platform_data *pdata; | ||
42 | |||
43 | pdata = (struct ath9k_platform_data *) pdev->dev.platform_data; | ||
44 | if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { | ||
45 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, | ||
46 | "%s: flash read failed, offset %08x is out of range\n", | ||
47 | __func__, off); | ||
48 | return false; | ||
49 | } | ||
50 | |||
51 | *data = pdata->eeprom_data[off]; | ||
52 | return true; | ||
53 | } | ||
54 | |||
55 | static struct ath_bus_ops ath_ahb_bus_ops = { | ||
56 | .read_cachesize = ath_ahb_read_cachesize, | ||
57 | .cleanup = ath_ahb_cleanup, | ||
58 | |||
59 | .eeprom_read = ath_ahb_eeprom_read, | ||
60 | }; | ||
61 | |||
62 | static int ath_ahb_probe(struct platform_device *pdev) | ||
63 | { | ||
64 | void __iomem *mem; | ||
65 | struct ath_softc *sc; | ||
66 | struct ieee80211_hw *hw; | ||
67 | struct resource *res; | ||
68 | int irq; | ||
69 | int ret = 0; | ||
70 | struct ath_hal *ah; | ||
71 | |||
72 | if (!pdev->dev.platform_data) { | ||
73 | dev_err(&pdev->dev, "no platform data specified\n"); | ||
74 | ret = -EINVAL; | ||
75 | goto err_out; | ||
76 | } | ||
77 | |||
78 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
79 | if (res == NULL) { | ||
80 | dev_err(&pdev->dev, "no memory resource found\n"); | ||
81 | ret = -ENXIO; | ||
82 | goto err_out; | ||
83 | } | ||
84 | |||
85 | mem = ioremap_nocache(res->start, res->end - res->start + 1); | ||
86 | if (mem == NULL) { | ||
87 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
88 | ret = -ENOMEM; | ||
89 | goto err_out; | ||
90 | } | ||
91 | |||
92 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
93 | if (res == NULL) { | ||
94 | dev_err(&pdev->dev, "no IRQ resource found\n"); | ||
95 | ret = -ENXIO; | ||
96 | goto err_iounmap; | ||
97 | } | ||
98 | |||
99 | irq = res->start; | ||
100 | |||
101 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); | ||
102 | if (hw == NULL) { | ||
103 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | ||
104 | ret = -ENOMEM; | ||
105 | goto err_iounmap; | ||
106 | } | ||
107 | |||
108 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
109 | platform_set_drvdata(pdev, hw); | ||
110 | |||
111 | sc = hw->priv; | ||
112 | sc->hw = hw; | ||
113 | sc->dev = &pdev->dev; | ||
114 | sc->mem = mem; | ||
115 | sc->bus_ops = &ath_ahb_bus_ops; | ||
116 | sc->irq = irq; | ||
117 | |||
118 | ret = ath_attach(AR5416_AR9100_DEVID, sc); | ||
119 | if (ret != 0) { | ||
120 | dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); | ||
121 | ret = -ENODEV; | ||
122 | goto err_free_hw; | ||
123 | } | ||
124 | |||
125 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | ||
126 | if (ret) { | ||
127 | dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret); | ||
128 | ret = -EIO; | ||
129 | goto err_detach; | ||
130 | } | ||
131 | |||
132 | ah = sc->sc_ah; | ||
133 | printk(KERN_INFO | ||
134 | "%s: Atheros AR%s MAC/BB Rev:%x, " | ||
135 | "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n", | ||
136 | wiphy_name(hw->wiphy), | ||
137 | ath_mac_bb_name(ah->ah_macVersion), | ||
138 | ah->ah_macRev, | ||
139 | ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)), | ||
140 | ah->ah_phyRev, | ||
141 | (unsigned long)mem, irq); | ||
142 | |||
143 | return 0; | ||
144 | |||
145 | err_detach: | ||
146 | ath_detach(sc); | ||
147 | err_free_hw: | ||
148 | ieee80211_free_hw(hw); | ||
149 | platform_set_drvdata(pdev, NULL); | ||
150 | err_iounmap: | ||
151 | iounmap(mem); | ||
152 | err_out: | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static int ath_ahb_remove(struct platform_device *pdev) | ||
157 | { | ||
158 | struct ieee80211_hw *hw = platform_get_drvdata(pdev); | ||
159 | |||
160 | if (hw) { | ||
161 | struct ath_softc *sc = hw->priv; | ||
162 | |||
163 | ath_cleanup(sc); | ||
164 | platform_set_drvdata(pdev, NULL); | ||
165 | } | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static struct platform_driver ath_ahb_driver = { | ||
171 | .probe = ath_ahb_probe, | ||
172 | .remove = ath_ahb_remove, | ||
173 | .driver = { | ||
174 | .name = "ath9k", | ||
175 | .owner = THIS_MODULE, | ||
176 | }, | ||
177 | }; | ||
178 | |||
179 | int ath_ahb_init(void) | ||
180 | { | ||
181 | return platform_driver_register(&ath_ahb_driver); | ||
182 | } | ||
183 | |||
184 | void ath_ahb_exit(void) | ||
185 | { | ||
186 | platform_driver_unregister(&ath_ahb_driver); | ||
187 | } | ||
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c index 251e2d9a7a4a..42197fff2a47 100644 --- a/drivers/net/wireless/ath9k/ani.c +++ b/drivers/net/wireless/ath9k/ani.c | |||
@@ -279,9 +279,8 @@ static void ath9k_ani_restart(struct ath_hal *ah) | |||
279 | static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) | 279 | static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) |
280 | { | 280 | { |
281 | struct ath_hal_5416 *ahp = AH5416(ah); | 281 | struct ath_hal_5416 *ahp = AH5416(ah); |
282 | struct ath9k_channel *chan = ah->ah_curchan; | 282 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
283 | struct ar5416AniState *aniState; | 283 | struct ar5416AniState *aniState; |
284 | enum wireless_mode mode; | ||
285 | int32_t rssi; | 284 | int32_t rssi; |
286 | 285 | ||
287 | if (!DO_ANI(ah)) | 286 | if (!DO_ANI(ah)) |
@@ -336,8 +335,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) | |||
336 | aniState->firstepLevel + 1); | 335 | aniState->firstepLevel + 1); |
337 | return; | 336 | return; |
338 | } else { | 337 | } else { |
339 | mode = ath9k_hw_chan2wmode(ah, chan); | 338 | if (conf->channel->band == IEEE80211_BAND_2GHZ) { |
340 | if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) { | ||
341 | if (!aniState->ofdmWeakSigDetectOff) | 339 | if (!aniState->ofdmWeakSigDetectOff) |
342 | ath9k_hw_ani_control(ah, | 340 | ath9k_hw_ani_control(ah, |
343 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, | 341 | ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, |
@@ -353,9 +351,8 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) | |||
353 | static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) | 351 | static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) |
354 | { | 352 | { |
355 | struct ath_hal_5416 *ahp = AH5416(ah); | 353 | struct ath_hal_5416 *ahp = AH5416(ah); |
356 | struct ath9k_channel *chan = ah->ah_curchan; | 354 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
357 | struct ar5416AniState *aniState; | 355 | struct ar5416AniState *aniState; |
358 | enum wireless_mode mode; | ||
359 | int32_t rssi; | 356 | int32_t rssi; |
360 | 357 | ||
361 | if (!DO_ANI(ah)) | 358 | if (!DO_ANI(ah)) |
@@ -381,8 +378,7 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) | |||
381 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, | 378 | ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, |
382 | aniState->firstepLevel + 1); | 379 | aniState->firstepLevel + 1); |
383 | } else { | 380 | } else { |
384 | mode = ath9k_hw_chan2wmode(ah, chan); | 381 | if (conf->channel->band == IEEE80211_BAND_2GHZ) { |
385 | if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) { | ||
386 | if (aniState->firstepLevel > 0) | 382 | if (aniState->firstepLevel > 0) |
387 | ath9k_hw_ani_control(ah, | 383 | ath9k_hw_ani_control(ah, |
388 | ATH9K_ANI_FIRSTEP_LEVEL, 0); | 384 | ATH9K_ANI_FIRSTEP_LEVEL, 0); |
@@ -555,6 +551,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, | |||
555 | struct ar5416AniState *aniState; | 551 | struct ar5416AniState *aniState; |
556 | int32_t listenTime; | 552 | int32_t listenTime; |
557 | 553 | ||
554 | if (!DO_ANI(ah)) | ||
555 | return; | ||
556 | |||
558 | aniState = ahp->ah_curani; | 557 | aniState = ahp->ah_curani; |
559 | ahp->ah_stats.ast_nodestats = *stats; | 558 | ahp->ah_stats.ast_nodestats = *stats; |
560 | 559 | ||
@@ -614,9 +613,6 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, | |||
614 | aniState->cckPhyErrCount = cckPhyErrCnt; | 613 | aniState->cckPhyErrCount = cckPhyErrCnt; |
615 | } | 614 | } |
616 | 615 | ||
617 | if (!DO_ANI(ah)) | ||
618 | return; | ||
619 | |||
620 | if (aniState->listenTime > 5 * ahp->ah_aniPeriod) { | 616 | if (aniState->listenTime > 5 * ahp->ah_aniPeriod) { |
621 | if (aniState->ofdmPhyErrCount <= aniState->listenTime * | 617 | if (aniState->ofdmPhyErrCount <= aniState->listenTime * |
622 | aniState->ofdmTrigLow / 1000 && | 618 | aniState->ofdmTrigLow / 1000 && |
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index d27813502953..5289d2878111 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h | |||
@@ -198,6 +198,7 @@ enum ath9k_hw_caps { | |||
198 | ATH9K_HW_CAP_AUTOSLEEP = BIT(19), | 198 | ATH9K_HW_CAP_AUTOSLEEP = BIT(19), |
199 | ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20), | 199 | ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20), |
200 | ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21), | 200 | ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21), |
201 | ATH9K_HW_CAP_BT_COEX = BIT(22) | ||
201 | }; | 202 | }; |
202 | 203 | ||
203 | enum ath9k_capability_type { | 204 | enum ath9k_capability_type { |
@@ -453,24 +454,15 @@ struct ath9k_11n_rate_series { | |||
453 | CHANNEL_HT40MINUS) | 454 | CHANNEL_HT40MINUS) |
454 | 455 | ||
455 | struct ath9k_channel { | 456 | struct ath9k_channel { |
457 | struct ieee80211_channel *chan; | ||
456 | u16 channel; | 458 | u16 channel; |
457 | u32 channelFlags; | 459 | u32 channelFlags; |
458 | u8 privFlags; | ||
459 | int8_t maxRegTxPower; | ||
460 | int8_t maxTxPower; | ||
461 | int8_t minTxPower; | ||
462 | u32 chanmode; | 460 | u32 chanmode; |
463 | int32_t CalValid; | 461 | int32_t CalValid; |
464 | bool oneTimeCalsDone; | 462 | bool oneTimeCalsDone; |
465 | int8_t iCoff; | 463 | int8_t iCoff; |
466 | int8_t qCoff; | 464 | int8_t qCoff; |
467 | int16_t rawNoiseFloor; | 465 | int16_t rawNoiseFloor; |
468 | int8_t antennaMax; | ||
469 | u32 regDmnFlags; | ||
470 | u32 conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */ | ||
471 | #ifdef ATH_NF_PER_CHAN | ||
472 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | ||
473 | #endif | ||
474 | }; | 466 | }; |
475 | 467 | ||
476 | #define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \ | 468 | #define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \ |
@@ -498,7 +490,6 @@ struct ath9k_channel { | |||
498 | ((_c)->chanmode == CHANNEL_G_HT40MINUS)) | 490 | ((_c)->chanmode == CHANNEL_G_HT40MINUS)) |
499 | #define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c))) | 491 | #define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c))) |
500 | 492 | ||
501 | #define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990) | ||
502 | #define IS_CHAN_A_5MHZ_SPACED(_c) \ | 493 | #define IS_CHAN_A_5MHZ_SPACED(_c) \ |
503 | ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ | 494 | ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ |
504 | (((_c)->channel % 20) != 0) && \ | 495 | (((_c)->channel % 20) != 0) && \ |
@@ -751,6 +742,7 @@ struct ath9k_node_stats { | |||
751 | #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 | 742 | #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 |
752 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 | 743 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 |
753 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2 | 744 | #define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2 |
745 | #define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3 | ||
754 | #define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5 | 746 | #define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5 |
755 | #define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6 | 747 | #define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6 |
756 | 748 | ||
@@ -787,23 +779,24 @@ struct ath_hal { | |||
787 | u16 ah_currentRD; | 779 | u16 ah_currentRD; |
788 | u16 ah_currentRDExt; | 780 | u16 ah_currentRDExt; |
789 | u16 ah_currentRDInUse; | 781 | u16 ah_currentRDInUse; |
790 | u16 ah_currentRD5G; | 782 | char alpha2[2]; |
791 | u16 ah_currentRD2G; | 783 | struct reg_dmn_pair_mapping *regpair; |
792 | char ah_iso[4]; | 784 | enum ath9k_power_mode ah_power_mode; |
785 | enum ath9k_power_mode ah_restore_mode; | ||
793 | 786 | ||
794 | struct ath9k_channel ah_channels[150]; | 787 | struct ath9k_channel ah_channels[38]; |
795 | struct ath9k_channel *ah_curchan; | 788 | struct ath9k_channel *ah_curchan; |
796 | u32 ah_nchan; | ||
797 | 789 | ||
798 | bool ah_isPciExpress; | 790 | bool ah_isPciExpress; |
799 | u16 ah_txTrigLevel; | 791 | u16 ah_txTrigLevel; |
800 | u16 ah_rfsilent; | 792 | u16 ah_rfsilent; |
801 | u32 ah_rfkill_gpio; | 793 | u32 ah_rfkill_gpio; |
802 | u32 ah_rfkill_polarity; | 794 | u32 ah_rfkill_polarity; |
803 | 795 | u32 ah_btactive_gpio; | |
804 | #ifndef ATH_NF_PER_CHAN | 796 | u32 ah_wlanactive_gpio; |
805 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | 797 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; |
806 | #endif | 798 | |
799 | bool sw_mgmt_crypto; | ||
807 | }; | 800 | }; |
808 | 801 | ||
809 | struct chan_centers { | 802 | struct chan_centers { |
@@ -816,8 +809,6 @@ struct ath_rate_table; | |||
816 | 809 | ||
817 | /* Helpers */ | 810 | /* Helpers */ |
818 | 811 | ||
819 | enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah, | ||
820 | const struct ath9k_channel *chan); | ||
821 | bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val); | 812 | bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val); |
822 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); | 813 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); |
823 | bool ath9k_get_channel_edges(struct ath_hal *ah, | 814 | bool ath9k_get_channel_edges(struct ath_hal *ah, |
@@ -827,7 +818,6 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, | |||
827 | struct ath_rate_table *rates, | 818 | struct ath_rate_table *rates, |
828 | u32 frameLen, u16 rateix, | 819 | u32 frameLen, u16 rateix, |
829 | bool shortPreamble); | 820 | bool shortPreamble); |
830 | u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags); | ||
831 | void ath9k_hw_get_channel_centers(struct ath_hal *ah, | 821 | void ath9k_hw_get_channel_centers(struct ath_hal *ah, |
832 | struct ath9k_channel *chan, | 822 | struct ath9k_channel *chan, |
833 | struct chan_centers *centers); | 823 | struct chan_centers *centers); |
@@ -843,11 +833,8 @@ void ath9k_hw_rfdetach(struct ath_hal *ah); | |||
843 | 833 | ||
844 | /* HW Reset */ | 834 | /* HW Reset */ |
845 | 835 | ||
846 | bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | 836 | int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, |
847 | enum ath9k_ht_macmode macmode, | 837 | bool bChannelChange); |
848 | u8 txchainmask, u8 rxchainmask, | ||
849 | enum ath9k_ht_extprotspacing extprotspacing, | ||
850 | bool bChannelChange, int *status); | ||
851 | 838 | ||
852 | /* Key Cache Management */ | 839 | /* Key Cache Management */ |
853 | 840 | ||
@@ -887,7 +874,6 @@ void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val); | |||
887 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 874 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
888 | void ath9k_enable_rfkill(struct ath_hal *ah); | 875 | void ath9k_enable_rfkill(struct ath_hal *ah); |
889 | #endif | 876 | #endif |
890 | int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg); | ||
891 | u32 ath9k_hw_getdefantenna(struct ath_hal *ah); | 877 | u32 ath9k_hw_getdefantenna(struct ath_hal *ah); |
892 | void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna); | 878 | void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna); |
893 | bool ath9k_hw_setantennaswitch(struct ath_hal *ah, | 879 | bool ath9k_hw_setantennaswitch(struct ath_hal *ah, |
@@ -912,23 +898,25 @@ void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask); | |||
912 | bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask); | 898 | bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask); |
913 | void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId); | 899 | void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId); |
914 | u64 ath9k_hw_gettsf64(struct ath_hal *ah); | 900 | u64 ath9k_hw_gettsf64(struct ath_hal *ah); |
901 | void ath9k_hw_settsf64(struct ath_hal *ah, u64 tsf64); | ||
915 | void ath9k_hw_reset_tsf(struct ath_hal *ah); | 902 | void ath9k_hw_reset_tsf(struct ath_hal *ah); |
916 | bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting); | 903 | bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting); |
917 | bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us); | 904 | bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us); |
918 | void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode); | 905 | void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode); |
919 | 906 | ||
920 | /* Regulatory */ | 907 | /* Regulatory */ |
908 | u16 ath9k_regd_get_rd(struct ath_hal *ah); | ||
909 | bool ath9k_is_world_regd(struct ath_hal *ah); | ||
910 | const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah); | ||
911 | const struct ieee80211_regdomain *ath9k_default_world_regdomain(void); | ||
912 | |||
913 | void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby); | ||
914 | void ath9k_reg_apply_radar_flags(struct wiphy *wiphy); | ||
921 | 915 | ||
922 | bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah); | 916 | int ath9k_regd_init(struct ath_hal *ah); |
923 | struct ath9k_channel* ath9k_regd_check_channel(struct ath_hal *ah, | 917 | bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah); |
924 | const struct ath9k_channel *c); | ||
925 | u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan); | 918 | u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan); |
926 | u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah, | 919 | int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); |
927 | struct ath9k_channel *chan); | ||
928 | bool ath9k_regd_init_channels(struct ath_hal *ah, | ||
929 | u32 maxchans, u32 *nchans, u8 *regclassids, | ||
930 | u32 maxregids, u32 *nregids, u16 cc, | ||
931 | bool enableOutdoor, bool enableExtendedChannels); | ||
932 | 920 | ||
933 | /* ANI */ | 921 | /* ANI */ |
934 | 922 | ||
@@ -951,8 +939,7 @@ void ath9k_hw_ani_detach(struct ath_hal *ah); | |||
951 | 939 | ||
952 | /* Calibration */ | 940 | /* Calibration */ |
953 | 941 | ||
954 | void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, | 942 | bool ath9k_hw_reset_calvalid(struct ath_hal *ah); |
955 | bool *isCalDone); | ||
956 | void ath9k_hw_start_nfcal(struct ath_hal *ah); | 943 | void ath9k_hw_start_nfcal(struct ath_hal *ah); |
957 | void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan); | 944 | void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan); |
958 | int16_t ath9k_hw_getnf(struct ath_hal *ah, | 945 | int16_t ath9k_hw_getnf(struct ath_hal *ah, |
@@ -987,9 +974,8 @@ bool ath9k_hw_set_power_cal_table(struct ath_hal *ah, | |||
987 | int16_t *pTxPowerIndexOffset); | 974 | int16_t *pTxPowerIndexOffset); |
988 | bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, | 975 | bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, |
989 | struct ath9k_channel *chan); | 976 | struct ath9k_channel *chan); |
990 | int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, | 977 | u16 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, |
991 | struct ath9k_channel *chan, | 978 | struct ath9k_channel *chan); |
992 | u8 index, u16 *config); | ||
993 | u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah, | 979 | u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah, |
994 | enum ieee80211_band freq_band); | 980 | enum ieee80211_band freq_band); |
995 | u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz); | 981 | u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz); |
@@ -1053,5 +1039,6 @@ void ath9k_hw_rxena(struct ath_hal *ah); | |||
1053 | void ath9k_hw_startpcureceive(struct ath_hal *ah); | 1039 | void ath9k_hw_startpcureceive(struct ath_hal *ah); |
1054 | void ath9k_hw_stoppcurecv(struct ath_hal *ah); | 1040 | void ath9k_hw_stoppcurecv(struct ath_hal *ah); |
1055 | bool ath9k_hw_stopdmarecv(struct ath_hal *ah); | 1041 | bool ath9k_hw_stopdmarecv(struct ath_hal *ah); |
1042 | void ath9k_hw_btcoex_enable(struct ath_hal *ah); | ||
1056 | 1043 | ||
1057 | #endif | 1044 | #endif |
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 3ab0b43aaf93..61d37be9717e 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c | |||
@@ -164,9 +164,9 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
164 | bf = avp->av_bcbuf; | 164 | bf = avp->av_bcbuf; |
165 | skb = (struct sk_buff *)bf->bf_mpdu; | 165 | skb = (struct sk_buff *)bf->bf_mpdu; |
166 | if (skb) { | 166 | if (skb) { |
167 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, | 167 | dma_unmap_single(sc->dev, bf->bf_dmacontext, |
168 | skb->len, | 168 | skb->len, |
169 | PCI_DMA_TODEVICE); | 169 | DMA_TO_DEVICE); |
170 | dev_kfree_skb_any(skb); | 170 | dev_kfree_skb_any(skb); |
171 | } | 171 | } |
172 | 172 | ||
@@ -188,14 +188,14 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
188 | } | 188 | } |
189 | 189 | ||
190 | bf->bf_buf_addr = bf->bf_dmacontext = | 190 | bf->bf_buf_addr = bf->bf_dmacontext = |
191 | pci_map_single(sc->pdev, skb->data, | 191 | dma_map_single(sc->dev, skb->data, |
192 | skb->len, | 192 | skb->len, |
193 | PCI_DMA_TODEVICE); | 193 | DMA_TO_DEVICE); |
194 | if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { | 194 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { |
195 | dev_kfree_skb_any(skb); | 195 | dev_kfree_skb_any(skb); |
196 | bf->bf_mpdu = NULL; | 196 | bf->bf_mpdu = NULL; |
197 | DPRINTF(sc, ATH_DBG_CONFIG, | 197 | DPRINTF(sc, ATH_DBG_CONFIG, |
198 | "pci_dma_mapping_error() on beaconing\n"); | 198 | "dma_mapping_error() on beaconing\n"); |
199 | return NULL; | 199 | return NULL; |
200 | } | 200 | } |
201 | 201 | ||
@@ -220,7 +220,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) | |||
220 | * acquires txq lock inside. | 220 | * acquires txq lock inside. |
221 | */ | 221 | */ |
222 | if (sc->sc_nvaps > 1) { | 222 | if (sc->sc_nvaps > 1) { |
223 | ath_tx_draintxq(sc, cabq, false); | 223 | ath_draintxq(sc, cabq, false); |
224 | DPRINTF(sc, ATH_DBG_BEACON, | 224 | DPRINTF(sc, ATH_DBG_BEACON, |
225 | "flush previous cabq traffic\n"); | 225 | "flush previous cabq traffic\n"); |
226 | } | 226 | } |
@@ -343,9 +343,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) | |||
343 | bf = avp->av_bcbuf; | 343 | bf = avp->av_bcbuf; |
344 | if (bf->bf_mpdu != NULL) { | 344 | if (bf->bf_mpdu != NULL) { |
345 | skb = (struct sk_buff *)bf->bf_mpdu; | 345 | skb = (struct sk_buff *)bf->bf_mpdu; |
346 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, | 346 | dma_unmap_single(sc->dev, bf->bf_dmacontext, |
347 | skb->len, | 347 | skb->len, |
348 | PCI_DMA_TODEVICE); | 348 | DMA_TO_DEVICE); |
349 | dev_kfree_skb_any(skb); | 349 | dev_kfree_skb_any(skb); |
350 | bf->bf_mpdu = NULL; | 350 | bf->bf_mpdu = NULL; |
351 | } | 351 | } |
@@ -402,14 +402,14 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) | |||
402 | 402 | ||
403 | bf->bf_mpdu = skb; | 403 | bf->bf_mpdu = skb; |
404 | bf->bf_buf_addr = bf->bf_dmacontext = | 404 | bf->bf_buf_addr = bf->bf_dmacontext = |
405 | pci_map_single(sc->pdev, skb->data, | 405 | dma_map_single(sc->dev, skb->data, |
406 | skb->len, | 406 | skb->len, |
407 | PCI_DMA_TODEVICE); | 407 | DMA_TO_DEVICE); |
408 | if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) { | 408 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { |
409 | dev_kfree_skb_any(skb); | 409 | dev_kfree_skb_any(skb); |
410 | bf->bf_mpdu = NULL; | 410 | bf->bf_mpdu = NULL; |
411 | DPRINTF(sc, ATH_DBG_CONFIG, | 411 | DPRINTF(sc, ATH_DBG_CONFIG, |
412 | "pci_dma_mapping_error() on beacon alloc\n"); | 412 | "dma_mapping_error() on beacon alloc\n"); |
413 | return -ENOMEM; | 413 | return -ENOMEM; |
414 | } | 414 | } |
415 | 415 | ||
@@ -429,9 +429,9 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) | |||
429 | bf = avp->av_bcbuf; | 429 | bf = avp->av_bcbuf; |
430 | if (bf->bf_mpdu != NULL) { | 430 | if (bf->bf_mpdu != NULL) { |
431 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; | 431 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; |
432 | pci_unmap_single(sc->pdev, bf->bf_dmacontext, | 432 | dma_unmap_single(sc->dev, bf->bf_dmacontext, |
433 | skb->len, | 433 | skb->len, |
434 | PCI_DMA_TODEVICE); | 434 | DMA_TO_DEVICE); |
435 | dev_kfree_skb_any(skb); | 435 | dev_kfree_skb_any(skb); |
436 | bf->bf_mpdu = NULL; | 436 | bf->bf_mpdu = NULL; |
437 | } | 437 | } |
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c index 3c7454fc51bd..69ff01ce968b 100644 --- a/drivers/net/wireless/ath9k/calib.c +++ b/drivers/net/wireless/ath9k/calib.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include "reg.h" | 19 | #include "reg.h" |
20 | #include "phy.h" | 20 | #include "phy.h" |
21 | 21 | ||
22 | static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 }; | ||
23 | |||
24 | /* We can tune this as we go by monitoring really low values */ | 22 | /* We can tune this as we go by monitoring really low values */ |
25 | #define ATH9K_NF_TOO_LOW -60 | 23 | #define ATH9K_NF_TOO_LOW -60 |
26 | 24 | ||
@@ -107,27 +105,29 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, | |||
107 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | 105 | "NF calibrated [ctl] [chain 0] is %d\n", nf); |
108 | nfarray[0] = nf; | 106 | nfarray[0] = nf; |
109 | 107 | ||
110 | if (AR_SREV_9280_10_OR_LATER(ah)) | 108 | if (!AR_SREV_9285(ah)) { |
111 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | 109 | if (AR_SREV_9280_10_OR_LATER(ah)) |
112 | AR9280_PHY_CH1_MINCCA_PWR); | 110 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), |
113 | else | 111 | AR9280_PHY_CH1_MINCCA_PWR); |
114 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | 112 | else |
115 | AR_PHY_CH1_MINCCA_PWR); | 113 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), |
114 | AR_PHY_CH1_MINCCA_PWR); | ||
116 | 115 | ||
117 | if (nf & 0x100) | ||
118 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
119 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
120 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | ||
121 | nfarray[1] = nf; | ||
122 | |||
123 | if (!AR_SREV_9280(ah)) { | ||
124 | nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), | ||
125 | AR_PHY_CH2_MINCCA_PWR); | ||
126 | if (nf & 0x100) | 116 | if (nf & 0x100) |
127 | nf = 0 - ((nf ^ 0x1ff) + 1); | 117 | nf = 0 - ((nf ^ 0x1ff) + 1); |
128 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 118 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
129 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | 119 | "NF calibrated [ctl] [chain 1] is %d\n", nf); |
130 | nfarray[2] = nf; | 120 | nfarray[1] = nf; |
121 | |||
122 | if (!AR_SREV_9280(ah)) { | ||
123 | nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), | ||
124 | AR_PHY_CH2_MINCCA_PWR); | ||
125 | if (nf & 0x100) | ||
126 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
127 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
128 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | ||
129 | nfarray[2] = nf; | ||
130 | } | ||
131 | } | 131 | } |
132 | 132 | ||
133 | if (AR_SREV_9280_10_OR_LATER(ah)) | 133 | if (AR_SREV_9280_10_OR_LATER(ah)) |
@@ -143,51 +143,45 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, | |||
143 | "NF calibrated [ext] [chain 0] is %d\n", nf); | 143 | "NF calibrated [ext] [chain 0] is %d\n", nf); |
144 | nfarray[3] = nf; | 144 | nfarray[3] = nf; |
145 | 145 | ||
146 | if (AR_SREV_9280_10_OR_LATER(ah)) | 146 | if (!AR_SREV_9285(ah)) { |
147 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | 147 | if (AR_SREV_9280_10_OR_LATER(ah)) |
148 | AR9280_PHY_CH1_EXT_MINCCA_PWR); | 148 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), |
149 | else | 149 | AR9280_PHY_CH1_EXT_MINCCA_PWR); |
150 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | 150 | else |
151 | AR_PHY_CH1_EXT_MINCCA_PWR); | 151 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), |
152 | 152 | AR_PHY_CH1_EXT_MINCCA_PWR); | |
153 | if (nf & 0x100) | ||
154 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
155 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
156 | "NF calibrated [ext] [chain 1] is %d\n", nf); | ||
157 | nfarray[4] = nf; | ||
158 | 153 | ||
159 | if (!AR_SREV_9280(ah)) { | ||
160 | nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), | ||
161 | AR_PHY_CH2_EXT_MINCCA_PWR); | ||
162 | if (nf & 0x100) | 154 | if (nf & 0x100) |
163 | nf = 0 - ((nf ^ 0x1ff) + 1); | 155 | nf = 0 - ((nf ^ 0x1ff) + 1); |
164 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 156 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
165 | "NF calibrated [ext] [chain 2] is %d\n", nf); | 157 | "NF calibrated [ext] [chain 1] is %d\n", nf); |
166 | nfarray[5] = nf; | 158 | nfarray[4] = nf; |
159 | |||
160 | if (!AR_SREV_9280(ah)) { | ||
161 | nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), | ||
162 | AR_PHY_CH2_EXT_MINCCA_PWR); | ||
163 | if (nf & 0x100) | ||
164 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
165 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
166 | "NF calibrated [ext] [chain 2] is %d\n", nf); | ||
167 | nfarray[5] = nf; | ||
168 | } | ||
167 | } | 169 | } |
168 | } | 170 | } |
169 | 171 | ||
170 | static bool getNoiseFloorThresh(struct ath_hal *ah, | 172 | static bool getNoiseFloorThresh(struct ath_hal *ah, |
171 | const struct ath9k_channel *chan, | 173 | enum ieee80211_band band, |
172 | int16_t *nft) | 174 | int16_t *nft) |
173 | { | 175 | { |
174 | switch (chan->chanmode) { | 176 | switch (band) { |
175 | case CHANNEL_A: | 177 | case IEEE80211_BAND_5GHZ: |
176 | case CHANNEL_A_HT20: | ||
177 | case CHANNEL_A_HT40PLUS: | ||
178 | case CHANNEL_A_HT40MINUS: | ||
179 | *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5); | 178 | *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5); |
180 | break; | 179 | break; |
181 | case CHANNEL_B: | 180 | case IEEE80211_BAND_2GHZ: |
182 | case CHANNEL_G: | ||
183 | case CHANNEL_G_HT20: | ||
184 | case CHANNEL_G_HT40PLUS: | ||
185 | case CHANNEL_G_HT40MINUS: | ||
186 | *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2); | 181 | *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2); |
187 | break; | 182 | break; |
188 | default: | 183 | default: |
189 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 184 | BUG_ON(1); |
190 | "invalid channel flags 0x%x\n", chan->channelFlags); | ||
191 | return false; | 185 | return false; |
192 | } | 186 | } |
193 | 187 | ||
@@ -285,27 +279,24 @@ static void ath9k_hw_per_calibration(struct ath_hal *ah, | |||
285 | } | 279 | } |
286 | } | 280 | } |
287 | 281 | ||
282 | /* Assumes you are talking about the currently configured channel */ | ||
288 | static bool ath9k_hw_iscal_supported(struct ath_hal *ah, | 283 | static bool ath9k_hw_iscal_supported(struct ath_hal *ah, |
289 | struct ath9k_channel *chan, | ||
290 | enum hal_cal_types calType) | 284 | enum hal_cal_types calType) |
291 | { | 285 | { |
292 | struct ath_hal_5416 *ahp = AH5416(ah); | 286 | struct ath_hal_5416 *ahp = AH5416(ah); |
293 | bool retval = false; | 287 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
294 | 288 | ||
295 | switch (calType & ahp->ah_suppCals) { | 289 | switch (calType & ahp->ah_suppCals) { |
296 | case IQ_MISMATCH_CAL: | 290 | case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ |
297 | if (!IS_CHAN_B(chan)) | 291 | return true; |
298 | retval = true; | ||
299 | break; | ||
300 | case ADC_GAIN_CAL: | 292 | case ADC_GAIN_CAL: |
301 | case ADC_DC_CAL: | 293 | case ADC_DC_CAL: |
302 | if (!IS_CHAN_B(chan) | 294 | if (conf->channel->band == IEEE80211_BAND_5GHZ && |
303 | && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) | 295 | conf_is_ht20(conf)) |
304 | retval = true; | 296 | return true; |
305 | break; | 297 | break; |
306 | } | 298 | } |
307 | 299 | return false; | |
308 | return retval; | ||
309 | } | 300 | } |
310 | 301 | ||
311 | static void ath9k_hw_iqcal_collect(struct ath_hal *ah) | 302 | static void ath9k_hw_iqcal_collect(struct ath_hal *ah) |
@@ -573,50 +564,40 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains) | |||
573 | AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); | 564 | AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); |
574 | } | 565 | } |
575 | 566 | ||
576 | void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, | 567 | /* This is done for the currently configured channel */ |
577 | bool *isCalDone) | 568 | bool ath9k_hw_reset_calvalid(struct ath_hal *ah) |
578 | { | 569 | { |
579 | struct ath_hal_5416 *ahp = AH5416(ah); | 570 | struct ath_hal_5416 *ahp = AH5416(ah); |
580 | struct ath9k_channel *ichan = | 571 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
581 | ath9k_regd_check_channel(ah, chan); | ||
582 | struct hal_cal_list *currCal = ahp->ah_cal_list_curr; | 572 | struct hal_cal_list *currCal = ahp->ah_cal_list_curr; |
583 | 573 | ||
584 | *isCalDone = true; | 574 | if (!ah->ah_curchan) |
575 | return true; | ||
585 | 576 | ||
586 | if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) | 577 | if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) |
587 | return; | 578 | return true; |
588 | 579 | ||
589 | if (currCal == NULL) | 580 | if (currCal == NULL) |
590 | return; | 581 | return true; |
591 | |||
592 | if (ichan == NULL) { | ||
593 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | ||
594 | "invalid channel %u/0x%x; no mapping\n", | ||
595 | chan->channel, chan->channelFlags); | ||
596 | return; | ||
597 | } | ||
598 | |||
599 | 582 | ||
600 | if (currCal->calState != CAL_DONE) { | 583 | if (currCal->calState != CAL_DONE) { |
601 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 584 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
602 | "Calibration state incorrect, %d\n", | 585 | "Calibration state incorrect, %d\n", |
603 | currCal->calState); | 586 | currCal->calState); |
604 | return; | 587 | return true; |
605 | } | 588 | } |
606 | 589 | ||
607 | 590 | if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType)) | |
608 | if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType)) | 591 | return true; |
609 | return; | ||
610 | 592 | ||
611 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 593 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
612 | "Resetting Cal %d state for channel %u/0x%x\n", | 594 | "Resetting Cal %d state for channel %u\n", |
613 | currCal->calData->calType, chan->channel, | 595 | currCal->calData->calType, conf->channel->center_freq); |
614 | chan->channelFlags); | ||
615 | 596 | ||
616 | ichan->CalValid &= ~currCal->calData->calType; | 597 | ah->ah_curchan->CalValid &= ~currCal->calData->calType; |
617 | currCal->calState = CAL_WAITING; | 598 | currCal->calState = CAL_WAITING; |
618 | 599 | ||
619 | *isCalDone = false; | 600 | return false; |
620 | } | 601 | } |
621 | 602 | ||
622 | void ath9k_hw_start_nfcal(struct ath_hal *ah) | 603 | void ath9k_hw_start_nfcal(struct ath_hal *ah) |
@@ -643,16 +624,14 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan) | |||
643 | }; | 624 | }; |
644 | u8 chainmask; | 625 | u8 chainmask; |
645 | 626 | ||
646 | if (AR_SREV_9280(ah)) | 627 | if (AR_SREV_9285(ah)) |
628 | chainmask = 0x9; | ||
629 | else if (AR_SREV_9280(ah)) | ||
647 | chainmask = 0x1B; | 630 | chainmask = 0x1B; |
648 | else | 631 | else |
649 | chainmask = 0x3F; | 632 | chainmask = 0x3F; |
650 | 633 | ||
651 | #ifdef ATH_NF_PER_CHAN | ||
652 | h = chan->nfCalHist; | ||
653 | #else | ||
654 | h = ah->nfCalHist; | 634 | h = ah->nfCalHist; |
655 | #endif | ||
656 | 635 | ||
657 | for (i = 0; i < NUM_NF_READINGS; i++) { | 636 | for (i = 0; i < NUM_NF_READINGS; i++) { |
658 | if (chainmask & (1 << i)) { | 637 | if (chainmask & (1 << i)) { |
@@ -692,12 +671,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, | |||
692 | int16_t nf, nfThresh; | 671 | int16_t nf, nfThresh; |
693 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; | 672 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; |
694 | struct ath9k_nfcal_hist *h; | 673 | struct ath9k_nfcal_hist *h; |
695 | u8 chainmask; | 674 | struct ieee80211_channel *c = chan->chan; |
696 | |||
697 | if (AR_SREV_9280(ah)) | ||
698 | chainmask = 0x1B; | ||
699 | else | ||
700 | chainmask = 0x3F; | ||
701 | 675 | ||
702 | chan->channelFlags &= (~CHANNEL_CW_INT); | 676 | chan->channelFlags &= (~CHANNEL_CW_INT); |
703 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { | 677 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { |
@@ -709,7 +683,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, | |||
709 | } else { | 683 | } else { |
710 | ath9k_hw_do_getnf(ah, nfarray); | 684 | ath9k_hw_do_getnf(ah, nfarray); |
711 | nf = nfarray[0]; | 685 | nf = nfarray[0]; |
712 | if (getNoiseFloorThresh(ah, chan, &nfThresh) | 686 | if (getNoiseFloorThresh(ah, c->band, &nfThresh) |
713 | && nf > nfThresh) { | 687 | && nf > nfThresh) { |
714 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 688 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
715 | "noise floor failed detected; " | 689 | "noise floor failed detected; " |
@@ -719,11 +693,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, | |||
719 | } | 693 | } |
720 | } | 694 | } |
721 | 695 | ||
722 | #ifdef ATH_NF_PER_CHAN | ||
723 | h = chan->nfCalHist; | ||
724 | #else | ||
725 | h = ah->nfCalHist; | 696 | h = ah->nfCalHist; |
726 | #endif | ||
727 | 697 | ||
728 | ath9k_hw_update_nfcal_hist_buffer(h, nfarray); | 698 | ath9k_hw_update_nfcal_hist_buffer(h, nfarray); |
729 | chan->rawNoiseFloor = h[0].privNF; | 699 | chan->rawNoiseFloor = h[0].privNF; |
@@ -750,21 +720,12 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah) | |||
750 | 720 | ||
751 | s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) | 721 | s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) |
752 | { | 722 | { |
753 | struct ath9k_channel *ichan; | ||
754 | s16 nf; | 723 | s16 nf; |
755 | 724 | ||
756 | ichan = ath9k_regd_check_channel(ah, chan); | 725 | if (chan->rawNoiseFloor == 0) |
757 | if (ichan == NULL) { | 726 | nf = -96; |
758 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 727 | else |
759 | "invalid channel %u/0x%x; no mapping\n", | 728 | nf = chan->rawNoiseFloor; |
760 | chan->channel, chan->channelFlags); | ||
761 | return ATH_DEFAULT_NOISE_FLOOR; | ||
762 | } | ||
763 | if (ichan->rawNoiseFloor == 0) { | ||
764 | enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); | ||
765 | nf = NOISE_FLOOR[mode]; | ||
766 | } else | ||
767 | nf = ichan->rawNoiseFloor; | ||
768 | 729 | ||
769 | if (!ath9k_hw_nf_in_range(ah, nf)) | 730 | if (!ath9k_hw_nf_in_range(ah, nf)) |
770 | nf = ATH_DEFAULT_NOISE_FLOOR; | 731 | nf = ATH_DEFAULT_NOISE_FLOOR; |
@@ -778,21 +739,13 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, | |||
778 | { | 739 | { |
779 | struct ath_hal_5416 *ahp = AH5416(ah); | 740 | struct ath_hal_5416 *ahp = AH5416(ah); |
780 | struct hal_cal_list *currCal = ahp->ah_cal_list_curr; | 741 | struct hal_cal_list *currCal = ahp->ah_cal_list_curr; |
781 | struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); | ||
782 | 742 | ||
783 | *isCalDone = true; | 743 | *isCalDone = true; |
784 | 744 | ||
785 | if (ichan == NULL) { | ||
786 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | ||
787 | "invalid channel %u/0x%x; no mapping\n", | ||
788 | chan->channel, chan->channelFlags); | ||
789 | return false; | ||
790 | } | ||
791 | |||
792 | if (currCal && | 745 | if (currCal && |
793 | (currCal->calState == CAL_RUNNING || | 746 | (currCal->calState == CAL_RUNNING || |
794 | currCal->calState == CAL_WAITING)) { | 747 | currCal->calState == CAL_WAITING)) { |
795 | ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal, | 748 | ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal, |
796 | isCalDone); | 749 | isCalDone); |
797 | if (*isCalDone) { | 750 | if (*isCalDone) { |
798 | ahp->ah_cal_list_curr = currCal = currCal->calNext; | 751 | ahp->ah_cal_list_curr = currCal = currCal->calNext; |
@@ -805,14 +758,12 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, | |||
805 | } | 758 | } |
806 | 759 | ||
807 | if (longcal) { | 760 | if (longcal) { |
808 | ath9k_hw_getnf(ah, ichan); | 761 | ath9k_hw_getnf(ah, chan); |
809 | ath9k_hw_loadnf(ah, ah->ah_curchan); | 762 | ath9k_hw_loadnf(ah, ah->ah_curchan); |
810 | ath9k_hw_start_nfcal(ah); | 763 | ath9k_hw_start_nfcal(ah); |
811 | 764 | ||
812 | if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) { | 765 | if (chan->channelFlags & CHANNEL_CW_INT) |
813 | chan->channelFlags |= CHANNEL_CW_INT; | 766 | chan->channelFlags &= ~CHANNEL_CW_INT; |
814 | ichan->channelFlags &= ~CHANNEL_CW_INT; | ||
815 | } | ||
816 | } | 767 | } |
817 | 768 | ||
818 | return true; | 769 | return true; |
@@ -917,7 +868,6 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, | |||
917 | struct ath9k_channel *chan) | 868 | struct ath9k_channel *chan) |
918 | { | 869 | { |
919 | struct ath_hal_5416 *ahp = AH5416(ah); | 870 | struct ath_hal_5416 *ahp = AH5416(ah); |
920 | struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); | ||
921 | 871 | ||
922 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 872 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, |
923 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | 873 | REG_READ(ah, AR_PHY_AGC_CONTROL) | |
@@ -940,19 +890,19 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, | |||
940 | ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL; | 890 | ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL; |
941 | 891 | ||
942 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { | 892 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { |
943 | if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) { | 893 | if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) { |
944 | INIT_CAL(&ahp->ah_adcGainCalData); | 894 | INIT_CAL(&ahp->ah_adcGainCalData); |
945 | INSERT_CAL(ahp, &ahp->ah_adcGainCalData); | 895 | INSERT_CAL(ahp, &ahp->ah_adcGainCalData); |
946 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 896 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
947 | "enabling ADC Gain Calibration.\n"); | 897 | "enabling ADC Gain Calibration.\n"); |
948 | } | 898 | } |
949 | if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { | 899 | if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { |
950 | INIT_CAL(&ahp->ah_adcDcCalData); | 900 | INIT_CAL(&ahp->ah_adcDcCalData); |
951 | INSERT_CAL(ahp, &ahp->ah_adcDcCalData); | 901 | INSERT_CAL(ahp, &ahp->ah_adcDcCalData); |
952 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 902 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
953 | "enabling ADC DC Calibration.\n"); | 903 | "enabling ADC DC Calibration.\n"); |
954 | } | 904 | } |
955 | if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { | 905 | if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { |
956 | INIT_CAL(&ahp->ah_iqCalData); | 906 | INIT_CAL(&ahp->ah_iqCalData); |
957 | INSERT_CAL(ahp, &ahp->ah_iqCalData); | 907 | INSERT_CAL(ahp, &ahp->ah_iqCalData); |
958 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, | 908 | DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, |
@@ -965,7 +915,7 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, | |||
965 | ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr); | 915 | ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr); |
966 | } | 916 | } |
967 | 917 | ||
968 | ichan->CalValid = 0; | 918 | chan->CalValid = 0; |
969 | 919 | ||
970 | return true; | 920 | return true; |
971 | } | 921 | } |
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 4ca2aed236e0..29251f8dabb0 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
@@ -18,7 +18,7 @@ | |||
18 | #define CORE_H | 18 | #define CORE_H |
19 | 19 | ||
20 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
21 | #include <linux/pci.h> | 21 | #include <linux/device.h> |
22 | #include <net/mac80211.h> | 22 | #include <net/mac80211.h> |
23 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
24 | #include <linux/rfkill.h> | 24 | #include <linux/rfkill.h> |
@@ -187,7 +187,6 @@ struct ath_config { | |||
187 | #define ATH_TXBUF_RESET(_bf) do { \ | 187 | #define ATH_TXBUF_RESET(_bf) do { \ |
188 | (_bf)->bf_status = 0; \ | 188 | (_bf)->bf_status = 0; \ |
189 | (_bf)->bf_lastbf = NULL; \ | 189 | (_bf)->bf_lastbf = NULL; \ |
190 | (_bf)->bf_lastfrm = NULL; \ | ||
191 | (_bf)->bf_next = NULL; \ | 190 | (_bf)->bf_next = NULL; \ |
192 | memset(&((_bf)->bf_state), 0, \ | 191 | memset(&((_bf)->bf_state), 0, \ |
193 | sizeof(struct ath_buf_state)); \ | 192 | sizeof(struct ath_buf_state)); \ |
@@ -245,10 +244,8 @@ struct ath_buf_state { | |||
245 | */ | 244 | */ |
246 | struct ath_buf { | 245 | struct ath_buf { |
247 | struct list_head list; | 246 | struct list_head list; |
248 | struct list_head *last; | ||
249 | struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or | 247 | struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or |
250 | an aggregate) */ | 248 | an aggregate) */ |
251 | struct ath_buf *bf_lastfrm; /* last buf of this frame */ | ||
252 | struct ath_buf *bf_next; /* next subframe in the aggregate */ | 249 | struct ath_buf *bf_next; /* next subframe in the aggregate */ |
253 | void *bf_mpdu; /* enclosing frame structure */ | 250 | void *bf_mpdu; /* enclosing frame structure */ |
254 | struct ath_desc *bf_desc; /* virtual addr of desc */ | 251 | struct ath_desc *bf_desc; /* virtual addr of desc */ |
@@ -261,13 +258,7 @@ struct ath_buf { | |||
261 | }; | 258 | }; |
262 | 259 | ||
263 | #define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) | 260 | #define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) |
264 | |||
265 | /* hw processing complete, desc processed by hal */ | ||
266 | #define ATH_BUFSTATUS_DONE 0x00000001 | ||
267 | /* hw processing complete, desc hold for hw */ | ||
268 | #define ATH_BUFSTATUS_STALE 0x00000002 | 261 | #define ATH_BUFSTATUS_STALE 0x00000002 |
269 | /* Rx-only: OS is done with this packet and it's ok to queued it to hw */ | ||
270 | #define ATH_BUFSTATUS_FREE 0x00000004 | ||
271 | 262 | ||
272 | /* DMA state for tx/rx descriptors */ | 263 | /* DMA state for tx/rx descriptors */ |
273 | 264 | ||
@@ -360,7 +351,6 @@ struct ath_txq { | |||
360 | u32 *axq_link; /* link ptr in last TX desc */ | 351 | u32 *axq_link; /* link ptr in last TX desc */ |
361 | struct list_head axq_q; /* transmit queue */ | 352 | struct list_head axq_q; /* transmit queue */ |
362 | spinlock_t axq_lock; | 353 | spinlock_t axq_lock; |
363 | unsigned long axq_lockflags; /* intr state when must cli */ | ||
364 | u32 axq_depth; /* queue depth */ | 354 | u32 axq_depth; /* queue depth */ |
365 | u8 axq_aggr_depth; /* aggregates queued */ | 355 | u8 axq_aggr_depth; /* aggregates queued */ |
366 | u32 axq_totalqueued; /* total ever queued */ | 356 | u32 axq_totalqueued; /* total ever queued */ |
@@ -485,28 +475,22 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush); | |||
485 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 475 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
486 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 476 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
487 | int ath_tx_setup(struct ath_softc *sc, int haltype); | 477 | int ath_tx_setup(struct ath_softc *sc, int haltype); |
488 | void ath_draintxq(struct ath_softc *sc, bool retry_tx); | 478 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); |
489 | void ath_tx_draintxq(struct ath_softc *sc, | 479 | void ath_draintxq(struct ath_softc *sc, |
490 | struct ath_txq *txq, bool retry_tx); | 480 | struct ath_txq *txq, bool retry_tx); |
491 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | 481 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); |
492 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); | 482 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); |
493 | void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an); | ||
494 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); | 483 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); |
495 | int ath_tx_init(struct ath_softc *sc, int nbufs); | 484 | int ath_tx_init(struct ath_softc *sc, int nbufs); |
496 | int ath_tx_cleanup(struct ath_softc *sc); | 485 | int ath_tx_cleanup(struct ath_softc *sc); |
497 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); | ||
498 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb); | 486 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb); |
499 | int ath_txq_update(struct ath_softc *sc, int qnum, | 487 | int ath_txq_update(struct ath_softc *sc, int qnum, |
500 | struct ath9k_tx_queue_info *q); | 488 | struct ath9k_tx_queue_info *q); |
501 | int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, | 489 | int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, |
502 | struct ath_tx_control *txctl); | 490 | struct ath_tx_control *txctl); |
503 | void ath_tx_tasklet(struct ath_softc *sc); | 491 | void ath_tx_tasklet(struct ath_softc *sc); |
504 | u32 ath_txq_depth(struct ath_softc *sc, int qnum); | ||
505 | u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum); | ||
506 | void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); | 492 | void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); |
507 | void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid); | ||
508 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); | 493 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); |
509 | void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno); | ||
510 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 494 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
511 | u16 tid, u16 *ssn); | 495 | u16 tid, u16 *ssn); |
512 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 496 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
@@ -692,14 +676,22 @@ enum PROT_MODE { | |||
692 | #define SC_OP_RFKILL_REGISTERED BIT(11) | 676 | #define SC_OP_RFKILL_REGISTERED BIT(11) |
693 | #define SC_OP_RFKILL_SW_BLOCKED BIT(12) | 677 | #define SC_OP_RFKILL_SW_BLOCKED BIT(12) |
694 | #define SC_OP_RFKILL_HW_BLOCKED BIT(13) | 678 | #define SC_OP_RFKILL_HW_BLOCKED BIT(13) |
679 | #define SC_OP_WAIT_FOR_BEACON BIT(14) | ||
680 | |||
681 | struct ath_bus_ops { | ||
682 | void (*read_cachesize)(struct ath_softc *sc, int *csz); | ||
683 | void (*cleanup)(struct ath_softc *sc); | ||
684 | bool (*eeprom_read)(struct ath_hal *ah, u32 off, u16 *data); | ||
685 | }; | ||
695 | 686 | ||
696 | struct ath_softc { | 687 | struct ath_softc { |
697 | struct ieee80211_hw *hw; | 688 | struct ieee80211_hw *hw; |
698 | struct pci_dev *pdev; | 689 | struct device *dev; |
699 | struct tasklet_struct intr_tq; | 690 | struct tasklet_struct intr_tq; |
700 | struct tasklet_struct bcon_tasklet; | 691 | struct tasklet_struct bcon_tasklet; |
701 | struct ath_hal *sc_ah; | 692 | struct ath_hal *sc_ah; |
702 | void __iomem *mem; | 693 | void __iomem *mem; |
694 | int irq; | ||
703 | spinlock_t sc_resetlock; | 695 | spinlock_t sc_resetlock; |
704 | struct mutex mutex; | 696 | struct mutex mutex; |
705 | 697 | ||
@@ -718,7 +710,7 @@ struct ath_softc { | |||
718 | u32 sc_keymax; | 710 | u32 sc_keymax; |
719 | DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); | 711 | DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); |
720 | u8 sc_splitmic; | 712 | u8 sc_splitmic; |
721 | u8 sc_protrix; | 713 | atomic_t ps_usecount; |
722 | enum ath9k_int sc_imask; | 714 | enum ath9k_int sc_imask; |
723 | enum PROT_MODE sc_protmode; | 715 | enum PROT_MODE sc_protmode; |
724 | enum ath9k_ht_extprotspacing sc_ht_extprotspacing; | 716 | enum ath9k_ht_extprotspacing sc_ht_extprotspacing; |
@@ -732,7 +724,6 @@ struct ath_softc { | |||
732 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; | 724 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; |
733 | struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; | 725 | struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; |
734 | struct ath_rate_table *cur_rate_table; | 726 | struct ath_rate_table *cur_rate_table; |
735 | struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; | ||
736 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | 727 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
737 | struct ath_led radio_led; | 728 | struct ath_led radio_led; |
738 | struct ath_led assoc_led; | 729 | struct ath_led assoc_led; |
@@ -744,6 +735,7 @@ struct ath_softc { | |||
744 | #ifdef CONFIG_ATH9K_DEBUG | 735 | #ifdef CONFIG_ATH9K_DEBUG |
745 | struct ath9k_debug sc_debug; | 736 | struct ath9k_debug sc_debug; |
746 | #endif | 737 | #endif |
738 | struct ath_bus_ops *bus_ops; | ||
747 | }; | 739 | }; |
748 | 740 | ||
749 | int ath_reset(struct ath_softc *sc, bool retry_tx); | 741 | int ath_reset(struct ath_softc *sc, bool retry_tx); |
@@ -751,4 +743,55 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); | |||
751 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); | 743 | int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); |
752 | int ath_cabq_update(struct ath_softc *); | 744 | int ath_cabq_update(struct ath_softc *); |
753 | 745 | ||
746 | static inline void ath_read_cachesize(struct ath_softc *sc, int *csz) | ||
747 | { | ||
748 | sc->bus_ops->read_cachesize(sc, csz); | ||
749 | } | ||
750 | |||
751 | static inline void ath_bus_cleanup(struct ath_softc *sc) | ||
752 | { | ||
753 | sc->bus_ops->cleanup(sc); | ||
754 | } | ||
755 | |||
756 | extern struct ieee80211_ops ath9k_ops; | ||
757 | |||
758 | irqreturn_t ath_isr(int irq, void *dev); | ||
759 | void ath_cleanup(struct ath_softc *sc); | ||
760 | int ath_attach(u16 devid, struct ath_softc *sc); | ||
761 | void ath_detach(struct ath_softc *sc); | ||
762 | const char *ath_mac_bb_name(u32 mac_bb_version); | ||
763 | const char *ath_rf_name(u16 rf_version); | ||
764 | |||
765 | #ifdef CONFIG_PCI | ||
766 | int ath_pci_init(void); | ||
767 | void ath_pci_exit(void); | ||
768 | #else | ||
769 | static inline int ath_pci_init(void) { return 0; }; | ||
770 | static inline void ath_pci_exit(void) {}; | ||
771 | #endif | ||
772 | |||
773 | #ifdef CONFIG_ATHEROS_AR71XX | ||
774 | int ath_ahb_init(void); | ||
775 | void ath_ahb_exit(void); | ||
776 | #else | ||
777 | static inline int ath_ahb_init(void) { return 0; }; | ||
778 | static inline void ath_ahb_exit(void) {}; | ||
779 | #endif | ||
780 | |||
781 | static inline void ath9k_ps_wakeup(struct ath_softc *sc) | ||
782 | { | ||
783 | if (atomic_inc_return(&sc->ps_usecount) == 1) | ||
784 | if (sc->sc_ah->ah_power_mode != ATH9K_PM_AWAKE) { | ||
785 | sc->sc_ah->ah_restore_mode = sc->sc_ah->ah_power_mode; | ||
786 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | static inline void ath9k_ps_restore(struct ath_softc *sc) | ||
791 | { | ||
792 | if (atomic_dec_and_test(&sc->ps_usecount)) | ||
793 | if (sc->hw->conf.flags & IEEE80211_CONF_PS) | ||
794 | ath9k_hw_setpower(sc->sc_ah, | ||
795 | sc->sc_ah->ah_restore_mode); | ||
796 | } | ||
754 | #endif /* CORE_H */ | 797 | #endif /* CORE_H */ |
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c index a80ed576830f..1680164b4adb 100644 --- a/drivers/net/wireless/ath9k/debug.c +++ b/drivers/net/wireless/ath9k/debug.c | |||
@@ -222,6 +222,7 @@ static const struct file_operations fops_interrupt = { | |||
222 | .owner = THIS_MODULE | 222 | .owner = THIS_MODULE |
223 | }; | 223 | }; |
224 | 224 | ||
225 | |||
225 | int ath9k_init_debug(struct ath_softc *sc) | 226 | int ath9k_init_debug(struct ath_softc *sc) |
226 | { | 227 | { |
227 | sc->sc_debug.debug_mask = ath9k_debug; | 228 | sc->sc_debug.debug_mask = ath9k_debug; |
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c index acd6c5374d44..5038907e7432 100644 --- a/drivers/net/wireless/ath9k/eeprom.c +++ b/drivers/net/wireless/ath9k/eeprom.c | |||
@@ -91,53 +91,11 @@ static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, | |||
91 | return false; | 91 | return false; |
92 | } | 92 | } |
93 | 93 | ||
94 | static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data) | ||
95 | { | ||
96 | (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); | ||
97 | |||
98 | if (!ath9k_hw_wait(ah, | ||
99 | AR_EEPROM_STATUS_DATA, | ||
100 | AR_EEPROM_STATUS_DATA_BUSY | | ||
101 | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) { | ||
102 | return false; | ||
103 | } | ||
104 | |||
105 | *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA), | ||
106 | AR_EEPROM_STATUS_DATA_VAL); | ||
107 | |||
108 | return true; | ||
109 | } | ||
110 | |||
111 | static int ath9k_hw_flash_map(struct ath_hal *ah) | ||
112 | { | ||
113 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
114 | |||
115 | ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX); | ||
116 | |||
117 | if (!ahp->ah_cal_mem) { | ||
118 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | ||
119 | "cannot remap eeprom region \n"); | ||
120 | return -EIO; | ||
121 | } | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data) | ||
127 | { | ||
128 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
129 | |||
130 | *data = ioread16(ahp->ah_cal_mem + off); | ||
131 | |||
132 | return true; | ||
133 | } | ||
134 | |||
135 | static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data) | 94 | static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data) |
136 | { | 95 | { |
137 | if (ath9k_hw_use_flash(ah)) | 96 | struct ath_softc *sc = ah->ah_sc; |
138 | return ath9k_hw_flash_read(ah, off, data); | 97 | |
139 | else | 98 | return sc->bus_ops->eeprom_read(ah, off, data); |
140 | return ath9k_hw_eeprom_read(ah, off, data); | ||
141 | } | 99 | } |
142 | 100 | ||
143 | static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah) | 101 | static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah) |
@@ -2121,19 +2079,19 @@ void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan) | |||
2121 | static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah, | 2079 | static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah, |
2122 | struct ath9k_channel *chan) | 2080 | struct ath9k_channel *chan) |
2123 | { | 2081 | { |
2082 | #define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) | ||
2124 | struct modal_eep_header *pModal; | 2083 | struct modal_eep_header *pModal; |
2125 | struct ath_hal_5416 *ahp = AH5416(ah); | 2084 | struct ath_hal_5416 *ahp = AH5416(ah); |
2126 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; | 2085 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; |
2127 | int i, regChainOffset; | 2086 | int i, regChainOffset; |
2128 | u8 txRxAttenLocal; | 2087 | u8 txRxAttenLocal; |
2129 | u16 ant_config; | ||
2130 | 2088 | ||
2131 | pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | 2089 | pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); |
2132 | 2090 | ||
2133 | txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; | 2091 | txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44; |
2134 | 2092 | ||
2135 | ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config); | 2093 | REG_WRITE(ah, AR_PHY_SWITCH_COM, |
2136 | REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config); | 2094 | ath9k_hw_get_eeprom_antenna_cfg(ah, chan)); |
2137 | 2095 | ||
2138 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | 2096 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { |
2139 | if (AR_SREV_9280(ah)) { | 2097 | if (AR_SREV_9280(ah)) { |
@@ -2163,9 +2121,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah, | |||
2163 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); | 2121 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); |
2164 | 2122 | ||
2165 | if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { | 2123 | if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { |
2166 | if ((eep->baseEepHeader.version & | 2124 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { |
2167 | AR5416_EEP_VER_MINOR_MASK) >= | ||
2168 | AR5416_EEP_MINOR_VER_3) { | ||
2169 | txRxAttenLocal = pModal->txRxAttenCh[i]; | 2125 | txRxAttenLocal = pModal->txRxAttenCh[i]; |
2170 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 2126 | if (AR_SREV_9280_10_OR_LATER(ah)) { |
2171 | REG_RMW_FIELD(ah, | 2127 | REG_RMW_FIELD(ah, |
@@ -2332,8 +2288,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah, | |||
2332 | pModal->thresh62); | 2288 | pModal->thresh62); |
2333 | } | 2289 | } |
2334 | 2290 | ||
2335 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | 2291 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) { |
2336 | AR5416_EEP_MINOR_VER_2) { | ||
2337 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, | 2292 | REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, |
2338 | AR_PHY_TX_END_DATA_START, | 2293 | AR_PHY_TX_END_DATA_START, |
2339 | pModal->txFrameToDataStart); | 2294 | pModal->txFrameToDataStart); |
@@ -2341,15 +2296,29 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah, | |||
2341 | pModal->txFrameToPaOn); | 2296 | pModal->txFrameToPaOn); |
2342 | } | 2297 | } |
2343 | 2298 | ||
2344 | if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= | 2299 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { |
2345 | AR5416_EEP_MINOR_VER_3) { | ||
2346 | if (IS_CHAN_HT40(chan)) | 2300 | if (IS_CHAN_HT40(chan)) |
2347 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, | 2301 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, |
2348 | AR_PHY_SETTLING_SWITCH, | 2302 | AR_PHY_SETTLING_SWITCH, |
2349 | pModal->swSettleHt40); | 2303 | pModal->swSettleHt40); |
2350 | } | 2304 | } |
2351 | 2305 | ||
2306 | if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { | ||
2307 | if (IS_CHAN_HT20(chan)) | ||
2308 | REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, | ||
2309 | eep->baseEepHeader.dacLpMode); | ||
2310 | else if (eep->baseEepHeader.dacHiPwrMode_5G) | ||
2311 | REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0); | ||
2312 | else | ||
2313 | REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, | ||
2314 | eep->baseEepHeader.dacLpMode); | ||
2315 | |||
2316 | REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, | ||
2317 | pModal->miscBits >> 2); | ||
2318 | } | ||
2319 | |||
2352 | return true; | 2320 | return true; |
2321 | #undef AR5416_VER_MASK | ||
2353 | } | 2322 | } |
2354 | 2323 | ||
2355 | static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah, | 2324 | static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah, |
@@ -2360,7 +2329,6 @@ static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah, | |||
2360 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; | 2329 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; |
2361 | int regChainOffset; | 2330 | int regChainOffset; |
2362 | u8 txRxAttenLocal; | 2331 | u8 txRxAttenLocal; |
2363 | u16 ant_config = 0; | ||
2364 | u8 ob[5], db1[5], db2[5]; | 2332 | u8 ob[5], db1[5], db2[5]; |
2365 | u8 ant_div_control1, ant_div_control2; | 2333 | u8 ant_div_control1, ant_div_control2; |
2366 | u32 regVal; | 2334 | u32 regVal; |
@@ -2370,8 +2338,8 @@ static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah, | |||
2370 | 2338 | ||
2371 | txRxAttenLocal = 23; | 2339 | txRxAttenLocal = 23; |
2372 | 2340 | ||
2373 | ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config); | 2341 | REG_WRITE(ah, AR_PHY_SWITCH_COM, |
2374 | REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config); | 2342 | ath9k_hw_get_eeprom_antenna_cfg(ah, chan)); |
2375 | 2343 | ||
2376 | regChainOffset = 0; | 2344 | regChainOffset = 0; |
2377 | REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, | 2345 | REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, |
@@ -2554,70 +2522,39 @@ bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, | |||
2554 | return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan); | 2522 | return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan); |
2555 | } | 2523 | } |
2556 | 2524 | ||
2557 | static int ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah, | 2525 | static u16 ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah, |
2558 | struct ath9k_channel *chan, | 2526 | struct ath9k_channel *chan) |
2559 | u8 index, u16 *config) | ||
2560 | { | 2527 | { |
2561 | struct ath_hal_5416 *ahp = AH5416(ah); | 2528 | struct ath_hal_5416 *ahp = AH5416(ah); |
2562 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; | 2529 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; |
2563 | struct modal_eep_header *pModal = | 2530 | struct modal_eep_header *pModal = |
2564 | &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); | 2531 | &(eep->modalHeader[IS_CHAN_2GHZ(chan)]); |
2565 | struct base_eep_header *pBase = &eep->baseEepHeader; | ||
2566 | 2532 | ||
2567 | switch (index) { | 2533 | return pModal->antCtrlCommon & 0xFFFF; |
2568 | case 0: | ||
2569 | *config = pModal->antCtrlCommon & 0xFFFF; | ||
2570 | return 0; | ||
2571 | case 1: | ||
2572 | if (pBase->version >= 0x0E0D) { | ||
2573 | if (pModal->useAnt1) { | ||
2574 | *config = | ||
2575 | ((pModal->antCtrlCommon & 0xFFFF0000) >> 16); | ||
2576 | return 0; | ||
2577 | } | ||
2578 | } | ||
2579 | break; | ||
2580 | default: | ||
2581 | break; | ||
2582 | } | ||
2583 | |||
2584 | return -EINVAL; | ||
2585 | } | 2534 | } |
2586 | 2535 | ||
2587 | static int ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah, | 2536 | static u16 ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah, |
2588 | struct ath9k_channel *chan, | 2537 | struct ath9k_channel *chan) |
2589 | u8 index, u16 *config) | ||
2590 | { | 2538 | { |
2591 | struct ath_hal_5416 *ahp = AH5416(ah); | 2539 | struct ath_hal_5416 *ahp = AH5416(ah); |
2592 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; | 2540 | struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k; |
2593 | struct modal_eep_4k_header *pModal = &eep->modalHeader; | 2541 | struct modal_eep_4k_header *pModal = &eep->modalHeader; |
2594 | 2542 | ||
2595 | switch (index) { | 2543 | return pModal->antCtrlCommon & 0xFFFF; |
2596 | case 0: | ||
2597 | *config = pModal->antCtrlCommon & 0xFFFF; | ||
2598 | return 0; | ||
2599 | default: | ||
2600 | break; | ||
2601 | } | ||
2602 | |||
2603 | return -EINVAL; | ||
2604 | } | 2544 | } |
2605 | 2545 | ||
2606 | static int (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *, | 2546 | static u16 (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *, |
2607 | struct ath9k_channel *, | 2547 | struct ath9k_channel *) = { |
2608 | u8, u16 *) = { | ||
2609 | ath9k_hw_get_def_eeprom_antenna_cfg, | 2548 | ath9k_hw_get_def_eeprom_antenna_cfg, |
2610 | ath9k_hw_get_4k_eeprom_antenna_cfg | 2549 | ath9k_hw_get_4k_eeprom_antenna_cfg |
2611 | }; | 2550 | }; |
2612 | 2551 | ||
2613 | int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, | 2552 | u16 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah, |
2614 | struct ath9k_channel *chan, | 2553 | struct ath9k_channel *chan) |
2615 | u8 index, u16 *config) | ||
2616 | { | 2554 | { |
2617 | struct ath_hal_5416 *ahp = AH5416(ah); | 2555 | struct ath_hal_5416 *ahp = AH5416(ah); |
2618 | 2556 | ||
2619 | return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan, | 2557 | return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan); |
2620 | index, config); | ||
2621 | } | 2558 | } |
2622 | 2559 | ||
2623 | static u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah, | 2560 | static u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah, |
@@ -2739,6 +2676,7 @@ static u32 ath9k_hw_get_eeprom_4k(struct ath_hal *ah, | |||
2739 | static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah, | 2676 | static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah, |
2740 | enum eeprom_param param) | 2677 | enum eeprom_param param) |
2741 | { | 2678 | { |
2679 | #define AR5416_VER_MASK (pBase->version & AR5416_EEP_VER_MINOR_MASK) | ||
2742 | struct ath_hal_5416 *ahp = AH5416(ah); | 2680 | struct ath_hal_5416 *ahp = AH5416(ah); |
2743 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; | 2681 | struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def; |
2744 | struct modal_eep_header *pModal = eep->modalHeader; | 2682 | struct modal_eep_header *pModal = eep->modalHeader; |
@@ -2774,7 +2712,7 @@ static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah, | |||
2774 | case EEP_DB_2: | 2712 | case EEP_DB_2: |
2775 | return pModal[1].db; | 2713 | return pModal[1].db; |
2776 | case EEP_MINOR_REV: | 2714 | case EEP_MINOR_REV: |
2777 | return pBase->version & AR5416_EEP_VER_MINOR_MASK; | 2715 | return AR5416_VER_MASK; |
2778 | case EEP_TX_MASK: | 2716 | case EEP_TX_MASK: |
2779 | return pBase->txMask; | 2717 | return pBase->txMask; |
2780 | case EEP_RX_MASK: | 2718 | case EEP_RX_MASK: |
@@ -2783,10 +2721,15 @@ static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah, | |||
2783 | return pBase->rxGainType; | 2721 | return pBase->rxGainType; |
2784 | case EEP_TXGAIN_TYPE: | 2722 | case EEP_TXGAIN_TYPE: |
2785 | return pBase->txGainType; | 2723 | return pBase->txGainType; |
2786 | 2724 | case EEP_DAC_HPWR_5G: | |
2725 | if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) | ||
2726 | return pBase->dacHiPwrMode_5G; | ||
2727 | else | ||
2728 | return 0; | ||
2787 | default: | 2729 | default: |
2788 | return 0; | 2730 | return 0; |
2789 | } | 2731 | } |
2732 | #undef AR5416_VER_MASK | ||
2790 | } | 2733 | } |
2791 | 2734 | ||
2792 | static u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = { | 2735 | static u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = { |
@@ -2807,9 +2750,6 @@ int ath9k_hw_eeprom_attach(struct ath_hal *ah) | |||
2807 | int status; | 2750 | int status; |
2808 | struct ath_hal_5416 *ahp = AH5416(ah); | 2751 | struct ath_hal_5416 *ahp = AH5416(ah); |
2809 | 2752 | ||
2810 | if (ath9k_hw_use_flash(ah)) | ||
2811 | ath9k_hw_flash_map(ah); | ||
2812 | |||
2813 | if (AR_SREV_9285(ah)) | 2753 | if (AR_SREV_9285(ah)) |
2814 | ahp->ah_eep_map = EEP_MAP_4KBITS; | 2754 | ahp->ah_eep_map = EEP_MAP_4KBITS; |
2815 | else | 2755 | else |
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 34474edefc97..77282345efc1 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c | |||
@@ -23,15 +23,13 @@ | |||
23 | #include "phy.h" | 23 | #include "phy.h" |
24 | #include "initvals.h" | 24 | #include "initvals.h" |
25 | 25 | ||
26 | static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 }; | 26 | static int btcoex_enable; |
27 | module_param(btcoex_enable, bool, 0); | ||
28 | MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support"); | ||
27 | 29 | ||
28 | extern struct hal_percal_data iq_cal_multi_sample; | 30 | #define ATH9K_CLOCK_RATE_CCK 22 |
29 | extern struct hal_percal_data iq_cal_single_sample; | 31 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 |
30 | extern struct hal_percal_data adc_gain_cal_multi_sample; | 32 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 |
31 | extern struct hal_percal_data adc_gain_cal_single_sample; | ||
32 | extern struct hal_percal_data adc_dc_cal_multi_sample; | ||
33 | extern struct hal_percal_data adc_dc_cal_single_sample; | ||
34 | extern struct hal_percal_data adc_init_dc_cal; | ||
35 | 33 | ||
36 | static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type); | 34 | static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type); |
37 | static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, | 35 | static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan, |
@@ -48,17 +46,18 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha | |||
48 | 46 | ||
49 | static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks) | 47 | static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks) |
50 | { | 48 | { |
51 | if (ah->ah_curchan != NULL) | 49 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
52 | return clks / CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)]; | 50 | if (!ah->ah_curchan) /* should really check for CCK instead */ |
53 | else | 51 | return clks / ATH9K_CLOCK_RATE_CCK; |
54 | return clks / CLOCK_RATE[ATH9K_MODE_11B]; | 52 | if (conf->channel->band == IEEE80211_BAND_2GHZ) |
53 | return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM; | ||
54 | return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
55 | } | 55 | } |
56 | 56 | ||
57 | static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks) | 57 | static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks) |
58 | { | 58 | { |
59 | struct ath9k_channel *chan = ah->ah_curchan; | 59 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
60 | 60 | if (conf_is_ht40(conf)) | |
61 | if (chan && IS_CHAN_HT40(chan)) | ||
62 | return ath9k_hw_mac_usec(ah, clks) / 2; | 61 | return ath9k_hw_mac_usec(ah, clks) / 2; |
63 | else | 62 | else |
64 | return ath9k_hw_mac_usec(ah, clks); | 63 | return ath9k_hw_mac_usec(ah, clks); |
@@ -66,34 +65,23 @@ static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks) | |||
66 | 65 | ||
67 | static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs) | 66 | static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs) |
68 | { | 67 | { |
69 | if (ah->ah_curchan != NULL) | 68 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
70 | return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah, | 69 | if (!ah->ah_curchan) /* should really check for CCK instead */ |
71 | ah->ah_curchan)]; | 70 | return usecs *ATH9K_CLOCK_RATE_CCK; |
72 | else | 71 | if (conf->channel->band == IEEE80211_BAND_2GHZ) |
73 | return usecs * CLOCK_RATE[ATH9K_MODE_11B]; | 72 | return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; |
73 | return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
74 | } | 74 | } |
75 | 75 | ||
76 | static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs) | 76 | static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs) |
77 | { | 77 | { |
78 | struct ath9k_channel *chan = ah->ah_curchan; | 78 | struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; |
79 | 79 | if (conf_is_ht40(conf)) | |
80 | if (chan && IS_CHAN_HT40(chan)) | ||
81 | return ath9k_hw_mac_clks(ah, usecs) * 2; | 80 | return ath9k_hw_mac_clks(ah, usecs) * 2; |
82 | else | 81 | else |
83 | return ath9k_hw_mac_clks(ah, usecs); | 82 | return ath9k_hw_mac_clks(ah, usecs); |
84 | } | 83 | } |
85 | 84 | ||
86 | enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah, | ||
87 | const struct ath9k_channel *chan) | ||
88 | { | ||
89 | if (IS_CHAN_B(chan)) | ||
90 | return ATH9K_MODE_11B; | ||
91 | if (IS_CHAN_G(chan)) | ||
92 | return ATH9K_MODE_11G; | ||
93 | |||
94 | return ATH9K_MODE_11A; | ||
95 | } | ||
96 | |||
97 | bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val) | 85 | bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val) |
98 | { | 86 | { |
99 | int i; | 87 | int i; |
@@ -199,46 +187,6 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, | |||
199 | return txTime; | 187 | return txTime; |
200 | } | 188 | } |
201 | 189 | ||
202 | u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags) | ||
203 | { | ||
204 | if (flags & CHANNEL_2GHZ) { | ||
205 | if (freq == 2484) | ||
206 | return 14; | ||
207 | if (freq < 2484) | ||
208 | return (freq - 2407) / 5; | ||
209 | else | ||
210 | return 15 + ((freq - 2512) / 20); | ||
211 | } else if (flags & CHANNEL_5GHZ) { | ||
212 | if (ath9k_regd_is_public_safety_sku(ah) && | ||
213 | IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) { | ||
214 | return ((freq * 10) + | ||
215 | (((freq % 5) == 2) ? 5 : 0) - 49400) / 5; | ||
216 | } else if ((flags & CHANNEL_A) && (freq <= 5000)) { | ||
217 | return (freq - 4000) / 5; | ||
218 | } else { | ||
219 | return (freq - 5000) / 5; | ||
220 | } | ||
221 | } else { | ||
222 | if (freq == 2484) | ||
223 | return 14; | ||
224 | if (freq < 2484) | ||
225 | return (freq - 2407) / 5; | ||
226 | if (freq < 5000) { | ||
227 | if (ath9k_regd_is_public_safety_sku(ah) | ||
228 | && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) { | ||
229 | return ((freq * 10) + | ||
230 | (((freq % 5) == | ||
231 | 2) ? 5 : 0) - 49400) / 5; | ||
232 | } else if (freq > 4900) { | ||
233 | return (freq - 4000) / 5; | ||
234 | } else { | ||
235 | return 15 + ((freq - 2512) / 20); | ||
236 | } | ||
237 | } | ||
238 | return (freq - 5000) / 5; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | void ath9k_hw_get_channel_centers(struct ath_hal *ah, | 190 | void ath9k_hw_get_channel_centers(struct ath_hal *ah, |
243 | struct ath9k_channel *chan, | 191 | struct ath9k_channel *chan, |
244 | struct chan_centers *centers) | 192 | struct chan_centers *centers) |
@@ -389,6 +337,8 @@ static const char *ath9k_hw_devname(u16 devid) | |||
389 | return "Atheros 5418"; | 337 | return "Atheros 5418"; |
390 | case AR9160_DEVID_PCI: | 338 | case AR9160_DEVID_PCI: |
391 | return "Atheros 9160"; | 339 | return "Atheros 9160"; |
340 | case AR5416_AR9100_DEVID: | ||
341 | return "Atheros 9100"; | ||
392 | case AR9280_DEVID_PCI: | 342 | case AR9280_DEVID_PCI: |
393 | case AR9280_DEVID_PCIE: | 343 | case AR9280_DEVID_PCIE: |
394 | return "Atheros 9280"; | 344 | return "Atheros 9280"; |
@@ -1023,7 +973,7 @@ static void ath9k_hw_init_pll(struct ath_hal *ah, | |||
1023 | pll |= SM(0xb, AR_RTC_PLL_DIV); | 973 | pll |= SM(0xb, AR_RTC_PLL_DIV); |
1024 | } | 974 | } |
1025 | } | 975 | } |
1026 | REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll); | 976 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
1027 | 977 | ||
1028 | udelay(RTC_PLL_SETTLE_DELAY); | 978 | udelay(RTC_PLL_SETTLE_DELAY); |
1029 | 979 | ||
@@ -1191,6 +1141,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc, | |||
1191 | switch (devid) { | 1141 | switch (devid) { |
1192 | case AR5416_DEVID_PCI: | 1142 | case AR5416_DEVID_PCI: |
1193 | case AR5416_DEVID_PCIE: | 1143 | case AR5416_DEVID_PCIE: |
1144 | case AR5416_AR9100_DEVID: | ||
1194 | case AR9160_DEVID_PCI: | 1145 | case AR9160_DEVID_PCI: |
1195 | case AR9280_DEVID_PCI: | 1146 | case AR9280_DEVID_PCI: |
1196 | case AR9280_DEVID_PCIE: | 1147 | case AR9280_DEVID_PCIE: |
@@ -1279,6 +1230,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, | |||
1279 | { | 1230 | { |
1280 | int i, regWrites = 0; | 1231 | int i, regWrites = 0; |
1281 | struct ath_hal_5416 *ahp = AH5416(ah); | 1232 | struct ath_hal_5416 *ahp = AH5416(ah); |
1233 | struct ieee80211_channel *channel = chan->chan; | ||
1282 | u32 modesIndex, freqIndex; | 1234 | u32 modesIndex, freqIndex; |
1283 | int status; | 1235 | int status; |
1284 | 1236 | ||
@@ -1383,9 +1335,8 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, | |||
1383 | 1335 | ||
1384 | status = ath9k_hw_set_txpower(ah, chan, | 1336 | status = ath9k_hw_set_txpower(ah, chan, |
1385 | ath9k_regd_get_ctl(ah, chan), | 1337 | ath9k_regd_get_ctl(ah, chan), |
1386 | ath9k_regd_get_antenna_allowed(ah, | 1338 | channel->max_antenna_gain * 2, |
1387 | chan), | 1339 | channel->max_power * 2, |
1388 | chan->maxRegTxPower * 2, | ||
1389 | min((u32) MAX_RATE_POWER, | 1340 | min((u32) MAX_RATE_POWER, |
1390 | (u32) ah->ah_powerLimit)); | 1341 | (u32) ah->ah_powerLimit)); |
1391 | if (status != 0) { | 1342 | if (status != 0) { |
@@ -1562,11 +1513,11 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type) | |||
1562 | rst_flags |= AR_RTC_RC_MAC_COLD; | 1513 | rst_flags |= AR_RTC_RC_MAC_COLD; |
1563 | } | 1514 | } |
1564 | 1515 | ||
1565 | REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags); | 1516 | REG_WRITE(ah, AR_RTC_RC, rst_flags); |
1566 | udelay(50); | 1517 | udelay(50); |
1567 | 1518 | ||
1568 | REG_WRITE(ah, (u16) (AR_RTC_RC), 0); | 1519 | REG_WRITE(ah, AR_RTC_RC, 0); |
1569 | if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) { | 1520 | if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) { |
1570 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, | 1521 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, |
1571 | "RTC stuck in MAC reset\n"); | 1522 | "RTC stuck in MAC reset\n"); |
1572 | return false; | 1523 | return false; |
@@ -1588,8 +1539,8 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah) | |||
1588 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | | 1539 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | |
1589 | AR_RTC_FORCE_WAKE_ON_INT); | 1540 | AR_RTC_FORCE_WAKE_ON_INT); |
1590 | 1541 | ||
1591 | REG_WRITE(ah, (u16) (AR_RTC_RESET), 0); | 1542 | REG_WRITE(ah, AR_RTC_RESET, 0); |
1592 | REG_WRITE(ah, (u16) (AR_RTC_RESET), 1); | 1543 | REG_WRITE(ah, AR_RTC_RESET, 1); |
1593 | 1544 | ||
1594 | if (!ath9k_hw_wait(ah, | 1545 | if (!ath9k_hw_wait(ah, |
1595 | AR_RTC_STATUS, | 1546 | AR_RTC_STATUS, |
@@ -1674,34 +1625,11 @@ static bool ath9k_hw_chip_reset(struct ath_hal *ah, | |||
1674 | return true; | 1625 | return true; |
1675 | } | 1626 | } |
1676 | 1627 | ||
1677 | static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah, | ||
1678 | struct ath9k_channel *chan) | ||
1679 | { | ||
1680 | if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) { | ||
1681 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | ||
1682 | "invalid channel %u/0x%x; not marked as " | ||
1683 | "2GHz or 5GHz\n", chan->channel, chan->channelFlags); | ||
1684 | return NULL; | ||
1685 | } | ||
1686 | |||
1687 | if (!IS_CHAN_OFDM(chan) && | ||
1688 | !IS_CHAN_B(chan) && | ||
1689 | !IS_CHAN_HT20(chan) && | ||
1690 | !IS_CHAN_HT40(chan)) { | ||
1691 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | ||
1692 | "invalid channel %u/0x%x; not marked as " | ||
1693 | "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n", | ||
1694 | chan->channel, chan->channelFlags); | ||
1695 | return NULL; | ||
1696 | } | ||
1697 | |||
1698 | return ath9k_regd_check_channel(ah, chan); | ||
1699 | } | ||
1700 | |||
1701 | static bool ath9k_hw_channel_change(struct ath_hal *ah, | 1628 | static bool ath9k_hw_channel_change(struct ath_hal *ah, |
1702 | struct ath9k_channel *chan, | 1629 | struct ath9k_channel *chan, |
1703 | enum ath9k_ht_macmode macmode) | 1630 | enum ath9k_ht_macmode macmode) |
1704 | { | 1631 | { |
1632 | struct ieee80211_channel *channel = chan->chan; | ||
1705 | u32 synthDelay, qnum; | 1633 | u32 synthDelay, qnum; |
1706 | 1634 | ||
1707 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { | 1635 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { |
@@ -1738,8 +1666,8 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, | |||
1738 | 1666 | ||
1739 | if (ath9k_hw_set_txpower(ah, chan, | 1667 | if (ath9k_hw_set_txpower(ah, chan, |
1740 | ath9k_regd_get_ctl(ah, chan), | 1668 | ath9k_regd_get_ctl(ah, chan), |
1741 | ath9k_regd_get_antenna_allowed(ah, chan), | 1669 | channel->max_antenna_gain * 2, |
1742 | chan->maxRegTxPower * 2, | 1670 | channel->max_power * 2, |
1743 | min((u32) MAX_RATE_POWER, | 1671 | min((u32) MAX_RATE_POWER, |
1744 | (u32) ah->ah_powerLimit)) != 0) { | 1672 | (u32) ah->ah_powerLimit)) != 0) { |
1745 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 1673 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
@@ -1918,9 +1846,9 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel | |||
1918 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | 1846 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { |
1919 | 1847 | ||
1920 | /* workaround for gcc bug #37014 */ | 1848 | /* workaround for gcc bug #37014 */ |
1921 | volatile int tmp = abs(cur_vit_mask - bin); | 1849 | volatile int tmp_v = abs(cur_vit_mask - bin); |
1922 | 1850 | ||
1923 | if (tmp < 75) | 1851 | if (tmp_v < 75) |
1924 | mask_amt = 1; | 1852 | mask_amt = 1; |
1925 | else | 1853 | else |
1926 | mask_amt = 0; | 1854 | mask_amt = 0; |
@@ -2119,9 +2047,9 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha | |||
2119 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | 2047 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { |
2120 | 2048 | ||
2121 | /* workaround for gcc bug #37014 */ | 2049 | /* workaround for gcc bug #37014 */ |
2122 | volatile int tmp = abs(cur_vit_mask - bin); | 2050 | volatile int tmp_v = abs(cur_vit_mask - bin); |
2123 | 2051 | ||
2124 | if (tmp < 75) | 2052 | if (tmp_v < 75) |
2125 | mask_amt = 1; | 2053 | mask_amt = 1; |
2126 | else | 2054 | else |
2127 | mask_amt = 0; | 2055 | mask_amt = 0; |
@@ -2222,41 +2150,31 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha | |||
2222 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | 2150 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); |
2223 | } | 2151 | } |
2224 | 2152 | ||
2225 | bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | 2153 | int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, |
2226 | enum ath9k_ht_macmode macmode, | 2154 | bool bChannelChange) |
2227 | u8 txchainmask, u8 rxchainmask, | ||
2228 | enum ath9k_ht_extprotspacing extprotspacing, | ||
2229 | bool bChannelChange, int *status) | ||
2230 | { | 2155 | { |
2231 | u32 saveLedState; | 2156 | u32 saveLedState; |
2157 | struct ath_softc *sc = ah->ah_sc; | ||
2232 | struct ath_hal_5416 *ahp = AH5416(ah); | 2158 | struct ath_hal_5416 *ahp = AH5416(ah); |
2233 | struct ath9k_channel *curchan = ah->ah_curchan; | 2159 | struct ath9k_channel *curchan = ah->ah_curchan; |
2234 | u32 saveDefAntenna; | 2160 | u32 saveDefAntenna; |
2235 | u32 macStaId1; | 2161 | u32 macStaId1; |
2236 | int ecode; | 2162 | int i, rx_chainmask, r; |
2237 | int i, rx_chainmask; | ||
2238 | 2163 | ||
2239 | ahp->ah_extprotspacing = extprotspacing; | 2164 | ahp->ah_extprotspacing = sc->sc_ht_extprotspacing; |
2240 | ahp->ah_txchainmask = txchainmask; | 2165 | ahp->ah_txchainmask = sc->sc_tx_chainmask; |
2241 | ahp->ah_rxchainmask = rxchainmask; | 2166 | ahp->ah_rxchainmask = sc->sc_rx_chainmask; |
2242 | 2167 | ||
2243 | if (AR_SREV_9280(ah)) { | 2168 | if (AR_SREV_9285(ah)) { |
2169 | ahp->ah_txchainmask &= 0x1; | ||
2170 | ahp->ah_rxchainmask &= 0x1; | ||
2171 | } else if (AR_SREV_9280(ah)) { | ||
2244 | ahp->ah_txchainmask &= 0x3; | 2172 | ahp->ah_txchainmask &= 0x3; |
2245 | ahp->ah_rxchainmask &= 0x3; | 2173 | ahp->ah_rxchainmask &= 0x3; |
2246 | } | 2174 | } |
2247 | 2175 | ||
2248 | if (ath9k_hw_check_chan(ah, chan) == NULL) { | 2176 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
2249 | DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, | 2177 | return -EIO; |
2250 | "invalid channel %u/0x%x; no mapping\n", | ||
2251 | chan->channel, chan->channelFlags); | ||
2252 | ecode = -EINVAL; | ||
2253 | goto bad; | ||
2254 | } | ||
2255 | |||
2256 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { | ||
2257 | ecode = -EIO; | ||
2258 | goto bad; | ||
2259 | } | ||
2260 | 2178 | ||
2261 | if (curchan) | 2179 | if (curchan) |
2262 | ath9k_hw_getnf(ah, curchan); | 2180 | ath9k_hw_getnf(ah, curchan); |
@@ -2270,10 +2188,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2270 | (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) && | 2188 | (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) && |
2271 | !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) { | 2189 | !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) { |
2272 | 2190 | ||
2273 | if (ath9k_hw_channel_change(ah, chan, macmode)) { | 2191 | if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) { |
2274 | ath9k_hw_loadnf(ah, ah->ah_curchan); | 2192 | ath9k_hw_loadnf(ah, ah->ah_curchan); |
2275 | ath9k_hw_start_nfcal(ah); | 2193 | ath9k_hw_start_nfcal(ah); |
2276 | return true; | 2194 | return 0; |
2277 | } | 2195 | } |
2278 | } | 2196 | } |
2279 | 2197 | ||
@@ -2291,28 +2209,32 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2291 | 2209 | ||
2292 | if (!ath9k_hw_chip_reset(ah, chan)) { | 2210 | if (!ath9k_hw_chip_reset(ah, chan)) { |
2293 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n"); | 2211 | DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n"); |
2294 | ecode = -EINVAL; | 2212 | return -EINVAL; |
2295 | goto bad; | ||
2296 | } | 2213 | } |
2297 | 2214 | ||
2298 | if (AR_SREV_9280(ah)) { | 2215 | if (AR_SREV_9280_10_OR_LATER(ah)) |
2299 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | 2216 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); |
2300 | AR_GPIO_JTAG_DISABLE); | ||
2301 | 2217 | ||
2302 | if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) { | 2218 | r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width); |
2303 | if (IS_CHAN_5GHZ(chan)) | 2219 | if (r) |
2304 | ath9k_hw_set_gpio(ah, 9, 0); | 2220 | return r; |
2305 | else | ||
2306 | ath9k_hw_set_gpio(ah, 9, 1); | ||
2307 | } | ||
2308 | ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
2309 | } | ||
2310 | 2221 | ||
2311 | ecode = ath9k_hw_process_ini(ah, chan, macmode); | 2222 | /* Setup MFP options for CCMP */ |
2312 | if (ecode != 0) { | 2223 | if (AR_SREV_9280_20_OR_LATER(ah)) { |
2313 | ecode = -EINVAL; | 2224 | /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt |
2314 | goto bad; | 2225 | * frames when constructing CCMP AAD. */ |
2315 | } | 2226 | REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, |
2227 | 0xc7ff); | ||
2228 | ah->sw_mgmt_crypto = false; | ||
2229 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
2230 | /* Disable hardware crypto for management frames */ | ||
2231 | REG_CLR_BIT(ah, AR_PCU_MISC_MODE2, | ||
2232 | AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE); | ||
2233 | REG_SET_BIT(ah, AR_PCU_MISC_MODE2, | ||
2234 | AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT); | ||
2235 | ah->sw_mgmt_crypto = true; | ||
2236 | } else | ||
2237 | ah->sw_mgmt_crypto = true; | ||
2316 | 2238 | ||
2317 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | 2239 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) |
2318 | ath9k_hw_set_delta_slope(ah, chan); | 2240 | ath9k_hw_set_delta_slope(ah, chan); |
@@ -2325,8 +2247,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2325 | if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { | 2247 | if (!ath9k_hw_eeprom_set_board_values(ah, chan)) { |
2326 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, | 2248 | DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, |
2327 | "error setting board options\n"); | 2249 | "error setting board options\n"); |
2328 | ecode = -EIO; | 2250 | return -EIO; |
2329 | goto bad; | ||
2330 | } | 2251 | } |
2331 | 2252 | ||
2332 | ath9k_hw_decrease_chain_power(ah, chan); | 2253 | ath9k_hw_decrease_chain_power(ah, chan); |
@@ -2354,15 +2275,11 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2354 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); | 2275 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); |
2355 | 2276 | ||
2356 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 2277 | if (AR_SREV_9280_10_OR_LATER(ah)) { |
2357 | if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { | 2278 | if (!(ath9k_hw_ar9280_set_channel(ah, chan))) |
2358 | ecode = -EIO; | 2279 | return -EIO; |
2359 | goto bad; | ||
2360 | } | ||
2361 | } else { | 2280 | } else { |
2362 | if (!(ath9k_hw_set_channel(ah, chan))) { | 2281 | if (!(ath9k_hw_set_channel(ah, chan))) |
2363 | ecode = -EIO; | 2282 | return -EIO; |
2364 | goto bad; | ||
2365 | } | ||
2366 | } | 2283 | } |
2367 | 2284 | ||
2368 | for (i = 0; i < AR_NUM_DCU; i++) | 2285 | for (i = 0; i < AR_NUM_DCU; i++) |
@@ -2396,10 +2313,8 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2396 | 2313 | ||
2397 | ath9k_hw_init_bb(ah, chan); | 2314 | ath9k_hw_init_bb(ah, chan); |
2398 | 2315 | ||
2399 | if (!ath9k_hw_init_cal(ah, chan)){ | 2316 | if (!ath9k_hw_init_cal(ah, chan)) |
2400 | ecode = -EIO;; | 2317 | return -EIO;; |
2401 | goto bad; | ||
2402 | } | ||
2403 | 2318 | ||
2404 | rx_chainmask = ahp->ah_rxchainmask; | 2319 | rx_chainmask = ahp->ah_rxchainmask; |
2405 | if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { | 2320 | if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { |
@@ -2428,11 +2343,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, | |||
2428 | #endif | 2343 | #endif |
2429 | } | 2344 | } |
2430 | 2345 | ||
2431 | return true; | 2346 | return 0; |
2432 | bad: | ||
2433 | if (status) | ||
2434 | *status = ecode; | ||
2435 | return false; | ||
2436 | } | 2347 | } |
2437 | 2348 | ||
2438 | /************************/ | 2349 | /************************/ |
@@ -2658,7 +2569,7 @@ static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip) | |||
2658 | if (!AR_SREV_9100(ah)) | 2569 | if (!AR_SREV_9100(ah)) |
2659 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | 2570 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); |
2660 | 2571 | ||
2661 | REG_CLR_BIT(ah, (u16) (AR_RTC_RESET), | 2572 | REG_CLR_BIT(ah, (AR_RTC_RESET), |
2662 | AR_RTC_RESET_EN); | 2573 | AR_RTC_RESET_EN); |
2663 | } | 2574 | } |
2664 | } | 2575 | } |
@@ -2734,7 +2645,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah, | |||
2734 | int status = true, setChip = true; | 2645 | int status = true, setChip = true; |
2735 | 2646 | ||
2736 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n", | 2647 | DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n", |
2737 | modes[ahp->ah_powerMode], modes[mode], | 2648 | modes[ah->ah_power_mode], modes[mode], |
2738 | setChip ? "set chip " : ""); | 2649 | setChip ? "set chip " : ""); |
2739 | 2650 | ||
2740 | switch (mode) { | 2651 | switch (mode) { |
@@ -2753,7 +2664,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah, | |||
2753 | "Unknown power mode %u\n", mode); | 2664 | "Unknown power mode %u\n", mode); |
2754 | return false; | 2665 | return false; |
2755 | } | 2666 | } |
2756 | ahp->ah_powerMode = mode; | 2667 | ah->ah_power_mode = mode; |
2757 | 2668 | ||
2758 | return status; | 2669 | return status; |
2759 | } | 2670 | } |
@@ -3332,7 +3243,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) | |||
3332 | pCap->num_mr_retries = 4; | 3243 | pCap->num_mr_retries = 4; |
3333 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; | 3244 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; |
3334 | 3245 | ||
3335 | if (AR_SREV_9280_10_OR_LATER(ah)) | 3246 | if (AR_SREV_9285_10_OR_LATER(ah)) |
3247 | pCap->num_gpio_pins = AR9285_NUM_GPIO; | ||
3248 | else if (AR_SREV_9280_10_OR_LATER(ah)) | ||
3336 | pCap->num_gpio_pins = AR928X_NUM_GPIO; | 3249 | pCap->num_gpio_pins = AR928X_NUM_GPIO; |
3337 | else | 3250 | else |
3338 | pCap->num_gpio_pins = AR_NUM_GPIO; | 3251 | pCap->num_gpio_pins = AR_NUM_GPIO; |
@@ -3399,6 +3312,12 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah) | |||
3399 | pCap->num_antcfg_2ghz = | 3312 | pCap->num_antcfg_2ghz = |
3400 | ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); | 3313 | ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); |
3401 | 3314 | ||
3315 | if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) { | ||
3316 | pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX; | ||
3317 | ah->ah_btactive_gpio = 6; | ||
3318 | ah->ah_wlanactive_gpio = 5; | ||
3319 | } | ||
3320 | |||
3402 | return true; | 3321 | return true; |
3403 | } | 3322 | } |
3404 | 3323 | ||
@@ -3577,17 +3496,18 @@ void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio) | |||
3577 | 3496 | ||
3578 | u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) | 3497 | u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio) |
3579 | { | 3498 | { |
3499 | #define MS_REG_READ(x, y) \ | ||
3500 | (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y))) | ||
3501 | |||
3580 | if (gpio >= ah->ah_caps.num_gpio_pins) | 3502 | if (gpio >= ah->ah_caps.num_gpio_pins) |
3581 | return 0xffffffff; | 3503 | return 0xffffffff; |
3582 | 3504 | ||
3583 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 3505 | if (AR_SREV_9285_10_OR_LATER(ah)) |
3584 | return (MS | 3506 | return MS_REG_READ(AR9285, gpio) != 0; |
3585 | (REG_READ(ah, AR_GPIO_IN_OUT), | 3507 | else if (AR_SREV_9280_10_OR_LATER(ah)) |
3586 | AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0; | 3508 | return MS_REG_READ(AR928X, gpio) != 0; |
3587 | } else { | 3509 | else |
3588 | return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) & | 3510 | return MS_REG_READ(AR, gpio) != 0; |
3589 | AR_GPIO_BIT(gpio)) != 0; | ||
3590 | } | ||
3591 | } | 3511 | } |
3592 | 3512 | ||
3593 | void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, | 3513 | void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio, |
@@ -3625,27 +3545,6 @@ void ath9k_enable_rfkill(struct ath_hal *ah) | |||
3625 | } | 3545 | } |
3626 | #endif | 3546 | #endif |
3627 | 3547 | ||
3628 | int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg) | ||
3629 | { | ||
3630 | struct ath9k_channel *chan = ah->ah_curchan; | ||
3631 | const struct ath9k_hw_capabilities *pCap = &ah->ah_caps; | ||
3632 | u16 ant_config; | ||
3633 | u32 halNumAntConfig; | ||
3634 | |||
3635 | halNumAntConfig = IS_CHAN_2GHZ(chan) ? | ||
3636 | pCap->num_antcfg_2ghz : pCap->num_antcfg_5ghz; | ||
3637 | |||
3638 | if (cfg < halNumAntConfig) { | ||
3639 | if (!ath9k_hw_get_eeprom_antenna_cfg(ah, chan, | ||
3640 | cfg, &ant_config)) { | ||
3641 | REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config); | ||
3642 | return 0; | ||
3643 | } | ||
3644 | } | ||
3645 | |||
3646 | return -EINVAL; | ||
3647 | } | ||
3648 | |||
3649 | u32 ath9k_hw_getdefantenna(struct ath_hal *ah) | 3548 | u32 ath9k_hw_getdefantenna(struct ath_hal *ah) |
3650 | { | 3549 | { |
3651 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; | 3550 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; |
@@ -3755,13 +3654,14 @@ bool ath9k_hw_disable(struct ath_hal *ah) | |||
3755 | bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit) | 3654 | bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit) |
3756 | { | 3655 | { |
3757 | struct ath9k_channel *chan = ah->ah_curchan; | 3656 | struct ath9k_channel *chan = ah->ah_curchan; |
3657 | struct ieee80211_channel *channel = chan->chan; | ||
3758 | 3658 | ||
3759 | ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER); | 3659 | ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER); |
3760 | 3660 | ||
3761 | if (ath9k_hw_set_txpower(ah, chan, | 3661 | if (ath9k_hw_set_txpower(ah, chan, |
3762 | ath9k_regd_get_ctl(ah, chan), | 3662 | ath9k_regd_get_ctl(ah, chan), |
3763 | ath9k_regd_get_antenna_allowed(ah, chan), | 3663 | channel->max_antenna_gain * 2, |
3764 | chan->maxRegTxPower * 2, | 3664 | channel->max_power * 2, |
3765 | min((u32) MAX_RATE_POWER, | 3665 | min((u32) MAX_RATE_POWER, |
3766 | (u32) ah->ah_powerLimit)) != 0) | 3666 | (u32) ah->ah_powerLimit)) != 0) |
3767 | return false; | 3667 | return false; |
@@ -3837,6 +3737,13 @@ u64 ath9k_hw_gettsf64(struct ath_hal *ah) | |||
3837 | return tsf; | 3737 | return tsf; |
3838 | } | 3738 | } |
3839 | 3739 | ||
3740 | void ath9k_hw_settsf64(struct ath_hal *ah, u64 tsf64) | ||
3741 | { | ||
3742 | REG_WRITE(ah, AR_TSF_L32, 0x00000000); | ||
3743 | REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); | ||
3744 | REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); | ||
3745 | } | ||
3746 | |||
3840 | void ath9k_hw_reset_tsf(struct ath_hal *ah) | 3747 | void ath9k_hw_reset_tsf(struct ath_hal *ah) |
3841 | { | 3748 | { |
3842 | int count; | 3749 | int count; |
@@ -3893,3 +3800,30 @@ void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode) | |||
3893 | 3800 | ||
3894 | REG_WRITE(ah, AR_2040_MODE, macmode); | 3801 | REG_WRITE(ah, AR_2040_MODE, macmode); |
3895 | } | 3802 | } |
3803 | |||
3804 | /***************************/ | ||
3805 | /* Bluetooth Coexistence */ | ||
3806 | /***************************/ | ||
3807 | |||
3808 | void ath9k_hw_btcoex_enable(struct ath_hal *ah) | ||
3809 | { | ||
3810 | /* connect bt_active to baseband */ | ||
3811 | REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
3812 | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | | ||
3813 | AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF)); | ||
3814 | |||
3815 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
3816 | AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB); | ||
3817 | |||
3818 | /* Set input mux for bt_active to gpio pin */ | ||
3819 | REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1, | ||
3820 | AR_GPIO_INPUT_MUX1_BT_ACTIVE, | ||
3821 | ah->ah_btactive_gpio); | ||
3822 | |||
3823 | /* Configure the desired gpio port for input */ | ||
3824 | ath9k_hw_cfg_gpio_input(ah, ah->ah_btactive_gpio); | ||
3825 | |||
3826 | /* Configure the desired GPIO port for TX_FRAME output */ | ||
3827 | ath9k_hw_cfg_output(ah, ah->ah_wlanactive_gpio, | ||
3828 | AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); | ||
3829 | } | ||
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index 91d8f594af81..087c5718707b 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h | |||
@@ -20,6 +20,14 @@ | |||
20 | #include <linux/if_ether.h> | 20 | #include <linux/if_ether.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | 22 | ||
23 | extern const struct hal_percal_data iq_cal_multi_sample; | ||
24 | extern const struct hal_percal_data iq_cal_single_sample; | ||
25 | extern const struct hal_percal_data adc_gain_cal_multi_sample; | ||
26 | extern const struct hal_percal_data adc_gain_cal_single_sample; | ||
27 | extern const struct hal_percal_data adc_dc_cal_multi_sample; | ||
28 | extern const struct hal_percal_data adc_dc_cal_single_sample; | ||
29 | extern const struct hal_percal_data adc_init_dc_cal; | ||
30 | |||
23 | struct ar5416_desc { | 31 | struct ar5416_desc { |
24 | u32 ds_link; | 32 | u32 ds_link; |
25 | u32 ds_data; | 33 | u32 ds_data; |
@@ -418,6 +426,7 @@ struct ar5416Stats { | |||
418 | #define AR5416_EEP_MINOR_VER_16 0x10 | 426 | #define AR5416_EEP_MINOR_VER_16 0x10 |
419 | #define AR5416_EEP_MINOR_VER_17 0x11 | 427 | #define AR5416_EEP_MINOR_VER_17 0x11 |
420 | #define AR5416_EEP_MINOR_VER_19 0x13 | 428 | #define AR5416_EEP_MINOR_VER_19 0x13 |
429 | #define AR5416_EEP_MINOR_VER_20 0x14 | ||
421 | 430 | ||
422 | #define AR5416_NUM_5G_CAL_PIERS 8 | 431 | #define AR5416_NUM_5G_CAL_PIERS 8 |
423 | #define AR5416_NUM_2G_CAL_PIERS 4 | 432 | #define AR5416_NUM_2G_CAL_PIERS 4 |
@@ -480,6 +489,7 @@ enum eeprom_param { | |||
480 | EEP_RX_MASK, | 489 | EEP_RX_MASK, |
481 | EEP_RXGAIN_TYPE, | 490 | EEP_RXGAIN_TYPE, |
482 | EEP_TXGAIN_TYPE, | 491 | EEP_TXGAIN_TYPE, |
492 | EEP_DAC_HPWR_5G, | ||
483 | }; | 493 | }; |
484 | 494 | ||
485 | enum ar5416_rates { | 495 | enum ar5416_rates { |
@@ -518,9 +528,13 @@ struct base_eep_header { | |||
518 | u8 pwdclkind; | 528 | u8 pwdclkind; |
519 | u8 futureBase_1[2]; | 529 | u8 futureBase_1[2]; |
520 | u8 rxGainType; | 530 | u8 rxGainType; |
521 | u8 futureBase_2[3]; | 531 | u8 dacHiPwrMode_5G; |
532 | u8 futureBase_2; | ||
533 | u8 dacLpMode; | ||
522 | u8 txGainType; | 534 | u8 txGainType; |
523 | u8 futureBase_3[25]; | 535 | u8 rcChainMask; |
536 | u8 desiredScaleCCK; | ||
537 | u8 futureBase_3[23]; | ||
524 | } __packed; | 538 | } __packed; |
525 | 539 | ||
526 | struct base_eep_header_4k { | 540 | struct base_eep_header_4k { |
@@ -587,7 +601,7 @@ struct modal_eep_header { | |||
587 | force_xpaon:1, | 601 | force_xpaon:1, |
588 | local_bias:1, | 602 | local_bias:1, |
589 | femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1; | 603 | femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1; |
590 | u8 futureModalar9280; | 604 | u8 miscBits; |
591 | u16 xpaBiasLvlFreq[3]; | 605 | u16 xpaBiasLvlFreq[3]; |
592 | u8 futureModal[6]; | 606 | u8 futureModal[6]; |
593 | 607 | ||
@@ -830,7 +844,6 @@ struct ath_hal_5416 { | |||
830 | bool ah_chipFullSleep; | 844 | bool ah_chipFullSleep; |
831 | u32 ah_atimWindow; | 845 | u32 ah_atimWindow; |
832 | u16 ah_antennaSwitchSwap; | 846 | u16 ah_antennaSwitchSwap; |
833 | enum ath9k_power_mode ah_powerMode; | ||
834 | enum ath9k_ant_setting ah_diversityControl; | 847 | enum ath9k_ant_setting ah_diversityControl; |
835 | 848 | ||
836 | /* Calibration */ | 849 | /* Calibration */ |
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h index f3cfa16525e4..d49236368a1c 100644 --- a/drivers/net/wireless/ath9k/initvals.h +++ b/drivers/net/wireless/ath9k/initvals.h | |||
@@ -14,7 +14,6 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* AR5416 to Fowl ar5146.ini */ | ||
18 | static const u32 ar5416Modes_9100[][6] = { | 17 | static const u32 ar5416Modes_9100[][6] = { |
19 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 18 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, |
20 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | 19 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, |
@@ -659,10 +658,9 @@ static const u32 ar5416Addac_9100[][2] = { | |||
659 | {0x0000989c, 0x00000000 }, | 658 | {0x0000989c, 0x00000000 }, |
660 | {0x0000989c, 0x00000000 }, | 659 | {0x0000989c, 0x00000000 }, |
661 | {0x0000989c, 0x00000000 }, | 660 | {0x0000989c, 0x00000000 }, |
662 | {0x000098c4, 0x00000000 }, | 661 | {0x000098cc, 0x00000000 }, |
663 | }; | 662 | }; |
664 | 663 | ||
665 | /* ar5416 - howl ar5416_howl.ini */ | ||
666 | static const u32 ar5416Modes[][6] = { | 664 | static const u32 ar5416Modes[][6] = { |
667 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 665 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, |
668 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | 666 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, |
@@ -1313,7 +1311,6 @@ static const u32 ar5416Addac[][2] = { | |||
1313 | {0x000098cc, 0x00000000 }, | 1311 | {0x000098cc, 0x00000000 }, |
1314 | }; | 1312 | }; |
1315 | 1313 | ||
1316 | /* AR5416 9160 Sowl ar5416_sowl.ini */ | ||
1317 | static const u32 ar5416Modes_9160[][6] = { | 1314 | static const u32 ar5416Modes_9160[][6] = { |
1318 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 1315 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, |
1319 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | 1316 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, |
@@ -2549,6 +2546,8 @@ static const u32 ar9280Modes_9280_2[][6] = { | |||
2549 | { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, | 2546 | { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 }, |
2550 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | 2547 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, |
2551 | { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, | 2548 | { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f }, |
2549 | { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, | ||
2550 | { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a }, | ||
2552 | { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, | 2551 | { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 }, |
2553 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | 2552 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, |
2554 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | 2553 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, |
@@ -2587,7 +2586,6 @@ static const u32 ar9280Modes_9280_2[][6] = { | |||
2587 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | 2586 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, |
2588 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | 2587 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, |
2589 | { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 }, | 2588 | { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 }, |
2590 | { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, | ||
2591 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, | 2589 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, |
2592 | { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 2590 | { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
2593 | { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 }, | 2591 | { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 }, |
@@ -2719,7 +2717,6 @@ static const u32 ar9280Common_9280_2[][2] = { | |||
2719 | { 0x00008110, 0x00000168 }, | 2717 | { 0x00008110, 0x00000168 }, |
2720 | { 0x00008118, 0x000100aa }, | 2718 | { 0x00008118, 0x000100aa }, |
2721 | { 0x0000811c, 0x00003210 }, | 2719 | { 0x0000811c, 0x00003210 }, |
2722 | { 0x00008120, 0x08f04800 }, | ||
2723 | { 0x00008124, 0x00000000 }, | 2720 | { 0x00008124, 0x00000000 }, |
2724 | { 0x00008128, 0x00000000 }, | 2721 | { 0x00008128, 0x00000000 }, |
2725 | { 0x0000812c, 0x00000000 }, | 2722 | { 0x0000812c, 0x00000000 }, |
@@ -2735,7 +2732,6 @@ static const u32 ar9280Common_9280_2[][2] = { | |||
2735 | { 0x00008178, 0x00000100 }, | 2732 | { 0x00008178, 0x00000100 }, |
2736 | { 0x0000817c, 0x00000000 }, | 2733 | { 0x0000817c, 0x00000000 }, |
2737 | { 0x000081c0, 0x00000000 }, | 2734 | { 0x000081c0, 0x00000000 }, |
2738 | { 0x000081d0, 0x00003210 }, | ||
2739 | { 0x000081ec, 0x00000000 }, | 2735 | { 0x000081ec, 0x00000000 }, |
2740 | { 0x000081f0, 0x00000000 }, | 2736 | { 0x000081f0, 0x00000000 }, |
2741 | { 0x000081f4, 0x00000000 }, | 2737 | { 0x000081f4, 0x00000000 }, |
@@ -2817,7 +2813,7 @@ static const u32 ar9280Common_9280_2[][2] = { | |||
2817 | { 0x00009958, 0x2108ecff }, | 2813 | { 0x00009958, 0x2108ecff }, |
2818 | { 0x00009940, 0x14750604 }, | 2814 | { 0x00009940, 0x14750604 }, |
2819 | { 0x0000c95c, 0x004b6a8e }, | 2815 | { 0x0000c95c, 0x004b6a8e }, |
2820 | { 0x00009968, 0x000003ce }, | 2816 | { 0x0000c968, 0x000003ce }, |
2821 | { 0x00009970, 0x190fb515 }, | 2817 | { 0x00009970, 0x190fb515 }, |
2822 | { 0x00009974, 0x00000000 }, | 2818 | { 0x00009974, 0x00000000 }, |
2823 | { 0x00009978, 0x00000001 }, | 2819 | { 0x00009978, 0x00000001 }, |
@@ -2909,16 +2905,12 @@ static const u32 ar9280Common_9280_2[][2] = { | |||
2909 | { 0x0000780c, 0x21084210 }, | 2905 | { 0x0000780c, 0x21084210 }, |
2910 | { 0x00007810, 0x6d801300 }, | 2906 | { 0x00007810, 0x6d801300 }, |
2911 | { 0x00007818, 0x07e41000 }, | 2907 | { 0x00007818, 0x07e41000 }, |
2912 | { 0x0000781c, 0x00392000 }, | ||
2913 | { 0x00007820, 0x92592480 }, | ||
2914 | { 0x00007824, 0x00040000 }, | 2908 | { 0x00007824, 0x00040000 }, |
2915 | { 0x00007828, 0xdb005012 }, | 2909 | { 0x00007828, 0xdb005012 }, |
2916 | { 0x0000782c, 0x04924914 }, | 2910 | { 0x0000782c, 0x04924914 }, |
2917 | { 0x00007830, 0x21084210 }, | 2911 | { 0x00007830, 0x21084210 }, |
2918 | { 0x00007834, 0x6d801300 }, | 2912 | { 0x00007834, 0x6d801300 }, |
2919 | { 0x0000783c, 0x07e40000 }, | 2913 | { 0x0000783c, 0x07e40000 }, |
2920 | { 0x00007840, 0x00392000 }, | ||
2921 | { 0x00007844, 0x92592480 }, | ||
2922 | { 0x00007848, 0x00100000 }, | 2914 | { 0x00007848, 0x00100000 }, |
2923 | { 0x0000784c, 0x773f0567 }, | 2915 | { 0x0000784c, 0x773f0567 }, |
2924 | { 0x00007850, 0x54214514 }, | 2916 | { 0x00007850, 0x54214514 }, |
@@ -2954,7 +2946,6 @@ static const u32 ar9280Modes_fast_clock_9280_2[][3] = { | |||
2954 | { 0x00009844, 0x03721821, 0x03721821 }, | 2946 | { 0x00009844, 0x03721821, 0x03721821 }, |
2955 | { 0x00009914, 0x00000898, 0x00001130 }, | 2947 | { 0x00009914, 0x00000898, 0x00001130 }, |
2956 | { 0x00009918, 0x0000000b, 0x00000016 }, | 2948 | { 0x00009918, 0x0000000b, 0x00000016 }, |
2957 | { 0x00009944, 0xdfbc1210, 0xdfbc1210 }, | ||
2958 | }; | 2949 | }; |
2959 | 2950 | ||
2960 | static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = { | 2951 | static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = { |
@@ -3366,21 +3357,26 @@ static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = { | |||
3366 | { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a }, | 3357 | { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a }, |
3367 | { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 }, | 3358 | { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 }, |
3368 | { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, | 3359 | { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 }, |
3369 | { 0x0000a324, 0x00020092, 0x00020092, 0x00022411, 0x00022411, 0x00022411 }, | 3360 | { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 }, |
3370 | { 0x0000a328, 0x0002410a, 0x0002410a, 0x00025413, 0x00025413, 0x00025413 }, | 3361 | { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 }, |
3371 | { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00029811, 0x00029811, 0x00029811 }, | 3362 | { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 }, |
3372 | { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002c813, 0x0002c813, 0x0002c813 }, | 3363 | { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 }, |
3373 | { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030a14, 0x00030a14, 0x00030a14 }, | 3364 | { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 }, |
3374 | { 0x0000a338, 0x000321ec, 0x000321ec, 0x00035a50, 0x00035a50, 0x00035a50 }, | 3365 | { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 }, |
3375 | { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00039c4c, 0x00039c4c, 0x00039c4c }, | 3366 | { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c }, |
3376 | { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003de8a, 0x0003de8a, 0x0003de8a }, | 3367 | { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a }, |
3377 | { 0x0000a344, 0x000321ec, 0x000321ec, 0x00042e92, 0x00042e92, 0x00042e92 }, | 3368 | { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 }, |
3378 | { 0x0000a348, 0x000321ec, 0x000321ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 }, | 3369 | { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 }, |
3379 | { 0x0000a34c, 0x000321ec, 0x000321ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 }, | 3370 | { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 }, |
3380 | { 0x0000a350, 0x000321ec, 0x000321ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 }, | 3371 | { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 }, |
3381 | { 0x0000a354, 0x000321ec, 0x000321ec, 0x00053fd5, 0x00053fd5, 0x00053fd5 }, | 3372 | { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 }, |
3382 | { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, | 3373 | { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, |
3383 | { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, | 3374 | { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff }, |
3375 | { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 }, | ||
3376 | { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 }, | ||
3377 | { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 }, | ||
3378 | { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 }, | ||
3379 | { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, | ||
3384 | { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce }, | 3380 | { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce }, |
3385 | }; | 3381 | }; |
3386 | 3382 | ||
@@ -3409,6 +3405,11 @@ static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = { | |||
3409 | { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 }, | 3405 | { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 }, |
3410 | { 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, | 3406 | { 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, |
3411 | { 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, | 3407 | { 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff }, |
3408 | { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 }, | ||
3409 | { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 }, | ||
3410 | { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 }, | ||
3411 | { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 }, | ||
3412 | { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 }, | ||
3412 | { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce }, | 3413 | { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce }, |
3413 | }; | 3414 | }; |
3414 | 3415 | ||
@@ -4135,11 +4136,11 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = { | |||
4135 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | 4136 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, |
4136 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | 4137 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, |
4137 | { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, | 4138 | { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, |
4138 | { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 }, | 4139 | { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 }, |
4139 | { 0x00009848, 0x00001066, 0x00001066, 0x00000057, 0x00000057, 0x00001059 }, | 4140 | { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 }, |
4140 | { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, | 4141 | { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, |
4141 | { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, | 4142 | { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, |
4142 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e }, | 4143 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e }, |
4143 | { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 }, | 4144 | { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 }, |
4144 | { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | 4145 | { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, |
4145 | { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, | 4146 | { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, |
@@ -4159,264 +4160,264 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = { | |||
4159 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | 4160 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, |
4160 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 4161 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
4161 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 4162 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
4162 | { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 }, | 4163 | { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, |
4163 | { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 }, | 4164 | { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, |
4164 | { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 }, | 4165 | { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, |
4165 | { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 }, | 4166 | { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, |
4166 | { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 }, | 4167 | { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, |
4167 | { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 }, | 4168 | { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, |
4168 | { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 }, | 4169 | { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, |
4169 | { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, | 4170 | { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, |
4170 | { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 }, | 4171 | { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, |
4171 | { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 }, | 4172 | { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, |
4172 | { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 }, | 4173 | { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, |
4173 | { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 }, | 4174 | { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, |
4174 | { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 }, | 4175 | { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, |
4175 | { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 }, | 4176 | { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, |
4176 | { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 }, | 4177 | { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, |
4177 | { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 }, | 4178 | { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, |
4178 | { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 }, | 4179 | { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, |
4179 | { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 }, | 4180 | { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, |
4180 | { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 }, | 4181 | { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, |
4181 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 }, | 4182 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, |
4182 | { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 }, | 4183 | { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, |
4183 | { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 }, | 4184 | { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, |
4184 | { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 }, | 4185 | { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, |
4185 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 }, | 4186 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, |
4186 | { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 }, | 4187 | { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, |
4187 | { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 }, | 4188 | { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, |
4188 | { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 }, | 4189 | { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, |
4189 | { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 }, | 4190 | { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, |
4190 | { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, | 4191 | { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, |
4191 | { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, | 4192 | { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, |
4192 | { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, | 4193 | { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, |
4193 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | 4194 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, |
4194 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | 4195 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, |
4195 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | 4196 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, |
4196 | { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 }, | 4197 | { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, |
4197 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 }, | 4198 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
4198 | { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 }, | 4199 | { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
4199 | { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 }, | 4200 | { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, |
4200 | { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 }, | 4201 | { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, |
4201 | { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 }, | 4202 | { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, |
4202 | { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 }, | 4203 | { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, |
4203 | { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 }, | 4204 | { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, |
4204 | { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 }, | 4205 | { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, |
4205 | { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 }, | 4206 | { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, |
4206 | { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, | 4207 | { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, |
4207 | { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 }, | 4208 | { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, |
4208 | { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 }, | 4209 | { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, |
4209 | { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 }, | 4210 | { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, |
4210 | { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 }, | 4211 | { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, |
4211 | { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 }, | 4212 | { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, |
4212 | { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 }, | 4213 | { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, |
4213 | { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 }, | 4214 | { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, |
4214 | { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 }, | 4215 | { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, |
4215 | { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 }, | 4216 | { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, |
4216 | { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 }, | 4217 | { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, |
4217 | { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 }, | 4218 | { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, |
4218 | { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 }, | 4219 | { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, |
4219 | { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 }, | 4220 | { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, |
4220 | { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 }, | 4221 | { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, |
4221 | { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 }, | 4222 | { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, |
4222 | { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 }, | 4223 | { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, |
4223 | { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 }, | 4224 | { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, |
4224 | { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 }, | 4225 | { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, |
4225 | { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 }, | 4226 | { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, |
4226 | { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 }, | 4227 | { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, |
4227 | { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 }, | 4228 | { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, |
4228 | { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 }, | 4229 | { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, |
4229 | { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 }, | 4230 | { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, |
4230 | { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 }, | 4231 | { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, |
4231 | { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 }, | 4232 | { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, |
4232 | { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 }, | 4233 | { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, |
4233 | { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 }, | 4234 | { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, |
4234 | { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 }, | 4235 | { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, |
4235 | { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 }, | 4236 | { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, |
4236 | { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 }, | 4237 | { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, |
4237 | { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 }, | 4238 | { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, |
4238 | { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 }, | 4239 | { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, |
4239 | { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 }, | 4240 | { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, |
4240 | { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 }, | 4241 | { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, |
4241 | { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 }, | 4242 | { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, |
4242 | { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 }, | 4243 | { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, |
4243 | { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 }, | 4244 | { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, |
4244 | { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 }, | 4245 | { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, |
4245 | { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 }, | 4246 | { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, |
4246 | { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 }, | 4247 | { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, |
4247 | { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 }, | 4248 | { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, |
4248 | { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 }, | 4249 | { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, |
4249 | { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 }, | 4250 | { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, |
4250 | { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 }, | 4251 | { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, |
4251 | { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4252 | { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4252 | { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4253 | { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4253 | { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4254 | { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4254 | { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4255 | { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4255 | { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4256 | { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4256 | { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4257 | { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4257 | { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4258 | { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4258 | { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4259 | { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4259 | { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4260 | { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4260 | { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4261 | { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4261 | { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4262 | { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4262 | { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4263 | { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4263 | { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4264 | { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4264 | { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4265 | { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4265 | { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4266 | { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4266 | { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4267 | { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4267 | { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4268 | { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4268 | { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4269 | { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4269 | { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4270 | { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4270 | { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4271 | { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4271 | { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4272 | { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4272 | { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4273 | { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4273 | { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4274 | { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4274 | { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4275 | { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4275 | { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4276 | { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4276 | { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4277 | { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4277 | { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4278 | { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4278 | { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4279 | { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4279 | { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4280 | { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4280 | { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4281 | { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4281 | { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4282 | { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4282 | { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4283 | { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4283 | { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4284 | { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4284 | { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4285 | { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4285 | { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4286 | { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4286 | { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4287 | { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4287 | { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4288 | { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4288 | { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4289 | { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4289 | { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 }, | 4290 | { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4290 | { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 }, | 4291 | { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 }, |
4291 | { 0x0000aa04, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 }, | 4292 | { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 }, |
4292 | { 0x0000aa08, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 }, | 4293 | { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 }, |
4293 | { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 }, | 4294 | { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 }, |
4294 | { 0x0000aa10, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 }, | 4295 | { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 }, |
4295 | { 0x0000aa14, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 }, | 4296 | { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 }, |
4296 | { 0x0000aa18, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 }, | 4297 | { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 }, |
4297 | { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 }, | 4298 | { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 }, |
4298 | { 0x0000aa20, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 }, | 4299 | { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 }, |
4299 | { 0x0000aa24, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 }, | 4300 | { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 }, |
4300 | { 0x0000aa28, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 }, | 4301 | { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 }, |
4301 | { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, | 4302 | { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 }, |
4302 | { 0x0000aa30, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 }, | 4303 | { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 }, |
4303 | { 0x0000aa34, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 }, | 4304 | { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 }, |
4304 | { 0x0000aa38, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 }, | 4305 | { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 }, |
4305 | { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 }, | 4306 | { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 }, |
4306 | { 0x0000aa40, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 }, | 4307 | { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 }, |
4307 | { 0x0000aa44, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 }, | 4308 | { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, |
4308 | { 0x0000aa48, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 }, | 4309 | { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, |
4309 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 }, | 4310 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, |
4310 | { 0x0000aa50, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 }, | 4311 | { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, |
4311 | { 0x0000aa54, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 }, | 4312 | { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, |
4312 | { 0x0000aa58, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 }, | 4313 | { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, |
4313 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 }, | 4314 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, |
4314 | { 0x0000aa60, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 }, | 4315 | { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 }, |
4315 | { 0x0000aa64, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 }, | 4316 | { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 }, |
4316 | { 0x0000aa68, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 }, | 4317 | { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 }, |
4317 | { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 }, | 4318 | { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 }, |
4318 | { 0x0000aa70, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 }, | 4319 | { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 }, |
4319 | { 0x0000aa74, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 }, | 4320 | { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 }, |
4320 | { 0x0000aa78, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 }, | 4321 | { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 }, |
4321 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 }, | 4322 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, |
4322 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 }, | 4323 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, |
4323 | { 0x0000aa84, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 }, | 4324 | { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, |
4324 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 }, | 4325 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, |
4325 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 }, | 4326 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
4326 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 }, | 4327 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
4327 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 }, | 4328 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, |
4328 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 }, | 4329 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, |
4329 | { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 }, | 4330 | { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 }, |
4330 | { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 }, | 4331 | { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 }, |
4331 | { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 }, | 4332 | { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 }, |
4332 | { 0x0000aaa8, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 }, | 4333 | { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 }, |
4333 | { 0x0000aaac, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 }, | 4334 | { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 }, |
4334 | { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 }, | 4335 | { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 }, |
4335 | { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 }, | 4336 | { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 }, |
4336 | { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 }, | 4337 | { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 }, |
4337 | { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, | 4338 | { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 }, |
4338 | { 0x0000aac0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 }, | 4339 | { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 }, |
4339 | { 0x0000aac4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 }, | 4340 | { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 }, |
4340 | { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 }, | 4341 | { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 }, |
4341 | { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 }, | 4342 | { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 }, |
4342 | { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 }, | 4343 | { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 }, |
4343 | { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 }, | 4344 | { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 }, |
4344 | { 0x0000aad8, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 }, | 4345 | { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 }, |
4345 | { 0x0000aadc, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 }, | 4346 | { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 }, |
4346 | { 0x0000aae0, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 }, | 4347 | { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 }, |
4347 | { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 }, | 4348 | { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 }, |
4348 | { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 }, | 4349 | { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 }, |
4349 | { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 }, | 4350 | { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 }, |
4350 | { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 }, | 4351 | { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 }, |
4351 | { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 }, | 4352 | { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 }, |
4352 | { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 }, | 4353 | { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 }, |
4353 | { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 }, | 4354 | { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 }, |
4354 | { 0x0000ab00, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 }, | 4355 | { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 }, |
4355 | { 0x0000ab04, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 }, | 4356 | { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 }, |
4356 | { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 }, | 4357 | { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 }, |
4357 | { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 }, | 4358 | { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 }, |
4358 | { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 }, | 4359 | { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 }, |
4359 | { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 }, | 4360 | { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 }, |
4360 | { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 }, | 4361 | { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 }, |
4361 | { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 }, | 4362 | { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 }, |
4362 | { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 }, | 4363 | { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 }, |
4363 | { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 }, | 4364 | { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 }, |
4364 | { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 }, | 4365 | { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 }, |
4365 | { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 }, | 4366 | { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 }, |
4366 | { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 }, | 4367 | { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 }, |
4367 | { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 }, | 4368 | { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 }, |
4368 | { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 }, | 4369 | { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 }, |
4369 | { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 }, | 4370 | { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 }, |
4370 | { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 }, | 4371 | { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 }, |
4371 | { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 }, | 4372 | { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 }, |
4372 | { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 }, | 4373 | { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 }, |
4373 | { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 }, | 4374 | { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 }, |
4374 | { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 }, | 4375 | { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 }, |
4375 | { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 }, | 4376 | { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 }, |
4376 | { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 }, | 4377 | { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 }, |
4377 | { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 }, | 4378 | { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 }, |
4378 | { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 }, | 4379 | { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 }, |
4379 | { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 }, | 4380 | { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4380 | { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 }, | 4381 | { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4381 | { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4382 | { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4382 | { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4383 | { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4383 | { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4384 | { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4384 | { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4385 | { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4385 | { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4386 | { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4386 | { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4387 | { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4387 | { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4388 | { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4388 | { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4389 | { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4389 | { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4390 | { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4390 | { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4391 | { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4391 | { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4392 | { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4392 | { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4393 | { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4393 | { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4394 | { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4394 | { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4395 | { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4395 | { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4396 | { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4396 | { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4397 | { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4397 | { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4398 | { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4398 | { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4399 | { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4399 | { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4400 | { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4400 | { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4401 | { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4401 | { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4402 | { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4402 | { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4403 | { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4403 | { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4404 | { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4404 | { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4405 | { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4405 | { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4406 | { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4406 | { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4407 | { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4407 | { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4408 | { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4408 | { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4409 | { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4409 | { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4410 | { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4410 | { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4411 | { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4411 | { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4412 | { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4412 | { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4413 | { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4413 | { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4414 | { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4414 | { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4415 | { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4415 | { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4416 | { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4416 | { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4417 | { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4417 | { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 }, | 4418 | { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, |
4418 | { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, | 4419 | { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, |
4419 | { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 }, | 4420 | { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 }, |
4420 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | 4421 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, |
4421 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | 4422 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, |
4422 | { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, | 4423 | { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, |
@@ -4679,7 +4680,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = { | |||
4679 | { 0x000099a0, 0x00000000 }, | 4680 | { 0x000099a0, 0x00000000 }, |
4680 | { 0x000099a4, 0x00000001 }, | 4681 | { 0x000099a4, 0x00000001 }, |
4681 | { 0x000099a8, 0x201fff00 }, | 4682 | { 0x000099a8, 0x201fff00 }, |
4682 | { 0x000099ac, 0x2def1000 }, | 4683 | { 0x000099ac, 0x2def0400 }, |
4683 | { 0x000099b0, 0x03051000 }, | 4684 | { 0x000099b0, 0x03051000 }, |
4684 | { 0x000099b4, 0x00000820 }, | 4685 | { 0x000099b4, 0x00000820 }, |
4685 | { 0x000099dc, 0x00000000 }, | 4686 | { 0x000099dc, 0x00000000 }, |
@@ -4688,7 +4689,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = { | |||
4688 | { 0x000099e8, 0x3c466478 }, | 4689 | { 0x000099e8, 0x3c466478 }, |
4689 | { 0x000099ec, 0x0cc80caa }, | 4690 | { 0x000099ec, 0x0cc80caa }, |
4690 | { 0x000099f0, 0x00000000 }, | 4691 | { 0x000099f0, 0x00000000 }, |
4691 | { 0x0000a208, 0x803e6788 }, | 4692 | { 0x0000a208, 0x803e68c8 }, |
4692 | { 0x0000a210, 0x4080a333 }, | 4693 | { 0x0000a210, 0x4080a333 }, |
4693 | { 0x0000a214, 0x00206c10 }, | 4694 | { 0x0000a214, 0x00206c10 }, |
4694 | { 0x0000a218, 0x009c4060 }, | 4695 | { 0x0000a218, 0x009c4060 }, |
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c index af32d091dc38..ef832a5ebbd8 100644 --- a/drivers/net/wireless/ath9k/mac.c +++ b/drivers/net/wireless/ath9k/mac.c | |||
@@ -107,14 +107,32 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel) | |||
107 | 107 | ||
108 | bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) | 108 | bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) |
109 | { | 109 | { |
110 | #define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ | ||
111 | #define ATH9K_TIME_QUANTUM 100 /* usec */ | ||
112 | |||
113 | struct ath_hal_5416 *ahp = AH5416(ah); | ||
114 | struct ath9k_hw_capabilities *pCap = &ah->ah_caps; | ||
115 | struct ath9k_tx_queue_info *qi; | ||
110 | u32 tsfLow, j, wait; | 116 | u32 tsfLow, j, wait; |
117 | u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; | ||
118 | |||
119 | if (q >= pCap->total_queues) { | ||
120 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); | ||
121 | return false; | ||
122 | } | ||
123 | |||
124 | qi = &ahp->ah_txq[q]; | ||
125 | if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { | ||
126 | DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); | ||
127 | return false; | ||
128 | } | ||
111 | 129 | ||
112 | REG_WRITE(ah, AR_Q_TXD, 1 << q); | 130 | REG_WRITE(ah, AR_Q_TXD, 1 << q); |
113 | 131 | ||
114 | for (wait = 1000; wait != 0; wait--) { | 132 | for (wait = wait_time; wait != 0; wait--) { |
115 | if (ath9k_hw_numtxpending(ah, q) == 0) | 133 | if (ath9k_hw_numtxpending(ah, q) == 0) |
116 | break; | 134 | break; |
117 | udelay(100); | 135 | udelay(ATH9K_TIME_QUANTUM); |
118 | } | 136 | } |
119 | 137 | ||
120 | if (ath9k_hw_numtxpending(ah, q)) { | 138 | if (ath9k_hw_numtxpending(ah, q)) { |
@@ -144,8 +162,7 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) | |||
144 | udelay(200); | 162 | udelay(200); |
145 | REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN); | 163 | REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN); |
146 | 164 | ||
147 | wait = 1000; | 165 | wait = wait_time; |
148 | |||
149 | while (ath9k_hw_numtxpending(ah, q)) { | 166 | while (ath9k_hw_numtxpending(ah, q)) { |
150 | if ((--wait) == 0) { | 167 | if ((--wait) == 0) { |
151 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, | 168 | DPRINTF(ah->ah_sc, ATH_DBG_XMIT, |
@@ -153,15 +170,17 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) | |||
153 | "msec after killing last frame\n"); | 170 | "msec after killing last frame\n"); |
154 | break; | 171 | break; |
155 | } | 172 | } |
156 | udelay(100); | 173 | udelay(ATH9K_TIME_QUANTUM); |
157 | } | 174 | } |
158 | 175 | ||
159 | REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); | 176 | REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); |
160 | } | 177 | } |
161 | 178 | ||
162 | REG_WRITE(ah, AR_Q_TXD, 0); | 179 | REG_WRITE(ah, AR_Q_TXD, 0); |
163 | |||
164 | return wait != 0; | 180 | return wait != 0; |
181 | |||
182 | #undef ATH9K_TX_STOP_DMA_TIMEOUT | ||
183 | #undef ATH9K_TIME_QUANTUM | ||
165 | } | 184 | } |
166 | 185 | ||
167 | bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds, | 186 | bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds, |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 727f067aca4f..d8e826659c15 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -28,72 +28,113 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | |||
28 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | 28 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); |
29 | MODULE_LICENSE("Dual BSD/GPL"); | 29 | MODULE_LICENSE("Dual BSD/GPL"); |
30 | 30 | ||
31 | static struct pci_device_id ath_pci_id_table[] __devinitdata = { | 31 | /* We use the hw_value as an index into our private channel structure */ |
32 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ | 32 | |
33 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ | 33 | #define CHAN2G(_freq, _idx) { \ |
34 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ | 34 | .center_freq = (_freq), \ |
35 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ | 35 | .hw_value = (_idx), \ |
36 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | 36 | .max_power = 30, \ |
37 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ | 37 | } |
38 | { 0 } | 38 | |
39 | #define CHAN5G(_freq, _idx) { \ | ||
40 | .band = IEEE80211_BAND_5GHZ, \ | ||
41 | .center_freq = (_freq), \ | ||
42 | .hw_value = (_idx), \ | ||
43 | .max_power = 30, \ | ||
44 | } | ||
45 | |||
46 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
47 | * on 5 MHz steps, we support the channels which we know | ||
48 | * we have calibration data for all cards though to make | ||
49 | * this static */ | ||
50 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
51 | CHAN2G(2412, 0), /* Channel 1 */ | ||
52 | CHAN2G(2417, 1), /* Channel 2 */ | ||
53 | CHAN2G(2422, 2), /* Channel 3 */ | ||
54 | CHAN2G(2427, 3), /* Channel 4 */ | ||
55 | CHAN2G(2432, 4), /* Channel 5 */ | ||
56 | CHAN2G(2437, 5), /* Channel 6 */ | ||
57 | CHAN2G(2442, 6), /* Channel 7 */ | ||
58 | CHAN2G(2447, 7), /* Channel 8 */ | ||
59 | CHAN2G(2452, 8), /* Channel 9 */ | ||
60 | CHAN2G(2457, 9), /* Channel 10 */ | ||
61 | CHAN2G(2462, 10), /* Channel 11 */ | ||
62 | CHAN2G(2467, 11), /* Channel 12 */ | ||
63 | CHAN2G(2472, 12), /* Channel 13 */ | ||
64 | CHAN2G(2484, 13), /* Channel 14 */ | ||
39 | }; | 65 | }; |
40 | 66 | ||
41 | static void ath_detach(struct ath_softc *sc); | 67 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY |
42 | 68 | * on 5 MHz steps, we support the channels which we know | |
43 | /* return bus cachesize in 4B word units */ | 69 | * we have calibration data for all cards though to make |
44 | 70 | * this static */ | |
45 | static void bus_read_cachesize(struct ath_softc *sc, int *csz) | 71 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { |
46 | { | 72 | /* _We_ call this UNII 1 */ |
47 | u8 u8tmp; | 73 | CHAN5G(5180, 14), /* Channel 36 */ |
48 | 74 | CHAN5G(5200, 15), /* Channel 40 */ | |
49 | pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp); | 75 | CHAN5G(5220, 16), /* Channel 44 */ |
50 | *csz = (int)u8tmp; | 76 | CHAN5G(5240, 17), /* Channel 48 */ |
51 | 77 | /* _We_ call this UNII 2 */ | |
52 | /* | 78 | CHAN5G(5260, 18), /* Channel 52 */ |
53 | * This check was put in to avoid "unplesant" consequences if | 79 | CHAN5G(5280, 19), /* Channel 56 */ |
54 | * the bootrom has not fully initialized all PCI devices. | 80 | CHAN5G(5300, 20), /* Channel 60 */ |
55 | * Sometimes the cache line size register is not set | 81 | CHAN5G(5320, 21), /* Channel 64 */ |
56 | */ | 82 | /* _We_ call this "Middle band" */ |
57 | 83 | CHAN5G(5500, 22), /* Channel 100 */ | |
58 | if (*csz == 0) | 84 | CHAN5G(5520, 23), /* Channel 104 */ |
59 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ | 85 | CHAN5G(5540, 24), /* Channel 108 */ |
60 | } | 86 | CHAN5G(5560, 25), /* Channel 112 */ |
61 | 87 | CHAN5G(5580, 26), /* Channel 116 */ | |
62 | static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode) | 88 | CHAN5G(5600, 27), /* Channel 120 */ |
63 | { | 89 | CHAN5G(5620, 28), /* Channel 124 */ |
64 | sc->cur_rate_table = sc->hw_rate_table[mode]; | 90 | CHAN5G(5640, 29), /* Channel 128 */ |
65 | /* | 91 | CHAN5G(5660, 30), /* Channel 132 */ |
66 | * All protection frames are transmited at 2Mb/s for | 92 | CHAN5G(5680, 31), /* Channel 136 */ |
67 | * 11g, otherwise at 1Mb/s. | 93 | CHAN5G(5700, 32), /* Channel 140 */ |
68 | * XXX select protection rate index from rate table. | 94 | /* _We_ call this UNII 3 */ |
69 | */ | 95 | CHAN5G(5745, 33), /* Channel 149 */ |
70 | sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0); | 96 | CHAN5G(5765, 34), /* Channel 153 */ |
71 | } | 97 | CHAN5G(5785, 35), /* Channel 157 */ |
98 | CHAN5G(5805, 36), /* Channel 161 */ | ||
99 | CHAN5G(5825, 37), /* Channel 165 */ | ||
100 | }; | ||
72 | 101 | ||
73 | static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan) | 102 | static void ath_cache_conf_rate(struct ath_softc *sc, |
103 | struct ieee80211_conf *conf) | ||
74 | { | 104 | { |
75 | if (chan->chanmode == CHANNEL_A) | 105 | switch (conf->channel->band) { |
76 | return ATH9K_MODE_11A; | 106 | case IEEE80211_BAND_2GHZ: |
77 | else if (chan->chanmode == CHANNEL_G) | 107 | if (conf_is_ht20(conf)) |
78 | return ATH9K_MODE_11G; | 108 | sc->cur_rate_table = |
79 | else if (chan->chanmode == CHANNEL_B) | 109 | sc->hw_rate_table[ATH9K_MODE_11NG_HT20]; |
80 | return ATH9K_MODE_11B; | 110 | else if (conf_is_ht40_minus(conf)) |
81 | else if (chan->chanmode == CHANNEL_A_HT20) | 111 | sc->cur_rate_table = |
82 | return ATH9K_MODE_11NA_HT20; | 112 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS]; |
83 | else if (chan->chanmode == CHANNEL_G_HT20) | 113 | else if (conf_is_ht40_plus(conf)) |
84 | return ATH9K_MODE_11NG_HT20; | 114 | sc->cur_rate_table = |
85 | else if (chan->chanmode == CHANNEL_A_HT40PLUS) | 115 | sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS]; |
86 | return ATH9K_MODE_11NA_HT40PLUS; | 116 | else |
87 | else if (chan->chanmode == CHANNEL_A_HT40MINUS) | 117 | sc->cur_rate_table = |
88 | return ATH9K_MODE_11NA_HT40MINUS; | 118 | sc->hw_rate_table[ATH9K_MODE_11G]; |
89 | else if (chan->chanmode == CHANNEL_G_HT40PLUS) | 119 | break; |
90 | return ATH9K_MODE_11NG_HT40PLUS; | 120 | case IEEE80211_BAND_5GHZ: |
91 | else if (chan->chanmode == CHANNEL_G_HT40MINUS) | 121 | if (conf_is_ht20(conf)) |
92 | return ATH9K_MODE_11NG_HT40MINUS; | 122 | sc->cur_rate_table = |
93 | 123 | sc->hw_rate_table[ATH9K_MODE_11NA_HT20]; | |
94 | WARN_ON(1); /* should not get here */ | 124 | else if (conf_is_ht40_minus(conf)) |
95 | 125 | sc->cur_rate_table = | |
96 | return ATH9K_MODE_11B; | 126 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS]; |
127 | else if (conf_is_ht40_plus(conf)) | ||
128 | sc->cur_rate_table = | ||
129 | sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS]; | ||
130 | else | ||
131 | sc->cur_rate_table = | ||
132 | sc->hw_rate_table[ATH9K_MODE_11A]; | ||
133 | break; | ||
134 | default: | ||
135 | BUG_ON(1); | ||
136 | break; | ||
137 | } | ||
97 | } | 138 | } |
98 | 139 | ||
99 | static void ath_update_txpow(struct ath_softc *sc) | 140 | static void ath_update_txpow(struct ath_softc *sc) |
@@ -176,79 +217,18 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | |||
176 | for (i = 0; i < maxrates; i++) { | 217 | for (i = 0; i < maxrates; i++) { |
177 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; | 218 | rate[i].bitrate = rate_table->info[i].ratekbps / 100; |
178 | rate[i].hw_value = rate_table->info[i].ratecode; | 219 | rate[i].hw_value = rate_table->info[i].ratecode; |
220 | if (rate_table->info[i].short_preamble) { | ||
221 | rate[i].hw_value_short = rate_table->info[i].ratecode | | ||
222 | rate_table->info[i].short_preamble; | ||
223 | rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE; | ||
224 | } | ||
179 | sband->n_bitrates++; | 225 | sband->n_bitrates++; |
226 | |||
180 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", | 227 | DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n", |
181 | rate[i].bitrate / 10, rate[i].hw_value); | 228 | rate[i].bitrate / 10, rate[i].hw_value); |
182 | } | 229 | } |
183 | } | 230 | } |
184 | 231 | ||
185 | static int ath_setup_channels(struct ath_softc *sc) | ||
186 | { | ||
187 | struct ath_hal *ah = sc->sc_ah; | ||
188 | int nchan, i, a = 0, b = 0; | ||
189 | u8 regclassids[ATH_REGCLASSIDS_MAX]; | ||
190 | u32 nregclass = 0; | ||
191 | struct ieee80211_supported_band *band_2ghz; | ||
192 | struct ieee80211_supported_band *band_5ghz; | ||
193 | struct ieee80211_channel *chan_2ghz; | ||
194 | struct ieee80211_channel *chan_5ghz; | ||
195 | struct ath9k_channel *c; | ||
196 | |||
197 | /* Fill in ah->ah_channels */ | ||
198 | if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan, | ||
199 | regclassids, ATH_REGCLASSIDS_MAX, | ||
200 | &nregclass, CTRY_DEFAULT, false, 1)) { | ||
201 | u32 rd = ah->ah_currentRD; | ||
202 | DPRINTF(sc, ATH_DBG_FATAL, | ||
203 | "Unable to collect channel list; " | ||
204 | "regdomain likely %u country code %u\n", | ||
205 | rd, CTRY_DEFAULT); | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
210 | band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
211 | chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ]; | ||
212 | chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ]; | ||
213 | |||
214 | for (i = 0; i < nchan; i++) { | ||
215 | c = &ah->ah_channels[i]; | ||
216 | if (IS_CHAN_2GHZ(c)) { | ||
217 | chan_2ghz[a].band = IEEE80211_BAND_2GHZ; | ||
218 | chan_2ghz[a].center_freq = c->channel; | ||
219 | chan_2ghz[a].max_power = c->maxTxPower; | ||
220 | |||
221 | if (c->privFlags & CHANNEL_DISALLOW_ADHOC) | ||
222 | chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS; | ||
223 | if (c->channelFlags & CHANNEL_PASSIVE) | ||
224 | chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
225 | |||
226 | band_2ghz->n_channels = ++a; | ||
227 | |||
228 | DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, " | ||
229 | "channelFlags: 0x%x\n", | ||
230 | c->channel, c->channelFlags); | ||
231 | } else if (IS_CHAN_5GHZ(c)) { | ||
232 | chan_5ghz[b].band = IEEE80211_BAND_5GHZ; | ||
233 | chan_5ghz[b].center_freq = c->channel; | ||
234 | chan_5ghz[b].max_power = c->maxTxPower; | ||
235 | |||
236 | if (c->privFlags & CHANNEL_DISALLOW_ADHOC) | ||
237 | chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS; | ||
238 | if (c->channelFlags & CHANNEL_PASSIVE) | ||
239 | chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
240 | |||
241 | band_5ghz->n_channels = ++b; | ||
242 | |||
243 | DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, " | ||
244 | "channelFlags: 0x%x\n", | ||
245 | c->channel, c->channelFlags); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | /* | 232 | /* |
253 | * Set/change channels. If the channel is really being changed, it's done | 233 | * Set/change channels. If the channel is really being changed, it's done |
254 | * by reseting the chip. To accomplish this we must first cleanup any pending | 234 | * by reseting the chip. To accomplish this we must first cleanup any pending |
@@ -258,68 +238,66 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
258 | { | 238 | { |
259 | struct ath_hal *ah = sc->sc_ah; | 239 | struct ath_hal *ah = sc->sc_ah; |
260 | bool fastcc = true, stopped; | 240 | bool fastcc = true, stopped; |
241 | struct ieee80211_hw *hw = sc->hw; | ||
242 | struct ieee80211_channel *channel = hw->conf.channel; | ||
243 | int r; | ||
261 | 244 | ||
262 | if (sc->sc_flags & SC_OP_INVALID) | 245 | if (sc->sc_flags & SC_OP_INVALID) |
263 | return -EIO; | 246 | return -EIO; |
264 | 247 | ||
265 | if (hchan->channel != sc->sc_ah->ah_curchan->channel || | 248 | ath9k_ps_wakeup(sc); |
266 | hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags || | ||
267 | (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) || | ||
268 | (sc->sc_flags & SC_OP_FULL_RESET)) { | ||
269 | int status; | ||
270 | /* | ||
271 | * This is only performed if the channel settings have | ||
272 | * actually changed. | ||
273 | * | ||
274 | * To switch channels clear any pending DMA operations; | ||
275 | * wait long enough for the RX fifo to drain, reset the | ||
276 | * hardware at the new frequency, and then re-enable | ||
277 | * the relevant bits of the h/w. | ||
278 | */ | ||
279 | ath9k_hw_set_interrupts(ah, 0); | ||
280 | ath_draintxq(sc, false); | ||
281 | stopped = ath_stoprecv(sc); | ||
282 | |||
283 | /* XXX: do not flush receive queue here. We don't want | ||
284 | * to flush data frames already in queue because of | ||
285 | * changing channel. */ | ||
286 | |||
287 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) | ||
288 | fastcc = false; | ||
289 | |||
290 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
291 | "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n", | ||
292 | sc->sc_ah->ah_curchan->channel, | ||
293 | hchan->channel, hchan->channelFlags, sc->tx_chan_width); | ||
294 | |||
295 | spin_lock_bh(&sc->sc_resetlock); | ||
296 | if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width, | ||
297 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | ||
298 | sc->sc_ht_extprotspacing, fastcc, &status)) { | ||
299 | DPRINTF(sc, ATH_DBG_FATAL, | ||
300 | "Unable to reset channel %u (%uMhz) " | ||
301 | "flags 0x%x hal status %u\n", | ||
302 | ath9k_hw_mhz2ieee(ah, hchan->channel, | ||
303 | hchan->channelFlags), | ||
304 | hchan->channel, hchan->channelFlags, status); | ||
305 | spin_unlock_bh(&sc->sc_resetlock); | ||
306 | return -EIO; | ||
307 | } | ||
308 | spin_unlock_bh(&sc->sc_resetlock); | ||
309 | 249 | ||
310 | sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; | 250 | /* |
311 | sc->sc_flags &= ~SC_OP_FULL_RESET; | 251 | * This is only performed if the channel settings have |
252 | * actually changed. | ||
253 | * | ||
254 | * To switch channels clear any pending DMA operations; | ||
255 | * wait long enough for the RX fifo to drain, reset the | ||
256 | * hardware at the new frequency, and then re-enable | ||
257 | * the relevant bits of the h/w. | ||
258 | */ | ||
259 | ath9k_hw_set_interrupts(ah, 0); | ||
260 | ath_drain_all_txq(sc, false); | ||
261 | stopped = ath_stoprecv(sc); | ||
312 | 262 | ||
313 | if (ath_startrecv(sc) != 0) { | 263 | /* XXX: do not flush receive queue here. We don't want |
314 | DPRINTF(sc, ATH_DBG_FATAL, | 264 | * to flush data frames already in queue because of |
315 | "Unable to restart recv logic\n"); | 265 | * changing channel. */ |
316 | return -EIO; | ||
317 | } | ||
318 | 266 | ||
319 | ath_setcurmode(sc, ath_chan2mode(hchan)); | 267 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) |
320 | ath_update_txpow(sc); | 268 | fastcc = false; |
321 | ath9k_hw_set_interrupts(ah, sc->sc_imask); | 269 | |
270 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
271 | "(%u MHz) -> (%u MHz), chanwidth: %d\n", | ||
272 | sc->sc_ah->ah_curchan->channel, | ||
273 | channel->center_freq, sc->tx_chan_width); | ||
274 | |||
275 | spin_lock_bh(&sc->sc_resetlock); | ||
276 | |||
277 | r = ath9k_hw_reset(ah, hchan, fastcc); | ||
278 | if (r) { | ||
279 | DPRINTF(sc, ATH_DBG_FATAL, | ||
280 | "Unable to reset channel (%u Mhz) " | ||
281 | "reset status %u\n", | ||
282 | channel->center_freq, r); | ||
283 | spin_unlock_bh(&sc->sc_resetlock); | ||
284 | return r; | ||
285 | } | ||
286 | spin_unlock_bh(&sc->sc_resetlock); | ||
287 | |||
288 | sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; | ||
289 | sc->sc_flags &= ~SC_OP_FULL_RESET; | ||
290 | |||
291 | if (ath_startrecv(sc) != 0) { | ||
292 | DPRINTF(sc, ATH_DBG_FATAL, | ||
293 | "Unable to restart recv logic\n"); | ||
294 | return -EIO; | ||
322 | } | 295 | } |
296 | |||
297 | ath_cache_conf_rate(sc, &hw->conf); | ||
298 | ath_update_txpow(sc); | ||
299 | ath9k_hw_set_interrupts(ah, sc->sc_imask); | ||
300 | ath9k_ps_restore(sc); | ||
323 | return 0; | 301 | return 0; |
324 | } | 302 | } |
325 | 303 | ||
@@ -369,8 +347,7 @@ static void ath_ani_calibrate(unsigned long data) | |||
369 | } else { | 347 | } else { |
370 | if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= | 348 | if ((timestamp - sc->sc_ani.sc_resetcal_timer) >= |
371 | ATH_RESTART_CALINTERVAL) { | 349 | ATH_RESTART_CALINTERVAL) { |
372 | ath9k_hw_reset_calvalid(ah, ah->ah_curchan, | 350 | sc->sc_ani.sc_caldone = ath9k_hw_reset_calvalid(ah); |
373 | &sc->sc_ani.sc_caldone); | ||
374 | if (sc->sc_ani.sc_caldone) | 351 | if (sc->sc_ani.sc_caldone) |
375 | sc->sc_ani.sc_resetcal_timer = timestamp; | 352 | sc->sc_ani.sc_resetcal_timer = timestamp; |
376 | } | 353 | } |
@@ -434,12 +411,14 @@ static void ath_ani_calibrate(unsigned long data) | |||
434 | /* | 411 | /* |
435 | * Update tx/rx chainmask. For legacy association, | 412 | * Update tx/rx chainmask. For legacy association, |
436 | * hard code chainmask to 1x1, for 11n association, use | 413 | * hard code chainmask to 1x1, for 11n association, use |
437 | * the chainmask configuration. | 414 | * the chainmask configuration, for bt coexistence, use |
415 | * the chainmask configuration even in legacy mode. | ||
438 | */ | 416 | */ |
439 | static void ath_update_chainmask(struct ath_softc *sc, int is_ht) | 417 | static void ath_update_chainmask(struct ath_softc *sc, int is_ht) |
440 | { | 418 | { |
441 | sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; | 419 | sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; |
442 | if (is_ht) { | 420 | if (is_ht || |
421 | (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) { | ||
443 | sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; | 422 | sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask; |
444 | sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; | 423 | sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask; |
445 | } else { | 424 | } else { |
@@ -499,7 +478,7 @@ static void ath9k_tasklet(unsigned long data) | |||
499 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); | 478 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask); |
500 | } | 479 | } |
501 | 480 | ||
502 | static irqreturn_t ath_isr(int irq, void *dev) | 481 | irqreturn_t ath_isr(int irq, void *dev) |
503 | { | 482 | { |
504 | struct ath_softc *sc = dev; | 483 | struct ath_softc *sc = dev; |
505 | struct ath_hal *ah = sc->sc_ah; | 484 | struct ath_hal *ah = sc->sc_ah; |
@@ -591,8 +570,10 @@ static irqreturn_t ath_isr(int irq, void *dev) | |||
591 | ATH9K_HW_CAP_AUTOSLEEP)) { | 570 | ATH9K_HW_CAP_AUTOSLEEP)) { |
592 | /* Clear RxAbort bit so that we can | 571 | /* Clear RxAbort bit so that we can |
593 | * receive frames */ | 572 | * receive frames */ |
573 | ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); | ||
594 | ath9k_hw_setrxabort(ah, 0); | 574 | ath9k_hw_setrxabort(ah, 0); |
595 | sched = true; | 575 | sched = true; |
576 | sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; | ||
596 | } | 577 | } |
597 | } | 578 | } |
598 | } | 579 | } |
@@ -609,19 +590,6 @@ static irqreturn_t ath_isr(int irq, void *dev) | |||
609 | return IRQ_HANDLED; | 590 | return IRQ_HANDLED; |
610 | } | 591 | } |
611 | 592 | ||
612 | static int ath_get_channel(struct ath_softc *sc, | ||
613 | struct ieee80211_channel *chan) | ||
614 | { | ||
615 | int i; | ||
616 | |||
617 | for (i = 0; i < sc->sc_ah->ah_nchan; i++) { | ||
618 | if (sc->sc_ah->ah_channels[i].channel == chan->center_freq) | ||
619 | return i; | ||
620 | } | ||
621 | |||
622 | return -1; | ||
623 | } | ||
624 | |||
625 | static u32 ath_get_extchanmode(struct ath_softc *sc, | 593 | static u32 ath_get_extchanmode(struct ath_softc *sc, |
626 | struct ieee80211_channel *chan, | 594 | struct ieee80211_channel *chan, |
627 | enum nl80211_channel_type channel_type) | 595 | enum nl80211_channel_type channel_type) |
@@ -797,7 +765,7 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc) | |||
797 | } | 765 | } |
798 | 766 | ||
799 | static int ath_key_config(struct ath_softc *sc, | 767 | static int ath_key_config(struct ath_softc *sc, |
800 | const u8 *addr, | 768 | struct ieee80211_sta *sta, |
801 | struct ieee80211_key_conf *key) | 769 | struct ieee80211_key_conf *key) |
802 | { | 770 | { |
803 | struct ath9k_keyval hk; | 771 | struct ath9k_keyval hk; |
@@ -818,7 +786,7 @@ static int ath_key_config(struct ath_softc *sc, | |||
818 | hk.kv_type = ATH9K_CIPHER_AES_CCM; | 786 | hk.kv_type = ATH9K_CIPHER_AES_CCM; |
819 | break; | 787 | break; |
820 | default: | 788 | default: |
821 | return -EINVAL; | 789 | return -EOPNOTSUPP; |
822 | } | 790 | } |
823 | 791 | ||
824 | hk.kv_len = key->keylen; | 792 | hk.kv_len = key->keylen; |
@@ -831,7 +799,10 @@ static int ath_key_config(struct ath_softc *sc, | |||
831 | } else if (key->keyidx) { | 799 | } else if (key->keyidx) { |
832 | struct ieee80211_vif *vif; | 800 | struct ieee80211_vif *vif; |
833 | 801 | ||
834 | mac = addr; | 802 | if (WARN_ON(!sta)) |
803 | return -EOPNOTSUPP; | ||
804 | mac = sta->addr; | ||
805 | |||
835 | vif = sc->sc_vaps[0]; | 806 | vif = sc->sc_vaps[0]; |
836 | if (vif->type != NL80211_IFTYPE_AP) { | 807 | if (vif->type != NL80211_IFTYPE_AP) { |
837 | /* Only keyidx 0 should be used with unicast key, but | 808 | /* Only keyidx 0 should be used with unicast key, but |
@@ -840,13 +811,16 @@ static int ath_key_config(struct ath_softc *sc, | |||
840 | } else | 811 | } else |
841 | return -EIO; | 812 | return -EIO; |
842 | } else { | 813 | } else { |
843 | mac = addr; | 814 | if (WARN_ON(!sta)) |
815 | return -EOPNOTSUPP; | ||
816 | mac = sta->addr; | ||
817 | |||
844 | if (key->alg == ALG_TKIP) | 818 | if (key->alg == ALG_TKIP) |
845 | idx = ath_reserve_key_cache_slot_tkip(sc); | 819 | idx = ath_reserve_key_cache_slot_tkip(sc); |
846 | else | 820 | else |
847 | idx = ath_reserve_key_cache_slot(sc); | 821 | idx = ath_reserve_key_cache_slot(sc); |
848 | if (idx < 0) | 822 | if (idx < 0) |
849 | return -EIO; /* no free key cache entries */ | 823 | return -ENOSPC; /* no free key cache entries */ |
850 | } | 824 | } |
851 | 825 | ||
852 | if (key->alg == ALG_TKIP) | 826 | if (key->alg == ALG_TKIP) |
@@ -886,7 +860,8 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key) | |||
886 | } | 860 | } |
887 | } | 861 | } |
888 | 862 | ||
889 | static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) | 863 | static void setup_ht_cap(struct ath_softc *sc, |
864 | struct ieee80211_sta_ht_cap *ht_info) | ||
890 | { | 865 | { |
891 | #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ | 866 | #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ |
892 | #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ | 867 | #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ |
@@ -899,10 +874,23 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) | |||
899 | 874 | ||
900 | ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; | 875 | ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; |
901 | ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; | 876 | ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; |
877 | |||
902 | /* set up supported mcs set */ | 878 | /* set up supported mcs set */ |
903 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | 879 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
904 | ht_info->mcs.rx_mask[0] = 0xff; | 880 | |
905 | ht_info->mcs.rx_mask[1] = 0xff; | 881 | switch(sc->sc_rx_chainmask) { |
882 | case 1: | ||
883 | ht_info->mcs.rx_mask[0] = 0xff; | ||
884 | break; | ||
885 | case 3: | ||
886 | case 5: | ||
887 | case 7: | ||
888 | default: | ||
889 | ht_info->mcs.rx_mask[0] = 0xff; | ||
890 | ht_info->mcs.rx_mask[1] = 0xff; | ||
891 | break; | ||
892 | } | ||
893 | |||
906 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | 894 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
907 | } | 895 | } |
908 | 896 | ||
@@ -1067,23 +1055,19 @@ fail: | |||
1067 | static void ath_radio_enable(struct ath_softc *sc) | 1055 | static void ath_radio_enable(struct ath_softc *sc) |
1068 | { | 1056 | { |
1069 | struct ath_hal *ah = sc->sc_ah; | 1057 | struct ath_hal *ah = sc->sc_ah; |
1070 | int status; | 1058 | struct ieee80211_channel *channel = sc->hw->conf.channel; |
1059 | int r; | ||
1071 | 1060 | ||
1061 | ath9k_ps_wakeup(sc); | ||
1072 | spin_lock_bh(&sc->sc_resetlock); | 1062 | spin_lock_bh(&sc->sc_resetlock); |
1073 | if (!ath9k_hw_reset(ah, ah->ah_curchan, | 1063 | |
1074 | sc->tx_chan_width, | 1064 | r = ath9k_hw_reset(ah, ah->ah_curchan, false); |
1075 | sc->sc_tx_chainmask, | 1065 | |
1076 | sc->sc_rx_chainmask, | 1066 | if (r) { |
1077 | sc->sc_ht_extprotspacing, | ||
1078 | false, &status)) { | ||
1079 | DPRINTF(sc, ATH_DBG_FATAL, | 1067 | DPRINTF(sc, ATH_DBG_FATAL, |
1080 | "Unable to reset channel %u (%uMhz) " | 1068 | "Unable to reset channel %u (%uMhz) ", |
1081 | "flags 0x%x hal status %u\n", | 1069 | "reset status %u\n", |
1082 | ath9k_hw_mhz2ieee(ah, | 1070 | channel->center_freq, r); |
1083 | ah->ah_curchan->channel, | ||
1084 | ah->ah_curchan->channelFlags), | ||
1085 | ah->ah_curchan->channel, | ||
1086 | ah->ah_curchan->channelFlags, status); | ||
1087 | } | 1071 | } |
1088 | spin_unlock_bh(&sc->sc_resetlock); | 1072 | spin_unlock_bh(&sc->sc_resetlock); |
1089 | 1073 | ||
@@ -1106,14 +1090,16 @@ static void ath_radio_enable(struct ath_softc *sc) | |||
1106 | ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0); | 1090 | ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0); |
1107 | 1091 | ||
1108 | ieee80211_wake_queues(sc->hw); | 1092 | ieee80211_wake_queues(sc->hw); |
1093 | ath9k_ps_restore(sc); | ||
1109 | } | 1094 | } |
1110 | 1095 | ||
1111 | static void ath_radio_disable(struct ath_softc *sc) | 1096 | static void ath_radio_disable(struct ath_softc *sc) |
1112 | { | 1097 | { |
1113 | struct ath_hal *ah = sc->sc_ah; | 1098 | struct ath_hal *ah = sc->sc_ah; |
1114 | int status; | 1099 | struct ieee80211_channel *channel = sc->hw->conf.channel; |
1115 | 1100 | int r; | |
1116 | 1101 | ||
1102 | ath9k_ps_wakeup(sc); | ||
1117 | ieee80211_stop_queues(sc->hw); | 1103 | ieee80211_stop_queues(sc->hw); |
1118 | 1104 | ||
1119 | /* Disable LED */ | 1105 | /* Disable LED */ |
@@ -1123,30 +1109,23 @@ static void ath_radio_disable(struct ath_softc *sc) | |||
1123 | /* Disable interrupts */ | 1109 | /* Disable interrupts */ |
1124 | ath9k_hw_set_interrupts(ah, 0); | 1110 | ath9k_hw_set_interrupts(ah, 0); |
1125 | 1111 | ||
1126 | ath_draintxq(sc, false); /* clear pending tx frames */ | 1112 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ |
1127 | ath_stoprecv(sc); /* turn off frame recv */ | 1113 | ath_stoprecv(sc); /* turn off frame recv */ |
1128 | ath_flushrecv(sc); /* flush recv queue */ | 1114 | ath_flushrecv(sc); /* flush recv queue */ |
1129 | 1115 | ||
1130 | spin_lock_bh(&sc->sc_resetlock); | 1116 | spin_lock_bh(&sc->sc_resetlock); |
1131 | if (!ath9k_hw_reset(ah, ah->ah_curchan, | 1117 | r = ath9k_hw_reset(ah, ah->ah_curchan, false); |
1132 | sc->tx_chan_width, | 1118 | if (r) { |
1133 | sc->sc_tx_chainmask, | ||
1134 | sc->sc_rx_chainmask, | ||
1135 | sc->sc_ht_extprotspacing, | ||
1136 | false, &status)) { | ||
1137 | DPRINTF(sc, ATH_DBG_FATAL, | 1119 | DPRINTF(sc, ATH_DBG_FATAL, |
1138 | "Unable to reset channel %u (%uMhz) " | 1120 | "Unable to reset channel %u (%uMhz) " |
1139 | "flags 0x%x hal status %u\n", | 1121 | "reset status %u\n", |
1140 | ath9k_hw_mhz2ieee(ah, | 1122 | channel->center_freq, r); |
1141 | ah->ah_curchan->channel, | ||
1142 | ah->ah_curchan->channelFlags), | ||
1143 | ah->ah_curchan->channel, | ||
1144 | ah->ah_curchan->channelFlags, status); | ||
1145 | } | 1123 | } |
1146 | spin_unlock_bh(&sc->sc_resetlock); | 1124 | spin_unlock_bh(&sc->sc_resetlock); |
1147 | 1125 | ||
1148 | ath9k_hw_phy_disable(ah); | 1126 | ath9k_hw_phy_disable(ah); |
1149 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 1127 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); |
1128 | ath9k_ps_restore(sc); | ||
1150 | } | 1129 | } |
1151 | 1130 | ||
1152 | static bool ath_is_rfkill_set(struct ath_softc *sc) | 1131 | static bool ath_is_rfkill_set(struct ath_softc *sc) |
@@ -1274,13 +1253,7 @@ static int ath_start_rfkill_poll(struct ath_softc *sc) | |||
1274 | rfkill_free(sc->rf_kill.rfkill); | 1253 | rfkill_free(sc->rf_kill.rfkill); |
1275 | 1254 | ||
1276 | /* Deinitialize the device */ | 1255 | /* Deinitialize the device */ |
1277 | ath_detach(sc); | 1256 | ath_cleanup(sc); |
1278 | if (sc->pdev->irq) | ||
1279 | free_irq(sc->pdev->irq, sc); | ||
1280 | pci_iounmap(sc->pdev, sc->mem); | ||
1281 | pci_release_region(sc->pdev, 0); | ||
1282 | pci_disable_device(sc->pdev); | ||
1283 | ieee80211_free_hw(sc->hw); | ||
1284 | return -EIO; | 1257 | return -EIO; |
1285 | } else { | 1258 | } else { |
1286 | sc->sc_flags |= SC_OP_RFKILL_REGISTERED; | 1259 | sc->sc_flags |= SC_OP_RFKILL_REGISTERED; |
@@ -1291,11 +1264,21 @@ static int ath_start_rfkill_poll(struct ath_softc *sc) | |||
1291 | } | 1264 | } |
1292 | #endif /* CONFIG_RFKILL */ | 1265 | #endif /* CONFIG_RFKILL */ |
1293 | 1266 | ||
1294 | static void ath_detach(struct ath_softc *sc) | 1267 | void ath_cleanup(struct ath_softc *sc) |
1268 | { | ||
1269 | ath_detach(sc); | ||
1270 | free_irq(sc->irq, sc); | ||
1271 | ath_bus_cleanup(sc); | ||
1272 | ieee80211_free_hw(sc->hw); | ||
1273 | } | ||
1274 | |||
1275 | void ath_detach(struct ath_softc *sc) | ||
1295 | { | 1276 | { |
1296 | struct ieee80211_hw *hw = sc->hw; | 1277 | struct ieee80211_hw *hw = sc->hw; |
1297 | int i = 0; | 1278 | int i = 0; |
1298 | 1279 | ||
1280 | ath9k_ps_wakeup(sc); | ||
1281 | |||
1299 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); | 1282 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); |
1300 | 1283 | ||
1301 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 1284 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
@@ -1320,6 +1303,7 @@ static void ath_detach(struct ath_softc *sc) | |||
1320 | 1303 | ||
1321 | ath9k_hw_detach(sc->sc_ah); | 1304 | ath9k_hw_detach(sc->sc_ah); |
1322 | ath9k_exit_debug(sc); | 1305 | ath9k_exit_debug(sc); |
1306 | ath9k_ps_restore(sc); | ||
1323 | } | 1307 | } |
1324 | 1308 | ||
1325 | static int ath_init(u16 devid, struct ath_softc *sc) | 1309 | static int ath_init(u16 devid, struct ath_softc *sc) |
@@ -1345,14 +1329,14 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1345 | * Cache line size is used to size and align various | 1329 | * Cache line size is used to size and align various |
1346 | * structures used to communicate with the hardware. | 1330 | * structures used to communicate with the hardware. |
1347 | */ | 1331 | */ |
1348 | bus_read_cachesize(sc, &csz); | 1332 | ath_read_cachesize(sc, &csz); |
1349 | /* XXX assert csz is non-zero */ | 1333 | /* XXX assert csz is non-zero */ |
1350 | sc->sc_cachelsz = csz << 2; /* convert to bytes */ | 1334 | sc->sc_cachelsz = csz << 2; /* convert to bytes */ |
1351 | 1335 | ||
1352 | ah = ath9k_hw_attach(devid, sc, sc->mem, &status); | 1336 | ah = ath9k_hw_attach(devid, sc, sc->mem, &status); |
1353 | if (ah == NULL) { | 1337 | if (ah == NULL) { |
1354 | DPRINTF(sc, ATH_DBG_FATAL, | 1338 | DPRINTF(sc, ATH_DBG_FATAL, |
1355 | "Unable to attach hardware; HAL status %u\n", status); | 1339 | "Unable to attach hardware; HAL status %d\n", status); |
1356 | error = -ENXIO; | 1340 | error = -ENXIO; |
1357 | goto bad; | 1341 | goto bad; |
1358 | } | 1342 | } |
@@ -1374,16 +1358,12 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1374 | for (i = 0; i < sc->sc_keymax; i++) | 1358 | for (i = 0; i < sc->sc_keymax; i++) |
1375 | ath9k_hw_keyreset(ah, (u16) i); | 1359 | ath9k_hw_keyreset(ah, (u16) i); |
1376 | 1360 | ||
1377 | /* Collect the channel list using the default country code */ | 1361 | if (ath9k_regd_init(sc->sc_ah)) |
1378 | |||
1379 | error = ath_setup_channels(sc); | ||
1380 | if (error) | ||
1381 | goto bad; | 1362 | goto bad; |
1382 | 1363 | ||
1383 | /* default to MONITOR mode */ | 1364 | /* default to MONITOR mode */ |
1384 | sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; | 1365 | sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; |
1385 | 1366 | ||
1386 | |||
1387 | /* Setup rate tables */ | 1367 | /* Setup rate tables */ |
1388 | 1368 | ||
1389 | ath_rate_attach(sc); | 1369 | ath_rate_attach(sc); |
@@ -1515,20 +1495,25 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1515 | 1495 | ||
1516 | /* setup channels and rates */ | 1496 | /* setup channels and rates */ |
1517 | 1497 | ||
1518 | sc->sbands[IEEE80211_BAND_2GHZ].channels = | 1498 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; |
1519 | sc->channels[IEEE80211_BAND_2GHZ]; | ||
1520 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = | 1499 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = |
1521 | sc->rates[IEEE80211_BAND_2GHZ]; | 1500 | sc->rates[IEEE80211_BAND_2GHZ]; |
1522 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | 1501 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; |
1502 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
1503 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
1523 | 1504 | ||
1524 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { | 1505 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { |
1525 | sc->sbands[IEEE80211_BAND_5GHZ].channels = | 1506 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; |
1526 | sc->channels[IEEE80211_BAND_5GHZ]; | ||
1527 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | 1507 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = |
1528 | sc->rates[IEEE80211_BAND_5GHZ]; | 1508 | sc->rates[IEEE80211_BAND_5GHZ]; |
1529 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | 1509 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; |
1510 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
1511 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
1530 | } | 1512 | } |
1531 | 1513 | ||
1514 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX) | ||
1515 | ath9k_hw_btcoex_enable(sc->sc_ah); | ||
1516 | |||
1532 | return 0; | 1517 | return 0; |
1533 | bad2: | 1518 | bad2: |
1534 | /* cleanup tx queues */ | 1519 | /* cleanup tx queues */ |
@@ -1542,7 +1527,7 @@ bad: | |||
1542 | return error; | 1527 | return error; |
1543 | } | 1528 | } |
1544 | 1529 | ||
1545 | static int ath_attach(u16 devid, struct ath_softc *sc) | 1530 | int ath_attach(u16 devid, struct ath_softc *sc) |
1546 | { | 1531 | { |
1547 | struct ieee80211_hw *hw = sc->hw; | 1532 | struct ieee80211_hw *hw = sc->hw; |
1548 | int error = 0; | 1533 | int error = 0; |
@@ -1560,13 +1545,21 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1560 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 1545 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
1561 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1546 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1562 | IEEE80211_HW_SIGNAL_DBM | | 1547 | IEEE80211_HW_SIGNAL_DBM | |
1563 | IEEE80211_HW_AMPDU_AGGREGATION; | 1548 | IEEE80211_HW_AMPDU_AGGREGATION | |
1549 | IEEE80211_HW_SUPPORTS_PS | | ||
1550 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
1551 | |||
1552 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah)) | ||
1553 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | ||
1564 | 1554 | ||
1565 | hw->wiphy->interface_modes = | 1555 | hw->wiphy->interface_modes = |
1566 | BIT(NL80211_IFTYPE_AP) | | 1556 | BIT(NL80211_IFTYPE_AP) | |
1567 | BIT(NL80211_IFTYPE_STATION) | | 1557 | BIT(NL80211_IFTYPE_STATION) | |
1568 | BIT(NL80211_IFTYPE_ADHOC); | 1558 | BIT(NL80211_IFTYPE_ADHOC); |
1569 | 1559 | ||
1560 | hw->wiphy->reg_notifier = ath9k_reg_notifier; | ||
1561 | hw->wiphy->strict_regulatory = true; | ||
1562 | |||
1570 | hw->queues = 4; | 1563 | hw->queues = 4; |
1571 | hw->max_rates = 4; | 1564 | hw->max_rates = 4; |
1572 | hw->max_rate_tries = ATH_11N_TXMAXTRY; | 1565 | hw->max_rate_tries = ATH_11N_TXMAXTRY; |
@@ -1576,9 +1569,9 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1576 | hw->rate_control_algorithm = "ath9k_rate_control"; | 1569 | hw->rate_control_algorithm = "ath9k_rate_control"; |
1577 | 1570 | ||
1578 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { | 1571 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) { |
1579 | setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); | 1572 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); |
1580 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) | 1573 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) |
1581 | setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); | 1574 | setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); |
1582 | } | 1575 | } |
1583 | 1576 | ||
1584 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; | 1577 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; |
@@ -1605,11 +1598,36 @@ static int ath_attach(u16 devid, struct ath_softc *sc) | |||
1605 | goto detach; | 1598 | goto detach; |
1606 | #endif | 1599 | #endif |
1607 | 1600 | ||
1601 | if (ath9k_is_world_regd(sc->sc_ah)) { | ||
1602 | /* Anything applied here (prior to wiphy registratoin) gets | ||
1603 | * saved on the wiphy orig_* parameters */ | ||
1604 | const struct ieee80211_regdomain *regd = | ||
1605 | ath9k_world_regdomain(sc->sc_ah); | ||
1606 | hw->wiphy->custom_regulatory = true; | ||
1607 | hw->wiphy->strict_regulatory = false; | ||
1608 | wiphy_apply_custom_regulatory(sc->hw->wiphy, regd); | ||
1609 | ath9k_reg_apply_radar_flags(hw->wiphy); | ||
1610 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); | ||
1611 | } else { | ||
1612 | /* This gets applied in the case of the absense of CRDA, | ||
1613 | * its our own custom world regulatory domain, similar to | ||
1614 | * cfg80211's but we enable passive scanning */ | ||
1615 | const struct ieee80211_regdomain *regd = | ||
1616 | ath9k_default_world_regdomain(); | ||
1617 | wiphy_apply_custom_regulatory(sc->hw->wiphy, regd); | ||
1618 | ath9k_reg_apply_radar_flags(hw->wiphy); | ||
1619 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); | ||
1620 | } | ||
1621 | |||
1608 | error = ieee80211_register_hw(hw); | 1622 | error = ieee80211_register_hw(hw); |
1609 | 1623 | ||
1624 | if (!ath9k_is_world_regd(sc->sc_ah)) | ||
1625 | regulatory_hint(hw->wiphy, sc->sc_ah->alpha2); | ||
1626 | |||
1610 | /* Initialize LED control */ | 1627 | /* Initialize LED control */ |
1611 | ath_init_leds(sc); | 1628 | ath_init_leds(sc); |
1612 | 1629 | ||
1630 | |||
1613 | return 0; | 1631 | return 0; |
1614 | detach: | 1632 | detach: |
1615 | ath_detach(sc); | 1633 | ath_detach(sc); |
@@ -1619,23 +1637,19 @@ detach: | |||
1619 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 1637 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
1620 | { | 1638 | { |
1621 | struct ath_hal *ah = sc->sc_ah; | 1639 | struct ath_hal *ah = sc->sc_ah; |
1622 | int status; | 1640 | struct ieee80211_hw *hw = sc->hw; |
1623 | int error = 0; | 1641 | int r; |
1624 | 1642 | ||
1625 | ath9k_hw_set_interrupts(ah, 0); | 1643 | ath9k_hw_set_interrupts(ah, 0); |
1626 | ath_draintxq(sc, retry_tx); | 1644 | ath_drain_all_txq(sc, retry_tx); |
1627 | ath_stoprecv(sc); | 1645 | ath_stoprecv(sc); |
1628 | ath_flushrecv(sc); | 1646 | ath_flushrecv(sc); |
1629 | 1647 | ||
1630 | spin_lock_bh(&sc->sc_resetlock); | 1648 | spin_lock_bh(&sc->sc_resetlock); |
1631 | if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, | 1649 | r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, false); |
1632 | sc->tx_chan_width, | 1650 | if (r) |
1633 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | ||
1634 | sc->sc_ht_extprotspacing, false, &status)) { | ||
1635 | DPRINTF(sc, ATH_DBG_FATAL, | 1651 | DPRINTF(sc, ATH_DBG_FATAL, |
1636 | "Unable to reset hardware; hal status %u\n", status); | 1652 | "Unable to reset hardware; reset status %u\n", r); |
1637 | error = -EIO; | ||
1638 | } | ||
1639 | spin_unlock_bh(&sc->sc_resetlock); | 1653 | spin_unlock_bh(&sc->sc_resetlock); |
1640 | 1654 | ||
1641 | if (ath_startrecv(sc) != 0) | 1655 | if (ath_startrecv(sc) != 0) |
@@ -1646,7 +1660,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1646 | * that changes the channel so update any state that | 1660 | * that changes the channel so update any state that |
1647 | * might change as a result. | 1661 | * might change as a result. |
1648 | */ | 1662 | */ |
1649 | ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan)); | 1663 | ath_cache_conf_rate(sc, &hw->conf); |
1650 | 1664 | ||
1651 | ath_update_txpow(sc); | 1665 | ath_update_txpow(sc); |
1652 | 1666 | ||
@@ -1666,7 +1680,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1666 | } | 1680 | } |
1667 | } | 1681 | } |
1668 | 1682 | ||
1669 | return error; | 1683 | return r; |
1670 | } | 1684 | } |
1671 | 1685 | ||
1672 | /* | 1686 | /* |
@@ -1720,9 +1734,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1720 | } | 1734 | } |
1721 | 1735 | ||
1722 | /* allocate descriptors */ | 1736 | /* allocate descriptors */ |
1723 | dd->dd_desc = pci_alloc_consistent(sc->pdev, | 1737 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, |
1724 | dd->dd_desc_len, | 1738 | &dd->dd_desc_paddr, GFP_ATOMIC); |
1725 | &dd->dd_desc_paddr); | ||
1726 | if (dd->dd_desc == NULL) { | 1739 | if (dd->dd_desc == NULL) { |
1727 | error = -ENOMEM; | 1740 | error = -ENOMEM; |
1728 | goto fail; | 1741 | goto fail; |
@@ -1768,8 +1781,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
1768 | } | 1781 | } |
1769 | return 0; | 1782 | return 0; |
1770 | fail2: | 1783 | fail2: |
1771 | pci_free_consistent(sc->pdev, | 1784 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, |
1772 | dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); | 1785 | dd->dd_desc_paddr); |
1773 | fail: | 1786 | fail: |
1774 | memset(dd, 0, sizeof(*dd)); | 1787 | memset(dd, 0, sizeof(*dd)); |
1775 | return error; | 1788 | return error; |
@@ -1782,8 +1795,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, | |||
1782 | struct ath_descdma *dd, | 1795 | struct ath_descdma *dd, |
1783 | struct list_head *head) | 1796 | struct list_head *head) |
1784 | { | 1797 | { |
1785 | pci_free_consistent(sc->pdev, | 1798 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, |
1786 | dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); | 1799 | dd->dd_desc_paddr); |
1787 | 1800 | ||
1788 | INIT_LIST_HEAD(head); | 1801 | INIT_LIST_HEAD(head); |
1789 | kfree(dd->dd_bufptr); | 1802 | kfree(dd->dd_bufptr); |
@@ -1840,6 +1853,37 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) | |||
1840 | return qnum; | 1853 | return qnum; |
1841 | } | 1854 | } |
1842 | 1855 | ||
1856 | /* XXX: Remove me once we don't depend on ath9k_channel for all | ||
1857 | * this redundant data */ | ||
1858 | static void ath9k_update_ichannel(struct ath_softc *sc, | ||
1859 | struct ath9k_channel *ichan) | ||
1860 | { | ||
1861 | struct ieee80211_hw *hw = sc->hw; | ||
1862 | struct ieee80211_channel *chan = hw->conf.channel; | ||
1863 | struct ieee80211_conf *conf = &hw->conf; | ||
1864 | |||
1865 | ichan->channel = chan->center_freq; | ||
1866 | ichan->chan = chan; | ||
1867 | |||
1868 | if (chan->band == IEEE80211_BAND_2GHZ) { | ||
1869 | ichan->chanmode = CHANNEL_G; | ||
1870 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; | ||
1871 | } else { | ||
1872 | ichan->chanmode = CHANNEL_A; | ||
1873 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | ||
1874 | } | ||
1875 | |||
1876 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
1877 | |||
1878 | if (conf_is_ht(conf)) { | ||
1879 | if (conf_is_ht40(conf)) | ||
1880 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
1881 | |||
1882 | ichan->chanmode = ath_get_extchanmode(sc, chan, | ||
1883 | conf->channel_type); | ||
1884 | } | ||
1885 | } | ||
1886 | |||
1843 | /**********************/ | 1887 | /**********************/ |
1844 | /* mac80211 callbacks */ | 1888 | /* mac80211 callbacks */ |
1845 | /**********************/ | 1889 | /**********************/ |
@@ -1849,24 +1893,17 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1849 | struct ath_softc *sc = hw->priv; | 1893 | struct ath_softc *sc = hw->priv; |
1850 | struct ieee80211_channel *curchan = hw->conf.channel; | 1894 | struct ieee80211_channel *curchan = hw->conf.channel; |
1851 | struct ath9k_channel *init_channel; | 1895 | struct ath9k_channel *init_channel; |
1852 | int error = 0, pos, status; | 1896 | int r, pos; |
1853 | 1897 | ||
1854 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " | 1898 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " |
1855 | "initial channel: %d MHz\n", curchan->center_freq); | 1899 | "initial channel: %d MHz\n", curchan->center_freq); |
1856 | 1900 | ||
1857 | /* setup initial channel */ | 1901 | /* setup initial channel */ |
1858 | 1902 | ||
1859 | pos = ath_get_channel(sc, curchan); | 1903 | pos = curchan->hw_value; |
1860 | if (pos == -1) { | ||
1861 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); | ||
1862 | error = -EINVAL; | ||
1863 | goto error; | ||
1864 | } | ||
1865 | 1904 | ||
1866 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
1867 | sc->sc_ah->ah_channels[pos].chanmode = | ||
1868 | (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; | ||
1869 | init_channel = &sc->sc_ah->ah_channels[pos]; | 1905 | init_channel = &sc->sc_ah->ah_channels[pos]; |
1906 | ath9k_update_ichannel(sc, init_channel); | ||
1870 | 1907 | ||
1871 | /* Reset SERDES registers */ | 1908 | /* Reset SERDES registers */ |
1872 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); | 1909 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); |
@@ -1879,17 +1916,14 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1879 | * and then setup of the interrupt mask. | 1916 | * and then setup of the interrupt mask. |
1880 | */ | 1917 | */ |
1881 | spin_lock_bh(&sc->sc_resetlock); | 1918 | spin_lock_bh(&sc->sc_resetlock); |
1882 | if (!ath9k_hw_reset(sc->sc_ah, init_channel, | 1919 | r = ath9k_hw_reset(sc->sc_ah, init_channel, false); |
1883 | sc->tx_chan_width, | 1920 | if (r) { |
1884 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | ||
1885 | sc->sc_ht_extprotspacing, false, &status)) { | ||
1886 | DPRINTF(sc, ATH_DBG_FATAL, | 1921 | DPRINTF(sc, ATH_DBG_FATAL, |
1887 | "Unable to reset hardware; hal status %u " | 1922 | "Unable to reset hardware; reset status %u " |
1888 | "(freq %u flags 0x%x)\n", status, | 1923 | "(freq %u MHz)\n", r, |
1889 | init_channel->channel, init_channel->channelFlags); | 1924 | curchan->center_freq); |
1890 | error = -EIO; | ||
1891 | spin_unlock_bh(&sc->sc_resetlock); | 1925 | spin_unlock_bh(&sc->sc_resetlock); |
1892 | goto error; | 1926 | return r; |
1893 | } | 1927 | } |
1894 | spin_unlock_bh(&sc->sc_resetlock); | 1928 | spin_unlock_bh(&sc->sc_resetlock); |
1895 | 1929 | ||
@@ -1909,8 +1943,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1909 | if (ath_startrecv(sc) != 0) { | 1943 | if (ath_startrecv(sc) != 0) { |
1910 | DPRINTF(sc, ATH_DBG_FATAL, | 1944 | DPRINTF(sc, ATH_DBG_FATAL, |
1911 | "Unable to start recv logic\n"); | 1945 | "Unable to start recv logic\n"); |
1912 | error = -EIO; | 1946 | return -EIO; |
1913 | goto error; | ||
1914 | } | 1947 | } |
1915 | 1948 | ||
1916 | /* Setup our intr mask. */ | 1949 | /* Setup our intr mask. */ |
@@ -1943,7 +1976,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1943 | !sc->sc_config.swBeaconProcess) | 1976 | !sc->sc_config.swBeaconProcess) |
1944 | sc->sc_imask |= ATH9K_INT_TIM; | 1977 | sc->sc_imask |= ATH9K_INT_TIM; |
1945 | 1978 | ||
1946 | ath_setcurmode(sc, ath_chan2mode(init_channel)); | 1979 | ath_cache_conf_rate(sc, &hw->conf); |
1947 | 1980 | ||
1948 | sc->sc_flags &= ~SC_OP_INVALID; | 1981 | sc->sc_flags &= ~SC_OP_INVALID; |
1949 | 1982 | ||
@@ -1954,11 +1987,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1954 | ieee80211_wake_queues(sc->hw); | 1987 | ieee80211_wake_queues(sc->hw); |
1955 | 1988 | ||
1956 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | 1989 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) |
1957 | error = ath_start_rfkill_poll(sc); | 1990 | r = ath_start_rfkill_poll(sc); |
1958 | #endif | 1991 | #endif |
1959 | 1992 | return r; | |
1960 | error: | ||
1961 | return error; | ||
1962 | } | 1993 | } |
1963 | 1994 | ||
1964 | static int ath9k_tx(struct ieee80211_hw *hw, | 1995 | static int ath9k_tx(struct ieee80211_hw *hw, |
@@ -2031,7 +2062,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2031 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | 2062 | ath9k_hw_set_interrupts(sc->sc_ah, 0); |
2032 | 2063 | ||
2033 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 2064 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
2034 | ath_draintxq(sc, false); | 2065 | ath_drain_all_txq(sc, false); |
2035 | ath_stoprecv(sc); | 2066 | ath_stoprecv(sc); |
2036 | ath9k_hw_phy_disable(sc->sc_ah); | 2067 | ath9k_hw_phy_disable(sc->sc_ah); |
2037 | } else | 2068 | } else |
@@ -2133,38 +2164,38 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2133 | struct ieee80211_conf *conf = &hw->conf; | 2164 | struct ieee80211_conf *conf = &hw->conf; |
2134 | 2165 | ||
2135 | mutex_lock(&sc->mutex); | 2166 | mutex_lock(&sc->mutex); |
2136 | if (changed & (IEEE80211_CONF_CHANGE_CHANNEL | | 2167 | if (changed & IEEE80211_CONF_CHANGE_PS) { |
2137 | IEEE80211_CONF_CHANGE_HT)) { | 2168 | if (conf->flags & IEEE80211_CONF_PS) { |
2169 | if ((sc->sc_imask & ATH9K_INT_TIM_TIMER) == 0) { | ||
2170 | sc->sc_imask |= ATH9K_INT_TIM_TIMER; | ||
2171 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
2172 | sc->sc_imask); | ||
2173 | } | ||
2174 | ath9k_hw_setrxabort(sc->sc_ah, 1); | ||
2175 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
2176 | } else { | ||
2177 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | ||
2178 | ath9k_hw_setrxabort(sc->sc_ah, 0); | ||
2179 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | ||
2180 | if (sc->sc_imask & ATH9K_INT_TIM_TIMER) { | ||
2181 | sc->sc_imask &= ~ATH9K_INT_TIM_TIMER; | ||
2182 | ath9k_hw_set_interrupts(sc->sc_ah, | ||
2183 | sc->sc_imask); | ||
2184 | } | ||
2185 | } | ||
2186 | } | ||
2187 | |||
2188 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
2138 | struct ieee80211_channel *curchan = hw->conf.channel; | 2189 | struct ieee80211_channel *curchan = hw->conf.channel; |
2139 | int pos; | 2190 | int pos = curchan->hw_value; |
2140 | 2191 | ||
2141 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 2192 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
2142 | curchan->center_freq); | 2193 | curchan->center_freq); |
2143 | 2194 | ||
2144 | pos = ath_get_channel(sc, curchan); | 2195 | /* XXX: remove me eventualy */ |
2145 | if (pos == -1) { | 2196 | ath9k_update_ichannel(sc, &sc->sc_ah->ah_channels[pos]); |
2146 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", | ||
2147 | curchan->center_freq); | ||
2148 | mutex_unlock(&sc->mutex); | ||
2149 | return -EINVAL; | ||
2150 | } | ||
2151 | |||
2152 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
2153 | sc->sc_ah->ah_channels[pos].chanmode = | ||
2154 | (curchan->band == IEEE80211_BAND_2GHZ) ? | ||
2155 | CHANNEL_G : CHANNEL_A; | ||
2156 | 2197 | ||
2157 | if (conf->ht.enabled) { | 2198 | ath_update_chainmask(sc, conf_is_ht(conf)); |
2158 | if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS || | ||
2159 | conf->ht.channel_type == NL80211_CHAN_HT40MINUS) | ||
2160 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
2161 | |||
2162 | sc->sc_ah->ah_channels[pos].chanmode = | ||
2163 | ath_get_extchanmode(sc, curchan, | ||
2164 | conf->ht.channel_type); | ||
2165 | } | ||
2166 | |||
2167 | ath_update_chainmask(sc, conf->ht.enabled); | ||
2168 | 2199 | ||
2169 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { | 2200 | if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) { |
2170 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); | 2201 | DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n"); |
@@ -2228,24 +2259,27 @@ static int ath9k_config_interface(struct ieee80211_hw *hw, | |||
2228 | } | 2259 | } |
2229 | } | 2260 | } |
2230 | 2261 | ||
2231 | if ((conf->changed & IEEE80211_IFCC_BEACON) && | 2262 | if ((vif->type == NL80211_IFTYPE_ADHOC) || |
2232 | ((vif->type == NL80211_IFTYPE_ADHOC) || | 2263 | (vif->type == NL80211_IFTYPE_AP)) { |
2233 | (vif->type == NL80211_IFTYPE_AP))) { | 2264 | if ((conf->changed & IEEE80211_IFCC_BEACON) || |
2234 | /* | 2265 | (conf->changed & IEEE80211_IFCC_BEACON_ENABLED && |
2235 | * Allocate and setup the beacon frame. | 2266 | conf->enable_beacon)) { |
2236 | * | 2267 | /* |
2237 | * Stop any previous beacon DMA. This may be | 2268 | * Allocate and setup the beacon frame. |
2238 | * necessary, for example, when an ibss merge | 2269 | * |
2239 | * causes reconfiguration; we may be called | 2270 | * Stop any previous beacon DMA. This may be |
2240 | * with beacon transmission active. | 2271 | * necessary, for example, when an ibss merge |
2241 | */ | 2272 | * causes reconfiguration; we may be called |
2242 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 2273 | * with beacon transmission active. |
2274 | */ | ||
2275 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
2243 | 2276 | ||
2244 | error = ath_beacon_alloc(sc, 0); | 2277 | error = ath_beacon_alloc(sc, 0); |
2245 | if (error != 0) | 2278 | if (error != 0) |
2246 | return error; | 2279 | return error; |
2247 | 2280 | ||
2248 | ath_beacon_sync(sc, 0); | 2281 | ath_beacon_sync(sc, 0); |
2282 | } | ||
2249 | } | 2283 | } |
2250 | 2284 | ||
2251 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ | 2285 | /* Check for WLAN_CAPABILITY_PRIVACY ? */ |
@@ -2348,24 +2382,27 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
2348 | 2382 | ||
2349 | static int ath9k_set_key(struct ieee80211_hw *hw, | 2383 | static int ath9k_set_key(struct ieee80211_hw *hw, |
2350 | enum set_key_cmd cmd, | 2384 | enum set_key_cmd cmd, |
2351 | const u8 *local_addr, | 2385 | struct ieee80211_vif *vif, |
2352 | const u8 *addr, | 2386 | struct ieee80211_sta *sta, |
2353 | struct ieee80211_key_conf *key) | 2387 | struct ieee80211_key_conf *key) |
2354 | { | 2388 | { |
2355 | struct ath_softc *sc = hw->priv; | 2389 | struct ath_softc *sc = hw->priv; |
2356 | int ret = 0; | 2390 | int ret = 0; |
2357 | 2391 | ||
2392 | ath9k_ps_wakeup(sc); | ||
2358 | DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); | 2393 | DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); |
2359 | 2394 | ||
2360 | switch (cmd) { | 2395 | switch (cmd) { |
2361 | case SET_KEY: | 2396 | case SET_KEY: |
2362 | ret = ath_key_config(sc, addr, key); | 2397 | ret = ath_key_config(sc, sta, key); |
2363 | if (ret >= 0) { | 2398 | if (ret >= 0) { |
2364 | key->hw_key_idx = ret; | 2399 | key->hw_key_idx = ret; |
2365 | /* push IV and Michael MIC generation to stack */ | 2400 | /* push IV and Michael MIC generation to stack */ |
2366 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | 2401 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
2367 | if (key->alg == ALG_TKIP) | 2402 | if (key->alg == ALG_TKIP) |
2368 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | 2403 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; |
2404 | if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP) | ||
2405 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; | ||
2369 | ret = 0; | 2406 | ret = 0; |
2370 | } | 2407 | } |
2371 | break; | 2408 | break; |
@@ -2376,6 +2413,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2376 | ret = -EINVAL; | 2413 | ret = -EINVAL; |
2377 | } | 2414 | } |
2378 | 2415 | ||
2416 | ath9k_ps_restore(sc); | ||
2379 | return ret; | 2417 | return ret; |
2380 | } | 2418 | } |
2381 | 2419 | ||
@@ -2423,6 +2461,14 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | |||
2423 | return tsf; | 2461 | return tsf; |
2424 | } | 2462 | } |
2425 | 2463 | ||
2464 | static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | ||
2465 | { | ||
2466 | struct ath_softc *sc = hw->priv; | ||
2467 | struct ath_hal *ah = sc->sc_ah; | ||
2468 | |||
2469 | ath9k_hw_settsf64(ah, tsf); | ||
2470 | } | ||
2471 | |||
2426 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) | 2472 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) |
2427 | { | 2473 | { |
2428 | struct ath_softc *sc = hw->priv; | 2474 | struct ath_softc *sc = hw->priv; |
@@ -2472,7 +2518,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2472 | return ret; | 2518 | return ret; |
2473 | } | 2519 | } |
2474 | 2520 | ||
2475 | static struct ieee80211_ops ath9k_ops = { | 2521 | struct ieee80211_ops ath9k_ops = { |
2476 | .tx = ath9k_tx, | 2522 | .tx = ath9k_tx, |
2477 | .start = ath9k_start, | 2523 | .start = ath9k_start, |
2478 | .stop = ath9k_stop, | 2524 | .stop = ath9k_stop, |
@@ -2486,6 +2532,7 @@ static struct ieee80211_ops ath9k_ops = { | |||
2486 | .bss_info_changed = ath9k_bss_info_changed, | 2532 | .bss_info_changed = ath9k_bss_info_changed, |
2487 | .set_key = ath9k_set_key, | 2533 | .set_key = ath9k_set_key, |
2488 | .get_tsf = ath9k_get_tsf, | 2534 | .get_tsf = ath9k_get_tsf, |
2535 | .set_tsf = ath9k_set_tsf, | ||
2489 | .reset_tsf = ath9k_reset_tsf, | 2536 | .reset_tsf = ath9k_reset_tsf, |
2490 | .ampdu_action = ath9k_ampdu_action, | 2537 | .ampdu_action = ath9k_ampdu_action, |
2491 | }; | 2538 | }; |
@@ -2516,7 +2563,7 @@ static struct { | |||
2516 | /* | 2563 | /* |
2517 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. | 2564 | * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown. |
2518 | */ | 2565 | */ |
2519 | static const char * | 2566 | const char * |
2520 | ath_mac_bb_name(u32 mac_bb_version) | 2567 | ath_mac_bb_name(u32 mac_bb_version) |
2521 | { | 2568 | { |
2522 | int i; | 2569 | int i; |
@@ -2533,7 +2580,7 @@ ath_mac_bb_name(u32 mac_bb_version) | |||
2533 | /* | 2580 | /* |
2534 | * Return the RF name. "????" is returned if the RF is unknown. | 2581 | * Return the RF name. "????" is returned if the RF is unknown. |
2535 | */ | 2582 | */ |
2536 | static const char * | 2583 | const char * |
2537 | ath_rf_name(u16 rf_version) | 2584 | ath_rf_name(u16 rf_version) |
2538 | { | 2585 | { |
2539 | int i; | 2586 | int i; |
@@ -2547,254 +2594,51 @@ ath_rf_name(u16 rf_version) | |||
2547 | return "????"; | 2594 | return "????"; |
2548 | } | 2595 | } |
2549 | 2596 | ||
2550 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 2597 | static int __init ath9k_init(void) |
2551 | { | ||
2552 | void __iomem *mem; | ||
2553 | struct ath_softc *sc; | ||
2554 | struct ieee80211_hw *hw; | ||
2555 | u8 csz; | ||
2556 | u32 val; | ||
2557 | int ret = 0; | ||
2558 | struct ath_hal *ah; | ||
2559 | |||
2560 | if (pci_enable_device(pdev)) | ||
2561 | return -EIO; | ||
2562 | |||
2563 | ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
2564 | |||
2565 | if (ret) { | ||
2566 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | ||
2567 | goto bad; | ||
2568 | } | ||
2569 | |||
2570 | ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
2571 | |||
2572 | if (ret) { | ||
2573 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | ||
2574 | "DMA enable failed\n"); | ||
2575 | goto bad; | ||
2576 | } | ||
2577 | |||
2578 | /* | ||
2579 | * Cache line size is used to size and align various | ||
2580 | * structures used to communicate with the hardware. | ||
2581 | */ | ||
2582 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); | ||
2583 | if (csz == 0) { | ||
2584 | /* | ||
2585 | * Linux 2.4.18 (at least) writes the cache line size | ||
2586 | * register as a 16-bit wide register which is wrong. | ||
2587 | * We must have this setup properly for rx buffer | ||
2588 | * DMA to work so force a reasonable value here if it | ||
2589 | * comes up zero. | ||
2590 | */ | ||
2591 | csz = L1_CACHE_BYTES / sizeof(u32); | ||
2592 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); | ||
2593 | } | ||
2594 | /* | ||
2595 | * The default setting of latency timer yields poor results, | ||
2596 | * set it to the value used by other systems. It may be worth | ||
2597 | * tweaking this setting more. | ||
2598 | */ | ||
2599 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); | ||
2600 | |||
2601 | pci_set_master(pdev); | ||
2602 | |||
2603 | /* | ||
2604 | * Disable the RETRY_TIMEOUT register (0x41) to keep | ||
2605 | * PCI Tx retries from interfering with C3 CPU state. | ||
2606 | */ | ||
2607 | pci_read_config_dword(pdev, 0x40, &val); | ||
2608 | if ((val & 0x0000ff00) != 0) | ||
2609 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | ||
2610 | |||
2611 | ret = pci_request_region(pdev, 0, "ath9k"); | ||
2612 | if (ret) { | ||
2613 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | ||
2614 | ret = -ENODEV; | ||
2615 | goto bad; | ||
2616 | } | ||
2617 | |||
2618 | mem = pci_iomap(pdev, 0, 0); | ||
2619 | if (!mem) { | ||
2620 | printk(KERN_ERR "PCI memory map error\n") ; | ||
2621 | ret = -EIO; | ||
2622 | goto bad1; | ||
2623 | } | ||
2624 | |||
2625 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); | ||
2626 | if (hw == NULL) { | ||
2627 | printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n"); | ||
2628 | goto bad2; | ||
2629 | } | ||
2630 | |||
2631 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
2632 | pci_set_drvdata(pdev, hw); | ||
2633 | |||
2634 | sc = hw->priv; | ||
2635 | sc->hw = hw; | ||
2636 | sc->pdev = pdev; | ||
2637 | sc->mem = mem; | ||
2638 | |||
2639 | if (ath_attach(id->device, sc) != 0) { | ||
2640 | ret = -ENODEV; | ||
2641 | goto bad3; | ||
2642 | } | ||
2643 | |||
2644 | /* setup interrupt service routine */ | ||
2645 | |||
2646 | if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) { | ||
2647 | printk(KERN_ERR "%s: request_irq failed\n", | ||
2648 | wiphy_name(hw->wiphy)); | ||
2649 | ret = -EIO; | ||
2650 | goto bad4; | ||
2651 | } | ||
2652 | |||
2653 | ah = sc->sc_ah; | ||
2654 | printk(KERN_INFO | ||
2655 | "%s: Atheros AR%s MAC/BB Rev:%x " | ||
2656 | "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n", | ||
2657 | wiphy_name(hw->wiphy), | ||
2658 | ath_mac_bb_name(ah->ah_macVersion), | ||
2659 | ah->ah_macRev, | ||
2660 | ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)), | ||
2661 | ah->ah_phyRev, | ||
2662 | (unsigned long)mem, pdev->irq); | ||
2663 | |||
2664 | return 0; | ||
2665 | bad4: | ||
2666 | ath_detach(sc); | ||
2667 | bad3: | ||
2668 | ieee80211_free_hw(hw); | ||
2669 | bad2: | ||
2670 | pci_iounmap(pdev, mem); | ||
2671 | bad1: | ||
2672 | pci_release_region(pdev, 0); | ||
2673 | bad: | ||
2674 | pci_disable_device(pdev); | ||
2675 | return ret; | ||
2676 | } | ||
2677 | |||
2678 | static void ath_pci_remove(struct pci_dev *pdev) | ||
2679 | { | ||
2680 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2681 | struct ath_softc *sc = hw->priv; | ||
2682 | |||
2683 | ath_detach(sc); | ||
2684 | if (pdev->irq) | ||
2685 | free_irq(pdev->irq, sc); | ||
2686 | pci_iounmap(pdev, sc->mem); | ||
2687 | pci_release_region(pdev, 0); | ||
2688 | pci_disable_device(pdev); | ||
2689 | ieee80211_free_hw(hw); | ||
2690 | } | ||
2691 | |||
2692 | #ifdef CONFIG_PM | ||
2693 | |||
2694 | static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
2695 | { | ||
2696 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2697 | struct ath_softc *sc = hw->priv; | ||
2698 | |||
2699 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
2700 | |||
2701 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2702 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
2703 | cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); | ||
2704 | #endif | ||
2705 | |||
2706 | pci_save_state(pdev); | ||
2707 | pci_disable_device(pdev); | ||
2708 | pci_set_power_state(pdev, 3); | ||
2709 | |||
2710 | return 0; | ||
2711 | } | ||
2712 | |||
2713 | static int ath_pci_resume(struct pci_dev *pdev) | ||
2714 | { | ||
2715 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
2716 | struct ath_softc *sc = hw->priv; | ||
2717 | u32 val; | ||
2718 | int err; | ||
2719 | |||
2720 | err = pci_enable_device(pdev); | ||
2721 | if (err) | ||
2722 | return err; | ||
2723 | pci_restore_state(pdev); | ||
2724 | /* | ||
2725 | * Suspend/Resume resets the PCI configuration space, so we have to | ||
2726 | * re-disable the RETRY_TIMEOUT register (0x41) to keep | ||
2727 | * PCI Tx retries from interfering with C3 CPU state | ||
2728 | */ | ||
2729 | pci_read_config_dword(pdev, 0x40, &val); | ||
2730 | if ((val & 0x0000ff00) != 0) | ||
2731 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | ||
2732 | |||
2733 | /* Enable LED */ | ||
2734 | ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, | ||
2735 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
2736 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
2737 | |||
2738 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2739 | /* | ||
2740 | * check the h/w rfkill state on resume | ||
2741 | * and start the rfkill poll timer | ||
2742 | */ | ||
2743 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
2744 | queue_delayed_work(sc->hw->workqueue, | ||
2745 | &sc->rf_kill.rfkill_poll, 0); | ||
2746 | #endif | ||
2747 | |||
2748 | return 0; | ||
2749 | } | ||
2750 | |||
2751 | #endif /* CONFIG_PM */ | ||
2752 | |||
2753 | MODULE_DEVICE_TABLE(pci, ath_pci_id_table); | ||
2754 | |||
2755 | static struct pci_driver ath_pci_driver = { | ||
2756 | .name = "ath9k", | ||
2757 | .id_table = ath_pci_id_table, | ||
2758 | .probe = ath_pci_probe, | ||
2759 | .remove = ath_pci_remove, | ||
2760 | #ifdef CONFIG_PM | ||
2761 | .suspend = ath_pci_suspend, | ||
2762 | .resume = ath_pci_resume, | ||
2763 | #endif /* CONFIG_PM */ | ||
2764 | }; | ||
2765 | |||
2766 | static int __init init_ath_pci(void) | ||
2767 | { | 2598 | { |
2768 | int error; | 2599 | int error; |
2769 | 2600 | ||
2770 | printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION); | ||
2771 | |||
2772 | /* Register rate control algorithm */ | 2601 | /* Register rate control algorithm */ |
2773 | error = ath_rate_control_register(); | 2602 | error = ath_rate_control_register(); |
2774 | if (error != 0) { | 2603 | if (error != 0) { |
2775 | printk(KERN_ERR | 2604 | printk(KERN_ERR |
2776 | "Unable to register rate control algorithm: %d\n", | 2605 | "ath9k: Unable to register rate control " |
2606 | "algorithm: %d\n", | ||
2777 | error); | 2607 | error); |
2778 | ath_rate_control_unregister(); | 2608 | goto err_out; |
2779 | return error; | ||
2780 | } | 2609 | } |
2781 | 2610 | ||
2782 | if (pci_register_driver(&ath_pci_driver) < 0) { | 2611 | error = ath_pci_init(); |
2612 | if (error < 0) { | ||
2783 | printk(KERN_ERR | 2613 | printk(KERN_ERR |
2784 | "ath_pci: No devices found, driver not installed.\n"); | 2614 | "ath9k: No PCI devices found, driver not installed.\n"); |
2785 | ath_rate_control_unregister(); | 2615 | error = -ENODEV; |
2786 | pci_unregister_driver(&ath_pci_driver); | 2616 | goto err_rate_unregister; |
2787 | return -ENODEV; | 2617 | } |
2618 | |||
2619 | error = ath_ahb_init(); | ||
2620 | if (error < 0) { | ||
2621 | error = -ENODEV; | ||
2622 | goto err_pci_exit; | ||
2788 | } | 2623 | } |
2789 | 2624 | ||
2790 | return 0; | 2625 | return 0; |
2626 | |||
2627 | err_pci_exit: | ||
2628 | ath_pci_exit(); | ||
2629 | |||
2630 | err_rate_unregister: | ||
2631 | ath_rate_control_unregister(); | ||
2632 | err_out: | ||
2633 | return error; | ||
2791 | } | 2634 | } |
2792 | module_init(init_ath_pci); | 2635 | module_init(ath9k_init); |
2793 | 2636 | ||
2794 | static void __exit exit_ath_pci(void) | 2637 | static void __exit ath9k_exit(void) |
2795 | { | 2638 | { |
2639 | ath_ahb_exit(); | ||
2640 | ath_pci_exit(); | ||
2796 | ath_rate_control_unregister(); | 2641 | ath_rate_control_unregister(); |
2797 | pci_unregister_driver(&ath_pci_driver); | ||
2798 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); | 2642 | printk(KERN_INFO "%s: Driver unloaded\n", dev_info); |
2799 | } | 2643 | } |
2800 | module_exit(exit_ath_pci); | 2644 | module_exit(ath9k_exit); |
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c new file mode 100644 index 000000000000..05612bf28360 --- /dev/null +++ b/drivers/net/wireless/ath9k/pci.c | |||
@@ -0,0 +1,305 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/nl80211.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include "core.h" | ||
20 | #include "reg.h" | ||
21 | #include "hw.h" | ||
22 | |||
23 | static struct pci_device_id ath_pci_id_table[] __devinitdata = { | ||
24 | { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */ | ||
25 | { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */ | ||
26 | { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */ | ||
27 | { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ | ||
28 | { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ | ||
29 | { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ | ||
30 | { 0 } | ||
31 | }; | ||
32 | |||
33 | /* return bus cachesize in 4B word units */ | ||
34 | static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz) | ||
35 | { | ||
36 | u8 u8tmp; | ||
37 | |||
38 | pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, | ||
39 | (u8 *)&u8tmp); | ||
40 | *csz = (int)u8tmp; | ||
41 | |||
42 | /* | ||
43 | * This check was put in to avoid "unplesant" consequences if | ||
44 | * the bootrom has not fully initialized all PCI devices. | ||
45 | * Sometimes the cache line size register is not set | ||
46 | */ | ||
47 | |||
48 | if (*csz == 0) | ||
49 | *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ | ||
50 | } | ||
51 | |||
52 | static void ath_pci_cleanup(struct ath_softc *sc) | ||
53 | { | ||
54 | struct pci_dev *pdev = to_pci_dev(sc->dev); | ||
55 | |||
56 | pci_iounmap(pdev, sc->mem); | ||
57 | pci_release_region(pdev, 0); | ||
58 | pci_disable_device(pdev); | ||
59 | } | ||
60 | |||
61 | static bool ath_pci_eeprom_read(struct ath_hal *ah, u32 off, u16 *data) | ||
62 | { | ||
63 | (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); | ||
64 | |||
65 | if (!ath9k_hw_wait(ah, | ||
66 | AR_EEPROM_STATUS_DATA, | ||
67 | AR_EEPROM_STATUS_DATA_BUSY | | ||
68 | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) { | ||
69 | return false; | ||
70 | } | ||
71 | |||
72 | *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA), | ||
73 | AR_EEPROM_STATUS_DATA_VAL); | ||
74 | |||
75 | return true; | ||
76 | } | ||
77 | |||
78 | static struct ath_bus_ops ath_pci_bus_ops = { | ||
79 | .read_cachesize = ath_pci_read_cachesize, | ||
80 | .cleanup = ath_pci_cleanup, | ||
81 | .eeprom_read = ath_pci_eeprom_read, | ||
82 | }; | ||
83 | |||
84 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | ||
85 | { | ||
86 | void __iomem *mem; | ||
87 | struct ath_softc *sc; | ||
88 | struct ieee80211_hw *hw; | ||
89 | u8 csz; | ||
90 | u32 val; | ||
91 | int ret = 0; | ||
92 | struct ath_hal *ah; | ||
93 | |||
94 | if (pci_enable_device(pdev)) | ||
95 | return -EIO; | ||
96 | |||
97 | ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
98 | |||
99 | if (ret) { | ||
100 | printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); | ||
101 | goto bad; | ||
102 | } | ||
103 | |||
104 | ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
105 | |||
106 | if (ret) { | ||
107 | printk(KERN_ERR "ath9k: 32-bit DMA consistent " | ||
108 | "DMA enable failed\n"); | ||
109 | goto bad; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Cache line size is used to size and align various | ||
114 | * structures used to communicate with the hardware. | ||
115 | */ | ||
116 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); | ||
117 | if (csz == 0) { | ||
118 | /* | ||
119 | * Linux 2.4.18 (at least) writes the cache line size | ||
120 | * register as a 16-bit wide register which is wrong. | ||
121 | * We must have this setup properly for rx buffer | ||
122 | * DMA to work so force a reasonable value here if it | ||
123 | * comes up zero. | ||
124 | */ | ||
125 | csz = L1_CACHE_BYTES / sizeof(u32); | ||
126 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); | ||
127 | } | ||
128 | /* | ||
129 | * The default setting of latency timer yields poor results, | ||
130 | * set it to the value used by other systems. It may be worth | ||
131 | * tweaking this setting more. | ||
132 | */ | ||
133 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); | ||
134 | |||
135 | pci_set_master(pdev); | ||
136 | |||
137 | /* | ||
138 | * Disable the RETRY_TIMEOUT register (0x41) to keep | ||
139 | * PCI Tx retries from interfering with C3 CPU state. | ||
140 | */ | ||
141 | pci_read_config_dword(pdev, 0x40, &val); | ||
142 | if ((val & 0x0000ff00) != 0) | ||
143 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | ||
144 | |||
145 | ret = pci_request_region(pdev, 0, "ath9k"); | ||
146 | if (ret) { | ||
147 | dev_err(&pdev->dev, "PCI memory region reserve error\n"); | ||
148 | ret = -ENODEV; | ||
149 | goto bad; | ||
150 | } | ||
151 | |||
152 | mem = pci_iomap(pdev, 0, 0); | ||
153 | if (!mem) { | ||
154 | printk(KERN_ERR "PCI memory map error\n") ; | ||
155 | ret = -EIO; | ||
156 | goto bad1; | ||
157 | } | ||
158 | |||
159 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); | ||
160 | if (hw == NULL) { | ||
161 | printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n"); | ||
162 | goto bad2; | ||
163 | } | ||
164 | |||
165 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
166 | pci_set_drvdata(pdev, hw); | ||
167 | |||
168 | sc = hw->priv; | ||
169 | sc->hw = hw; | ||
170 | sc->dev = &pdev->dev; | ||
171 | sc->mem = mem; | ||
172 | sc->bus_ops = &ath_pci_bus_ops; | ||
173 | |||
174 | if (ath_attach(id->device, sc) != 0) { | ||
175 | ret = -ENODEV; | ||
176 | goto bad3; | ||
177 | } | ||
178 | |||
179 | /* setup interrupt service routine */ | ||
180 | |||
181 | if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) { | ||
182 | printk(KERN_ERR "%s: request_irq failed\n", | ||
183 | wiphy_name(hw->wiphy)); | ||
184 | ret = -EIO; | ||
185 | goto bad4; | ||
186 | } | ||
187 | |||
188 | sc->irq = pdev->irq; | ||
189 | |||
190 | ah = sc->sc_ah; | ||
191 | printk(KERN_INFO | ||
192 | "%s: Atheros AR%s MAC/BB Rev:%x " | ||
193 | "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n", | ||
194 | wiphy_name(hw->wiphy), | ||
195 | ath_mac_bb_name(ah->ah_macVersion), | ||
196 | ah->ah_macRev, | ||
197 | ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)), | ||
198 | ah->ah_phyRev, | ||
199 | (unsigned long)mem, pdev->irq); | ||
200 | |||
201 | return 0; | ||
202 | bad4: | ||
203 | ath_detach(sc); | ||
204 | bad3: | ||
205 | ieee80211_free_hw(hw); | ||
206 | bad2: | ||
207 | pci_iounmap(pdev, mem); | ||
208 | bad1: | ||
209 | pci_release_region(pdev, 0); | ||
210 | bad: | ||
211 | pci_disable_device(pdev); | ||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | static void ath_pci_remove(struct pci_dev *pdev) | ||
216 | { | ||
217 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
218 | struct ath_softc *sc = hw->priv; | ||
219 | |||
220 | ath_cleanup(sc); | ||
221 | } | ||
222 | |||
223 | #ifdef CONFIG_PM | ||
224 | |||
225 | static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
226 | { | ||
227 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
228 | struct ath_softc *sc = hw->priv; | ||
229 | |||
230 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
231 | |||
232 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
233 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
234 | cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll); | ||
235 | #endif | ||
236 | |||
237 | pci_save_state(pdev); | ||
238 | pci_disable_device(pdev); | ||
239 | pci_set_power_state(pdev, PCI_D3hot); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static int ath_pci_resume(struct pci_dev *pdev) | ||
245 | { | ||
246 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
247 | struct ath_softc *sc = hw->priv; | ||
248 | u32 val; | ||
249 | int err; | ||
250 | |||
251 | err = pci_enable_device(pdev); | ||
252 | if (err) | ||
253 | return err; | ||
254 | pci_restore_state(pdev); | ||
255 | /* | ||
256 | * Suspend/Resume resets the PCI configuration space, so we have to | ||
257 | * re-disable the RETRY_TIMEOUT register (0x41) to keep | ||
258 | * PCI Tx retries from interfering with C3 CPU state | ||
259 | */ | ||
260 | pci_read_config_dword(pdev, 0x40, &val); | ||
261 | if ((val & 0x0000ff00) != 0) | ||
262 | pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); | ||
263 | |||
264 | /* Enable LED */ | ||
265 | ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, | ||
266 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
267 | ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); | ||
268 | |||
269 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
270 | /* | ||
271 | * check the h/w rfkill state on resume | ||
272 | * and start the rfkill poll timer | ||
273 | */ | ||
274 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
275 | queue_delayed_work(sc->hw->workqueue, | ||
276 | &sc->rf_kill.rfkill_poll, 0); | ||
277 | #endif | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | #endif /* CONFIG_PM */ | ||
283 | |||
284 | MODULE_DEVICE_TABLE(pci, ath_pci_id_table); | ||
285 | |||
286 | static struct pci_driver ath_pci_driver = { | ||
287 | .name = "ath9k", | ||
288 | .id_table = ath_pci_id_table, | ||
289 | .probe = ath_pci_probe, | ||
290 | .remove = ath_pci_remove, | ||
291 | #ifdef CONFIG_PM | ||
292 | .suspend = ath_pci_suspend, | ||
293 | .resume = ath_pci_resume, | ||
294 | #endif /* CONFIG_PM */ | ||
295 | }; | ||
296 | |||
297 | int __init ath_pci_init(void) | ||
298 | { | ||
299 | return pci_register_driver(&ath_pci_driver); | ||
300 | } | ||
301 | |||
302 | void ath_pci_exit(void) | ||
303 | { | ||
304 | pci_unregister_driver(&ath_pci_driver); | ||
305 | } | ||
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 1b71b934bb5e..eb557add6567 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -19,12 +19,11 @@ | |||
19 | 19 | ||
20 | static struct ath_rate_table ar5416_11na_ratetable = { | 20 | static struct ath_rate_table ar5416_11na_ratetable = { |
21 | 42, | 21 | 42, |
22 | {0}, | ||
23 | { | 22 | { |
24 | { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | 23 | { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ |
25 | 5400, 0x0b, 0x00, 12, | 24 | 5400, 0x0b, 0x00, 12, |
26 | 0, 2, 1, 0, 0, 0, 0, 0 }, | 25 | 0, 2, 1, 0, 0, 0, 0, 0 }, |
27 | { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ | 26 | { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ |
28 | 7800, 0x0f, 0x00, 18, | 27 | 7800, 0x0f, 0x00, 18, |
29 | 0, 3, 1, 1, 1, 1, 1, 0 }, | 28 | 0, 3, 1, 1, 1, 1, 1, 0 }, |
30 | { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ | 29 | { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ |
@@ -158,7 +157,6 @@ static struct ath_rate_table ar5416_11na_ratetable = { | |||
158 | 157 | ||
159 | static struct ath_rate_table ar5416_11ng_ratetable = { | 158 | static struct ath_rate_table ar5416_11ng_ratetable = { |
160 | 46, | 159 | 46, |
161 | {0}, | ||
162 | { | 160 | { |
163 | { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | 161 | { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ |
164 | 900, 0x1b, 0x00, 2, | 162 | 900, 0x1b, 0x00, 2, |
@@ -306,7 +304,6 @@ static struct ath_rate_table ar5416_11ng_ratetable = { | |||
306 | 304 | ||
307 | static struct ath_rate_table ar5416_11a_ratetable = { | 305 | static struct ath_rate_table ar5416_11a_ratetable = { |
308 | 8, | 306 | 8, |
309 | {0}, | ||
310 | { | 307 | { |
311 | { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ | 308 | { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ |
312 | 5400, 0x0b, 0x00, (0x80|12), | 309 | 5400, 0x0b, 0x00, (0x80|12), |
@@ -340,7 +337,6 @@ static struct ath_rate_table ar5416_11a_ratetable = { | |||
340 | 337 | ||
341 | static struct ath_rate_table ar5416_11g_ratetable = { | 338 | static struct ath_rate_table ar5416_11g_ratetable = { |
342 | 12, | 339 | 12, |
343 | {0}, | ||
344 | { | 340 | { |
345 | { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | 341 | { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ |
346 | 900, 0x1b, 0x00, 2, | 342 | 900, 0x1b, 0x00, 2, |
@@ -386,7 +382,6 @@ static struct ath_rate_table ar5416_11g_ratetable = { | |||
386 | 382 | ||
387 | static struct ath_rate_table ar5416_11b_ratetable = { | 383 | static struct ath_rate_table ar5416_11b_ratetable = { |
388 | 4, | 384 | 4, |
389 | {0}, | ||
390 | { | 385 | { |
391 | { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ | 386 | { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ |
392 | 900, 0x1b, 0x00, (0x80|2), | 387 | 900, 0x1b, 0x00, (0x80|2), |
@@ -875,7 +870,7 @@ static void ath_rc_ratefind(struct ath_softc *sc, | |||
875 | * above conditions. | 870 | * above conditions. |
876 | */ | 871 | */ |
877 | if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) && | 872 | if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) && |
878 | (sc->hw->conf.ht.enabled)) { | 873 | (conf_is_ht(&sc->hw->conf))) { |
879 | u8 dot11rate = rate_table->info[rix].dot11rate; | 874 | u8 dot11rate = rate_table->info[rix].dot11rate; |
880 | u8 phy = rate_table->info[rix].phy; | 875 | u8 phy = rate_table->info[rix].phy; |
881 | if (i == 4 && | 876 | if (i == 4 && |
@@ -1363,9 +1358,13 @@ static void ath_rc_init(struct ath_softc *sc, | |||
1363 | } | 1358 | } |
1364 | 1359 | ||
1365 | if (sta->ht_cap.ht_supported) { | 1360 | if (sta->ht_cap.ht_supported) { |
1366 | ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG); | 1361 | ath_rc_priv->ht_cap = WLAN_RC_HT_FLAG; |
1362 | if (sc->sc_ah->ah_caps.tx_chainmask != 1) | ||
1363 | ath_rc_priv->ht_cap |= WLAN_RC_DS_FLAG; | ||
1367 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | 1364 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) |
1368 | ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; | 1365 | ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; |
1366 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) | ||
1367 | ath_rc_priv->ht_cap |= WLAN_RC_SGI_FLAG; | ||
1369 | } | 1368 | } |
1370 | 1369 | ||
1371 | /* Initial rate table size. Will change depending | 1370 | /* Initial rate table size. Will change depending |
@@ -1511,7 +1510,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
1511 | tx_info, &is_probe, false); | 1510 | tx_info, &is_probe, false); |
1512 | 1511 | ||
1513 | /* Check if aggregation has to be enabled for this tid */ | 1512 | /* Check if aggregation has to be enabled for this tid */ |
1514 | if (hw->conf.ht.enabled) { | 1513 | if (conf_is_ht(&hw->conf)) { |
1515 | if (ieee80211_is_data_qos(fc)) { | 1514 | if (ieee80211_is_data_qos(fc)) { |
1516 | u8 *qc, tid; | 1515 | u8 *qc, tid; |
1517 | struct ath_node *an; | 1516 | struct ath_node *an; |
@@ -1607,16 +1606,8 @@ static void ath_setup_rate_table(struct ath_softc *sc, | |||
1607 | { | 1606 | { |
1608 | int i; | 1607 | int i; |
1609 | 1608 | ||
1610 | for (i = 0; i < 256; i++) | ||
1611 | rate_table->rateCodeToIndex[i] = (u8)-1; | ||
1612 | |||
1613 | for (i = 0; i < rate_table->rate_cnt; i++) { | 1609 | for (i = 0; i < rate_table->rate_cnt; i++) { |
1614 | u8 code = rate_table->info[i].ratecode; | ||
1615 | u8 cix = rate_table->info[i].ctrl_rate; | 1610 | u8 cix = rate_table->info[i].ctrl_rate; |
1616 | u8 sh = rate_table->info[i].short_preamble; | ||
1617 | |||
1618 | rate_table->rateCodeToIndex[code] = i; | ||
1619 | rate_table->rateCodeToIndex[code | sh] = i; | ||
1620 | 1611 | ||
1621 | rate_table->info[i].lpAckDuration = | 1612 | rate_table->info[i].lpAckDuration = |
1622 | ath9k_hw_computetxtime(sc->sc_ah, rate_table, | 1613 | ath9k_hw_computetxtime(sc->sc_ah, rate_table, |
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index 97c60d12e8aa..a987cb9e74e2 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h | |||
@@ -90,7 +90,6 @@ struct ath_softc; | |||
90 | */ | 90 | */ |
91 | struct ath_rate_table { | 91 | struct ath_rate_table { |
92 | int rate_cnt; | 92 | int rate_cnt; |
93 | u8 rateCodeToIndex[256]; | ||
94 | struct { | 93 | struct { |
95 | int valid; | 94 | int valid; |
96 | int valid_single_stream; | 95 | int valid_single_stream; |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 462e08c3d09d..8da08f9b463c 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -291,15 +291,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
291 | } | 291 | } |
292 | 292 | ||
293 | bf->bf_mpdu = skb; | 293 | bf->bf_mpdu = skb; |
294 | bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, | 294 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
295 | sc->rx.bufsize, | 295 | sc->rx.bufsize, |
296 | PCI_DMA_FROMDEVICE); | 296 | DMA_FROM_DEVICE); |
297 | if (unlikely(pci_dma_mapping_error(sc->pdev, | 297 | if (unlikely(dma_mapping_error(sc->dev, |
298 | bf->bf_buf_addr))) { | 298 | bf->bf_buf_addr))) { |
299 | dev_kfree_skb_any(skb); | 299 | dev_kfree_skb_any(skb); |
300 | bf->bf_mpdu = NULL; | 300 | bf->bf_mpdu = NULL; |
301 | DPRINTF(sc, ATH_DBG_CONFIG, | 301 | DPRINTF(sc, ATH_DBG_CONFIG, |
302 | "pci_dma_mapping_error() on RX init\n"); | 302 | "dma_mapping_error() on RX init\n"); |
303 | error = -ENOMEM; | 303 | error = -ENOMEM; |
304 | break; | 304 | break; |
305 | } | 305 | } |
@@ -524,9 +524,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
524 | * 1. accessing the frame | 524 | * 1. accessing the frame |
525 | * 2. requeueing the same buffer to h/w | 525 | * 2. requeueing the same buffer to h/w |
526 | */ | 526 | */ |
527 | pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, | 527 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, |
528 | sc->rx.bufsize, | 528 | sc->rx.bufsize, |
529 | PCI_DMA_FROMDEVICE); | 529 | DMA_FROM_DEVICE); |
530 | 530 | ||
531 | /* | 531 | /* |
532 | * If we're asked to flush receive queue, directly | 532 | * If we're asked to flush receive queue, directly |
@@ -557,9 +557,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
557 | goto requeue; | 557 | goto requeue; |
558 | 558 | ||
559 | /* Unmap the frame */ | 559 | /* Unmap the frame */ |
560 | pci_unmap_single(sc->pdev, bf->bf_buf_addr, | 560 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
561 | sc->rx.bufsize, | 561 | sc->rx.bufsize, |
562 | PCI_DMA_FROMDEVICE); | 562 | DMA_FROM_DEVICE); |
563 | 563 | ||
564 | skb_put(skb, ds->ds_rxstat.rs_datalen); | 564 | skb_put(skb, ds->ds_rxstat.rs_datalen); |
565 | skb->protocol = cpu_to_be16(ETH_P_CONTROL); | 565 | skb->protocol = cpu_to_be16(ETH_P_CONTROL); |
@@ -593,21 +593,27 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
593 | if (test_bit(keyix, sc->sc_keymap)) | 593 | if (test_bit(keyix, sc->sc_keymap)) |
594 | rx_status.flag |= RX_FLAG_DECRYPTED; | 594 | rx_status.flag |= RX_FLAG_DECRYPTED; |
595 | } | 595 | } |
596 | if (ah->sw_mgmt_crypto && | ||
597 | (rx_status.flag & RX_FLAG_DECRYPTED) && | ||
598 | ieee80211_is_mgmt(hdr->frame_control)) { | ||
599 | /* Use software decrypt for management frames. */ | ||
600 | rx_status.flag &= ~RX_FLAG_DECRYPTED; | ||
601 | } | ||
596 | 602 | ||
597 | /* Send the frame to mac80211 */ | 603 | /* Send the frame to mac80211 */ |
598 | __ieee80211_rx(sc->hw, skb, &rx_status); | 604 | __ieee80211_rx(sc->hw, skb, &rx_status); |
599 | 605 | ||
600 | /* We will now give hardware our shiny new allocated skb */ | 606 | /* We will now give hardware our shiny new allocated skb */ |
601 | bf->bf_mpdu = requeue_skb; | 607 | bf->bf_mpdu = requeue_skb; |
602 | bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, | 608 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, |
603 | sc->rx.bufsize, | 609 | sc->rx.bufsize, |
604 | PCI_DMA_FROMDEVICE); | 610 | DMA_FROM_DEVICE); |
605 | if (unlikely(pci_dma_mapping_error(sc->pdev, | 611 | if (unlikely(dma_mapping_error(sc->dev, |
606 | bf->bf_buf_addr))) { | 612 | bf->bf_buf_addr))) { |
607 | dev_kfree_skb_any(requeue_skb); | 613 | dev_kfree_skb_any(requeue_skb); |
608 | bf->bf_mpdu = NULL; | 614 | bf->bf_mpdu = NULL; |
609 | DPRINTF(sc, ATH_DBG_CONFIG, | 615 | DPRINTF(sc, ATH_DBG_CONFIG, |
610 | "pci_dma_mapping_error() on RX\n"); | 616 | "dma_mapping_error() on RX\n"); |
611 | break; | 617 | break; |
612 | } | 618 | } |
613 | bf->bf_dmacontext = bf->bf_buf_addr; | 619 | bf->bf_dmacontext = bf->bf_buf_addr; |
@@ -622,6 +628,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
622 | } else { | 628 | } else { |
623 | sc->rx.rxotherant = 0; | 629 | sc->rx.rxotherant = 0; |
624 | } | 630 | } |
631 | |||
632 | if (ieee80211_is_beacon(hdr->frame_control) && | ||
633 | (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { | ||
634 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | ||
635 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | ||
636 | } | ||
625 | requeue: | 637 | requeue: |
626 | list_move_tail(&bf->list, &sc->rx.rxbuf); | 638 | list_move_tail(&bf->list, &sc->rx.rxbuf); |
627 | ath_rx_buf_link(sc, bf); | 639 | ath_rx_buf_link(sc, bf); |
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h index 9fedb4911bc3..150eda56055a 100644 --- a/drivers/net/wireless/ath9k/reg.h +++ b/drivers/net/wireless/ath9k/reg.h | |||
@@ -875,12 +875,15 @@ enum { | |||
875 | 875 | ||
876 | #define AR_NUM_GPIO 14 | 876 | #define AR_NUM_GPIO 14 |
877 | #define AR928X_NUM_GPIO 10 | 877 | #define AR928X_NUM_GPIO 10 |
878 | #define AR9285_NUM_GPIO 12 | ||
878 | 879 | ||
879 | #define AR_GPIO_IN_OUT 0x4048 | 880 | #define AR_GPIO_IN_OUT 0x4048 |
880 | #define AR_GPIO_IN_VAL 0x0FFFC000 | 881 | #define AR_GPIO_IN_VAL 0x0FFFC000 |
881 | #define AR_GPIO_IN_VAL_S 14 | 882 | #define AR_GPIO_IN_VAL_S 14 |
882 | #define AR928X_GPIO_IN_VAL 0x000FFC00 | 883 | #define AR928X_GPIO_IN_VAL 0x000FFC00 |
883 | #define AR928X_GPIO_IN_VAL_S 10 | 884 | #define AR928X_GPIO_IN_VAL_S 10 |
885 | #define AR9285_GPIO_IN_VAL 0x00FFF000 | ||
886 | #define AR9285_GPIO_IN_VAL_S 12 | ||
884 | 887 | ||
885 | #define AR_GPIO_OE_OUT 0x404c | 888 | #define AR_GPIO_OE_OUT 0x404c |
886 | #define AR_GPIO_OE_OUT_DRV 0x3 | 889 | #define AR_GPIO_OE_OUT_DRV 0x3 |
@@ -894,14 +897,24 @@ enum { | |||
894 | #define AR_GPIO_INTR_POL_VAL_S 0 | 897 | #define AR_GPIO_INTR_POL_VAL_S 0 |
895 | 898 | ||
896 | #define AR_GPIO_INPUT_EN_VAL 0x4054 | 899 | #define AR_GPIO_INPUT_EN_VAL 0x4054 |
900 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 | ||
901 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 | ||
902 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 | ||
903 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S 3 | ||
904 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF 0x00000010 | ||
905 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S 4 | ||
897 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080 | 906 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080 |
898 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7 | 907 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7 |
908 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000 | ||
909 | #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S 12 | ||
899 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000 | 910 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000 |
900 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15 | 911 | #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15 |
901 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 | 912 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 |
902 | #define AR_GPIO_JTAG_DISABLE 0x00020000 | 913 | #define AR_GPIO_JTAG_DISABLE 0x00020000 |
903 | 914 | ||
904 | #define AR_GPIO_INPUT_MUX1 0x4058 | 915 | #define AR_GPIO_INPUT_MUX1 0x4058 |
916 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 | ||
917 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 | ||
905 | 918 | ||
906 | #define AR_GPIO_INPUT_MUX2 0x405c | 919 | #define AR_GPIO_INPUT_MUX2 0x405c |
907 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f | 920 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f |
@@ -940,7 +953,7 @@ enum { | |||
940 | 953 | ||
941 | #define AR_RTC_BASE 0x00020000 | 954 | #define AR_RTC_BASE 0x00020000 |
942 | #define AR_RTC_RC \ | 955 | #define AR_RTC_RC \ |
943 | (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000 | 956 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000) |
944 | #define AR_RTC_RC_M 0x00000003 | 957 | #define AR_RTC_RC_M 0x00000003 |
945 | #define AR_RTC_RC_MAC_WARM 0x00000001 | 958 | #define AR_RTC_RC_MAC_WARM 0x00000001 |
946 | #define AR_RTC_RC_MAC_COLD 0x00000002 | 959 | #define AR_RTC_RC_MAC_COLD 0x00000002 |
@@ -948,7 +961,7 @@ enum { | |||
948 | #define AR_RTC_RC_WARM_RESET 0x00000008 | 961 | #define AR_RTC_RC_WARM_RESET 0x00000008 |
949 | 962 | ||
950 | #define AR_RTC_PLL_CONTROL \ | 963 | #define AR_RTC_PLL_CONTROL \ |
951 | (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014 | 964 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) |
952 | 965 | ||
953 | #define AR_RTC_PLL_DIV 0x0000001f | 966 | #define AR_RTC_PLL_DIV 0x0000001f |
954 | #define AR_RTC_PLL_DIV_S 0 | 967 | #define AR_RTC_PLL_DIV_S 0 |
@@ -1021,6 +1034,10 @@ enum { | |||
1021 | #define AR_AN_RF5G1_CH1_DB5 0x00380000 | 1034 | #define AR_AN_RF5G1_CH1_DB5 0x00380000 |
1022 | #define AR_AN_RF5G1_CH1_DB5_S 19 | 1035 | #define AR_AN_RF5G1_CH1_DB5_S 19 |
1023 | 1036 | ||
1037 | #define AR_AN_TOP1 0x7890 | ||
1038 | #define AR_AN_TOP1_DACIPMODE 0x00040000 | ||
1039 | #define AR_AN_TOP1_DACIPMODE_S 18 | ||
1040 | |||
1024 | #define AR_AN_TOP2 0x7894 | 1041 | #define AR_AN_TOP2 0x7894 |
1025 | #define AR_AN_TOP2_XPABIAS_LVL 0xC0000000 | 1042 | #define AR_AN_TOP2_XPABIAS_LVL 0xC0000000 |
1026 | #define AR_AN_TOP2_XPABIAS_LVL_S 30 | 1043 | #define AR_AN_TOP2_XPABIAS_LVL_S 30 |
@@ -1236,6 +1253,8 @@ enum { | |||
1236 | 1253 | ||
1237 | #define AR_AES_MUTE_MASK1 0x8060 | 1254 | #define AR_AES_MUTE_MASK1 0x8060 |
1238 | #define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF | 1255 | #define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF |
1256 | #define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000 | ||
1257 | #define AR_AES_MUTE_MASK1_FC_MGMT_S 16 | ||
1239 | 1258 | ||
1240 | #define AR_GATED_CLKS 0x8064 | 1259 | #define AR_GATED_CLKS 0x8064 |
1241 | #define AR_GATED_CLKS_TX 0x00000002 | 1260 | #define AR_GATED_CLKS_TX 0x00000002 |
@@ -1460,6 +1479,10 @@ enum { | |||
1460 | #define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700 | 1479 | #define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700 |
1461 | #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380 | 1480 | #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380 |
1462 | 1481 | ||
1482 | #define AR_PCU_MISC_MODE2 0x8344 | ||
1483 | #define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002 | ||
1484 | #define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004 | ||
1485 | |||
1463 | #define AR_KEYTABLE_0 0x8800 | 1486 | #define AR_KEYTABLE_0 0x8800 |
1464 | #define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) | 1487 | #define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) |
1465 | #define AR_KEY_CACHE_SIZE 128 | 1488 | #define AR_KEY_CACHE_SIZE 128 |
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 64043e99facf..ec88f78743e9 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c | |||
@@ -21,174 +21,323 @@ | |||
21 | #include "regd.h" | 21 | #include "regd.h" |
22 | #include "regd_common.h" | 22 | #include "regd_common.h" |
23 | 23 | ||
24 | static int ath9k_regd_chansort(const void *a, const void *b) | 24 | /* |
25 | { | 25 | * This is a set of common rules used by our world regulatory domains. |
26 | const struct ath9k_channel *ca = a; | 26 | * We have 12 world regulatory domains. To save space we consolidate |
27 | const struct ath9k_channel *cb = b; | 27 | * the regulatory domains in 5 structures by frequency and change |
28 | 28 | * the flags on our reg_notifier() on a case by case basis. | |
29 | return (ca->channel == cb->channel) ? | 29 | */ |
30 | (ca->channelFlags & CHAN_FLAGS) - | ||
31 | (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel; | ||
32 | } | ||
33 | 30 | ||
34 | static void | 31 | /* Only these channels all allow active scan on all world regulatory domains */ |
35 | ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp) | 32 | #define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) |
36 | { | 33 | |
37 | u8 *aa = a; | 34 | /* We enable active scan on these a case by case basis by regulatory domain */ |
38 | u8 *ai, *t; | 35 | #define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ |
39 | 36 | NL80211_RRF_PASSIVE_SCAN) | |
40 | for (ai = aa + size; --n >= 1; ai += size) | 37 | #define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ |
41 | for (t = ai; t > aa; t -= size) { | 38 | NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) |
42 | u8 *u = t - size; | 39 | |
43 | if (cmp(u, t) <= 0) | 40 | /* We allow IBSS on these on a case by case basis by regulatory domain */ |
44 | break; | 41 | #define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\ |
45 | swap_array(u, t, size); | 42 | NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) |
46 | } | 43 | #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\ |
47 | } | 44 | NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) |
45 | #define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 40, 0, 30,\ | ||
46 | NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) | ||
47 | |||
48 | #define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \ | ||
49 | ATH9K_2GHZ_CH12_13, \ | ||
50 | ATH9K_2GHZ_CH14 | ||
51 | |||
52 | #define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ | ||
53 | ATH9K_5GHZ_5470_5850 | ||
54 | /* This one skips what we call "mid band" */ | ||
55 | #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ | ||
56 | ATH9K_5GHZ_5725_5850 | ||
57 | |||
58 | /* Can be used for: | ||
59 | * 0x60, 0x61, 0x62 */ | ||
60 | static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = { | ||
61 | .n_reg_rules = 5, | ||
62 | .alpha2 = "99", | ||
63 | .reg_rules = { | ||
64 | ATH9K_2GHZ_ALL, | ||
65 | ATH9K_5GHZ_ALL, | ||
66 | } | ||
67 | }; | ||
68 | |||
69 | /* Can be used by 0x63 and 0x65 */ | ||
70 | static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = { | ||
71 | .n_reg_rules = 4, | ||
72 | .alpha2 = "99", | ||
73 | .reg_rules = { | ||
74 | ATH9K_2GHZ_CH01_11, | ||
75 | ATH9K_2GHZ_CH12_13, | ||
76 | ATH9K_5GHZ_NO_MIDBAND, | ||
77 | } | ||
78 | }; | ||
79 | |||
80 | /* Can be used by 0x64 only */ | ||
81 | static const struct ieee80211_regdomain ath9k_world_regdom_64 = { | ||
82 | .n_reg_rules = 3, | ||
83 | .alpha2 = "99", | ||
84 | .reg_rules = { | ||
85 | ATH9K_2GHZ_CH01_11, | ||
86 | ATH9K_5GHZ_NO_MIDBAND, | ||
87 | } | ||
88 | }; | ||
89 | |||
90 | /* Can be used by 0x66 and 0x69 */ | ||
91 | static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = { | ||
92 | .n_reg_rules = 3, | ||
93 | .alpha2 = "99", | ||
94 | .reg_rules = { | ||
95 | ATH9K_2GHZ_CH01_11, | ||
96 | ATH9K_5GHZ_ALL, | ||
97 | } | ||
98 | }; | ||
99 | |||
100 | /* Can be used by 0x67, 0x6A and 0x68 */ | ||
101 | static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = { | ||
102 | .n_reg_rules = 4, | ||
103 | .alpha2 = "99", | ||
104 | .reg_rules = { | ||
105 | ATH9K_2GHZ_CH01_11, | ||
106 | ATH9K_2GHZ_CH12_13, | ||
107 | ATH9K_5GHZ_ALL, | ||
108 | } | ||
109 | }; | ||
48 | 110 | ||
49 | static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah) | 111 | static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah) |
50 | { | 112 | { |
51 | return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG; | 113 | return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG; |
52 | } | 114 | } |
53 | 115 | ||
54 | static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask) | 116 | u16 ath9k_regd_get_rd(struct ath_hal *ah) |
55 | { | 117 | { |
56 | int i; | 118 | return ath9k_regd_get_eepromRD(ah); |
119 | } | ||
57 | 120 | ||
58 | for (i = 0; i < BMLEN; i++) { | 121 | bool ath9k_is_world_regd(struct ath_hal *ah) |
59 | if (bitmask[i] != 0) | 122 | { |
60 | return false; | 123 | return isWwrSKU(ah); |
61 | } | ||
62 | return true; | ||
63 | } | 124 | } |
64 | 125 | ||
65 | static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) | 126 | const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) |
66 | { | 127 | { |
67 | u16 rd = ath9k_regd_get_eepromRD(ah); | 128 | /* this is the most restrictive */ |
68 | int i; | 129 | return &ath9k_world_regdom_64; |
130 | } | ||
69 | 131 | ||
70 | if (rd & COUNTRY_ERD_FLAG) { | 132 | const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah) |
71 | u16 cc = rd & ~COUNTRY_ERD_FLAG; | 133 | { |
72 | for (i = 0; i < ARRAY_SIZE(allCountries); i++) | 134 | switch (ah->regpair->regDmnEnum) { |
73 | if (allCountries[i].countryCode == cc) | 135 | case 0x60: |
74 | return true; | 136 | case 0x61: |
75 | } else { | 137 | case 0x62: |
76 | for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) | 138 | return &ath9k_world_regdom_60_61_62; |
77 | if (regDomainPairs[i].regDmnEnum == rd) | 139 | case 0x63: |
78 | return true; | 140 | case 0x65: |
141 | return &ath9k_world_regdom_63_65; | ||
142 | case 0x64: | ||
143 | return &ath9k_world_regdom_64; | ||
144 | case 0x66: | ||
145 | case 0x69: | ||
146 | return &ath9k_world_regdom_66_69; | ||
147 | case 0x67: | ||
148 | case 0x68: | ||
149 | case 0x6A: | ||
150 | return &ath9k_world_regdom_67_68_6A; | ||
151 | default: | ||
152 | WARN_ON(1); | ||
153 | return ath9k_default_world_regdomain(); | ||
79 | } | 154 | } |
80 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
81 | "invalid regulatory domain/country code 0x%x\n", rd); | ||
82 | return false; | ||
83 | } | 155 | } |
84 | 156 | ||
85 | static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah) | 157 | /* Enable adhoc on 5 GHz if allowed by 11d */ |
158 | static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy, | ||
159 | enum reg_set_by setby) | ||
86 | { | 160 | { |
87 | u32 regcap; | 161 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
88 | 162 | struct ath_softc *sc = hw->priv; | |
89 | regcap = ah->ah_caps.reg_cap; | 163 | struct ieee80211_supported_band *sband; |
164 | const struct ieee80211_reg_rule *reg_rule; | ||
165 | struct ieee80211_channel *ch; | ||
166 | unsigned int i; | ||
167 | u32 bandwidth = 0; | ||
168 | int r; | ||
169 | |||
170 | if (setby != REGDOM_SET_BY_COUNTRY_IE) | ||
171 | return; | ||
172 | if (!test_bit(ATH9K_MODE_11A, | ||
173 | sc->sc_ah->ah_caps.wireless_modes)) | ||
174 | return; | ||
90 | 175 | ||
91 | if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND) | 176 | sband = wiphy->bands[IEEE80211_BAND_5GHZ]; |
92 | return true; | 177 | for (i = 0; i < sband->n_channels; i++) { |
93 | else | 178 | ch = &sband->channels[i]; |
94 | return false; | 179 | r = freq_reg_info(wiphy, ch->center_freq, |
180 | &bandwidth, ®_rule); | ||
181 | if (r) | ||
182 | continue; | ||
183 | /* If 11d had a rule for this channel ensure we enable adhoc | ||
184 | * if it allows us to use it. Note that we would have disabled | ||
185 | * it by applying our static world regdomain by default during | ||
186 | * probe */ | ||
187 | if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) | ||
188 | ch->flags &= ~NL80211_RRF_NO_IBSS; | ||
189 | } | ||
95 | } | 190 | } |
96 | 191 | ||
97 | static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, | 192 | /* Allows active scan scan on Ch 12 and 13 */ |
98 | u16 cc) | 193 | static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy, |
194 | enum reg_set_by setby) | ||
99 | { | 195 | { |
100 | u16 rd; | 196 | struct ieee80211_supported_band *sband; |
101 | int i; | 197 | struct ieee80211_channel *ch; |
102 | 198 | const struct ieee80211_reg_rule *reg_rule; | |
103 | if (cc == CTRY_DEFAULT) | 199 | u32 bandwidth = 0; |
104 | return true; | 200 | int r; |
105 | if (cc == CTRY_DEBUG) | 201 | |
106 | return true; | 202 | /* Force passive scan on Channels 12-13 */ |
203 | sband = wiphy->bands[IEEE80211_BAND_2GHZ]; | ||
204 | |||
205 | /* If no country IE has been received always enable active scan | ||
206 | * on these channels */ | ||
207 | if (setby != REGDOM_SET_BY_COUNTRY_IE) { | ||
208 | ch = &sband->channels[11]; /* CH 12 */ | ||
209 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) | ||
210 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | ||
211 | ch = &sband->channels[12]; /* CH 13 */ | ||
212 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) | ||
213 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | ||
214 | return; | ||
215 | } | ||
107 | 216 | ||
108 | rd = ath9k_regd_get_eepromRD(ah); | 217 | /* If a country IE has been recieved check its rule for this |
109 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd); | 218 | * channel first before enabling active scan. The passive scan |
219 | * would have been enforced by the initial probe processing on | ||
220 | * our custom regulatory domain. */ | ||
110 | 221 | ||
111 | if (rd & COUNTRY_ERD_FLAG) { | 222 | ch = &sband->channels[11]; /* CH 12 */ |
112 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 223 | r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); |
113 | "EEPROM setting is country code %u\n", | 224 | if (!r) { |
114 | rd & ~COUNTRY_ERD_FLAG); | 225 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) |
115 | return cc == (rd & ~COUNTRY_ERD_FLAG); | 226 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
227 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; | ||
116 | } | 228 | } |
117 | 229 | ||
118 | for (i = 0; i < ARRAY_SIZE(allCountries); i++) { | 230 | ch = &sband->channels[12]; /* CH 13 */ |
119 | if (cc == allCountries[i].countryCode) { | 231 | r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); |
120 | #ifdef AH_SUPPORT_11D | 232 | if (!r) { |
121 | if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) | 233 | if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) |
122 | return true; | 234 | if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) |
123 | #endif | 235 | ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; |
124 | if (allCountries[i].regDmnEnum == rd || | ||
125 | rd == DEBUG_REG_DMN || rd == NO_ENUMRD) | ||
126 | return true; | ||
127 | } | ||
128 | } | 236 | } |
129 | return false; | ||
130 | } | 237 | } |
131 | 238 | ||
132 | static void | 239 | /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ |
133 | ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, | 240 | void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) |
134 | struct country_code_to_enum_rd *country, | ||
135 | struct regDomain *rd5GHz, | ||
136 | unsigned long *modes_allowed) | ||
137 | { | 241 | { |
138 | bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX); | 242 | struct ieee80211_supported_band *sband; |
243 | struct ieee80211_channel *ch; | ||
244 | unsigned int i; | ||
139 | 245 | ||
140 | if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) && | 246 | if (!wiphy->bands[IEEE80211_BAND_5GHZ]) |
141 | (!country->allow11g)) | 247 | return; |
142 | clear_bit(ATH9K_MODE_11G, modes_allowed); | ||
143 | 248 | ||
144 | if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) && | 249 | sband = wiphy->bands[IEEE80211_BAND_5GHZ]; |
145 | (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a))) | ||
146 | clear_bit(ATH9K_MODE_11A, modes_allowed); | ||
147 | 250 | ||
148 | if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes) | 251 | for (i = 0; i < sband->n_channels; i++) { |
149 | && (!country->allow11ng20)) | 252 | ch = &sband->channels[i]; |
150 | clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed); | 253 | if (ch->center_freq < 5260) |
254 | continue; | ||
255 | if (ch->center_freq > 5700) | ||
256 | continue; | ||
257 | /* We always enable radar detection/DFS on this | ||
258 | * frequency range. Additionally we also apply on | ||
259 | * this frequency range: | ||
260 | * - If STA mode does not yet have DFS supports disable | ||
261 | * active scanning | ||
262 | * - If adhoc mode does not support DFS yet then | ||
263 | * disable adhoc in the frequency. | ||
264 | * - If AP mode does not yet support radar detection/DFS | ||
265 | * do not allow AP mode | ||
266 | */ | ||
267 | if (!(ch->flags & IEEE80211_CHAN_DISABLED)) | ||
268 | ch->flags |= IEEE80211_CHAN_RADAR | | ||
269 | IEEE80211_CHAN_NO_IBSS | | ||
270 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
271 | } | ||
272 | } | ||
151 | 273 | ||
152 | if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes) | 274 | void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) |
153 | && (!country->allow11na20)) | 275 | { |
154 | clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed); | 276 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
277 | struct ath_softc *sc = hw->priv; | ||
278 | struct ath_hal *ah = sc->sc_ah; | ||
279 | |||
280 | switch (ah->regpair->regDmnEnum) { | ||
281 | case 0x60: | ||
282 | case 0x63: | ||
283 | case 0x66: | ||
284 | case 0x67: | ||
285 | ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby); | ||
286 | break; | ||
287 | case 0x68: | ||
288 | ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby); | ||
289 | ath9k_reg_apply_active_scan_flags(wiphy, setby); | ||
290 | break; | ||
291 | } | ||
292 | return; | ||
293 | } | ||
155 | 294 | ||
156 | if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) && | 295 | int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) |
157 | (!country->allow11ng40)) | 296 | { |
158 | clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed); | 297 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
298 | struct ath_softc *sc = hw->priv; | ||
159 | 299 | ||
160 | if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) && | 300 | /* We always apply this */ |
161 | (!country->allow11ng40)) | 301 | ath9k_reg_apply_radar_flags(wiphy); |
162 | clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed); | ||
163 | 302 | ||
164 | if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) && | 303 | switch (request->initiator) { |
165 | (!country->allow11na40)) | 304 | case REGDOM_SET_BY_DRIVER: |
166 | clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed); | 305 | case REGDOM_SET_BY_INIT: |
306 | case REGDOM_SET_BY_CORE: | ||
307 | case REGDOM_SET_BY_USER: | ||
308 | break; | ||
309 | case REGDOM_SET_BY_COUNTRY_IE: | ||
310 | if (ath9k_is_world_regd(sc->sc_ah)) | ||
311 | ath9k_reg_apply_world_flags(wiphy, request->initiator); | ||
312 | break; | ||
313 | } | ||
167 | 314 | ||
168 | if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) && | 315 | return 0; |
169 | (!country->allow11na40)) | ||
170 | clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed); | ||
171 | } | 316 | } |
172 | 317 | ||
173 | bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) | 318 | bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) |
174 | { | 319 | { |
175 | u16 rd; | 320 | u16 rd = ath9k_regd_get_eepromRD(ah); |
176 | 321 | int i; | |
177 | rd = ath9k_regd_get_eepromRD(ah); | ||
178 | 322 | ||
179 | switch (rd) { | 323 | if (rd & COUNTRY_ERD_FLAG) { |
180 | case FCC4_FCCA: | 324 | /* EEPROM value is a country code */ |
181 | case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG): | 325 | u16 cc = rd & ~COUNTRY_ERD_FLAG; |
182 | return true; | 326 | for (i = 0; i < ARRAY_SIZE(allCountries); i++) |
183 | case DEBUG_REG_DMN: | 327 | if (allCountries[i].countryCode == cc) |
184 | case NO_ENUMRD: | 328 | return true; |
185 | if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49) | 329 | } else { |
186 | return true; | 330 | /* EEPROM value is a regpair value */ |
187 | break; | 331 | for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) |
332 | if (regDomainPairs[i].regDmnEnum == rd) | ||
333 | return true; | ||
188 | } | 334 | } |
335 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
336 | "invalid regulatory domain/country code 0x%x\n", rd); | ||
189 | return false; | 337 | return false; |
190 | } | 338 | } |
191 | 339 | ||
340 | /* EEPROM country code to regpair mapping */ | ||
192 | static struct country_code_to_enum_rd* | 341 | static struct country_code_to_enum_rd* |
193 | ath9k_regd_find_country(u16 countryCode) | 342 | ath9k_regd_find_country(u16 countryCode) |
194 | { | 343 | { |
@@ -201,10 +350,23 @@ ath9k_regd_find_country(u16 countryCode) | |||
201 | return NULL; | 350 | return NULL; |
202 | } | 351 | } |
203 | 352 | ||
353 | /* EEPROM rd code to regpair mapping */ | ||
354 | static struct country_code_to_enum_rd* | ||
355 | ath9k_regd_find_country_by_rd(int regdmn) | ||
356 | { | ||
357 | int i; | ||
358 | |||
359 | for (i = 0; i < ARRAY_SIZE(allCountries); i++) { | ||
360 | if (allCountries[i].regDmnEnum == regdmn) | ||
361 | return &allCountries[i]; | ||
362 | } | ||
363 | return NULL; | ||
364 | } | ||
365 | |||
366 | /* Returns the map of the EEPROM set RD to a country code */ | ||
204 | static u16 ath9k_regd_get_default_country(struct ath_hal *ah) | 367 | static u16 ath9k_regd_get_default_country(struct ath_hal *ah) |
205 | { | 368 | { |
206 | u16 rd; | 369 | u16 rd; |
207 | int i; | ||
208 | 370 | ||
209 | rd = ath9k_regd_get_eepromRD(ah); | 371 | rd = ath9k_regd_get_eepromRD(ah); |
210 | if (rd & COUNTRY_ERD_FLAG) { | 372 | if (rd & COUNTRY_ERD_FLAG) { |
@@ -216,798 +378,104 @@ static u16 ath9k_regd_get_default_country(struct ath_hal *ah) | |||
216 | return cc; | 378 | return cc; |
217 | } | 379 | } |
218 | 380 | ||
219 | for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) | ||
220 | if (regDomainPairs[i].regDmnEnum == rd) { | ||
221 | if (regDomainPairs[i].singleCC != 0) | ||
222 | return regDomainPairs[i].singleCC; | ||
223 | else | ||
224 | i = ARRAY_SIZE(regDomainPairs); | ||
225 | } | ||
226 | return CTRY_DEFAULT; | 381 | return CTRY_DEFAULT; |
227 | } | 382 | } |
228 | 383 | ||
229 | static bool ath9k_regd_is_valid_reg_domain(int regDmn, | 384 | static struct reg_dmn_pair_mapping* |
230 | struct regDomain *rd) | 385 | ath9k_get_regpair(int regdmn) |
231 | { | ||
232 | int i; | ||
233 | |||
234 | for (i = 0; i < ARRAY_SIZE(regDomains); i++) { | ||
235 | if (regDomains[i].regDmnEnum == regDmn) { | ||
236 | if (rd != NULL) { | ||
237 | memcpy(rd, ®Domains[i], | ||
238 | sizeof(struct regDomain)); | ||
239 | } | ||
240 | return true; | ||
241 | } | ||
242 | } | ||
243 | return false; | ||
244 | } | ||
245 | |||
246 | static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair) | ||
247 | { | 386 | { |
248 | int i; | 387 | int i; |
249 | 388 | ||
250 | if (regDmnPair == NO_ENUMRD) | 389 | if (regdmn == NO_ENUMRD) |
251 | return false; | 390 | return NULL; |
252 | for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { | 391 | for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { |
253 | if (regDomainPairs[i].regDmnEnum == regDmnPair) | 392 | if (regDomainPairs[i].regDmnEnum == regdmn) |
254 | return true; | 393 | return ®DomainPairs[i]; |
255 | } | 394 | } |
256 | return false; | 395 | return NULL; |
257 | } | ||
258 | |||
259 | static bool | ||
260 | ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, | ||
261 | u16 channelFlag, struct regDomain *rd) | ||
262 | { | ||
263 | int i, found; | ||
264 | u64 flags = NO_REQ; | ||
265 | struct reg_dmn_pair_mapping *regPair = NULL; | ||
266 | int regOrg; | ||
267 | |||
268 | regOrg = regDmn; | ||
269 | if (regDmn == CTRY_DEFAULT) { | ||
270 | u16 rdnum; | ||
271 | rdnum = ath9k_regd_get_eepromRD(ah); | ||
272 | |||
273 | if (!(rdnum & COUNTRY_ERD_FLAG)) { | ||
274 | if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) || | ||
275 | ath9k_regd_is_valid_reg_domainPair(rdnum)) { | ||
276 | regDmn = rdnum; | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | |||
281 | if ((regDmn & MULTI_DOMAIN_MASK) == 0) { | ||
282 | for (i = 0, found = 0; | ||
283 | (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) { | ||
284 | if (regDomainPairs[i].regDmnEnum == regDmn) { | ||
285 | regPair = ®DomainPairs[i]; | ||
286 | found = 1; | ||
287 | } | ||
288 | } | ||
289 | if (!found) { | ||
290 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
291 | "Failed to find reg domain pair %u\n", regDmn); | ||
292 | return false; | ||
293 | } | ||
294 | if (!(channelFlag & CHANNEL_2GHZ)) { | ||
295 | regDmn = regPair->regDmn5GHz; | ||
296 | flags = regPair->flags5GHz; | ||
297 | } | ||
298 | if (channelFlag & CHANNEL_2GHZ) { | ||
299 | regDmn = regPair->regDmn2GHz; | ||
300 | flags = regPair->flags2GHz; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | found = ath9k_regd_is_valid_reg_domain(regDmn, rd); | ||
305 | if (!found) { | ||
306 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
307 | "Failed to find unitary reg domain %u\n", regDmn); | ||
308 | return false; | ||
309 | } else { | ||
310 | rd->pscan &= regPair->pscanMask; | ||
311 | if (((regOrg & MULTI_DOMAIN_MASK) == 0) && | ||
312 | (flags != NO_REQ)) { | ||
313 | rd->flags = flags; | ||
314 | } | ||
315 | |||
316 | rd->flags &= (channelFlag & CHANNEL_2GHZ) ? | ||
317 | REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK; | ||
318 | return true; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask) | ||
323 | { | ||
324 | int byteOffset, bitnum; | ||
325 | u64 val; | ||
326 | |||
327 | byteOffset = bit / 64; | ||
328 | bitnum = bit - byteOffset * 64; | ||
329 | val = ((u64) 1) << bitnum; | ||
330 | if (bitmask[byteOffset] & val) | ||
331 | return true; | ||
332 | else | ||
333 | return false; | ||
334 | } | ||
335 | |||
336 | static void | ||
337 | ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids, | ||
338 | u32 *nregids, u8 regclassid) | ||
339 | { | ||
340 | int i; | ||
341 | |||
342 | if (regclassid == 0) | ||
343 | return; | ||
344 | |||
345 | for (i = 0; i < maxregids; i++) { | ||
346 | if (regclassids[i] == regclassid) | ||
347 | return; | ||
348 | if (regclassids[i] == 0) | ||
349 | break; | ||
350 | } | ||
351 | |||
352 | if (i == maxregids) | ||
353 | return; | ||
354 | else { | ||
355 | regclassids[i] = regclassid; | ||
356 | *nregids += 1; | ||
357 | } | ||
358 | |||
359 | return; | ||
360 | } | ||
361 | |||
362 | static bool | ||
363 | ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah, | ||
364 | enum reg_ext_bitmap bit) | ||
365 | { | ||
366 | return (ah->ah_currentRDExt & (1 << bit)) ? true : false; | ||
367 | } | ||
368 | |||
369 | #ifdef ATH_NF_PER_CHAN | ||
370 | |||
371 | static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans, | ||
372 | int nchans) | ||
373 | { | ||
374 | int i, j, next; | ||
375 | |||
376 | for (next = 0; next < nchans; next++) { | ||
377 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
378 | ichans[next].nfCalHist[i].currIndex = 0; | ||
379 | ichans[next].nfCalHist[i].privNF = | ||
380 | AR_PHY_CCA_MAX_GOOD_VALUE; | ||
381 | ichans[next].nfCalHist[i].invalidNFcount = | ||
382 | AR_PHY_CCA_FILTERWINDOW_LENGTH; | ||
383 | for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { | ||
384 | ichans[next].nfCalHist[i].nfCalBuffer[j] = | ||
385 | AR_PHY_CCA_MAX_GOOD_VALUE; | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | #endif | ||
391 | |||
392 | static int ath9k_regd_is_chan_present(struct ath_hal *ah, | ||
393 | u16 c) | ||
394 | { | ||
395 | int i; | ||
396 | |||
397 | for (i = 0; i < 150; i++) { | ||
398 | if (!ah->ah_channels[i].channel) | ||
399 | return -1; | ||
400 | else if (ah->ah_channels[i].channel == c) | ||
401 | return i; | ||
402 | } | ||
403 | |||
404 | return -1; | ||
405 | } | ||
406 | |||
407 | static bool | ||
408 | ath9k_regd_add_channel(struct ath_hal *ah, | ||
409 | u16 c, | ||
410 | u16 c_lo, | ||
411 | u16 c_hi, | ||
412 | u16 maxChan, | ||
413 | u8 ctl, | ||
414 | int pos, | ||
415 | struct regDomain rd5GHz, | ||
416 | struct RegDmnFreqBand *fband, | ||
417 | struct regDomain *rd, | ||
418 | const struct cmode *cm, | ||
419 | struct ath9k_channel *ichans, | ||
420 | bool enableExtendedChannels) | ||
421 | { | ||
422 | struct ath9k_channel *chan; | ||
423 | int ret; | ||
424 | u32 channelFlags = 0; | ||
425 | u8 privFlags = 0; | ||
426 | |||
427 | if (!(c_lo <= c && c <= c_hi)) { | ||
428 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
429 | "c %u out of range [%u..%u]\n", | ||
430 | c, c_lo, c_hi); | ||
431 | return false; | ||
432 | } | ||
433 | if ((fband->channelBW == CHANNEL_HALF_BW) && | ||
434 | !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) { | ||
435 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
436 | "Skipping %u half rate channel\n", c); | ||
437 | return false; | ||
438 | } | ||
439 | |||
440 | if ((fband->channelBW == CHANNEL_QUARTER_BW) && | ||
441 | !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) { | ||
442 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
443 | "Skipping %u quarter rate channel\n", c); | ||
444 | return false; | ||
445 | } | ||
446 | |||
447 | if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { | ||
448 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
449 | "c %u > maxChan %u\n", c, maxChan); | ||
450 | return false; | ||
451 | } | ||
452 | |||
453 | if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) { | ||
454 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
455 | "Skipping ecm channel\n"); | ||
456 | return false; | ||
457 | } | ||
458 | |||
459 | if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) { | ||
460 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
461 | "Skipping HOSTAP channel\n"); | ||
462 | return false; | ||
463 | } | ||
464 | |||
465 | if (IS_HT40_MODE(cm->mode) && | ||
466 | !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) && | ||
467 | (fband->useDfs) && | ||
468 | (rd->conformanceTestLimit != MKK)) { | ||
469 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
470 | "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n"); | ||
471 | return false; | ||
472 | } | ||
473 | |||
474 | if (IS_HT40_MODE(cm->mode) && | ||
475 | !(ath9k_regd_get_eeprom_reg_ext_bits(ah, | ||
476 | REG_EXT_JAPAN_NONDFS_HT40)) && | ||
477 | !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) { | ||
478 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
479 | "Skipping HT40 channel (en_jap_ht40 = 0)\n"); | ||
480 | return false; | ||
481 | } | ||
482 | |||
483 | if (IS_HT40_MODE(cm->mode) && | ||
484 | !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) && | ||
485 | (fband->useDfs) && | ||
486 | (rd->conformanceTestLimit == MKK)) { | ||
487 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
488 | "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n"); | ||
489 | return false; | ||
490 | } | ||
491 | |||
492 | /* Calculate channel flags */ | ||
493 | |||
494 | channelFlags = cm->flags; | ||
495 | |||
496 | switch (fband->channelBW) { | ||
497 | case CHANNEL_HALF_BW: | ||
498 | channelFlags |= CHANNEL_HALF; | ||
499 | break; | ||
500 | case CHANNEL_QUARTER_BW: | ||
501 | channelFlags |= CHANNEL_QUARTER; | ||
502 | break; | ||
503 | } | ||
504 | |||
505 | if (fband->usePassScan & rd->pscan) | ||
506 | channelFlags |= CHANNEL_PASSIVE; | ||
507 | else | ||
508 | channelFlags &= ~CHANNEL_PASSIVE; | ||
509 | if (fband->useDfs & rd->dfsMask) | ||
510 | privFlags = CHANNEL_DFS; | ||
511 | else | ||
512 | privFlags = 0; | ||
513 | if (rd->flags & LIMIT_FRAME_4MS) | ||
514 | privFlags |= CHANNEL_4MS_LIMIT; | ||
515 | if (privFlags & CHANNEL_DFS) | ||
516 | privFlags |= CHANNEL_DISALLOW_ADHOC; | ||
517 | if (rd->flags & ADHOC_PER_11D) | ||
518 | privFlags |= CHANNEL_PER_11D_ADHOC; | ||
519 | |||
520 | if (channelFlags & CHANNEL_PASSIVE) { | ||
521 | if ((c < 2412) || (c > 2462)) { | ||
522 | if (rd5GHz.regDmnEnum == MKK1 || | ||
523 | rd5GHz.regDmnEnum == MKK2) { | ||
524 | u32 regcap = ah->ah_caps.reg_cap; | ||
525 | if (!(regcap & | ||
526 | (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | | ||
527 | AR_EEPROM_EEREGCAP_EN_KK_U2 | | ||
528 | AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) && | ||
529 | isUNII1OddChan(c)) { | ||
530 | channelFlags &= ~CHANNEL_PASSIVE; | ||
531 | } else { | ||
532 | privFlags |= CHANNEL_DISALLOW_ADHOC; | ||
533 | } | ||
534 | } else { | ||
535 | privFlags |= CHANNEL_DISALLOW_ADHOC; | ||
536 | } | ||
537 | } | ||
538 | } | ||
539 | |||
540 | if ((cm->mode == ATH9K_MODE_11A) || | ||
541 | (cm->mode == ATH9K_MODE_11NA_HT20) || | ||
542 | (cm->mode == ATH9K_MODE_11NA_HT40PLUS) || | ||
543 | (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) { | ||
544 | if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A)) | ||
545 | privFlags |= CHANNEL_DISALLOW_ADHOC; | ||
546 | } | ||
547 | |||
548 | /* Fill in channel details */ | ||
549 | |||
550 | ret = ath9k_regd_is_chan_present(ah, c); | ||
551 | if (ret == -1) { | ||
552 | chan = &ah->ah_channels[pos]; | ||
553 | chan->channel = c; | ||
554 | chan->maxRegTxPower = fband->powerDfs; | ||
555 | chan->antennaMax = fband->antennaMax; | ||
556 | chan->regDmnFlags = rd->flags; | ||
557 | chan->maxTxPower = AR5416_MAX_RATE_POWER; | ||
558 | chan->minTxPower = AR5416_MAX_RATE_POWER; | ||
559 | chan->channelFlags = channelFlags; | ||
560 | chan->privFlags = privFlags; | ||
561 | } else { | ||
562 | chan = &ah->ah_channels[ret]; | ||
563 | chan->channelFlags |= channelFlags; | ||
564 | chan->privFlags |= privFlags; | ||
565 | } | ||
566 | |||
567 | /* Set CTLs */ | ||
568 | |||
569 | if ((cm->flags & CHANNEL_ALL) == CHANNEL_A) | ||
570 | chan->conformanceTestLimit[0] = ctl; | ||
571 | else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B) | ||
572 | chan->conformanceTestLimit[1] = ctl; | ||
573 | else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G) | ||
574 | chan->conformanceTestLimit[2] = ctl; | ||
575 | |||
576 | return (ret == -1) ? true : false; | ||
577 | } | ||
578 | |||
579 | static bool ath9k_regd_japan_check(struct ath_hal *ah, | ||
580 | int b, | ||
581 | struct regDomain *rd5GHz) | ||
582 | { | ||
583 | bool skipband = false; | ||
584 | int i; | ||
585 | u32 regcap; | ||
586 | |||
587 | for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) { | ||
588 | if (j_bandcheck[i].freqbandbit == b) { | ||
589 | regcap = ah->ah_caps.reg_cap; | ||
590 | if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) { | ||
591 | skipband = true; | ||
592 | } else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) || | ||
593 | (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) { | ||
594 | rd5GHz->dfsMask |= DFS_MKK4; | ||
595 | rd5GHz->pscan |= PSCAN_MKK3; | ||
596 | } | ||
597 | break; | ||
598 | } | ||
599 | } | ||
600 | |||
601 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
602 | "Skipping %d freq band\n", j_bandcheck[i].freqbandbit); | ||
603 | |||
604 | return skipband; | ||
605 | } | 396 | } |
606 | 397 | ||
607 | bool | 398 | int ath9k_regd_init(struct ath_hal *ah) |
608 | ath9k_regd_init_channels(struct ath_hal *ah, | ||
609 | u32 maxchans, | ||
610 | u32 *nchans, u8 *regclassids, | ||
611 | u32 maxregids, u32 *nregids, u16 cc, | ||
612 | bool enableOutdoor, | ||
613 | bool enableExtendedChannels) | ||
614 | { | 399 | { |
615 | u16 maxChan = 7000; | ||
616 | struct country_code_to_enum_rd *country = NULL; | 400 | struct country_code_to_enum_rd *country = NULL; |
617 | struct regDomain rd5GHz, rd2GHz; | ||
618 | const struct cmode *cm; | ||
619 | struct ath9k_channel *ichans = &ah->ah_channels[0]; | ||
620 | int next = 0, b; | ||
621 | u8 ctl; | ||
622 | int regdmn; | 401 | int regdmn; |
623 | u16 chanSep; | ||
624 | unsigned long *modes_avail; | ||
625 | DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX); | ||
626 | |||
627 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc, | ||
628 | enableOutdoor ? "Enable outdoor" : "", | ||
629 | enableExtendedChannels ? "Enable ecm" : ""); | ||
630 | |||
631 | if (!ath9k_regd_is_ccode_valid(ah, cc)) { | ||
632 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
633 | "Invalid country code %d\n", cc); | ||
634 | return false; | ||
635 | } | ||
636 | 402 | ||
637 | if (!ath9k_regd_is_eeprom_valid(ah)) { | 403 | if (!ath9k_regd_is_eeprom_valid(ah)) { |
638 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 404 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
639 | "Invalid EEPROM contents\n"); | 405 | "Invalid EEPROM contents\n"); |
640 | return false; | 406 | return -EINVAL; |
641 | } | 407 | } |
642 | 408 | ||
643 | ah->ah_countryCode = ath9k_regd_get_default_country(ah); | 409 | ah->ah_countryCode = ath9k_regd_get_default_country(ah); |
644 | 410 | ||
645 | if (ah->ah_countryCode == CTRY_DEFAULT) { | 411 | if (ah->ah_countryCode == CTRY_DEFAULT && |
646 | ah->ah_countryCode = cc & COUNTRY_CODE_MASK; | 412 | ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT) |
647 | if ((ah->ah_countryCode == CTRY_DEFAULT) && | 413 | ah->ah_countryCode = CTRY_UNITED_STATES; |
648 | (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) { | ||
649 | ah->ah_countryCode = CTRY_UNITED_STATES; | ||
650 | } | ||
651 | } | ||
652 | 414 | ||
653 | #ifdef AH_SUPPORT_11D | ||
654 | if (ah->ah_countryCode == CTRY_DEFAULT) { | 415 | if (ah->ah_countryCode == CTRY_DEFAULT) { |
655 | regdmn = ath9k_regd_get_eepromRD(ah); | 416 | regdmn = ath9k_regd_get_eepromRD(ah); |
656 | country = NULL; | 417 | country = NULL; |
657 | } else { | 418 | } else { |
658 | #endif | ||
659 | country = ath9k_regd_find_country(ah->ah_countryCode); | 419 | country = ath9k_regd_find_country(ah->ah_countryCode); |
660 | if (country == NULL) { | 420 | if (country == NULL) { |
661 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 421 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
662 | "Country is NULL!!!!, cc= %d\n", | 422 | "Country is NULL!!!!, cc= %d\n", |
663 | ah->ah_countryCode); | 423 | ah->ah_countryCode); |
664 | return false; | 424 | return -EINVAL; |
665 | } else { | 425 | } else |
666 | regdmn = country->regDmnEnum; | 426 | regdmn = country->regDmnEnum; |
667 | #ifdef AH_SUPPORT_11D | ||
668 | if (((ath9k_regd_get_eepromRD(ah) & | ||
669 | WORLD_SKU_MASK) == WORLD_SKU_PREFIX) && | ||
670 | (cc == CTRY_UNITED_STATES)) { | ||
671 | if (!isWwrSKU_NoMidband(ah) | ||
672 | && ath9k_regd_is_fcc_midband_supported(ah)) | ||
673 | regdmn = FCC3_FCCA; | ||
674 | else | ||
675 | regdmn = FCC1_FCCA; | ||
676 | } | ||
677 | #endif | ||
678 | } | ||
679 | #ifdef AH_SUPPORT_11D | ||
680 | } | ||
681 | #endif | ||
682 | if (!ath9k_regd_get_wmode_regdomain(ah, | ||
683 | regdmn, | ||
684 | ~CHANNEL_2GHZ, | ||
685 | &rd5GHz)) { | ||
686 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
687 | "Couldn't find unitary " | ||
688 | "5GHz reg domain for country %u\n", | ||
689 | ah->ah_countryCode); | ||
690 | return false; | ||
691 | } | ||
692 | if (!ath9k_regd_get_wmode_regdomain(ah, | ||
693 | regdmn, | ||
694 | CHANNEL_2GHZ, | ||
695 | &rd2GHz)) { | ||
696 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
697 | "Couldn't find unitary 2GHz " | ||
698 | "reg domain for country %u\n", | ||
699 | ah->ah_countryCode); | ||
700 | return false; | ||
701 | } | 427 | } |
702 | 428 | ||
703 | if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) || | 429 | ah->ah_currentRDInUse = regdmn; |
704 | (rd5GHz.regDmnEnum == FCC2))) { | 430 | ah->regpair = ath9k_get_regpair(regdmn); |
705 | if (ath9k_regd_is_fcc_midband_supported(ah)) { | ||
706 | if (!ath9k_regd_get_wmode_regdomain(ah, | ||
707 | FCC3_FCCA, | ||
708 | ~CHANNEL_2GHZ, | ||
709 | &rd5GHz)) { | ||
710 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
711 | "Couldn't find unitary 5GHz " | ||
712 | "reg domain for country %u\n", | ||
713 | ah->ah_countryCode); | ||
714 | return false; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | |||
719 | if (country == NULL) { | ||
720 | modes_avail = ah->ah_caps.wireless_modes; | ||
721 | } else { | ||
722 | ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed); | ||
723 | modes_avail = modes_allowed; | ||
724 | |||
725 | if (!enableOutdoor) | ||
726 | maxChan = country->outdoorChanStart; | ||
727 | } | ||
728 | |||
729 | next = 0; | ||
730 | |||
731 | if (maxchans > ARRAY_SIZE(ah->ah_channels)) | ||
732 | maxchans = ARRAY_SIZE(ah->ah_channels); | ||
733 | |||
734 | for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) { | ||
735 | u16 c, c_hi, c_lo; | ||
736 | u64 *channelBM = NULL; | ||
737 | struct regDomain *rd = NULL; | ||
738 | struct RegDmnFreqBand *fband = NULL, *freqs; | ||
739 | int8_t low_adj = 0, hi_adj = 0; | ||
740 | |||
741 | if (!test_bit(cm->mode, modes_avail)) { | ||
742 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
743 | "!avail mode %d flags 0x%x\n", | ||
744 | cm->mode, cm->flags); | ||
745 | continue; | ||
746 | } | ||
747 | if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { | ||
748 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
749 | "channels 0x%x not supported " | ||
750 | "by hardware\n", cm->flags); | ||
751 | continue; | ||
752 | } | ||
753 | |||
754 | switch (cm->mode) { | ||
755 | case ATH9K_MODE_11A: | ||
756 | case ATH9K_MODE_11NA_HT20: | ||
757 | case ATH9K_MODE_11NA_HT40PLUS: | ||
758 | case ATH9K_MODE_11NA_HT40MINUS: | ||
759 | rd = &rd5GHz; | ||
760 | channelBM = rd->chan11a; | ||
761 | freqs = ®Dmn5GhzFreq[0]; | ||
762 | ctl = rd->conformanceTestLimit; | ||
763 | break; | ||
764 | case ATH9K_MODE_11B: | ||
765 | rd = &rd2GHz; | ||
766 | channelBM = rd->chan11b; | ||
767 | freqs = ®Dmn2GhzFreq[0]; | ||
768 | ctl = rd->conformanceTestLimit | CTL_11B; | ||
769 | break; | ||
770 | case ATH9K_MODE_11G: | ||
771 | case ATH9K_MODE_11NG_HT20: | ||
772 | case ATH9K_MODE_11NG_HT40PLUS: | ||
773 | case ATH9K_MODE_11NG_HT40MINUS: | ||
774 | rd = &rd2GHz; | ||
775 | channelBM = rd->chan11g; | ||
776 | freqs = ®Dmn2Ghz11gFreq[0]; | ||
777 | ctl = rd->conformanceTestLimit | CTL_11G; | ||
778 | break; | ||
779 | default: | ||
780 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
781 | "Unknown HAL mode 0x%x\n", cm->mode); | ||
782 | continue; | ||
783 | } | ||
784 | |||
785 | if (ath9k_regd_is_chan_bm_zero(channelBM)) | ||
786 | continue; | ||
787 | |||
788 | if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) || | ||
789 | (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) { | ||
790 | hi_adj = -20; | ||
791 | } | ||
792 | |||
793 | if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) || | ||
794 | (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) { | ||
795 | low_adj = 20; | ||
796 | } | ||
797 | |||
798 | /* XXX: Add a helper here instead */ | ||
799 | for (b = 0; b < 64 * BMLEN; b++) { | ||
800 | if (ath9k_regd_is_bit_set(b, channelBM)) { | ||
801 | fband = &freqs[b]; | ||
802 | if (rd5GHz.regDmnEnum == MKK1 | ||
803 | || rd5GHz.regDmnEnum == MKK2) { | ||
804 | if (ath9k_regd_japan_check(ah, | ||
805 | b, | ||
806 | &rd5GHz)) | ||
807 | continue; | ||
808 | } | ||
809 | |||
810 | ath9k_regd_add_reg_classid(regclassids, | ||
811 | maxregids, | ||
812 | nregids, | ||
813 | fband-> | ||
814 | regClassId); | ||
815 | |||
816 | if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) { | ||
817 | chanSep = 40; | ||
818 | if (fband->lowChannel == 5280) | ||
819 | low_adj += 20; | ||
820 | |||
821 | if (fband->lowChannel == 5170) | ||
822 | continue; | ||
823 | } else | ||
824 | chanSep = fband->channelSep; | ||
825 | |||
826 | for (c = fband->lowChannel + low_adj; | ||
827 | ((c <= (fband->highChannel + hi_adj)) && | ||
828 | (c >= (fband->lowChannel + low_adj))); | ||
829 | c += chanSep) { | ||
830 | if (next >= maxchans) { | ||
831 | DPRINTF(ah->ah_sc, | ||
832 | ATH_DBG_REGULATORY, | ||
833 | "too many channels " | ||
834 | "for channel table\n"); | ||
835 | goto done; | ||
836 | } | ||
837 | if (ath9k_regd_add_channel(ah, | ||
838 | c, c_lo, c_hi, | ||
839 | maxChan, ctl, | ||
840 | next, | ||
841 | rd5GHz, | ||
842 | fband, rd, cm, | ||
843 | ichans, | ||
844 | enableExtendedChannels)) | ||
845 | next++; | ||
846 | } | ||
847 | if (IS_HT40_MODE(cm->mode) && | ||
848 | (fband->lowChannel == 5280)) { | ||
849 | low_adj -= 20; | ||
850 | } | ||
851 | } | ||
852 | } | ||
853 | } | ||
854 | done: | ||
855 | if (next != 0) { | ||
856 | int i; | ||
857 | 431 | ||
858 | if (next > ARRAY_SIZE(ah->ah_channels)) { | 432 | if (!ah->regpair) { |
859 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 433 | DPRINTF(ah->ah_sc, ATH_DBG_FATAL, |
860 | "too many channels %u; truncating to %u\n", | 434 | "No regulatory domain pair found, cannot continue\n"); |
861 | next, (int) ARRAY_SIZE(ah->ah_channels)); | 435 | return -EINVAL; |
862 | next = ARRAY_SIZE(ah->ah_channels); | ||
863 | } | ||
864 | #ifdef ATH_NF_PER_CHAN | ||
865 | ath9k_regd_init_rf_buffer(ichans, next); | ||
866 | #endif | ||
867 | ath9k_regd_sort(ichans, next, | ||
868 | sizeof(struct ath9k_channel), | ||
869 | ath9k_regd_chansort); | ||
870 | |||
871 | ah->ah_nchan = next; | ||
872 | |||
873 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n"); | ||
874 | for (i = 0; i < next; i++) { | ||
875 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
876 | "chan: %d flags: 0x%x\n", | ||
877 | ah->ah_channels[i].channel, | ||
878 | ah->ah_channels[i].channelFlags); | ||
879 | } | ||
880 | } | 436 | } |
881 | *nchans = next; | ||
882 | 437 | ||
883 | ah->ah_countryCode = ah->ah_countryCode; | 438 | if (!country) |
439 | country = ath9k_regd_find_country_by_rd(regdmn); | ||
884 | 440 | ||
885 | ah->ah_currentRDInUse = regdmn; | 441 | if (country) { |
886 | ah->ah_currentRD5G = rd5GHz.regDmnEnum; | 442 | ah->alpha2[0] = country->isoName[0]; |
887 | ah->ah_currentRD2G = rd2GHz.regDmnEnum; | 443 | ah->alpha2[1] = country->isoName[1]; |
888 | if (country == NULL) { | ||
889 | ah->ah_iso[0] = 0; | ||
890 | ah->ah_iso[1] = 0; | ||
891 | } else { | 444 | } else { |
892 | ah->ah_iso[0] = country->isoName[0]; | 445 | ah->alpha2[0] = '0'; |
893 | ah->ah_iso[1] = country->isoName[1]; | 446 | ah->alpha2[1] = '0'; |
894 | } | 447 | } |
895 | 448 | ||
896 | return next != 0; | ||
897 | } | ||
898 | |||
899 | struct ath9k_channel* | ||
900 | ath9k_regd_check_channel(struct ath_hal *ah, | ||
901 | const struct ath9k_channel *c) | ||
902 | { | ||
903 | struct ath9k_channel *base, *cc; | ||
904 | |||
905 | int flags = c->channelFlags & CHAN_FLAGS; | ||
906 | int n, lim; | ||
907 | |||
908 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | 449 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, |
909 | "channel %u/0x%x (0x%x) requested\n", | 450 | "Country alpha2 being used: %c%c\n" |
910 | c->channel, c->channelFlags, flags); | 451 | "Regpair detected: 0x%0x\n", |
911 | 452 | ah->alpha2[0], ah->alpha2[1], | |
912 | cc = ah->ah_curchan; | 453 | ah->regpair->regDmnEnum); |
913 | if (cc != NULL && cc->channel == c->channel && | ||
914 | (cc->channelFlags & CHAN_FLAGS) == flags) { | ||
915 | if ((cc->privFlags & CHANNEL_INTERFERENCE) && | ||
916 | (cc->privFlags & CHANNEL_DFS)) | ||
917 | return NULL; | ||
918 | else | ||
919 | return cc; | ||
920 | } | ||
921 | 454 | ||
922 | base = ah->ah_channels; | 455 | return 0; |
923 | n = ah->ah_nchan; | ||
924 | |||
925 | for (lim = n; lim != 0; lim >>= 1) { | ||
926 | int d; | ||
927 | cc = &base[lim >> 1]; | ||
928 | d = c->channel - cc->channel; | ||
929 | if (d == 0) { | ||
930 | if ((cc->channelFlags & CHAN_FLAGS) == flags) { | ||
931 | if ((cc->privFlags & CHANNEL_INTERFERENCE) && | ||
932 | (cc->privFlags & CHANNEL_DFS)) | ||
933 | return NULL; | ||
934 | else | ||
935 | return cc; | ||
936 | } | ||
937 | d = flags - (cc->channelFlags & CHAN_FLAGS); | ||
938 | } | ||
939 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, | ||
940 | "channel %u/0x%x d %d\n", | ||
941 | cc->channel, cc->channelFlags, d); | ||
942 | if (d > 0) { | ||
943 | base = cc + 1; | ||
944 | lim--; | ||
945 | } | ||
946 | } | ||
947 | DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n", | ||
948 | c->channel, c->channelFlags); | ||
949 | return NULL; | ||
950 | } | ||
951 | |||
952 | u32 | ||
953 | ath9k_regd_get_antenna_allowed(struct ath_hal *ah, | ||
954 | struct ath9k_channel *chan) | ||
955 | { | ||
956 | struct ath9k_channel *ichan = NULL; | ||
957 | |||
958 | ichan = ath9k_regd_check_channel(ah, chan); | ||
959 | if (!ichan) | ||
960 | return 0; | ||
961 | |||
962 | return ichan->antennaMax; | ||
963 | } | 456 | } |
964 | 457 | ||
965 | u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) | 458 | u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) |
966 | { | 459 | { |
967 | u32 ctl = NO_CTL; | 460 | u32 ctl = NO_CTL; |
968 | struct ath9k_channel *ichan; | ||
969 | 461 | ||
970 | if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) { | 462 | if (!ah->regpair || |
463 | (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah))) { | ||
971 | if (IS_CHAN_B(chan)) | 464 | if (IS_CHAN_B(chan)) |
972 | ctl = SD_NO_CTL | CTL_11B; | 465 | ctl = SD_NO_CTL | CTL_11B; |
973 | else if (IS_CHAN_G(chan)) | 466 | else if (IS_CHAN_G(chan)) |
974 | ctl = SD_NO_CTL | CTL_11G; | 467 | ctl = SD_NO_CTL | CTL_11G; |
975 | else | 468 | else |
976 | ctl = SD_NO_CTL | CTL_11A; | 469 | ctl = SD_NO_CTL | CTL_11A; |
977 | } else { | 470 | return ctl; |
978 | ichan = ath9k_regd_check_channel(ah, chan); | ||
979 | if (ichan != NULL) { | ||
980 | /* FIXME */ | ||
981 | if (IS_CHAN_A(ichan)) | ||
982 | ctl = ichan->conformanceTestLimit[0]; | ||
983 | else if (IS_CHAN_B(ichan)) | ||
984 | ctl = ichan->conformanceTestLimit[1]; | ||
985 | else if (IS_CHAN_G(ichan)) | ||
986 | ctl = ichan->conformanceTestLimit[2]; | ||
987 | |||
988 | if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B) | ||
989 | ctl = (ctl & ~0xf) | CTL_11G; | ||
990 | } | ||
991 | } | 471 | } |
992 | return ctl; | ||
993 | } | ||
994 | 472 | ||
995 | void ath9k_regd_get_current_country(struct ath_hal *ah, | 473 | if (IS_CHAN_B(chan)) |
996 | struct ath9k_country_entry *ctry) | 474 | ctl = ah->regpair->reg_2ghz_ctl | CTL_11B; |
997 | { | 475 | else if (IS_CHAN_G(chan)) |
998 | u16 rd = ath9k_regd_get_eepromRD(ah); | 476 | ctl = ah->regpair->reg_5ghz_ctl | CTL_11G; |
477 | else | ||
478 | ctl = ah->regpair->reg_5ghz_ctl | CTL_11A; | ||
999 | 479 | ||
1000 | ctry->isMultidomain = false; | 480 | return ctl; |
1001 | if (rd == CTRY_DEFAULT) | ||
1002 | ctry->isMultidomain = true; | ||
1003 | else if (!(rd & COUNTRY_ERD_FLAG)) | ||
1004 | ctry->isMultidomain = isWwrSKU(ah); | ||
1005 | |||
1006 | ctry->countryCode = ah->ah_countryCode; | ||
1007 | ctry->regDmnEnum = ah->ah_currentRD; | ||
1008 | ctry->regDmn5G = ah->ah_currentRD5G; | ||
1009 | ctry->regDmn2G = ah->ah_currentRD2G; | ||
1010 | ctry->iso[0] = ah->ah_iso[0]; | ||
1011 | ctry->iso[1] = ah->ah_iso[1]; | ||
1012 | ctry->iso[2] = ah->ah_iso[2]; | ||
1013 | } | 481 | } |
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h index 512d990aa7ea..ba2d2dfb0d1f 100644 --- a/drivers/net/wireless/ath9k/regd.h +++ b/drivers/net/wireless/ath9k/regd.h | |||
@@ -19,126 +19,14 @@ | |||
19 | 19 | ||
20 | #include "ath9k.h" | 20 | #include "ath9k.h" |
21 | 21 | ||
22 | #define BMLEN 2 | ||
23 | #define BMZERO {(u64) 0, (u64) 0} | ||
24 | |||
25 | #define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \ | ||
26 | {((((_fa >= 0) && (_fa < 64)) ? \ | ||
27 | (((u64) 1) << _fa) : (u64) 0) | \ | ||
28 | (((_fb >= 0) && (_fb < 64)) ? \ | ||
29 | (((u64) 1) << _fb) : (u64) 0) | \ | ||
30 | (((_fc >= 0) && (_fc < 64)) ? \ | ||
31 | (((u64) 1) << _fc) : (u64) 0) | \ | ||
32 | (((_fd >= 0) && (_fd < 64)) ? \ | ||
33 | (((u64) 1) << _fd) : (u64) 0) | \ | ||
34 | (((_fe >= 0) && (_fe < 64)) ? \ | ||
35 | (((u64) 1) << _fe) : (u64) 0) | \ | ||
36 | (((_ff >= 0) && (_ff < 64)) ? \ | ||
37 | (((u64) 1) << _ff) : (u64) 0) | \ | ||
38 | (((_fg >= 0) && (_fg < 64)) ? \ | ||
39 | (((u64) 1) << _fg) : (u64) 0) | \ | ||
40 | (((_fh >= 0) && (_fh < 64)) ? \ | ||
41 | (((u64) 1) << _fh) : (u64) 0) | \ | ||
42 | (((_fi >= 0) && (_fi < 64)) ? \ | ||
43 | (((u64) 1) << _fi) : (u64) 0) | \ | ||
44 | (((_fj >= 0) && (_fj < 64)) ? \ | ||
45 | (((u64) 1) << _fj) : (u64) 0) | \ | ||
46 | (((_fk >= 0) && (_fk < 64)) ? \ | ||
47 | (((u64) 1) << _fk) : (u64) 0) | \ | ||
48 | (((_fl >= 0) && (_fl < 64)) ? \ | ||
49 | (((u64) 1) << _fl) : (u64) 0) | \ | ||
50 | ((((_fa > 63) && (_fa < 128)) ? \ | ||
51 | (((u64) 1) << (_fa - 64)) : (u64) 0) | \ | ||
52 | (((_fb > 63) && (_fb < 128)) ? \ | ||
53 | (((u64) 1) << (_fb - 64)) : (u64) 0) | \ | ||
54 | (((_fc > 63) && (_fc < 128)) ? \ | ||
55 | (((u64) 1) << (_fc - 64)) : (u64) 0) | \ | ||
56 | (((_fd > 63) && (_fd < 128)) ? \ | ||
57 | (((u64) 1) << (_fd - 64)) : (u64) 0) | \ | ||
58 | (((_fe > 63) && (_fe < 128)) ? \ | ||
59 | (((u64) 1) << (_fe - 64)) : (u64) 0) | \ | ||
60 | (((_ff > 63) && (_ff < 128)) ? \ | ||
61 | (((u64) 1) << (_ff - 64)) : (u64) 0) | \ | ||
62 | (((_fg > 63) && (_fg < 128)) ? \ | ||
63 | (((u64) 1) << (_fg - 64)) : (u64) 0) | \ | ||
64 | (((_fh > 63) && (_fh < 128)) ? \ | ||
65 | (((u64) 1) << (_fh - 64)) : (u64) 0) | \ | ||
66 | (((_fi > 63) && (_fi < 128)) ? \ | ||
67 | (((u64) 1) << (_fi - 64)) : (u64) 0) | \ | ||
68 | (((_fj > 63) && (_fj < 128)) ? \ | ||
69 | (((u64) 1) << (_fj - 64)) : (u64) 0) | \ | ||
70 | (((_fk > 63) && (_fk < 128)) ? \ | ||
71 | (((u64) 1) << (_fk - 64)) : (u64) 0) | \ | ||
72 | (((_fl > 63) && (_fl < 128)) ? \ | ||
73 | (((u64) 1) << (_fl - 64)) : (u64) 0)))} | ||
74 | |||
75 | #define DEF_REGDMN FCC1_FCCA | ||
76 | #define DEF_DMN_5 FCC1 | ||
77 | #define DEF_DMN_2 FCCA | ||
78 | #define COUNTRY_ERD_FLAG 0x8000 | 22 | #define COUNTRY_ERD_FLAG 0x8000 |
79 | #define WORLDWIDE_ROAMING_FLAG 0x4000 | 23 | #define WORLDWIDE_ROAMING_FLAG 0x4000 |
80 | #define SUPER_DOMAIN_MASK 0x0fff | ||
81 | #define COUNTRY_CODE_MASK 0x3fff | ||
82 | #define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT) | ||
83 | #define CHANNEL_14 (2484) | ||
84 | #define IS_11G_CH14(_ch,_cf) \ | ||
85 | (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G)) | ||
86 | |||
87 | #define NO_PSCAN 0x0ULL | ||
88 | #define PSCAN_FCC 0x0000000000000001ULL | ||
89 | #define PSCAN_FCC_T 0x0000000000000002ULL | ||
90 | #define PSCAN_ETSI 0x0000000000000004ULL | ||
91 | #define PSCAN_MKK1 0x0000000000000008ULL | ||
92 | #define PSCAN_MKK2 0x0000000000000010ULL | ||
93 | #define PSCAN_MKKA 0x0000000000000020ULL | ||
94 | #define PSCAN_MKKA_G 0x0000000000000040ULL | ||
95 | #define PSCAN_ETSIA 0x0000000000000080ULL | ||
96 | #define PSCAN_ETSIB 0x0000000000000100ULL | ||
97 | #define PSCAN_ETSIC 0x0000000000000200ULL | ||
98 | #define PSCAN_WWR 0x0000000000000400ULL | ||
99 | #define PSCAN_MKKA1 0x0000000000000800ULL | ||
100 | #define PSCAN_MKKA1_G 0x0000000000001000ULL | ||
101 | #define PSCAN_MKKA2 0x0000000000002000ULL | ||
102 | #define PSCAN_MKKA2_G 0x0000000000004000ULL | ||
103 | #define PSCAN_MKK3 0x0000000000008000ULL | ||
104 | #define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL | ||
105 | #define IS_ECM_CHAN 0x8000000000000000ULL | ||
106 | 24 | ||
107 | #define isWwrSKU(_ah) \ | 25 | #define isWwrSKU(_ah) \ |
108 | (((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \ | 26 | (((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \ |
109 | WORLD_SKU_PREFIX) || \ | 27 | WORLD_SKU_PREFIX) || \ |
110 | (ath9k_regd_get_eepromRD(_ah) == WORLD)) | 28 | (ath9k_regd_get_eepromRD(_ah) == WORLD)) |
111 | 29 | ||
112 | #define isWwrSKU_NoMidband(_ah) \ | ||
113 | ((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \ | ||
114 | (ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \ | ||
115 | (ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC)) | ||
116 | |||
117 | #define isUNII1OddChan(ch) \ | ||
118 | ((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230)) | ||
119 | |||
120 | #define IS_HT40_MODE(_mode) \ | ||
121 | (((_mode == ATH9K_MODE_11NA_HT40PLUS || \ | ||
122 | _mode == ATH9K_MODE_11NG_HT40PLUS || \ | ||
123 | _mode == ATH9K_MODE_11NA_HT40MINUS || \ | ||
124 | _mode == ATH9K_MODE_11NG_HT40MINUS) ? true : false)) | ||
125 | |||
126 | #define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) | ||
127 | |||
128 | #define swap_array(_a, _b, _size) { \ | ||
129 | u8 *s = _b; \ | ||
130 | int i = _size; \ | ||
131 | do { \ | ||
132 | u8 tmp = *_a; \ | ||
133 | *_a++ = *s; \ | ||
134 | *s++ = tmp; \ | ||
135 | } while (--i); \ | ||
136 | _a -= _size; \ | ||
137 | } | ||
138 | |||
139 | |||
140 | #define HALF_MAXCHANBW 10 | ||
141 | |||
142 | #define MULTI_DOMAIN_MASK 0xFF00 | 30 | #define MULTI_DOMAIN_MASK 0xFF00 |
143 | 31 | ||
144 | #define WORLD_SKU_MASK 0x00F0 | 32 | #define WORLD_SKU_MASK 0x00F0 |
@@ -147,81 +35,16 @@ | |||
147 | #define CHANNEL_HALF_BW 10 | 35 | #define CHANNEL_HALF_BW 10 |
148 | #define CHANNEL_QUARTER_BW 5 | 36 | #define CHANNEL_QUARTER_BW 5 |
149 | 37 | ||
150 | typedef int ath_hal_cmp_t(const void *, const void *); | ||
151 | |||
152 | struct reg_dmn_pair_mapping { | 38 | struct reg_dmn_pair_mapping { |
153 | u16 regDmnEnum; | 39 | u16 regDmnEnum; |
154 | u16 regDmn5GHz; | 40 | u16 reg_5ghz_ctl; |
155 | u16 regDmn2GHz; | 41 | u16 reg_2ghz_ctl; |
156 | u32 flags5GHz; | ||
157 | u32 flags2GHz; | ||
158 | u64 pscanMask; | ||
159 | u16 singleCC; | ||
160 | }; | ||
161 | |||
162 | struct ccmap { | ||
163 | char isoName[3]; | ||
164 | u16 countryCode; | ||
165 | }; | 42 | }; |
166 | 43 | ||
167 | struct country_code_to_enum_rd { | 44 | struct country_code_to_enum_rd { |
168 | u16 countryCode; | 45 | u16 countryCode; |
169 | u16 regDmnEnum; | 46 | u16 regDmnEnum; |
170 | const char *isoName; | 47 | const char *isoName; |
171 | const char *name; | ||
172 | bool allow11g; | ||
173 | bool allow11aTurbo; | ||
174 | bool allow11gTurbo; | ||
175 | bool allow11ng20; | ||
176 | bool allow11ng40; | ||
177 | bool allow11na20; | ||
178 | bool allow11na40; | ||
179 | u16 outdoorChanStart; | ||
180 | }; | ||
181 | |||
182 | struct RegDmnFreqBand { | ||
183 | u16 lowChannel; | ||
184 | u16 highChannel; | ||
185 | u8 powerDfs; | ||
186 | u8 antennaMax; | ||
187 | u8 channelBW; | ||
188 | u8 channelSep; | ||
189 | u64 useDfs; | ||
190 | u64 usePassScan; | ||
191 | u8 regClassId; | ||
192 | }; | ||
193 | |||
194 | struct regDomain { | ||
195 | u16 regDmnEnum; | ||
196 | u8 conformanceTestLimit; | ||
197 | u64 dfsMask; | ||
198 | u64 pscan; | ||
199 | u32 flags; | ||
200 | u64 chan11a[BMLEN]; | ||
201 | u64 chan11a_turbo[BMLEN]; | ||
202 | u64 chan11a_dyn_turbo[BMLEN]; | ||
203 | u64 chan11b[BMLEN]; | ||
204 | u64 chan11g[BMLEN]; | ||
205 | u64 chan11g_turbo[BMLEN]; | ||
206 | }; | ||
207 | |||
208 | struct cmode { | ||
209 | u32 mode; | ||
210 | u32 flags; | ||
211 | }; | ||
212 | |||
213 | #define YES true | ||
214 | #define NO false | ||
215 | |||
216 | struct japan_bandcheck { | ||
217 | u16 freqbandbit; | ||
218 | u32 eepromflagtocheck; | ||
219 | }; | ||
220 | |||
221 | struct common_mode_power { | ||
222 | u16 lchan; | ||
223 | u16 hchan; | ||
224 | u8 pwrlvl; | ||
225 | }; | 48 | }; |
226 | 49 | ||
227 | enum CountryCode { | 50 | enum CountryCode { |
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h index 6df1b3b77c25..b41d0002f3fe 100644 --- a/drivers/net/wireless/ath9k/regd_common.h +++ b/drivers/net/wireless/ath9k/regd_common.h | |||
@@ -150,1766 +150,324 @@ enum EnumRd { | |||
150 | MKK9_MKKC = 0xFE, | 150 | MKK9_MKKC = 0xFE, |
151 | MKK9_MKKA2 = 0xFF, | 151 | MKK9_MKKA2 = 0xFF, |
152 | 152 | ||
153 | APL1 = 0x0150, | ||
154 | APL2 = 0x0250, | ||
155 | APL3 = 0x0350, | ||
156 | APL4 = 0x0450, | ||
157 | APL5 = 0x0550, | ||
158 | APL6 = 0x0650, | ||
159 | APL7 = 0x0750, | ||
160 | APL8 = 0x0850, | ||
161 | APL9 = 0x0950, | ||
162 | APL10 = 0x1050, | ||
163 | |||
164 | ETSI1 = 0x0130, | ||
165 | ETSI2 = 0x0230, | ||
166 | ETSI3 = 0x0330, | ||
167 | ETSI4 = 0x0430, | ||
168 | ETSI5 = 0x0530, | ||
169 | ETSI6 = 0x0630, | ||
170 | ETSIA = 0x0A30, | ||
171 | ETSIB = 0x0B30, | ||
172 | ETSIC = 0x0C30, | ||
173 | |||
174 | FCC1 = 0x0110, | ||
175 | FCC2 = 0x0120, | ||
176 | FCC3 = 0x0160, | ||
177 | FCC4 = 0x0165, | ||
178 | FCC5 = 0x0510, | ||
179 | FCC6 = 0x0610, | ||
180 | FCCA = 0x0A10, | ||
181 | |||
182 | APLD = 0x0D50, | ||
183 | |||
184 | MKK1 = 0x0140, | ||
185 | MKK2 = 0x0240, | ||
186 | MKK3 = 0x0340, | ||
187 | MKK4 = 0x0440, | ||
188 | MKK5 = 0x0540, | ||
189 | MKK6 = 0x0640, | ||
190 | MKK7 = 0x0740, | ||
191 | MKK8 = 0x0840, | ||
192 | MKK9 = 0x0940, | ||
193 | MKK10 = 0x0B40, | ||
194 | MKK11 = 0x1140, | ||
195 | MKK12 = 0x1240, | ||
196 | MKK13 = 0x0C40, | ||
197 | MKK14 = 0x1440, | ||
198 | MKK15 = 0x1540, | ||
199 | MKKA = 0x0A40, | ||
200 | MKKC = 0x0A50, | ||
201 | |||
202 | NULL1 = 0x0198, | ||
203 | WORLD = 0x0199, | 153 | WORLD = 0x0199, |
204 | DEBUG_REG_DMN = 0x01ff, | 154 | DEBUG_REG_DMN = 0x01ff, |
205 | }; | 155 | }; |
206 | 156 | ||
207 | enum { | 157 | enum ctl_group { |
208 | FCC = 0x10, | 158 | CTL_FCC = 0x10, |
209 | MKK = 0x40, | 159 | CTL_MKK = 0x40, |
210 | ETSI = 0x30, | 160 | CTL_ETSI = 0x30, |
211 | }; | ||
212 | |||
213 | enum { | ||
214 | NO_REQ = 0x00000000, | ||
215 | DISALLOW_ADHOC_11A = 0x00000001, | ||
216 | DISALLOW_ADHOC_11A_TURB = 0x00000002, | ||
217 | NEED_NFC = 0x00000004, | ||
218 | |||
219 | ADHOC_PER_11D = 0x00000008, | ||
220 | ADHOC_NO_11A = 0x00000010, | ||
221 | |||
222 | PUBLIC_SAFETY_DOMAIN = 0x00000020, | ||
223 | LIMIT_FRAME_4MS = 0x00000040, | ||
224 | |||
225 | NO_HOSTAP = 0x00000080, | ||
226 | |||
227 | REQ_MASK = 0x000000FF, | ||
228 | }; | 161 | }; |
229 | 162 | ||
230 | #define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \ | 163 | /* Regpair to CTL band mapping */ |
231 | (~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB))) | ||
232 | #define REG_DOMAIN_5GHZ_MASK REQ_MASK | ||
233 | |||
234 | static struct reg_dmn_pair_mapping regDomainPairs[] = { | 164 | static struct reg_dmn_pair_mapping regDomainPairs[] = { |
235 | {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, | 165 | /* regpair, 5 GHz CTL, 2 GHz CTL */ |
236 | PSCAN_DEFER, 0}, | 166 | {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN}, |
237 | {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 167 | {NULL1_WORLD, NO_CTL, CTL_ETSI}, |
238 | {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 168 | {NULL1_ETSIB, NO_CTL, CTL_ETSI}, |
239 | {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 169 | {NULL1_ETSIC, NO_CTL, CTL_ETSI}, |
240 | 170 | ||
241 | {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 171 | {FCC2_FCCA, CTL_FCC, CTL_FCC}, |
242 | {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 172 | {FCC2_WORLD, CTL_FCC, CTL_ETSI}, |
243 | {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 173 | {FCC2_ETSIC, CTL_FCC, CTL_ETSI}, |
244 | {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 174 | {FCC3_FCCA, CTL_FCC, CTL_FCC}, |
245 | {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 175 | {FCC3_WORLD, CTL_FCC, CTL_ETSI}, |
246 | {FCC4_FCCA, FCC4, FCCA, | 176 | {FCC4_FCCA, CTL_FCC, CTL_FCC}, |
247 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 177 | {FCC5_FCCA, CTL_FCC, CTL_FCC}, |
248 | 0}, | 178 | {FCC6_FCCA, CTL_FCC, CTL_FCC}, |
249 | {FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 179 | {FCC6_WORLD, CTL_FCC, CTL_ETSI}, |
250 | {FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 180 | |
251 | {FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 181 | {ETSI1_WORLD, CTL_ETSI, CTL_ETSI}, |
252 | 182 | {ETSI2_WORLD, CTL_ETSI, CTL_ETSI}, | |
253 | {ETSI1_WORLD, ETSI1, WORLD, | 183 | {ETSI3_WORLD, CTL_ETSI, CTL_ETSI}, |
254 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 184 | {ETSI4_WORLD, CTL_ETSI, CTL_ETSI}, |
255 | 0}, | 185 | {ETSI5_WORLD, CTL_ETSI, CTL_ETSI}, |
256 | {ETSI2_WORLD, ETSI2, WORLD, | 186 | {ETSI6_WORLD, CTL_ETSI, CTL_ETSI}, |
257 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 187 | |
258 | 0}, | 188 | /* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */ |
259 | {ETSI3_WORLD, ETSI3, WORLD, | 189 | {ETSI3_ETSIA, CTL_ETSI, CTL_ETSI}, |
260 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 190 | {FRANCE_RES, CTL_ETSI, CTL_ETSI}, |
261 | 0}, | 191 | |
262 | {ETSI4_WORLD, ETSI4, WORLD, | 192 | {FCC1_WORLD, CTL_FCC, CTL_ETSI}, |
263 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 193 | {FCC1_FCCA, CTL_FCC, CTL_FCC}, |
264 | 0}, | 194 | {APL1_WORLD, CTL_FCC, CTL_ETSI}, |
265 | {ETSI5_WORLD, ETSI5, WORLD, | 195 | {APL2_WORLD, CTL_FCC, CTL_ETSI}, |
266 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 196 | {APL3_WORLD, CTL_FCC, CTL_ETSI}, |
267 | 0}, | 197 | {APL4_WORLD, CTL_FCC, CTL_ETSI}, |
268 | {ETSI6_WORLD, ETSI6, WORLD, | 198 | {APL5_WORLD, CTL_FCC, CTL_ETSI}, |
269 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 199 | {APL6_WORLD, CTL_ETSI, CTL_ETSI}, |
270 | 0}, | 200 | {APL8_WORLD, CTL_ETSI, CTL_ETSI}, |
271 | 201 | {APL9_WORLD, CTL_ETSI, CTL_ETSI}, | |
272 | {ETSI3_ETSIA, ETSI3, WORLD, | 202 | |
273 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | 203 | {APL3_FCCA, CTL_FCC, CTL_FCC}, |
274 | 0}, | 204 | {APL1_ETSIC, CTL_FCC, CTL_ETSI}, |
275 | {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 205 | {APL2_ETSIC, CTL_FCC, CTL_ETSI}, |
276 | 206 | {APL2_APLD, CTL_FCC, NO_CTL}, | |
277 | {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 207 | |
278 | {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 208 | {MKK1_MKKA, CTL_MKK, CTL_MKK}, |
279 | {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 209 | {MKK1_MKKB, CTL_MKK, CTL_MKK}, |
280 | {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 210 | {MKK1_FCCA, CTL_MKK, CTL_FCC}, |
281 | {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 211 | {MKK1_MKKA1, CTL_MKK, CTL_MKK}, |
282 | {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 212 | {MKK1_MKKA2, CTL_MKK, CTL_MKK}, |
283 | {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 213 | {MKK1_MKKC, CTL_MKK, CTL_MKK}, |
284 | {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 214 | |
285 | {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 215 | {MKK2_MKKA, CTL_MKK, CTL_MKK}, |
286 | {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 216 | {MKK3_MKKA, CTL_MKK, CTL_MKK}, |
287 | 217 | {MKK3_MKKB, CTL_MKK, CTL_MKK}, | |
288 | {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 218 | {MKK3_MKKA1, CTL_MKK, CTL_MKK}, |
289 | {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 219 | {MKK3_MKKA2, CTL_MKK, CTL_MKK}, |
290 | {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | 220 | {MKK3_MKKC, CTL_MKK, CTL_MKK}, |
291 | {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER,}, | 221 | {MKK3_FCCA, CTL_MKK, CTL_FCC}, |
292 | 222 | ||
293 | {MKK1_MKKA, MKK1, MKKA, | 223 | {MKK4_MKKA, CTL_MKK, CTL_MKK}, |
294 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 224 | {MKK4_MKKB, CTL_MKK, CTL_MKK}, |
295 | PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN}, | 225 | {MKK4_MKKA1, CTL_MKK, CTL_MKK}, |
296 | {MKK1_MKKB, MKK1, MKKA, | 226 | {MKK4_MKKA2, CTL_MKK, CTL_MKK}, |
297 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | 227 | {MKK4_MKKC, CTL_MKK, CTL_MKK}, |
298 | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, | 228 | {MKK4_FCCA, CTL_MKK, CTL_FCC}, |
299 | CTRY_JAPAN1}, | 229 | |
300 | {MKK1_FCCA, MKK1, FCCA, | 230 | {MKK5_MKKB, CTL_MKK, CTL_MKK}, |
301 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 231 | {MKK5_MKKA2, CTL_MKK, CTL_MKK}, |
302 | PSCAN_MKK1, CTRY_JAPAN2}, | 232 | {MKK5_MKKC, CTL_MKK, CTL_MKK}, |
303 | {MKK1_MKKA1, MKK1, MKKA, | 233 | |
304 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 234 | {MKK6_MKKB, CTL_MKK, CTL_MKK}, |
305 | PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4}, | 235 | {MKK6_MKKA1, CTL_MKK, CTL_MKK}, |
306 | {MKK1_MKKA2, MKK1, MKKA, | 236 | {MKK6_MKKA2, CTL_MKK, CTL_MKK}, |
307 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 237 | {MKK6_MKKC, CTL_MKK, CTL_MKK}, |
308 | PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5}, | 238 | {MKK6_FCCA, CTL_MKK, CTL_FCC}, |
309 | {MKK1_MKKC, MKK1, MKKC, | 239 | |
310 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 240 | {MKK7_MKKB, CTL_MKK, CTL_MKK}, |
311 | PSCAN_MKK1, CTRY_JAPAN6}, | 241 | {MKK7_MKKA1, CTL_MKK, CTL_MKK}, |
312 | 242 | {MKK7_MKKA2, CTL_MKK, CTL_MKK}, | |
313 | {MKK2_MKKA, MKK2, MKKA, | 243 | {MKK7_MKKC, CTL_MKK, CTL_MKK}, |
314 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | 244 | {MKK7_FCCA, CTL_MKK, CTL_FCC}, |
315 | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G, | 245 | |
316 | CTRY_JAPAN3}, | 246 | {MKK8_MKKB, CTL_MKK, CTL_MKK}, |
317 | 247 | {MKK8_MKKA2, CTL_MKK, CTL_MKK}, | |
318 | {MKK3_MKKA, MKK3, MKKA, | 248 | {MKK8_MKKC, CTL_MKK, CTL_MKK}, |
319 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 249 | |
320 | PSCAN_MKKA, CTRY_JAPAN25}, | 250 | {MKK9_MKKA, CTL_MKK, CTL_MKK}, |
321 | {MKK3_MKKB, MKK3, MKKA, | 251 | {MKK9_FCCA, CTL_MKK, CTL_FCC}, |
322 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | 252 | {MKK9_MKKA1, CTL_MKK, CTL_MKK}, |
323 | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, | 253 | {MKK9_MKKA2, CTL_MKK, CTL_MKK}, |
324 | CTRY_JAPAN7}, | 254 | {MKK9_MKKC, CTL_MKK, CTL_MKK}, |
325 | {MKK3_MKKA1, MKK3, MKKA, | 255 | |
326 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 256 | {MKK10_MKKA, CTL_MKK, CTL_MKK}, |
327 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26}, | 257 | {MKK10_FCCA, CTL_MKK, CTL_FCC}, |
328 | {MKK3_MKKA2, MKK3, MKKA, | 258 | {MKK10_MKKA1, CTL_MKK, CTL_MKK}, |
329 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 259 | {MKK10_MKKA2, CTL_MKK, CTL_MKK}, |
330 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8}, | 260 | {MKK10_MKKC, CTL_MKK, CTL_MKK}, |
331 | {MKK3_MKKC, MKK3, MKKC, | 261 | |
332 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 262 | {MKK11_MKKA, CTL_MKK, CTL_MKK}, |
333 | NO_PSCAN, CTRY_JAPAN9}, | 263 | {MKK11_FCCA, CTL_MKK, CTL_FCC}, |
334 | {MKK3_FCCA, MKK3, FCCA, | 264 | {MKK11_MKKA1, CTL_MKK, CTL_MKK}, |
335 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 265 | {MKK11_MKKA2, CTL_MKK, CTL_MKK}, |
336 | NO_PSCAN, CTRY_JAPAN27}, | 266 | {MKK11_MKKC, CTL_MKK, CTL_MKK}, |
337 | 267 | ||
338 | {MKK4_MKKA, MKK4, MKKA, | 268 | {MKK12_MKKA, CTL_MKK, CTL_MKK}, |
339 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 269 | {MKK12_FCCA, CTL_MKK, CTL_FCC}, |
340 | PSCAN_MKK3, CTRY_JAPAN36}, | 270 | {MKK12_MKKA1, CTL_MKK, CTL_MKK}, |
341 | {MKK4_MKKB, MKK4, MKKA, | 271 | {MKK12_MKKA2, CTL_MKK, CTL_MKK}, |
342 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | 272 | {MKK12_MKKC, CTL_MKK, CTL_MKK}, |
343 | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, | 273 | |
344 | CTRY_JAPAN10}, | 274 | {MKK13_MKKB, CTL_MKK, CTL_MKK}, |
345 | {MKK4_MKKA1, MKK4, MKKA, | 275 | {MKK14_MKKA1, CTL_MKK, CTL_MKK}, |
346 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 276 | {MKK15_MKKA1, CTL_MKK, CTL_MKK}, |
347 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28}, | 277 | |
348 | {MKK4_MKKA2, MKK4, MKKA, | 278 | {WOR0_WORLD, NO_CTL, NO_CTL}, |
349 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 279 | {WOR1_WORLD, NO_CTL, NO_CTL}, |
350 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11}, | 280 | {WOR2_WORLD, NO_CTL, NO_CTL}, |
351 | {MKK4_MKKC, MKK4, MKKC, | 281 | {WOR3_WORLD, NO_CTL, NO_CTL}, |
352 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 282 | {WOR4_WORLD, NO_CTL, NO_CTL}, |
353 | PSCAN_MKK3, CTRY_JAPAN12}, | 283 | {WOR5_ETSIC, NO_CTL, NO_CTL}, |
354 | {MKK4_FCCA, MKK4, FCCA, | 284 | {WOR01_WORLD, NO_CTL, NO_CTL}, |
355 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | 285 | {WOR02_WORLD, NO_CTL, NO_CTL}, |
356 | PSCAN_MKK3, CTRY_JAPAN29}, | 286 | {EU1_WORLD, NO_CTL, NO_CTL}, |
357 | 287 | {WOR9_WORLD, NO_CTL, NO_CTL}, | |
358 | {MKK5_MKKB, MKK5, MKKA, | 288 | {WORA_WORLD, NO_CTL, NO_CTL}, |
359 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | 289 | {WORB_WORLD, NO_CTL, NO_CTL}, |
360 | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, | ||
361 | CTRY_JAPAN13}, | ||
362 | {MKK5_MKKA2, MKK5, MKKA, | ||
363 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
364 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14}, | ||
365 | {MKK5_MKKC, MKK5, MKKC, | ||
366 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
367 | PSCAN_MKK3, CTRY_JAPAN15}, | ||
368 | |||
369 | {MKK6_MKKB, MKK6, MKKA, | ||
370 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
371 | PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16}, | ||
372 | {MKK6_MKKA1, MKK6, MKKA, | ||
373 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
374 | PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30}, | ||
375 | {MKK6_MKKA2, MKK6, MKKA, | ||
376 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
377 | PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17}, | ||
378 | {MKK6_MKKC, MKK6, MKKC, | ||
379 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
380 | PSCAN_MKK1, CTRY_JAPAN18}, | ||
381 | {MKK6_FCCA, MKK6, FCCA, | ||
382 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
383 | NO_PSCAN, CTRY_JAPAN31}, | ||
384 | |||
385 | {MKK7_MKKB, MKK7, MKKA, | ||
386 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
387 | PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, | ||
388 | CTRY_JAPAN19}, | ||
389 | {MKK7_MKKA1, MKK7, MKKA, | ||
390 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
391 | PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32}, | ||
392 | {MKK7_MKKA2, MKK7, MKKA, | ||
393 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
394 | PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, | ||
395 | CTRY_JAPAN20}, | ||
396 | {MKK7_MKKC, MKK7, MKKC, | ||
397 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
398 | PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21}, | ||
399 | {MKK7_FCCA, MKK7, FCCA, | ||
400 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
401 | PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33}, | ||
402 | |||
403 | {MKK8_MKKB, MKK8, MKKA, | ||
404 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
405 | PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, | ||
406 | CTRY_JAPAN22}, | ||
407 | {MKK8_MKKA2, MKK8, MKKA, | ||
408 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
409 | PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, | ||
410 | CTRY_JAPAN23}, | ||
411 | {MKK8_MKKC, MKK8, MKKC, | ||
412 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
413 | PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24}, | ||
414 | |||
415 | {MKK9_MKKA, MKK9, MKKA, | ||
416 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | ||
417 | LIMIT_FRAME_4MS, NEED_NFC, | ||
418 | PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, | ||
419 | CTRY_JAPAN34}, | ||
420 | {MKK9_FCCA, MKK9, FCCA, | ||
421 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
422 | NO_PSCAN, CTRY_JAPAN37}, | ||
423 | {MKK9_MKKA1, MKK9, MKKA, | ||
424 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
425 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38}, | ||
426 | {MKK9_MKKA2, MKK9, MKKA, | ||
427 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
428 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40}, | ||
429 | {MKK9_MKKC, MKK9, MKKC, | ||
430 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
431 | NO_PSCAN, CTRY_JAPAN39}, | ||
432 | |||
433 | {MKK10_MKKA, MKK10, MKKA, | ||
434 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | ||
435 | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35}, | ||
436 | {MKK10_FCCA, MKK10, FCCA, | ||
437 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
438 | NO_PSCAN, CTRY_JAPAN41}, | ||
439 | {MKK10_MKKA1, MKK10, MKKA, | ||
440 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
441 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42}, | ||
442 | {MKK10_MKKA2, MKK10, MKKA, | ||
443 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
444 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44}, | ||
445 | {MKK10_MKKC, MKK10, MKKC, | ||
446 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
447 | NO_PSCAN, CTRY_JAPAN43}, | ||
448 | |||
449 | {MKK11_MKKA, MKK11, MKKA, | ||
450 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
451 | PSCAN_MKK3, CTRY_JAPAN45}, | ||
452 | {MKK11_FCCA, MKK11, FCCA, | ||
453 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
454 | PSCAN_MKK3, CTRY_JAPAN46}, | ||
455 | {MKK11_MKKA1, MKK11, MKKA, | ||
456 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
457 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47}, | ||
458 | {MKK11_MKKA2, MKK11, MKKA, | ||
459 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
460 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49}, | ||
461 | {MKK11_MKKC, MKK11, MKKC, | ||
462 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
463 | PSCAN_MKK3, CTRY_JAPAN48}, | ||
464 | |||
465 | {MKK12_MKKA, MKK12, MKKA, | ||
466 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
467 | PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50}, | ||
468 | {MKK12_FCCA, MKK12, FCCA, | ||
469 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
470 | PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51}, | ||
471 | {MKK12_MKKA1, MKK12, MKKA, | ||
472 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
473 | PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, | ||
474 | CTRY_JAPAN52}, | ||
475 | {MKK12_MKKA2, MKK12, MKKA, | ||
476 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
477 | PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, | ||
478 | CTRY_JAPAN54}, | ||
479 | {MKK12_MKKC, MKK12, MKKC, | ||
480 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
481 | PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53}, | ||
482 | |||
483 | {MKK13_MKKB, MKK13, MKKA, | ||
484 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | | ||
485 | LIMIT_FRAME_4MS, NEED_NFC, | ||
486 | PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, | ||
487 | CTRY_JAPAN57}, | ||
488 | |||
489 | {MKK14_MKKA1, MKK14, MKKA, | ||
490 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
491 | PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58}, | ||
492 | {MKK15_MKKA1, MKK15, MKKA, | ||
493 | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, | ||
494 | PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59}, | ||
495 | |||
496 | {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, | ||
497 | 0}, | ||
498 | {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, | ||
499 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | ||
500 | 0}, | ||
501 | {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, | ||
502 | NO_REQ, PSCAN_DEFER, 0}, | ||
503 | {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, | ||
504 | 0}, | ||
505 | {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, | ||
506 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | ||
507 | 0}, | ||
508 | {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, | ||
509 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | ||
510 | 0}, | ||
511 | {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, | ||
512 | PSCAN_DEFER, 0}, | ||
513 | {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, | ||
514 | PSCAN_DEFER, 0}, | ||
515 | {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, | ||
516 | {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, | ||
517 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | ||
518 | 0}, | ||
519 | {WORA_WORLD, WORA_WORLD, WORA_WORLD, | ||
520 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | ||
521 | 0}, | ||
522 | {WORB_WORLD, WORB_WORLD, WORB_WORLD, | ||
523 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, | ||
524 | 0}, | ||
525 | }; | 290 | }; |
526 | 291 | ||
527 | #define NO_INTERSECT_REQ 0xFFFFFFFF | ||
528 | #define NO_UNION_REQ 0 | ||
529 | |||
530 | static struct country_code_to_enum_rd allCountries[] = { | 292 | static struct country_code_to_enum_rd allCountries[] = { |
531 | {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES, | 293 | {CTRY_DEBUG, NO_ENUMRD, "DB"}, |
532 | YES, YES, 7000}, | 294 | {CTRY_DEFAULT, FCC1_FCCA, "CO"}, |
533 | {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES, | 295 | {CTRY_ALBANIA, NULL1_WORLD, "AL"}, |
534 | YES, YES, YES, YES, 7000}, | 296 | {CTRY_ALGERIA, NULL1_WORLD, "DZ"}, |
535 | {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO, | 297 | {CTRY_ARGENTINA, APL3_WORLD, "AR"}, |
536 | NO, NO, 7000}, | 298 | {CTRY_ARMENIA, ETSI4_WORLD, "AM"}, |
537 | {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO, | 299 | {CTRY_AUSTRALIA, FCC2_WORLD, "AU"}, |
538 | NO, NO, 7000}, | 300 | {CTRY_AUSTRALIA2, FCC6_WORLD, "AU"}, |
539 | {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES, | 301 | {CTRY_AUSTRIA, ETSI1_WORLD, "AT"}, |
540 | NO, YES, NO, 7000}, | 302 | {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"}, |
541 | {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES, | 303 | {CTRY_BAHRAIN, APL6_WORLD, "BH"}, |
542 | YES, NO, NO, 7000}, | 304 | {CTRY_BELARUS, ETSI1_WORLD, "BY"}, |
543 | {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES, | 305 | {CTRY_BELGIUM, ETSI1_WORLD, "BE"}, |
544 | YES, YES, YES, 7000}, | 306 | {CTRY_BELGIUM2, ETSI4_WORLD, "BL"}, |
545 | {CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES, | 307 | {CTRY_BELIZE, APL1_ETSIC, "BZ"}, |
546 | YES, YES, YES, YES, 7000}, | 308 | {CTRY_BOLIVIA, APL1_ETSIC, "BO"}, |
547 | {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES, | 309 | {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"}, |
548 | YES, YES, YES, 7000}, | 310 | {CTRY_BRAZIL, FCC3_WORLD, "BR"}, |
549 | {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES, | 311 | {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"}, |
550 | YES, YES, YES, YES, 7000}, | 312 | {CTRY_BULGARIA, ETSI6_WORLD, "BG"}, |
551 | {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES, | 313 | {CTRY_CANADA, FCC2_FCCA, "CA"}, |
552 | YES, NO, 7000}, | 314 | {CTRY_CANADA2, FCC6_FCCA, "CA"}, |
553 | {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES, | 315 | {CTRY_CHILE, APL6_WORLD, "CL"}, |
554 | YES, YES, YES, 7000}, | 316 | {CTRY_CHINA, APL1_WORLD, "CN"}, |
555 | {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES, | 317 | {CTRY_COLOMBIA, FCC1_FCCA, "CO"}, |
556 | YES, YES, YES, 7000}, | 318 | {CTRY_COSTA_RICA, FCC1_WORLD, "CR"}, |
557 | {CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES, | 319 | {CTRY_CROATIA, ETSI3_WORLD, "HR"}, |
558 | YES, YES, YES, 7000}, | 320 | {CTRY_CYPRUS, ETSI1_WORLD, "CY"}, |
559 | {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES, | 321 | {CTRY_CZECH, ETSI3_WORLD, "CZ"}, |
560 | YES, YES, 7000}, | 322 | {CTRY_DENMARK, ETSI1_WORLD, "DK"}, |
561 | {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES, | 323 | {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"}, |
562 | YES, YES, 7000}, | 324 | {CTRY_ECUADOR, FCC1_WORLD, "EC"}, |
563 | {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO, | 325 | {CTRY_EGYPT, ETSI3_WORLD, "EG"}, |
564 | YES, YES, YES, YES, NO, 7000}, | 326 | {CTRY_EL_SALVADOR, FCC1_WORLD, "SV"}, |
565 | {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO, | 327 | {CTRY_ESTONIA, ETSI1_WORLD, "EE"}, |
566 | YES, NO, 7000}, | 328 | {CTRY_FINLAND, ETSI1_WORLD, "FI"}, |
567 | {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM", | 329 | {CTRY_FRANCE, ETSI1_WORLD, "FR"}, |
568 | YES, YES, YES, YES, YES, YES, YES, 7000}, | 330 | {CTRY_GEORGIA, ETSI4_WORLD, "GE"}, |
569 | {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES, | 331 | {CTRY_GERMANY, ETSI1_WORLD, "DE"}, |
570 | YES, YES, YES, 7000}, | 332 | {CTRY_GREECE, ETSI1_WORLD, "GR"}, |
571 | {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES, | 333 | {CTRY_GUATEMALA, FCC1_FCCA, "GT"}, |
572 | YES, YES, 7000}, | 334 | {CTRY_HONDURAS, NULL1_WORLD, "HN"}, |
573 | {CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES, | 335 | {CTRY_HONG_KONG, FCC2_WORLD, "HK"}, |
574 | YES, YES, 7000}, | 336 | {CTRY_HUNGARY, ETSI1_WORLD, "HU"}, |
575 | {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES, | 337 | {CTRY_ICELAND, ETSI1_WORLD, "IS"}, |
576 | YES, YES, 7000}, | 338 | {CTRY_INDIA, APL6_WORLD, "IN"}, |
577 | {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES, | 339 | {CTRY_INDONESIA, APL1_WORLD, "ID"}, |
578 | YES, YES, 7000}, | 340 | {CTRY_IRAN, APL1_WORLD, "IR"}, |
579 | {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES, | 341 | {CTRY_IRELAND, ETSI1_WORLD, "IE"}, |
580 | YES, YES, NO, 7000}, | 342 | {CTRY_ISRAEL, NULL1_WORLD, "IL"}, |
581 | {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES, | 343 | {CTRY_ITALY, ETSI1_WORLD, "IT"}, |
582 | YES, YES, YES, NO, 7000}, | 344 | {CTRY_JAMAICA, ETSI1_WORLD, "JM"}, |
583 | {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES, | 345 | |
584 | YES, YES, NO, 7000}, | 346 | {CTRY_JAPAN, MKK1_MKKA, "JP"}, |
585 | {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES, | 347 | {CTRY_JAPAN1, MKK1_MKKB, "JP"}, |
586 | YES, YES, 7000}, | 348 | {CTRY_JAPAN2, MKK1_FCCA, "JP"}, |
587 | {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES, | 349 | {CTRY_JAPAN3, MKK2_MKKA, "JP"}, |
588 | YES, YES, YES, YES, 7000}, | 350 | {CTRY_JAPAN4, MKK1_MKKA1, "JP"}, |
589 | {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES, | 351 | {CTRY_JAPAN5, MKK1_MKKA2, "JP"}, |
590 | YES, YES, YES, 7000}, | 352 | {CTRY_JAPAN6, MKK1_MKKC, "JP"}, |
591 | {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC", | 353 | {CTRY_JAPAN7, MKK3_MKKB, "JP"}, |
592 | YES, YES, YES, YES, YES, YES, YES, 7000}, | 354 | {CTRY_JAPAN8, MKK3_MKKA2, "JP"}, |
593 | {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES, | 355 | {CTRY_JAPAN9, MKK3_MKKC, "JP"}, |
594 | YES, NO, 7000}, | 356 | {CTRY_JAPAN10, MKK4_MKKB, "JP"}, |
595 | {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES, | 357 | {CTRY_JAPAN11, MKK4_MKKA2, "JP"}, |
596 | YES, NO, 7000}, | 358 | {CTRY_JAPAN12, MKK4_MKKC, "JP"}, |
597 | {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES, | 359 | {CTRY_JAPAN13, MKK5_MKKB, "JP"}, |
598 | YES, YES, YES, NO, 7000}, | 360 | {CTRY_JAPAN14, MKK5_MKKA2, "JP"}, |
599 | {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES, | 361 | {CTRY_JAPAN15, MKK5_MKKC, "JP"}, |
600 | YES, YES, YES, 7000}, | 362 | {CTRY_JAPAN16, MKK6_MKKB, "JP"}, |
601 | {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES, | 363 | {CTRY_JAPAN17, MKK6_MKKA2, "JP"}, |
602 | YES, YES, YES, 7000}, | 364 | {CTRY_JAPAN18, MKK6_MKKC, "JP"}, |
603 | {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES, | 365 | {CTRY_JAPAN19, MKK7_MKKB, "JP"}, |
604 | YES, YES, 7000}, | 366 | {CTRY_JAPAN20, MKK7_MKKA2, "JP"}, |
605 | {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES, | 367 | {CTRY_JAPAN21, MKK7_MKKC, "JP"}, |
606 | YES, YES, YES, 7000}, | 368 | {CTRY_JAPAN22, MKK8_MKKB, "JP"}, |
607 | {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES, | 369 | {CTRY_JAPAN23, MKK8_MKKA2, "JP"}, |
608 | YES, YES, YES, 7000}, | 370 | {CTRY_JAPAN24, MKK8_MKKC, "JP"}, |
609 | {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES, | 371 | {CTRY_JAPAN25, MKK3_MKKA, "JP"}, |
610 | YES, YES, 7000}, | 372 | {CTRY_JAPAN26, MKK3_MKKA1, "JP"}, |
611 | {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES, | 373 | {CTRY_JAPAN27, MKK3_FCCA, "JP"}, |
612 | YES, YES, YES, 7000}, | 374 | {CTRY_JAPAN28, MKK4_MKKA1, "JP"}, |
613 | {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES, | 375 | {CTRY_JAPAN29, MKK4_FCCA, "JP"}, |
614 | YES, NO, NO, 7000}, | 376 | {CTRY_JAPAN30, MKK6_MKKA1, "JP"}, |
615 | {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES, | 377 | {CTRY_JAPAN31, MKK6_FCCA, "JP"}, |
616 | YES, YES, YES, 7000}, | 378 | {CTRY_JAPAN32, MKK7_MKKA1, "JP"}, |
617 | {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES, | 379 | {CTRY_JAPAN33, MKK7_FCCA, "JP"}, |
618 | YES, YES, YES, 7000}, | 380 | {CTRY_JAPAN34, MKK9_MKKA, "JP"}, |
619 | {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES, | 381 | {CTRY_JAPAN35, MKK10_MKKA, "JP"}, |
620 | YES, YES, YES, 7000}, | 382 | {CTRY_JAPAN36, MKK4_MKKA, "JP"}, |
621 | {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES, | 383 | {CTRY_JAPAN37, MKK9_FCCA, "JP"}, |
622 | YES, NO, 7000}, | 384 | {CTRY_JAPAN38, MKK9_MKKA1, "JP"}, |
623 | {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES, | 385 | {CTRY_JAPAN39, MKK9_MKKC, "JP"}, |
624 | YES, YES, NO, 7000}, | 386 | {CTRY_JAPAN40, MKK9_MKKA2, "JP"}, |
625 | {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES, | 387 | {CTRY_JAPAN41, MKK10_FCCA, "JP"}, |
626 | YES, 7000}, | 388 | {CTRY_JAPAN42, MKK10_MKKA1, "JP"}, |
627 | {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES, | 389 | {CTRY_JAPAN43, MKK10_MKKC, "JP"}, |
628 | YES, YES, YES, 7000}, | 390 | {CTRY_JAPAN44, MKK10_MKKA2, "JP"}, |
629 | {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES, | 391 | {CTRY_JAPAN45, MKK11_MKKA, "JP"}, |
630 | NO, NO, 7000}, | 392 | {CTRY_JAPAN46, MKK11_FCCA, "JP"}, |
631 | {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES, | 393 | {CTRY_JAPAN47, MKK11_MKKA1, "JP"}, |
632 | YES, YES, 7000}, | 394 | {CTRY_JAPAN48, MKK11_MKKC, "JP"}, |
633 | {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES, | 395 | {CTRY_JAPAN49, MKK11_MKKA2, "JP"}, |
634 | YES, YES, YES, 7000}, | 396 | {CTRY_JAPAN50, MKK12_MKKA, "JP"}, |
635 | 397 | {CTRY_JAPAN51, MKK12_FCCA, "JP"}, | |
636 | {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES, | 398 | {CTRY_JAPAN52, MKK12_MKKA1, "JP"}, |
637 | YES, 7000}, | 399 | {CTRY_JAPAN53, MKK12_MKKC, "JP"}, |
638 | {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES, | 400 | {CTRY_JAPAN54, MKK12_MKKA2, "JP"}, |
639 | YES, YES, 7000}, | 401 | {CTRY_JAPAN57, MKK13_MKKB, "JP"}, |
640 | {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES, | 402 | {CTRY_JAPAN58, MKK14_MKKA1, "JP"}, |
641 | YES, YES, 7000}, | 403 | {CTRY_JAPAN59, MKK15_MKKA1, "JP"}, |
642 | {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES, | 404 | |
643 | YES, YES, 7000}, | 405 | {CTRY_JORDAN, ETSI2_WORLD, "JO"}, |
644 | {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES, | 406 | {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"}, |
645 | YES, YES, 7000}, | 407 | {CTRY_KOREA_NORTH, APL9_WORLD, "KP"}, |
646 | {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES, | 408 | {CTRY_KOREA_ROC, APL9_WORLD, "KR"}, |
647 | YES, YES, 7000}, | 409 | {CTRY_KOREA_ROC2, APL2_WORLD, "K2"}, |
648 | {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES, | 410 | {CTRY_KOREA_ROC3, APL9_WORLD, "K3"}, |
649 | YES, YES, 7000}, | 411 | {CTRY_KUWAIT, NULL1_WORLD, "KW"}, |
650 | 412 | {CTRY_LATVIA, ETSI1_WORLD, "LV"}, | |
651 | {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES, | 413 | {CTRY_LEBANON, NULL1_WORLD, "LB"}, |
652 | YES, YES, 7000}, | 414 | {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"}, |
653 | {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES, | 415 | {CTRY_LITHUANIA, ETSI1_WORLD, "LT"}, |
654 | YES, YES, 7000}, | 416 | {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"}, |
655 | {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES, | 417 | {CTRY_MACAU, FCC2_WORLD, "MO"}, |
656 | YES, YES, 7000}, | 418 | {CTRY_MACEDONIA, NULL1_WORLD, "MK"}, |
657 | 419 | {CTRY_MALAYSIA, APL8_WORLD, "MY"}, | |
658 | {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES, | 420 | {CTRY_MALTA, ETSI1_WORLD, "MT"}, |
659 | YES, YES, 7000}, | 421 | {CTRY_MEXICO, FCC1_FCCA, "MX"}, |
660 | {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES, | 422 | {CTRY_MONACO, ETSI4_WORLD, "MC"}, |
661 | YES, YES, 7000}, | 423 | {CTRY_MOROCCO, NULL1_WORLD, "MA"}, |
662 | {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES, | 424 | {CTRY_NEPAL, APL1_WORLD, "NP"}, |
663 | YES, YES, 7000}, | 425 | {CTRY_NETHERLANDS, ETSI1_WORLD, "NL"}, |
664 | 426 | {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"}, | |
665 | {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES, | 427 | {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"}, |
666 | YES, YES, 7000}, | 428 | {CTRY_NORWAY, ETSI1_WORLD, "NO"}, |
667 | {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES, | 429 | {CTRY_OMAN, APL6_WORLD, "OM"}, |
668 | YES, YES, 7000}, | 430 | {CTRY_PAKISTAN, NULL1_WORLD, "PK"}, |
669 | {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES, | 431 | {CTRY_PANAMA, FCC1_FCCA, "PA"}, |
670 | YES, YES, 7000}, | 432 | {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"}, |
671 | 433 | {CTRY_PERU, APL1_WORLD, "PE"}, | |
672 | {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES, | 434 | {CTRY_PHILIPPINES, APL1_WORLD, "PH"}, |
673 | YES, YES, 7000}, | 435 | {CTRY_POLAND, ETSI1_WORLD, "PL"}, |
674 | {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES, | 436 | {CTRY_PORTUGAL, ETSI1_WORLD, "PT"}, |
675 | YES, YES, 7000}, | 437 | {CTRY_PUERTO_RICO, FCC1_FCCA, "PR"}, |
676 | {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES, | 438 | {CTRY_QATAR, NULL1_WORLD, "QA"}, |
677 | YES, YES, 7000}, | 439 | {CTRY_ROMANIA, NULL1_WORLD, "RO"}, |
678 | 440 | {CTRY_RUSSIA, NULL1_WORLD, "RU"}, | |
679 | {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES, | 441 | {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"}, |
680 | YES, YES, 7000}, | 442 | {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"}, |
681 | {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES, | 443 | {CTRY_SINGAPORE, APL6_WORLD, "SG"}, |
682 | YES, YES, 7000}, | 444 | {CTRY_SLOVAKIA, ETSI1_WORLD, "SK"}, |
683 | {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES, | 445 | {CTRY_SLOVENIA, ETSI1_WORLD, "SI"}, |
684 | YES, YES, 7000}, | 446 | {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"}, |
685 | 447 | {CTRY_SPAIN, ETSI1_WORLD, "ES"}, | |
686 | {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES, | 448 | {CTRY_SRI_LANKA, FCC3_WORLD, "LK"}, |
687 | YES, YES, 7000}, | 449 | {CTRY_SWEDEN, ETSI1_WORLD, "SE"}, |
688 | {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES, | 450 | {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"}, |
689 | YES, YES, 7000}, | 451 | {CTRY_SYRIA, NULL1_WORLD, "SY"}, |
690 | {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES, | 452 | {CTRY_TAIWAN, APL3_FCCA, "TW"}, |
691 | YES, YES, 7000}, | 453 | {CTRY_THAILAND, NULL1_WORLD, "TH"}, |
692 | 454 | {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"}, | |
693 | {CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES, | 455 | {CTRY_TUNISIA, ETSI3_WORLD, "TN"}, |
694 | YES, YES, 7000}, | 456 | {CTRY_TURKEY, ETSI3_WORLD, "TR"}, |
695 | {CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES, | 457 | {CTRY_UKRAINE, NULL1_WORLD, "UA"}, |
696 | YES, YES, 7000}, | 458 | {CTRY_UAE, NULL1_WORLD, "AE"}, |
697 | {CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES, | 459 | {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"}, |
698 | YES, YES, 7000}, | 460 | {CTRY_UNITED_STATES, FCC3_FCCA, "US"}, |
699 | {CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES, | 461 | /* This "PS" is for US public safety actually... to support this we |
700 | YES, YES, 7000}, | 462 | * would need to assign new special alpha2 to CRDA db as with the world |
701 | {CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES, | 463 | * regdomain and use another alpha2 */ |
702 | YES, YES, 7000}, | 464 | {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"}, |
703 | {CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES, | 465 | {CTRY_URUGUAY, APL2_WORLD, "UY"}, |
704 | YES, YES, 7000}, | 466 | {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"}, |
705 | {CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES, | 467 | {CTRY_VENEZUELA, APL2_ETSIC, "VE"}, |
706 | YES, YES, 7000}, | 468 | {CTRY_VIET_NAM, NULL1_WORLD, "VN"}, |
707 | {CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES, | 469 | {CTRY_YEMEN, NULL1_WORLD, "YE"}, |
708 | YES, YES, 7000}, | 470 | {CTRY_ZIMBABWE, NULL1_WORLD, "ZW"}, |
709 | {CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES, | ||
710 | YES, YES, 7000}, | ||
711 | {CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES, | ||
712 | YES, YES, 7000}, | ||
713 | {CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES, | ||
714 | YES, YES, 7000}, | ||
715 | {CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES, | ||
716 | YES, YES, 7000}, | ||
717 | {CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES, | ||
718 | YES, YES, 7000}, | ||
719 | {CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES, | ||
720 | YES, YES, 7000}, | ||
721 | {CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES, | ||
722 | YES, YES, 7000}, | ||
723 | {CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES, | ||
724 | YES, YES, 7000}, | ||
725 | {CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES, | ||
726 | YES, YES, 7000}, | ||
727 | {CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES, | ||
728 | YES, YES, 7000}, | ||
729 | {CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES, | ||
730 | YES, YES, 7000}, | ||
731 | {CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES, | ||
732 | YES, YES, 7000}, | ||
733 | {CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES, | ||
734 | YES, YES, 7000}, | ||
735 | {CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES, | ||
736 | YES, YES, 7000}, | ||
737 | {CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES, | ||
738 | YES, YES, 7000}, | ||
739 | {CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES, | ||
740 | YES, YES, 7000}, | ||
741 | {CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES, | ||
742 | YES, YES, 7000}, | ||
743 | {CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES, | ||
744 | YES, YES, 7000}, | ||
745 | {CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES, | ||
746 | YES, YES, 7000}, | ||
747 | {CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES, | ||
748 | YES, YES, 7000}, | ||
749 | {CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES, | ||
750 | YES, YES, 7000}, | ||
751 | {CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES, | ||
752 | YES, YES, 7000}, | ||
753 | |||
754 | {CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES, | ||
755 | YES, YES, 7000}, | ||
756 | {CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES, | ||
757 | YES, YES, 7000}, | ||
758 | {CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES, | ||
759 | YES, YES, 7000}, | ||
760 | |||
761 | {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES, | ||
762 | YES, NO, 7000}, | ||
763 | {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES, | ||
764 | YES, YES, NO, NO, 7000}, | ||
765 | {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO, | ||
766 | YES, YES, YES, YES, 7000}, | ||
767 | {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO, | ||
768 | YES, NO, YES, NO, 7000}, | ||
769 | {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO, | ||
770 | YES, NO, YES, NO, 7000}, | ||
771 | {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO, | ||
772 | YES, NO, YES, NO, 7000}, | ||
773 | {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES, | ||
774 | NO, NO, 7000}, | ||
775 | {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES, | ||
776 | YES, YES, 7000}, | ||
777 | {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES, | ||
778 | YES, NO, NO, 7000}, | ||
779 | {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO, | ||
780 | YES, YES, YES, YES, YES, 7000}, | ||
781 | {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES, | ||
782 | YES, YES, YES, 7000}, | ||
783 | {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES, | ||
784 | YES, YES, YES, YES, 7000}, | ||
785 | {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES, | ||
786 | YES, YES, 7000}, | ||
787 | {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES, | ||
788 | YES, NO, NO, 7000}, | ||
789 | {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO, | ||
790 | YES, NO, 7000}, | ||
791 | {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES, | ||
792 | YES, YES, 7000}, | ||
793 | {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES, | ||
794 | YES, YES, 7000}, | ||
795 | {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES, | ||
796 | YES, YES, 7000}, | ||
797 | {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES, | ||
798 | YES, NO, NO, 7000}, | ||
799 | {CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES, | ||
800 | YES, YES, 7000}, | ||
801 | {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES, | ||
802 | YES, YES, YES, YES, 7000}, | ||
803 | {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN", | ||
804 | "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000}, | ||
805 | {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES, | ||
806 | YES, YES, YES, NO, 7000}, | ||
807 | {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES, | ||
808 | YES, YES, 7000}, | ||
809 | {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES, | ||
810 | NO, 7000}, | ||
811 | {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES, | ||
812 | YES, NO, NO, 7000}, | ||
813 | {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES, | ||
814 | YES, YES, 7000}, | ||
815 | {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES, | ||
816 | YES, YES, YES, YES, YES, YES, 7000}, | ||
817 | {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES, | ||
818 | NO, 7000}, | ||
819 | {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES, | ||
820 | YES, YES, YES, YES, 7000}, | ||
821 | {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES, | ||
822 | YES, YES, 7000}, | ||
823 | {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES, | ||
824 | YES, YES, YES, 7000}, | ||
825 | {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES, | ||
826 | YES, YES, YES, YES, 7000}, | ||
827 | {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES, | ||
828 | NO, NO, 7000}, | ||
829 | {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES, | ||
830 | YES, NO, NO, 7000}, | ||
831 | {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES, | ||
832 | NO, NO, 7000}, | ||
833 | {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO, | ||
834 | YES, YES, YES, NO, NO, 7000}, | ||
835 | {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO", | ||
836 | YES, NO, YES, YES, YES, YES, YES, 7000}, | ||
837 | {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES, | ||
838 | YES, YES, YES, 7000}, | ||
839 | {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES, | ||
840 | YES, YES, YES, YES, 7000}, | ||
841 | {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES, | ||
842 | YES, YES, YES, 7000}, | ||
843 | {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES, | ||
844 | YES, YES, YES, NO, 7000}, | ||
845 | {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES, | ||
846 | YES, YES, 7000}, | ||
847 | {CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES, | ||
848 | YES, YES, NO, 7000}, | ||
849 | {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES, | ||
850 | YES, YES, 7000}, | ||
851 | {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES, | ||
852 | YES, YES, YES, YES, 7000}, | ||
853 | {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES, | ||
854 | NO, NO, 7000}, | ||
855 | {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES, | ||
856 | YES, YES, 7000}, | ||
857 | {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES, | ||
858 | YES, NO, NO, 7000}, | ||
859 | {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO", | ||
860 | YES, NO, YES, YES, YES, YES, NO, 7000}, | ||
861 | {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES, | ||
862 | YES, YES, NO, 7000}, | ||
863 | {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES, | ||
864 | YES, NO, 7000}, | ||
865 | {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES, | ||
866 | YES, NO, NO, 7000}, | ||
867 | {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES, | ||
868 | YES, YES, NO, NO, 7000}, | ||
869 | {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO, | ||
870 | YES, YES, YES, YES, YES, 7000}, | ||
871 | {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES, | ||
872 | YES, YES, YES, YES, YES, 5825}, | ||
873 | {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", | ||
874 | "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES, | ||
875 | YES, 7000}, | ||
876 | {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES, | ||
877 | YES, NO, 7000}, | ||
878 | {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES, | ||
879 | YES, YES, YES, YES, 7000}, | ||
880 | {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES, | ||
881 | YES, YES, NO, 7000}, | ||
882 | {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES, | ||
883 | YES, NO, NO, 7000}, | ||
884 | {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES, | ||
885 | NO, NO, 7000}, | ||
886 | {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES, | ||
887 | YES, NO, NO, 7000} | ||
888 | }; | ||
889 | |||
890 | enum { | ||
891 | NO_DFS = 0x0000000000000000ULL, | ||
892 | DFS_FCC3 = 0x0000000000000001ULL, | ||
893 | DFS_ETSI = 0x0000000000000002ULL, | ||
894 | DFS_MKK4 = 0x0000000000000004ULL, | ||
895 | }; | ||
896 | |||
897 | enum { | ||
898 | F1_4915_4925, | ||
899 | F1_4935_4945, | ||
900 | F1_4920_4980, | ||
901 | F1_4942_4987, | ||
902 | F1_4945_4985, | ||
903 | F1_4950_4980, | ||
904 | F1_5035_5040, | ||
905 | F1_5040_5080, | ||
906 | F1_5055_5055, | ||
907 | |||
908 | F1_5120_5240, | ||
909 | |||
910 | F1_5170_5230, | ||
911 | F2_5170_5230, | ||
912 | |||
913 | F1_5180_5240, | ||
914 | F2_5180_5240, | ||
915 | F3_5180_5240, | ||
916 | F4_5180_5240, | ||
917 | F5_5180_5240, | ||
918 | F6_5180_5240, | ||
919 | F7_5180_5240, | ||
920 | F8_5180_5240, | ||
921 | |||
922 | F1_5180_5320, | ||
923 | |||
924 | F1_5240_5280, | ||
925 | |||
926 | F1_5260_5280, | ||
927 | |||
928 | F1_5260_5320, | ||
929 | F2_5260_5320, | ||
930 | F3_5260_5320, | ||
931 | F4_5260_5320, | ||
932 | F5_5260_5320, | ||
933 | F6_5260_5320, | ||
934 | |||
935 | F1_5260_5700, | ||
936 | |||
937 | F1_5280_5320, | ||
938 | |||
939 | F1_5500_5580, | ||
940 | |||
941 | F1_5500_5620, | ||
942 | |||
943 | F1_5500_5700, | ||
944 | F2_5500_5700, | ||
945 | F3_5500_5700, | ||
946 | F4_5500_5700, | ||
947 | F5_5500_5700, | ||
948 | |||
949 | F1_5660_5700, | ||
950 | |||
951 | F1_5745_5805, | ||
952 | F2_5745_5805, | ||
953 | F3_5745_5805, | ||
954 | |||
955 | F1_5745_5825, | ||
956 | F2_5745_5825, | ||
957 | F3_5745_5825, | ||
958 | F4_5745_5825, | ||
959 | F5_5745_5825, | ||
960 | F6_5745_5825, | ||
961 | |||
962 | W1_4920_4980, | ||
963 | W1_5040_5080, | ||
964 | W1_5170_5230, | ||
965 | W1_5180_5240, | ||
966 | W1_5260_5320, | ||
967 | W1_5745_5825, | ||
968 | W1_5500_5700, | ||
969 | A_DEMO_ALL_CHANNELS | ||
970 | }; | ||
971 | |||
972 | static struct RegDmnFreqBand regDmn5GhzFreq[] = { | ||
973 | {4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16}, | ||
974 | {4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16}, | ||
975 | {4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7}, | ||
976 | {4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0}, | ||
977 | {4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0}, | ||
978 | {4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0}, | ||
979 | {5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12}, | ||
980 | {5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2}, | ||
981 | {5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12}, | ||
982 | |||
983 | {5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
984 | |||
985 | {5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1}, | ||
986 | {5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1}, | ||
987 | |||
988 | {5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0}, | ||
989 | {5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1}, | ||
990 | {5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0}, | ||
991 | {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0}, | ||
992 | {5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0}, | ||
993 | {5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0}, | ||
994 | {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0}, | ||
995 | {5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
996 | |||
997 | {5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0}, | ||
998 | |||
999 | {5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0}, | ||
1000 | |||
1001 | {5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, | ||
1002 | PSCAN_FCC | PSCAN_ETSI, 0}, | ||
1003 | |||
1004 | {5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, | ||
1005 | PSCAN_FCC | PSCAN_ETSI, 0}, | ||
1006 | |||
1007 | {5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, | ||
1008 | PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0}, | ||
1009 | |||
1010 | |||
1011 | {5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, | ||
1012 | PSCAN_FCC | PSCAN_ETSI, 2}, | ||
1013 | {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2}, | ||
1014 | {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0}, | ||
1015 | {5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1016 | |||
1017 | {5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0}, | ||
1018 | |||
1019 | {5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0}, | ||
1020 | |||
1021 | {5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0}, | ||
1022 | |||
1023 | {5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0}, | ||
1024 | |||
1025 | {5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4}, | ||
1026 | {5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, | ||
1027 | PSCAN_FCC | PSCAN_ETSI, 0}, | ||
1028 | {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, | ||
1029 | PSCAN_FCC | PSCAN_ETSI, 0}, | ||
1030 | {5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, | ||
1031 | PSCAN_MKK3 | PSCAN_FCC, 0}, | ||
1032 | {5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0}, | ||
1033 | |||
1034 | {5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0}, | ||
1035 | |||
1036 | {5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1037 | {5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1038 | {5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0}, | ||
1039 | {5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1040 | {5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1041 | {5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1042 | {5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1043 | {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3}, | ||
1044 | {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1045 | |||
1046 | |||
1047 | {4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0}, | ||
1048 | {5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0}, | ||
1049 | {5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0}, | ||
1050 | {5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0}, | ||
1051 | {5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, | ||
1052 | {5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0}, | ||
1053 | {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0}, | ||
1054 | {4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0}, | ||
1055 | }; | ||
1056 | |||
1057 | enum { | ||
1058 | T1_5130_5650, | ||
1059 | T1_5150_5670, | ||
1060 | |||
1061 | T1_5200_5200, | ||
1062 | T2_5200_5200, | ||
1063 | T3_5200_5200, | ||
1064 | T4_5200_5200, | ||
1065 | T5_5200_5200, | ||
1066 | T6_5200_5200, | ||
1067 | T7_5200_5200, | ||
1068 | T8_5200_5200, | ||
1069 | |||
1070 | T1_5200_5280, | ||
1071 | T2_5200_5280, | ||
1072 | T3_5200_5280, | ||
1073 | T4_5200_5280, | ||
1074 | T5_5200_5280, | ||
1075 | T6_5200_5280, | ||
1076 | |||
1077 | T1_5200_5240, | ||
1078 | T1_5210_5210, | ||
1079 | T2_5210_5210, | ||
1080 | T3_5210_5210, | ||
1081 | T4_5210_5210, | ||
1082 | T5_5210_5210, | ||
1083 | T6_5210_5210, | ||
1084 | T7_5210_5210, | ||
1085 | T8_5210_5210, | ||
1086 | T9_5210_5210, | ||
1087 | T10_5210_5210, | ||
1088 | T1_5240_5240, | ||
1089 | |||
1090 | T1_5210_5250, | ||
1091 | T1_5210_5290, | ||
1092 | T2_5210_5290, | ||
1093 | T3_5210_5290, | ||
1094 | |||
1095 | T1_5280_5280, | ||
1096 | T2_5280_5280, | ||
1097 | T1_5290_5290, | ||
1098 | T2_5290_5290, | ||
1099 | T3_5290_5290, | ||
1100 | T1_5250_5290, | ||
1101 | T2_5250_5290, | ||
1102 | T3_5250_5290, | ||
1103 | T4_5250_5290, | ||
1104 | |||
1105 | T1_5540_5660, | ||
1106 | T2_5540_5660, | ||
1107 | T3_5540_5660, | ||
1108 | T1_5760_5800, | ||
1109 | T2_5760_5800, | ||
1110 | T3_5760_5800, | ||
1111 | T4_5760_5800, | ||
1112 | T5_5760_5800, | ||
1113 | T6_5760_5800, | ||
1114 | T7_5760_5800, | ||
1115 | |||
1116 | T1_5765_5805, | ||
1117 | T2_5765_5805, | ||
1118 | T3_5765_5805, | ||
1119 | T4_5765_5805, | ||
1120 | T5_5765_5805, | ||
1121 | T6_5765_5805, | ||
1122 | T7_5765_5805, | ||
1123 | T8_5765_5805, | ||
1124 | T9_5765_5805, | ||
1125 | |||
1126 | WT1_5210_5250, | ||
1127 | WT1_5290_5290, | ||
1128 | WT1_5540_5660, | ||
1129 | WT1_5760_5800, | ||
1130 | }; | ||
1131 | |||
1132 | enum { | ||
1133 | F1_2312_2372, | ||
1134 | F2_2312_2372, | ||
1135 | |||
1136 | F1_2412_2472, | ||
1137 | F2_2412_2472, | ||
1138 | F3_2412_2472, | ||
1139 | |||
1140 | F1_2412_2462, | ||
1141 | F2_2412_2462, | ||
1142 | |||
1143 | F1_2432_2442, | ||
1144 | |||
1145 | F1_2457_2472, | ||
1146 | |||
1147 | F1_2467_2472, | ||
1148 | |||
1149 | F1_2484_2484, | ||
1150 | F2_2484_2484, | ||
1151 | |||
1152 | F1_2512_2732, | ||
1153 | |||
1154 | W1_2312_2372, | ||
1155 | W1_2412_2412, | ||
1156 | W1_2417_2432, | ||
1157 | W1_2437_2442, | ||
1158 | W1_2447_2457, | ||
1159 | W1_2462_2462, | ||
1160 | W1_2467_2467, | ||
1161 | W2_2467_2467, | ||
1162 | W1_2472_2472, | ||
1163 | W2_2472_2472, | ||
1164 | W1_2484_2484, | ||
1165 | W2_2484_2484, | ||
1166 | }; | ||
1167 | |||
1168 | static struct RegDmnFreqBand regDmn2GhzFreq[] = { | ||
1169 | {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1170 | {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1171 | |||
1172 | {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1173 | {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0}, | ||
1174 | {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1175 | |||
1176 | {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1177 | {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0}, | ||
1178 | |||
1179 | {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1180 | |||
1181 | {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1182 | |||
1183 | {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0}, | ||
1184 | |||
1185 | {2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1186 | {2484, 2484, 20, 0, 20, 5, NO_DFS, | ||
1187 | PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0}, | ||
1188 | |||
1189 | {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1190 | |||
1191 | {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1192 | {2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1193 | {2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1194 | {2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1195 | {2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1196 | {2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1197 | {2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, | ||
1198 | {2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, | ||
1199 | {2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, | ||
1200 | {2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, | ||
1201 | {2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, | ||
1202 | {2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, | ||
1203 | }; | ||
1204 | |||
1205 | enum { | ||
1206 | G1_2312_2372, | ||
1207 | G2_2312_2372, | ||
1208 | |||
1209 | G1_2412_2472, | ||
1210 | G2_2412_2472, | ||
1211 | G3_2412_2472, | ||
1212 | |||
1213 | G1_2412_2462, | ||
1214 | G2_2412_2462, | ||
1215 | |||
1216 | G1_2432_2442, | ||
1217 | |||
1218 | G1_2457_2472, | ||
1219 | |||
1220 | G1_2512_2732, | ||
1221 | |||
1222 | G1_2467_2472, | ||
1223 | |||
1224 | WG1_2312_2372, | ||
1225 | WG1_2412_2462, | ||
1226 | WG1_2467_2472, | ||
1227 | WG2_2467_2472, | ||
1228 | G_DEMO_ALL_CHANNELS | ||
1229 | }; | ||
1230 | |||
1231 | static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = { | ||
1232 | {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1233 | {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1234 | |||
1235 | {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1236 | {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0}, | ||
1237 | {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1238 | |||
1239 | {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1240 | {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0}, | ||
1241 | |||
1242 | {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1243 | |||
1244 | {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1245 | |||
1246 | {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1247 | |||
1248 | {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0}, | ||
1249 | |||
1250 | {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1251 | {2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1252 | {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0}, | ||
1253 | {2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0}, | ||
1254 | {2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0}, | ||
1255 | }; | ||
1256 | |||
1257 | enum { | ||
1258 | T1_2312_2372, | ||
1259 | T1_2437_2437, | ||
1260 | T2_2437_2437, | ||
1261 | T3_2437_2437, | ||
1262 | T1_2512_2732 | ||
1263 | }; | 471 | }; |
1264 | 472 | ||
1265 | static struct regDomain regDomains[] = { | ||
1266 | |||
1267 | {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ, | ||
1268 | BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1269 | -1), | ||
1270 | BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1271 | -1), | ||
1272 | BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1, | ||
1273 | -1, -1, -1, -1, -1, -1), | ||
1274 | BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1, | ||
1275 | -1, -1, -1, -1, -1, -1), | ||
1276 | BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1277 | -1), | ||
1278 | BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1, | ||
1279 | -1, -1, -1, -1)}, | ||
1280 | |||
1281 | {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1282 | BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1283 | BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1284 | BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1285 | BMZERO, | ||
1286 | BMZERO, | ||
1287 | BMZERO}, | ||
1288 | |||
1289 | {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1290 | BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1291 | BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1292 | BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1293 | BMZERO, | ||
1294 | BMZERO, | ||
1295 | BMZERO}, | ||
1296 | |||
1297 | {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1298 | BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1299 | -1), | ||
1300 | BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1301 | -1), | ||
1302 | BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1303 | BMZERO, | ||
1304 | BMZERO, | ||
1305 | BMZERO}, | ||
1306 | |||
1307 | {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1308 | BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1309 | -1), | ||
1310 | BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1311 | -1), | ||
1312 | BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1313 | -1), | ||
1314 | BMZERO, | ||
1315 | BMZERO, | ||
1316 | BMZERO}, | ||
1317 | |||
1318 | {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1319 | BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1320 | BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1321 | BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1322 | BMZERO, | ||
1323 | BMZERO, | ||
1324 | BMZERO}, | ||
1325 | |||
1326 | {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ, | ||
1327 | BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1, | ||
1328 | -1, -1, -1, -1), | ||
1329 | BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1, | ||
1330 | -1, -1, -1, -1), | ||
1331 | BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1332 | -1), | ||
1333 | BMZERO, | ||
1334 | BMZERO, | ||
1335 | BMZERO}, | ||
1336 | |||
1337 | {APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ, | ||
1338 | BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1, | ||
1339 | -1, -1, -1, -1), | ||
1340 | BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1341 | -1), | ||
1342 | BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1343 | -1), | ||
1344 | BMZERO, | ||
1345 | BMZERO, | ||
1346 | BMZERO}, | ||
1347 | |||
1348 | {APL8, ETSI, NO_DFS, NO_PSCAN, | ||
1349 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1350 | BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1351 | -1), | ||
1352 | BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1353 | -1), | ||
1354 | BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1355 | -1), | ||
1356 | BMZERO, | ||
1357 | BMZERO, | ||
1358 | BMZERO}, | ||
1359 | |||
1360 | {APL9, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1361 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1362 | BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1, | ||
1363 | -1, -1, -1, -1), | ||
1364 | BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1365 | -1), | ||
1366 | BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1367 | -1), | ||
1368 | BMZERO, | ||
1369 | BMZERO, | ||
1370 | BMZERO}, | ||
1371 | |||
1372 | {APL10, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1373 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1374 | BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1, | ||
1375 | -1, -1, -1, -1), | ||
1376 | BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1377 | -1), | ||
1378 | BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1379 | -1), | ||
1380 | BMZERO, | ||
1381 | BMZERO, | ||
1382 | BMZERO}, | ||
1383 | |||
1384 | {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1385 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1386 | BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1, | ||
1387 | -1, -1, -1, -1), | ||
1388 | BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1389 | BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1390 | -1), | ||
1391 | BMZERO, | ||
1392 | BMZERO, | ||
1393 | BMZERO}, | ||
1394 | |||
1395 | {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1396 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1397 | BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1398 | BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1399 | BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1400 | BMZERO, | ||
1401 | BMZERO, | ||
1402 | BMZERO}, | ||
1403 | |||
1404 | {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1405 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1406 | BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1407 | -1), | ||
1408 | BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1409 | BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1410 | BMZERO, | ||
1411 | BMZERO, | ||
1412 | BMZERO}, | ||
1413 | |||
1414 | {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1415 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1416 | BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1417 | -1), | ||
1418 | BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1419 | BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1420 | BMZERO, | ||
1421 | BMZERO, | ||
1422 | BMZERO}, | ||
1423 | |||
1424 | {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1425 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1426 | BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1427 | BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1428 | BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1429 | BMZERO, | ||
1430 | BMZERO, | ||
1431 | BMZERO}, | ||
1432 | |||
1433 | {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI, | ||
1434 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1435 | BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1, | ||
1436 | -1, -1, -1, -1), | ||
1437 | BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1438 | BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1439 | BMZERO, | ||
1440 | BMZERO, | ||
1441 | BMZERO}, | ||
1442 | |||
1443 | {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1444 | BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1, | ||
1445 | -1, -1, -1, -1), | ||
1446 | BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1, | ||
1447 | -1, -1, -1, -1), | ||
1448 | BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1, | ||
1449 | -1, -1, -1, -1), | ||
1450 | BMZERO, | ||
1451 | BMZERO, | ||
1452 | BMZERO}, | ||
1453 | |||
1454 | {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1455 | BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1, | ||
1456 | -1, -1, -1, -1), | ||
1457 | BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1, | ||
1458 | -1, -1, -1, -1), | ||
1459 | BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1, | ||
1460 | -1, -1, -1, -1, -1, -1), | ||
1461 | BMZERO, | ||
1462 | BMZERO, | ||
1463 | BMZERO}, | ||
1464 | |||
1465 | {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, | ||
1466 | BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1, | ||
1467 | -1, -1, -1, -1, -1, -1), | ||
1468 | BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1469 | -1), | ||
1470 | BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1471 | -1), | ||
1472 | BMZERO, | ||
1473 | BMZERO, | ||
1474 | BMZERO}, | ||
1475 | |||
1476 | {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, | ||
1477 | BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1, | ||
1478 | -1, -1, -1, -1), | ||
1479 | BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1, | ||
1480 | -1, -1, -1, -1), | ||
1481 | BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1, | ||
1482 | -1, -1, -1, -1), | ||
1483 | BMZERO, | ||
1484 | BMZERO, | ||
1485 | BMZERO}, | ||
1486 | |||
1487 | {FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1488 | BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1489 | -1), | ||
1490 | BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1491 | -1), | ||
1492 | BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1493 | -1), | ||
1494 | BMZERO, | ||
1495 | BMZERO, | ||
1496 | BMZERO}, | ||
1497 | |||
1498 | {FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ, | ||
1499 | BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700, | ||
1500 | F6_5745_5825, -1, -1, -1, -1, -1, -1, -1), | ||
1501 | BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1, | ||
1502 | -1, -1, -1, -1), | ||
1503 | BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1, | ||
1504 | -1, -1, -1, -1, -1, -1), | ||
1505 | BMZERO, | ||
1506 | BMZERO, | ||
1507 | BMZERO}, | ||
1508 | |||
1509 | {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, | ||
1510 | BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, | ||
1511 | -1, -1, -1, -1, -1, -1), | ||
1512 | BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1513 | BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1514 | BMZERO, | ||
1515 | BMZERO, | ||
1516 | BMZERO}, | ||
1517 | |||
1518 | {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB, | ||
1519 | BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, | ||
1520 | F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240, | ||
1521 | F2_5260_5320, F4_5500_5700, -1, -1), | ||
1522 | BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1523 | BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1524 | BMZERO, | ||
1525 | BMZERO, | ||
1526 | BMZERO}, | ||
1527 | |||
1528 | |||
1529 | {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, | ||
1530 | BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1531 | BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1532 | BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1533 | BMZERO, | ||
1534 | BMZERO, | ||
1535 | BMZERO}, | ||
1536 | |||
1537 | |||
1538 | {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, | ||
1539 | BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1540 | -1), | ||
1541 | BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1542 | BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1543 | BMZERO, | ||
1544 | BMZERO, | ||
1545 | BMZERO}, | ||
1546 | |||
1547 | |||
1548 | {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, | ||
1549 | BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, | ||
1550 | -1, -1, -1, -1), | ||
1551 | BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1552 | BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1553 | -1), | ||
1554 | BMZERO, | ||
1555 | BMZERO, | ||
1556 | BMZERO}, | ||
1557 | |||
1558 | |||
1559 | {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, | ||
1560 | BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1561 | -1), | ||
1562 | BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1563 | BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1564 | BMZERO, | ||
1565 | BMZERO, | ||
1566 | BMZERO}, | ||
1567 | |||
1568 | |||
1569 | {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3, | ||
1570 | DISALLOW_ADHOC_11A_TURB, | ||
1571 | BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, | ||
1572 | -1, -1, -1, -1), | ||
1573 | BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1574 | BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1575 | BMZERO, | ||
1576 | BMZERO, | ||
1577 | BMZERO}, | ||
1578 | |||
1579 | |||
1580 | {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3, | ||
1581 | DISALLOW_ADHOC_11A_TURB, | ||
1582 | BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, | ||
1583 | -1, -1, -1, -1, -1, -1), | ||
1584 | BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1585 | BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1586 | -1), | ||
1587 | BMZERO, | ||
1588 | BMZERO, | ||
1589 | BMZERO}, | ||
1590 | |||
1591 | |||
1592 | {MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3, | ||
1593 | DISALLOW_ADHOC_11A_TURB, | ||
1594 | BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, | ||
1595 | F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1), | ||
1596 | BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1597 | BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1598 | BMZERO, | ||
1599 | BMZERO, | ||
1600 | BMZERO}, | ||
1601 | |||
1602 | |||
1603 | {MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3, | ||
1604 | DISALLOW_ADHOC_11A_TURB, | ||
1605 | BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, | ||
1606 | F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1, | ||
1607 | -1, -1), | ||
1608 | BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1609 | BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1610 | BMZERO, | ||
1611 | BMZERO, | ||
1612 | BMZERO}, | ||
1613 | |||
1614 | |||
1615 | {MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, | ||
1616 | BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, | ||
1617 | F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, | ||
1618 | F4_5500_5700, -1, -1, -1), | ||
1619 | BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1620 | BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1621 | BMZERO, | ||
1622 | BMZERO, | ||
1623 | BMZERO}, | ||
1624 | |||
1625 | |||
1626 | {MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3, | ||
1627 | DISALLOW_ADHOC_11A_TURB, | ||
1628 | BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, | ||
1629 | F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240, | ||
1630 | F2_5260_5320, F4_5500_5700, -1, -1), | ||
1631 | BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1632 | BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1633 | BMZERO, | ||
1634 | BMZERO, | ||
1635 | BMZERO}, | ||
1636 | |||
1637 | |||
1638 | {MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3, | ||
1639 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1640 | BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, | ||
1641 | -1, -1, -1, -1, -1, -1), | ||
1642 | BMZERO, | ||
1643 | BMZERO, | ||
1644 | BMZERO, | ||
1645 | BMZERO, | ||
1646 | BMZERO}, | ||
1647 | |||
1648 | |||
1649 | {MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, | ||
1650 | BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, | ||
1651 | F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1, | ||
1652 | -1, -1), | ||
1653 | BMZERO, | ||
1654 | BMZERO, | ||
1655 | BMZERO, | ||
1656 | BMZERO, | ||
1657 | BMZERO}, | ||
1658 | |||
1659 | |||
1660 | {MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, | ||
1661 | BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, | ||
1662 | F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, | ||
1663 | F2_5260_5320, -1, -1, -1), | ||
1664 | BMZERO, | ||
1665 | BMZERO, | ||
1666 | BMZERO, | ||
1667 | BMZERO, | ||
1668 | BMZERO}, | ||
1669 | |||
1670 | |||
1671 | {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, | ||
1672 | BMZERO, | ||
1673 | BMZERO, | ||
1674 | BMZERO, | ||
1675 | BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1676 | -1), | ||
1677 | BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1678 | -1), | ||
1679 | BMZERO}, | ||
1680 | |||
1681 | {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA, | ||
1682 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1683 | BMZERO, | ||
1684 | BMZERO, | ||
1685 | BMZERO, | ||
1686 | BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1687 | BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1688 | BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1689 | |||
1690 | {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB, | ||
1691 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1692 | BMZERO, | ||
1693 | BMZERO, | ||
1694 | BMZERO, | ||
1695 | BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1696 | BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1697 | BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1698 | |||
1699 | {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC, | ||
1700 | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, | ||
1701 | BMZERO, | ||
1702 | BMZERO, | ||
1703 | BMZERO, | ||
1704 | BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1705 | BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1706 | BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1707 | |||
1708 | {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ, | ||
1709 | BMZERO, | ||
1710 | BMZERO, | ||
1711 | BMZERO, | ||
1712 | BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1713 | BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1714 | BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1715 | |||
1716 | {MKKA, MKK, NO_DFS, | ||
1717 | PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G | | ||
1718 | PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB, | ||
1719 | BMZERO, | ||
1720 | BMZERO, | ||
1721 | BMZERO, | ||
1722 | BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1, | ||
1723 | -1, -1, -1, -1), | ||
1724 | BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1725 | -1), | ||
1726 | BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1727 | |||
1728 | {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ, | ||
1729 | BMZERO, | ||
1730 | BMZERO, | ||
1731 | BMZERO, | ||
1732 | BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1733 | BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1734 | BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1735 | |||
1736 | {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ, | ||
1737 | BMZERO, | ||
1738 | BMZERO, | ||
1739 | BMZERO, | ||
1740 | BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1741 | BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1742 | BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1743 | |||
1744 | {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, | ||
1745 | BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, | ||
1746 | W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), | ||
1747 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1748 | -1, -1, -1, -1, -1), | ||
1749 | BMZERO, | ||
1750 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1751 | W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, | ||
1752 | -1, -1), | ||
1753 | BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1754 | -1, -1), | ||
1755 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1756 | |||
1757 | {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, | ||
1758 | ADHOC_PER_11D, | ||
1759 | BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, | ||
1760 | W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), | ||
1761 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1762 | -1, -1, -1, -1, -1), | ||
1763 | BMZERO, | ||
1764 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, | ||
1765 | W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), | ||
1766 | BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1767 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1768 | |||
1769 | {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, | ||
1770 | ADHOC_PER_11D, | ||
1771 | BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, | ||
1772 | W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), | ||
1773 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1774 | -1, -1, -1, -1, -1), | ||
1775 | BMZERO, | ||
1776 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1777 | W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), | ||
1778 | BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1779 | -1, -1), | ||
1780 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1781 | |||
1782 | {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, | ||
1783 | BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, | ||
1784 | W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), | ||
1785 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1786 | -1, -1, -1, -1, -1), | ||
1787 | BMZERO, | ||
1788 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472, | ||
1789 | W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), | ||
1790 | BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1791 | -1, -1), | ||
1792 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1793 | |||
1794 | {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, | ||
1795 | BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, | ||
1796 | W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), | ||
1797 | BMZERO, | ||
1798 | BMZERO, | ||
1799 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1800 | W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, | ||
1801 | -1, -1), | ||
1802 | BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1803 | -1, -1), | ||
1804 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1805 | |||
1806 | {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, | ||
1807 | BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, | ||
1808 | W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), | ||
1809 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1810 | -1, -1, -1, -1, -1), | ||
1811 | BMZERO, | ||
1812 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1813 | W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, | ||
1814 | -1, -1), | ||
1815 | BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1816 | -1, -1), | ||
1817 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1818 | |||
1819 | {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, | ||
1820 | BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1, | ||
1821 | -1, -1, -1, -1, -1, -1), | ||
1822 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1823 | -1, -1, -1, -1, -1), | ||
1824 | BMZERO, | ||
1825 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1826 | W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), | ||
1827 | BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1828 | -1, -1), | ||
1829 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1830 | |||
1831 | {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, | ||
1832 | BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1, | ||
1833 | -1, -1, -1, -1), | ||
1834 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1835 | -1, -1, -1, -1, -1), | ||
1836 | BMZERO, | ||
1837 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, | ||
1838 | W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), | ||
1839 | BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1840 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1841 | |||
1842 | {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, | ||
1843 | BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1, | ||
1844 | -1, -1, -1, -1), | ||
1845 | BMZERO, | ||
1846 | BMZERO, | ||
1847 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1848 | W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), | ||
1849 | BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1850 | -1, -1), | ||
1851 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1852 | |||
1853 | {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, | ||
1854 | BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, | ||
1855 | -1, -1, -1, -1, -1, -1), | ||
1856 | BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, | ||
1857 | -1, -1, -1, -1, -1), | ||
1858 | BMZERO, | ||
1859 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, | ||
1860 | W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), | ||
1861 | BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), | ||
1862 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1863 | |||
1864 | {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, | ||
1865 | BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, | ||
1866 | -1, -1, -1, -1, -1, -1), | ||
1867 | BMZERO, | ||
1868 | BMZERO, | ||
1869 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1870 | W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), | ||
1871 | BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1872 | -1, -1), | ||
1873 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1874 | |||
1875 | {WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, | ||
1876 | BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1, | ||
1877 | -1, -1, -1, -1), | ||
1878 | BMZERO, | ||
1879 | BMZERO, | ||
1880 | BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, | ||
1881 | W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), | ||
1882 | BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, | ||
1883 | -1, -1), | ||
1884 | BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, | ||
1885 | |||
1886 | {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, | ||
1887 | BMZERO, | ||
1888 | BMZERO, | ||
1889 | BMZERO, | ||
1890 | BMZERO, | ||
1891 | BMZERO, | ||
1892 | BMZERO} | ||
1893 | }; | ||
1894 | |||
1895 | static const struct cmode modes[] = { | ||
1896 | {ATH9K_MODE_11A, CHANNEL_A}, | ||
1897 | {ATH9K_MODE_11B, CHANNEL_B}, | ||
1898 | {ATH9K_MODE_11G, CHANNEL_G}, | ||
1899 | {ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20}, | ||
1900 | {ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS}, | ||
1901 | {ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS}, | ||
1902 | {ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20}, | ||
1903 | {ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS}, | ||
1904 | {ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS}, | ||
1905 | }; | ||
1906 | |||
1907 | static struct japan_bandcheck j_bandcheck[] = { | ||
1908 | {F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD}, | ||
1909 | {F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN}, | ||
1910 | {F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2}, | ||
1911 | {F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND} | ||
1912 | }; | ||
1913 | |||
1914 | |||
1915 | #endif | 473 | #endif |
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index c92f0c6e4adc..007ca91188d1 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
@@ -55,94 +55,19 @@ static u32 bits_per_symbol[][2] = { | |||
55 | 55 | ||
56 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) | 56 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) |
57 | 57 | ||
58 | /* | 58 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, |
59 | * Insert a chain of ath_buf (descriptors) on a txq and | 59 | struct ath_atx_tid *tid, |
60 | * assume the descriptors are already chained together by caller. | 60 | struct list_head *bf_head); |
61 | * NB: must be called with txq lock held | 61 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
62 | */ | 62 | struct list_head *bf_q, |
63 | 63 | int txok, int sendbar); | |
64 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 64 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
65 | struct list_head *head) | 65 | struct list_head *head); |
66 | { | 66 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); |
67 | struct ath_hal *ah = sc->sc_ah; | ||
68 | struct ath_buf *bf; | ||
69 | 67 | ||
70 | /* | 68 | /*********************/ |
71 | * Insert the frame on the outbound list and | 69 | /* Aggregation logic */ |
72 | * pass it on to the hardware. | 70 | /*********************/ |
73 | */ | ||
74 | |||
75 | if (list_empty(head)) | ||
76 | return; | ||
77 | |||
78 | bf = list_first_entry(head, struct ath_buf, list); | ||
79 | |||
80 | list_splice_tail_init(head, &txq->axq_q); | ||
81 | txq->axq_depth++; | ||
82 | txq->axq_totalqueued++; | ||
83 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); | ||
84 | |||
85 | DPRINTF(sc, ATH_DBG_QUEUE, | ||
86 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | ||
87 | |||
88 | if (txq->axq_link == NULL) { | ||
89 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | ||
90 | DPRINTF(sc, ATH_DBG_XMIT, | ||
91 | "TXDP[%u] = %llx (%p)\n", | ||
92 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | ||
93 | } else { | ||
94 | *txq->axq_link = bf->bf_daddr; | ||
95 | DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n", | ||
96 | txq->axq_qnum, txq->axq_link, | ||
97 | ito64(bf->bf_daddr), bf->bf_desc); | ||
98 | } | ||
99 | txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link); | ||
100 | ath9k_hw_txstart(ah, txq->axq_qnum); | ||
101 | } | ||
102 | |||
103 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | ||
104 | struct ath_xmit_status *tx_status) | ||
105 | { | ||
106 | struct ieee80211_hw *hw = sc->hw; | ||
107 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
108 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
109 | int hdrlen, padsize; | ||
110 | |||
111 | DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | ||
112 | |||
113 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | ||
114 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
115 | kfree(tx_info_priv); | ||
116 | tx_info->rate_driver_data[0] = NULL; | ||
117 | } | ||
118 | |||
119 | if (tx_status->flags & ATH_TX_BAR) { | ||
120 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | ||
121 | tx_status->flags &= ~ATH_TX_BAR; | ||
122 | } | ||
123 | |||
124 | if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { | ||
125 | /* Frame was ACKed */ | ||
126 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | ||
127 | } | ||
128 | |||
129 | tx_info->status.rates[0].count = tx_status->retries + 1; | ||
130 | |||
131 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
132 | padsize = hdrlen & 3; | ||
133 | if (padsize && hdrlen >= 24) { | ||
134 | /* | ||
135 | * Remove MAC header padding before giving the frame back to | ||
136 | * mac80211. | ||
137 | */ | ||
138 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
139 | skb_pull(skb, padsize); | ||
140 | } | ||
141 | |||
142 | ieee80211_tx_status(hw, skb); | ||
143 | } | ||
144 | |||
145 | /* Check if it's okay to send out aggregates */ | ||
146 | 71 | ||
147 | static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) | 72 | static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) |
148 | { | 73 | { |
@@ -156,232 +81,19 @@ static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno) | |||
156 | return 0; | 81 | return 0; |
157 | } | 82 | } |
158 | 83 | ||
159 | static void ath_get_beaconconfig(struct ath_softc *sc, int if_id, | ||
160 | struct ath_beacon_config *conf) | ||
161 | { | ||
162 | struct ieee80211_hw *hw = sc->hw; | ||
163 | |||
164 | /* fill in beacon config data */ | ||
165 | |||
166 | conf->beacon_interval = hw->conf.beacon_int; | ||
167 | conf->listen_interval = 100; | ||
168 | conf->dtim_count = 1; | ||
169 | conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; | ||
170 | } | ||
171 | |||
172 | /* Calculate Atheros packet type from IEEE80211 packet header */ | ||
173 | |||
174 | static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | ||
175 | { | ||
176 | struct ieee80211_hdr *hdr; | ||
177 | enum ath9k_pkt_type htype; | ||
178 | __le16 fc; | ||
179 | |||
180 | hdr = (struct ieee80211_hdr *)skb->data; | ||
181 | fc = hdr->frame_control; | ||
182 | |||
183 | if (ieee80211_is_beacon(fc)) | ||
184 | htype = ATH9K_PKT_TYPE_BEACON; | ||
185 | else if (ieee80211_is_probe_resp(fc)) | ||
186 | htype = ATH9K_PKT_TYPE_PROBE_RESP; | ||
187 | else if (ieee80211_is_atim(fc)) | ||
188 | htype = ATH9K_PKT_TYPE_ATIM; | ||
189 | else if (ieee80211_is_pspoll(fc)) | ||
190 | htype = ATH9K_PKT_TYPE_PSPOLL; | ||
191 | else | ||
192 | htype = ATH9K_PKT_TYPE_NORMAL; | ||
193 | |||
194 | return htype; | ||
195 | } | ||
196 | |||
197 | static bool is_pae(struct sk_buff *skb) | ||
198 | { | ||
199 | struct ieee80211_hdr *hdr; | ||
200 | __le16 fc; | ||
201 | |||
202 | hdr = (struct ieee80211_hdr *)skb->data; | ||
203 | fc = hdr->frame_control; | ||
204 | |||
205 | if (ieee80211_is_data(fc)) { | ||
206 | if (ieee80211_is_nullfunc(fc) || | ||
207 | /* Port Access Entity (IEEE 802.1X) */ | ||
208 | (skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
209 | return true; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | return false; | ||
214 | } | ||
215 | |||
216 | static int get_hw_crypto_keytype(struct sk_buff *skb) | ||
217 | { | ||
218 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
219 | |||
220 | if (tx_info->control.hw_key) { | ||
221 | if (tx_info->control.hw_key->alg == ALG_WEP) | ||
222 | return ATH9K_KEY_TYPE_WEP; | ||
223 | else if (tx_info->control.hw_key->alg == ALG_TKIP) | ||
224 | return ATH9K_KEY_TYPE_TKIP; | ||
225 | else if (tx_info->control.hw_key->alg == ALG_CCMP) | ||
226 | return ATH9K_KEY_TYPE_AES; | ||
227 | } | ||
228 | |||
229 | return ATH9K_KEY_TYPE_CLEAR; | ||
230 | } | ||
231 | |||
232 | /* Called only when tx aggregation is enabled and HT is supported */ | ||
233 | |||
234 | static void assign_aggr_tid_seqno(struct sk_buff *skb, | ||
235 | struct ath_buf *bf) | ||
236 | { | ||
237 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
238 | struct ieee80211_hdr *hdr; | ||
239 | struct ath_node *an; | ||
240 | struct ath_atx_tid *tid; | ||
241 | __le16 fc; | ||
242 | u8 *qc; | ||
243 | |||
244 | if (!tx_info->control.sta) | ||
245 | return; | ||
246 | |||
247 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | ||
248 | hdr = (struct ieee80211_hdr *)skb->data; | ||
249 | fc = hdr->frame_control; | ||
250 | |||
251 | /* Get tidno */ | ||
252 | |||
253 | if (ieee80211_is_data_qos(fc)) { | ||
254 | qc = ieee80211_get_qos_ctl(hdr); | ||
255 | bf->bf_tidno = qc[0] & 0xf; | ||
256 | } | ||
257 | |||
258 | /* Get seqno */ | ||
259 | /* For HT capable stations, we save tidno for later use. | ||
260 | * We also override seqno set by upper layer with the one | ||
261 | * in tx aggregation state. | ||
262 | * | ||
263 | * If fragmentation is on, the sequence number is | ||
264 | * not overridden, since it has been | ||
265 | * incremented by the fragmentation routine. | ||
266 | * | ||
267 | * FIXME: check if the fragmentation threshold exceeds | ||
268 | * IEEE80211 max. | ||
269 | */ | ||
270 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
271 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << | ||
272 | IEEE80211_SEQ_SEQ_SHIFT); | ||
273 | bf->bf_seqno = tid->seq_next; | ||
274 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
275 | } | ||
276 | |||
277 | static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, | ||
278 | struct ath_txq *txq) | ||
279 | { | ||
280 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
281 | int flags = 0; | ||
282 | |||
283 | flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ | ||
284 | flags |= ATH9K_TXDESC_INTREQ; | ||
285 | |||
286 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
287 | flags |= ATH9K_TXDESC_NOACK; | ||
288 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
289 | flags |= ATH9K_TXDESC_RTSENA; | ||
290 | |||
291 | return flags; | ||
292 | } | ||
293 | |||
294 | static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) | ||
295 | { | ||
296 | struct ath_buf *bf = NULL; | ||
297 | |||
298 | spin_lock_bh(&sc->tx.txbuflock); | ||
299 | |||
300 | if (unlikely(list_empty(&sc->tx.txbuf))) { | ||
301 | spin_unlock_bh(&sc->tx.txbuflock); | ||
302 | return NULL; | ||
303 | } | ||
304 | |||
305 | bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | ||
306 | list_del(&bf->list); | ||
307 | |||
308 | spin_unlock_bh(&sc->tx.txbuflock); | ||
309 | |||
310 | return bf; | ||
311 | } | ||
312 | |||
313 | /* To complete a chain of buffers associated a frame */ | ||
314 | |||
315 | static void ath_tx_complete_buf(struct ath_softc *sc, | ||
316 | struct ath_buf *bf, | ||
317 | struct list_head *bf_q, | ||
318 | int txok, int sendbar) | ||
319 | { | ||
320 | struct sk_buff *skb = bf->bf_mpdu; | ||
321 | struct ath_xmit_status tx_status; | ||
322 | unsigned long flags; | ||
323 | |||
324 | /* | ||
325 | * Set retry information. | ||
326 | * NB: Don't use the information in the descriptor, because the frame | ||
327 | * could be software retried. | ||
328 | */ | ||
329 | tx_status.retries = bf->bf_retries; | ||
330 | tx_status.flags = 0; | ||
331 | |||
332 | if (sendbar) | ||
333 | tx_status.flags = ATH_TX_BAR; | ||
334 | |||
335 | if (!txok) { | ||
336 | tx_status.flags |= ATH_TX_ERROR; | ||
337 | |||
338 | if (bf_isxretried(bf)) | ||
339 | tx_status.flags |= ATH_TX_XRETRY; | ||
340 | } | ||
341 | |||
342 | /* Unmap this frame */ | ||
343 | pci_unmap_single(sc->pdev, | ||
344 | bf->bf_dmacontext, | ||
345 | skb->len, | ||
346 | PCI_DMA_TODEVICE); | ||
347 | /* complete this frame */ | ||
348 | ath_tx_complete(sc, skb, &tx_status); | ||
349 | |||
350 | /* | ||
351 | * Return the list of ath_buf of this mpdu to free queue | ||
352 | */ | ||
353 | spin_lock_irqsave(&sc->tx.txbuflock, flags); | ||
354 | list_splice_tail_init(bf_q, &sc->tx.txbuf); | ||
355 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); | ||
356 | } | ||
357 | |||
358 | /* | ||
359 | * queue up a dest/ac pair for tx scheduling | ||
360 | * NB: must be called with txq lock held | ||
361 | */ | ||
362 | |||
363 | static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) | 84 | static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) |
364 | { | 85 | { |
365 | struct ath_atx_ac *ac = tid->ac; | 86 | struct ath_atx_ac *ac = tid->ac; |
366 | 87 | ||
367 | /* | ||
368 | * if tid is paused, hold off | ||
369 | */ | ||
370 | if (tid->paused) | 88 | if (tid->paused) |
371 | return; | 89 | return; |
372 | 90 | ||
373 | /* | ||
374 | * add tid to ac atmost once | ||
375 | */ | ||
376 | if (tid->sched) | 91 | if (tid->sched) |
377 | return; | 92 | return; |
378 | 93 | ||
379 | tid->sched = true; | 94 | tid->sched = true; |
380 | list_add_tail(&tid->list, &ac->tid_q); | 95 | list_add_tail(&tid->list, &ac->tid_q); |
381 | 96 | ||
382 | /* | ||
383 | * add node ac to txq atmost once | ||
384 | */ | ||
385 | if (ac->sched) | 97 | if (ac->sched) |
386 | return; | 98 | return; |
387 | 99 | ||
@@ -389,22 +101,16 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) | |||
389 | list_add_tail(&ac->list, &txq->axq_acq); | 101 | list_add_tail(&ac->list, &txq->axq_acq); |
390 | } | 102 | } |
391 | 103 | ||
392 | /* pause a tid */ | ||
393 | |||
394 | static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 104 | static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
395 | { | 105 | { |
396 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | 106 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; |
397 | 107 | ||
398 | spin_lock_bh(&txq->axq_lock); | 108 | spin_lock_bh(&txq->axq_lock); |
399 | |||
400 | tid->paused++; | 109 | tid->paused++; |
401 | |||
402 | spin_unlock_bh(&txq->axq_lock); | 110 | spin_unlock_bh(&txq->axq_lock); |
403 | } | 111 | } |
404 | 112 | ||
405 | /* resume a tid and schedule aggregate */ | 113 | static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
406 | |||
407 | void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | ||
408 | { | 114 | { |
409 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | 115 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; |
410 | 116 | ||
@@ -419,63 +125,39 @@ void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
419 | if (list_empty(&tid->buf_q)) | 125 | if (list_empty(&tid->buf_q)) |
420 | goto unlock; | 126 | goto unlock; |
421 | 127 | ||
422 | /* | ||
423 | * Add this TID to scheduler and try to send out aggregates | ||
424 | */ | ||
425 | ath_tx_queue_tid(txq, tid); | 128 | ath_tx_queue_tid(txq, tid); |
426 | ath_txq_schedule(sc, txq); | 129 | ath_txq_schedule(sc, txq); |
427 | unlock: | 130 | unlock: |
428 | spin_unlock_bh(&txq->axq_lock); | 131 | spin_unlock_bh(&txq->axq_lock); |
429 | } | 132 | } |
430 | 133 | ||
431 | /* Compute the number of bad frames */ | 134 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
432 | |||
433 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | ||
434 | int txok) | ||
435 | { | 135 | { |
436 | struct ath_buf *bf_last = bf->bf_lastbf; | 136 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; |
437 | struct ath_desc *ds = bf_last->bf_desc; | 137 | struct ath_buf *bf; |
438 | u16 seq_st = 0; | 138 | struct list_head bf_head; |
439 | u32 ba[WME_BA_BMP_SIZE >> 5]; | 139 | INIT_LIST_HEAD(&bf_head); |
440 | int ba_index; | ||
441 | int nbad = 0; | ||
442 | int isaggr = 0; | ||
443 | |||
444 | if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) | ||
445 | return 0; | ||
446 | 140 | ||
447 | isaggr = bf_isaggr(bf); | 141 | ASSERT(tid->paused > 0); |
448 | if (isaggr) { | 142 | spin_lock_bh(&txq->axq_lock); |
449 | seq_st = ATH_DS_BA_SEQ(ds); | ||
450 | memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); | ||
451 | } | ||
452 | 143 | ||
453 | while (bf) { | 144 | tid->paused--; |
454 | ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno); | ||
455 | if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) | ||
456 | nbad++; | ||
457 | 145 | ||
458 | bf = bf->bf_next; | 146 | if (tid->paused > 0) { |
147 | spin_unlock_bh(&txq->axq_lock); | ||
148 | return; | ||
459 | } | 149 | } |
460 | 150 | ||
461 | return nbad; | 151 | while (!list_empty(&tid->buf_q)) { |
462 | } | 152 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); |
463 | 153 | ASSERT(!bf_isretried(bf)); | |
464 | static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) | 154 | list_move_tail(&bf->list, &bf_head); |
465 | { | 155 | ath_tx_send_normal(sc, txq, tid, &bf_head); |
466 | struct sk_buff *skb; | 156 | } |
467 | struct ieee80211_hdr *hdr; | ||
468 | |||
469 | bf->bf_state.bf_type |= BUF_RETRY; | ||
470 | bf->bf_retries++; | ||
471 | 157 | ||
472 | skb = bf->bf_mpdu; | 158 | spin_unlock_bh(&txq->axq_lock); |
473 | hdr = (struct ieee80211_hdr *)skb->data; | ||
474 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); | ||
475 | } | 159 | } |
476 | 160 | ||
477 | /* Update block ack window */ | ||
478 | |||
479 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 161 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
480 | int seqno) | 162 | int seqno) |
481 | { | 163 | { |
@@ -492,290 +174,142 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
492 | } | 174 | } |
493 | } | 175 | } |
494 | 176 | ||
495 | /* | 177 | static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
496 | * ath_pkt_dur - compute packet duration (NB: not NAV) | 178 | struct ath_buf *bf) |
497 | * | ||
498 | * rix - rate index | ||
499 | * pktlen - total bytes (delims + data + fcs + pads + pad delims) | ||
500 | * width - 0 for 20 MHz, 1 for 40 MHz | ||
501 | * half_gi - to use 4us v/s 3.6 us for symbol time | ||
502 | */ | ||
503 | static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | ||
504 | int width, int half_gi, bool shortPreamble) | ||
505 | { | 179 | { |
506 | struct ath_rate_table *rate_table = sc->cur_rate_table; | 180 | int index, cindex; |
507 | u32 nbits, nsymbits, duration, nsymbols; | ||
508 | u8 rc; | ||
509 | int streams, pktlen; | ||
510 | |||
511 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; | ||
512 | rc = rate_table->info[rix].ratecode; | ||
513 | |||
514 | /* for legacy rates, use old function to compute packet duration */ | ||
515 | if (!IS_HT_RATE(rc)) | ||
516 | return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen, | ||
517 | rix, shortPreamble); | ||
518 | 181 | ||
519 | /* find number of symbols: PLCP + data */ | 182 | if (bf_isretried(bf)) |
520 | nbits = (pktlen << 3) + OFDM_PLCP_BITS; | 183 | return; |
521 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; | ||
522 | nsymbols = (nbits + nsymbits - 1) / nsymbits; | ||
523 | 184 | ||
524 | if (!half_gi) | 185 | index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); |
525 | duration = SYMBOL_TIME(nsymbols); | 186 | cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); |
526 | else | ||
527 | duration = SYMBOL_TIME_HALFGI(nsymbols); | ||
528 | 187 | ||
529 | /* addup duration for legacy/ht training and signal fields */ | 188 | ASSERT(tid->tx_buf[cindex] == NULL); |
530 | streams = HT_RC_2_STREAMS(rc); | 189 | tid->tx_buf[cindex] = bf; |
531 | duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | ||
532 | 190 | ||
533 | return duration; | 191 | if (index >= ((tid->baw_tail - tid->baw_head) & |
192 | (ATH_TID_MAX_BUFS - 1))) { | ||
193 | tid->baw_tail = cindex; | ||
194 | INCR(tid->baw_tail, ATH_TID_MAX_BUFS); | ||
195 | } | ||
534 | } | 196 | } |
535 | 197 | ||
536 | /* Rate module function to set rate related fields in tx descriptor */ | 198 | /* |
199 | * TODO: For frame(s) that are in the retry state, we will reuse the | ||
200 | * sequence number(s) without setting the retry bit. The | ||
201 | * alternative is to give up on these and BAR the receiver's window | ||
202 | * forward. | ||
203 | */ | ||
204 | static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | ||
205 | struct ath_atx_tid *tid) | ||
537 | 206 | ||
538 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | ||
539 | { | 207 | { |
540 | struct ath_hal *ah = sc->sc_ah; | 208 | struct ath_buf *bf; |
541 | struct ath_rate_table *rt; | 209 | struct list_head bf_head; |
542 | struct ath_desc *ds = bf->bf_desc; | 210 | INIT_LIST_HEAD(&bf_head); |
543 | struct ath_desc *lastds = bf->bf_lastbf->bf_desc; | ||
544 | struct ath9k_11n_rate_series series[4]; | ||
545 | struct sk_buff *skb; | ||
546 | struct ieee80211_tx_info *tx_info; | ||
547 | struct ieee80211_tx_rate *rates; | ||
548 | struct ieee80211_hdr *hdr; | ||
549 | int i, flags, rtsctsena = 0; | ||
550 | u32 ctsduration = 0; | ||
551 | u8 rix = 0, cix, ctsrate = 0; | ||
552 | __le16 fc; | ||
553 | |||
554 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | ||
555 | |||
556 | skb = (struct sk_buff *)bf->bf_mpdu; | ||
557 | hdr = (struct ieee80211_hdr *)skb->data; | ||
558 | fc = hdr->frame_control; | ||
559 | tx_info = IEEE80211_SKB_CB(skb); | ||
560 | rates = tx_info->control.rates; | ||
561 | |||
562 | if (ieee80211_has_morefrags(fc) || | ||
563 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { | ||
564 | rates[1].count = rates[2].count = rates[3].count = 0; | ||
565 | rates[1].idx = rates[2].idx = rates[3].idx = 0; | ||
566 | rates[0].count = ATH_TXMAXTRY; | ||
567 | } | ||
568 | 211 | ||
569 | /* get the cix for the lowest valid rix */ | 212 | for (;;) { |
570 | rt = sc->cur_rate_table; | 213 | if (list_empty(&tid->buf_q)) |
571 | for (i = 3; i >= 0; i--) { | ||
572 | if (rates[i].count && (rates[i].idx >= 0)) { | ||
573 | rix = rates[i].idx; | ||
574 | break; | 214 | break; |
575 | } | ||
576 | } | ||
577 | 215 | ||
578 | flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)); | 216 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); |
579 | cix = rt->info[rix].ctrl_rate; | 217 | list_move_tail(&bf->list, &bf_head); |
580 | |||
581 | /* | ||
582 | * If 802.11g protection is enabled, determine whether to use RTS/CTS or | ||
583 | * just CTS. Note that this is only done for OFDM/HT unicast frames. | ||
584 | */ | ||
585 | if (sc->sc_protmode != PROT_M_NONE && !(bf->bf_flags & ATH9K_TXDESC_NOACK) | ||
586 | && (rt->info[rix].phy == WLAN_RC_PHY_OFDM || | ||
587 | WLAN_RC_PHY_HT(rt->info[rix].phy))) { | ||
588 | if (sc->sc_protmode == PROT_M_RTSCTS) | ||
589 | flags = ATH9K_TXDESC_RTSENA; | ||
590 | else if (sc->sc_protmode == PROT_M_CTSONLY) | ||
591 | flags = ATH9K_TXDESC_CTSENA; | ||
592 | |||
593 | cix = rt->info[sc->sc_protrix].ctrl_rate; | ||
594 | rtsctsena = 1; | ||
595 | } | ||
596 | |||
597 | /* For 11n, the default behavior is to enable RTS for hw retried frames. | ||
598 | * We enable the global flag here and let rate series flags determine | ||
599 | * which rates will actually use RTS. | ||
600 | */ | ||
601 | if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) { | ||
602 | /* 802.11g protection not needed, use our default behavior */ | ||
603 | if (!rtsctsena) | ||
604 | flags = ATH9K_TXDESC_RTSENA; | ||
605 | } | ||
606 | |||
607 | /* Set protection if aggregate protection on */ | ||
608 | if (sc->sc_config.ath_aggr_prot && | ||
609 | (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { | ||
610 | flags = ATH9K_TXDESC_RTSENA; | ||
611 | cix = rt->info[sc->sc_protrix].ctrl_rate; | ||
612 | rtsctsena = 1; | ||
613 | } | ||
614 | |||
615 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ | ||
616 | if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) | ||
617 | flags &= ~(ATH9K_TXDESC_RTSENA); | ||
618 | |||
619 | /* | ||
620 | * CTS transmit rate is derived from the transmit rate by looking in the | ||
621 | * h/w rate table. We must also factor in whether or not a short | ||
622 | * preamble is to be used. NB: cix is set above where RTS/CTS is enabled | ||
623 | */ | ||
624 | ctsrate = rt->info[cix].ratecode | | ||
625 | (bf_isshpreamble(bf) ? rt->info[cix].short_preamble : 0); | ||
626 | |||
627 | for (i = 0; i < 4; i++) { | ||
628 | if (!rates[i].count || (rates[i].idx < 0)) | ||
629 | continue; | ||
630 | |||
631 | rix = rates[i].idx; | ||
632 | |||
633 | series[i].Rate = rt->info[rix].ratecode | | ||
634 | (bf_isshpreamble(bf) ? rt->info[rix].short_preamble : 0); | ||
635 | |||
636 | series[i].Tries = rates[i].count; | ||
637 | |||
638 | series[i].RateFlags = ( | ||
639 | (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) ? | ||
640 | ATH9K_RATESERIES_RTS_CTS : 0) | | ||
641 | ((rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? | ||
642 | ATH9K_RATESERIES_2040 : 0) | | ||
643 | ((rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ? | ||
644 | ATH9K_RATESERIES_HALFGI : 0); | ||
645 | |||
646 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, | ||
647 | (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0, | ||
648 | (rates[i].flags & IEEE80211_TX_RC_SHORT_GI), | ||
649 | bf_isshpreamble(bf)); | ||
650 | 218 | ||
651 | series[i].ChSel = sc->sc_tx_chainmask; | 219 | if (bf_isretried(bf)) |
220 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | ||
652 | 221 | ||
653 | if (rtsctsena) | 222 | spin_unlock(&txq->axq_lock); |
654 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | 223 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); |
224 | spin_lock(&txq->axq_lock); | ||
655 | } | 225 | } |
656 | 226 | ||
657 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ | 227 | tid->seq_next = tid->seq_start; |
658 | ath9k_hw_set11n_ratescenario(ah, ds, lastds, !bf_ispspoll(bf), | 228 | tid->baw_tail = tid->baw_head; |
659 | ctsrate, ctsduration, | ||
660 | series, 4, flags); | ||
661 | |||
662 | if (sc->sc_config.ath_aggr_prot && flags) | ||
663 | ath9k_hw_set11n_burstduration(ah, ds, 8192); | ||
664 | } | 229 | } |
665 | 230 | ||
666 | /* | 231 | static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) |
667 | * Function to send a normal HT (non-AMPDU) frame | ||
668 | * NB: must be called with txq lock held | ||
669 | */ | ||
670 | static int ath_tx_send_normal(struct ath_softc *sc, | ||
671 | struct ath_txq *txq, | ||
672 | struct ath_atx_tid *tid, | ||
673 | struct list_head *bf_head) | ||
674 | { | 232 | { |
675 | struct ath_buf *bf; | 233 | struct sk_buff *skb; |
676 | 234 | struct ieee80211_hdr *hdr; | |
677 | BUG_ON(list_empty(bf_head)); | ||
678 | |||
679 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
680 | bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */ | ||
681 | |||
682 | /* update starting sequence number for subsequent ADDBA request */ | ||
683 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | ||
684 | 235 | ||
685 | /* Queue to h/w without aggregation */ | 236 | bf->bf_state.bf_type |= BUF_RETRY; |
686 | bf->bf_nframes = 1; | 237 | bf->bf_retries++; |
687 | bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */ | ||
688 | ath_buf_set_rate(sc, bf); | ||
689 | ath_tx_txqaddbuf(sc, txq, bf_head); | ||
690 | 238 | ||
691 | return 0; | 239 | skb = bf->bf_mpdu; |
240 | hdr = (struct ieee80211_hdr *)skb->data; | ||
241 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); | ||
692 | } | 242 | } |
693 | 243 | ||
694 | /* flush tid's software queue and send frames as non-ampdu's */ | 244 | static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) |
695 | |||
696 | static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | ||
697 | { | 245 | { |
698 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | 246 | struct ath_buf *tbf; |
699 | struct ath_buf *bf; | ||
700 | struct list_head bf_head; | ||
701 | INIT_LIST_HEAD(&bf_head); | ||
702 | |||
703 | ASSERT(tid->paused > 0); | ||
704 | spin_lock_bh(&txq->axq_lock); | ||
705 | 247 | ||
706 | tid->paused--; | 248 | spin_lock_bh(&sc->tx.txbuflock); |
249 | ASSERT(!list_empty((&sc->tx.txbuf))); | ||
250 | tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | ||
251 | list_del(&tbf->list); | ||
252 | spin_unlock_bh(&sc->tx.txbuflock); | ||
707 | 253 | ||
708 | if (tid->paused > 0) { | 254 | ATH_TXBUF_RESET(tbf); |
709 | spin_unlock_bh(&txq->axq_lock); | ||
710 | return; | ||
711 | } | ||
712 | 255 | ||
713 | while (!list_empty(&tid->buf_q)) { | 256 | tbf->bf_mpdu = bf->bf_mpdu; |
714 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | 257 | tbf->bf_buf_addr = bf->bf_buf_addr; |
715 | ASSERT(!bf_isretried(bf)); | 258 | *(tbf->bf_desc) = *(bf->bf_desc); |
716 | list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list); | 259 | tbf->bf_state = bf->bf_state; |
717 | ath_tx_send_normal(sc, txq, tid, &bf_head); | 260 | tbf->bf_dmacontext = bf->bf_dmacontext; |
718 | } | ||
719 | 261 | ||
720 | spin_unlock_bh(&txq->axq_lock); | 262 | return tbf; |
721 | } | 263 | } |
722 | 264 | ||
723 | /* Completion routine of an aggregate */ | 265 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, |
724 | 266 | struct ath_buf *bf, struct list_head *bf_q, | |
725 | static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | 267 | int txok) |
726 | struct ath_txq *txq, | ||
727 | struct ath_buf *bf, | ||
728 | struct list_head *bf_q, | ||
729 | int txok) | ||
730 | { | 268 | { |
731 | struct ath_node *an = NULL; | 269 | struct ath_node *an = NULL; |
732 | struct sk_buff *skb; | 270 | struct sk_buff *skb; |
733 | struct ieee80211_tx_info *tx_info; | 271 | struct ieee80211_sta *sta; |
272 | struct ieee80211_hdr *hdr; | ||
734 | struct ath_atx_tid *tid = NULL; | 273 | struct ath_atx_tid *tid = NULL; |
735 | struct ath_buf *bf_last = bf->bf_lastbf; | 274 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
736 | struct ath_desc *ds = bf_last->bf_desc; | 275 | struct ath_desc *ds = bf_last->bf_desc; |
737 | struct ath_buf *bf_next, *bf_lastq = NULL; | ||
738 | struct list_head bf_head, bf_pending; | 276 | struct list_head bf_head, bf_pending; |
739 | u16 seq_st = 0; | 277 | u16 seq_st = 0; |
740 | u32 ba[WME_BA_BMP_SIZE >> 5]; | 278 | u32 ba[WME_BA_BMP_SIZE >> 5]; |
741 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0; | 279 | int isaggr, txfail, txpending, sendbar = 0, needreset = 0; |
742 | 280 | ||
743 | skb = (struct sk_buff *)bf->bf_mpdu; | 281 | skb = (struct sk_buff *)bf->bf_mpdu; |
744 | tx_info = IEEE80211_SKB_CB(skb); | 282 | hdr = (struct ieee80211_hdr *)skb->data; |
745 | 283 | ||
746 | if (tx_info->control.sta) { | 284 | rcu_read_lock(); |
747 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | 285 | |
748 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | 286 | sta = ieee80211_find_sta(sc->hw, hdr->addr1); |
287 | if (!sta) { | ||
288 | rcu_read_unlock(); | ||
289 | return; | ||
749 | } | 290 | } |
750 | 291 | ||
292 | an = (struct ath_node *)sta->drv_priv; | ||
293 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
294 | |||
751 | isaggr = bf_isaggr(bf); | 295 | isaggr = bf_isaggr(bf); |
752 | if (isaggr) { | 296 | memset(ba, 0, WME_BA_BMP_SIZE >> 3); |
753 | if (txok) { | ||
754 | if (ATH_DS_TX_BA(ds)) { | ||
755 | /* | ||
756 | * extract starting sequence and | ||
757 | * block-ack bitmap | ||
758 | */ | ||
759 | seq_st = ATH_DS_BA_SEQ(ds); | ||
760 | memcpy(ba, | ||
761 | ATH_DS_BA_BITMAP(ds), | ||
762 | WME_BA_BMP_SIZE >> 3); | ||
763 | } else { | ||
764 | memset(ba, 0, WME_BA_BMP_SIZE >> 3); | ||
765 | 297 | ||
766 | /* | 298 | if (isaggr && txok) { |
767 | * AR5416 can become deaf/mute when BA | 299 | if (ATH_DS_TX_BA(ds)) { |
768 | * issue happens. Chip needs to be reset. | 300 | seq_st = ATH_DS_BA_SEQ(ds); |
769 | * But AP code may have sychronization issues | 301 | memcpy(ba, ATH_DS_BA_BITMAP(ds), |
770 | * when perform internal reset in this routine. | 302 | WME_BA_BMP_SIZE >> 3); |
771 | * Only enable reset in STA mode for now. | ||
772 | */ | ||
773 | if (sc->sc_ah->ah_opmode == | ||
774 | NL80211_IFTYPE_STATION) | ||
775 | needreset = 1; | ||
776 | } | ||
777 | } else { | 303 | } else { |
778 | memset(ba, 0, WME_BA_BMP_SIZE >> 3); | 304 | /* |
305 | * AR5416 can become deaf/mute when BA | ||
306 | * issue happens. Chip needs to be reset. | ||
307 | * But AP code may have sychronization issues | ||
308 | * when perform internal reset in this routine. | ||
309 | * Only enable reset in STA mode for now. | ||
310 | */ | ||
311 | if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) | ||
312 | needreset = 1; | ||
779 | } | 313 | } |
780 | } | 314 | } |
781 | 315 | ||
@@ -792,7 +326,6 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
792 | } else if (!isaggr && txok) { | 326 | } else if (!isaggr && txok) { |
793 | /* transmit completion */ | 327 | /* transmit completion */ |
794 | } else { | 328 | } else { |
795 | |||
796 | if (!(tid->state & AGGR_CLEANUP) && | 329 | if (!(tid->state & AGGR_CLEANUP) && |
797 | ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { | 330 | ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { |
798 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { | 331 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { |
@@ -811,37 +344,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
811 | txfail = 1; | 344 | txfail = 1; |
812 | } | 345 | } |
813 | } | 346 | } |
814 | /* | ||
815 | * Remove ath_buf's of this sub-frame from aggregate queue. | ||
816 | */ | ||
817 | if (bf_next == NULL) { /* last subframe in the aggregate */ | ||
818 | ASSERT(bf->bf_lastfrm == bf_last); | ||
819 | |||
820 | /* | ||
821 | * The last descriptor of the last sub frame could be | ||
822 | * a holding descriptor for h/w. If that's the case, | ||
823 | * bf->bf_lastfrm won't be in the bf_q. | ||
824 | * Make sure we handle bf_q properly here. | ||
825 | */ | ||
826 | 347 | ||
827 | if (!list_empty(bf_q)) { | 348 | if (bf_next == NULL) { |
828 | bf_lastq = list_entry(bf_q->prev, | 349 | INIT_LIST_HEAD(&bf_head); |
829 | struct ath_buf, list); | ||
830 | list_cut_position(&bf_head, | ||
831 | bf_q, &bf_lastq->list); | ||
832 | } else { | ||
833 | /* | ||
834 | * XXX: if the last subframe only has one | ||
835 | * descriptor which is also being used as | ||
836 | * a holding descriptor. Then the ath_buf | ||
837 | * is not in the bf_q at all. | ||
838 | */ | ||
839 | INIT_LIST_HEAD(&bf_head); | ||
840 | } | ||
841 | } else { | 350 | } else { |
842 | ASSERT(!list_empty(bf_q)); | 351 | ASSERT(!list_empty(bf_q)); |
843 | list_cut_position(&bf_head, | 352 | list_move_tail(&bf->list, &bf_head); |
844 | bf_q, &bf->bf_lastfrm->list); | ||
845 | } | 353 | } |
846 | 354 | ||
847 | if (!txpending) { | 355 | if (!txpending) { |
@@ -853,62 +361,22 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
853 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | 361 | ath_tx_update_baw(sc, tid, bf->bf_seqno); |
854 | spin_unlock_bh(&txq->axq_lock); | 362 | spin_unlock_bh(&txq->axq_lock); |
855 | 363 | ||
856 | /* complete this sub-frame */ | ||
857 | ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); | 364 | ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); |
858 | } else { | 365 | } else { |
859 | /* | 366 | /* retry the un-acked ones */ |
860 | * retry the un-acked ones | ||
861 | */ | ||
862 | /* | ||
863 | * XXX: if the last descriptor is holding descriptor, | ||
864 | * in order to requeue the frame to software queue, we | ||
865 | * need to allocate a new descriptor and | ||
866 | * copy the content of holding descriptor to it. | ||
867 | */ | ||
868 | if (bf->bf_next == NULL && | 367 | if (bf->bf_next == NULL && |
869 | bf_last->bf_status & ATH_BUFSTATUS_STALE) { | 368 | bf_last->bf_status & ATH_BUFSTATUS_STALE) { |
870 | struct ath_buf *tbf; | 369 | struct ath_buf *tbf; |
871 | 370 | ||
872 | /* allocate new descriptor */ | 371 | tbf = ath_clone_txbuf(sc, bf_last); |
873 | spin_lock_bh(&sc->tx.txbuflock); | 372 | ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc); |
874 | ASSERT(!list_empty((&sc->tx.txbuf))); | ||
875 | tbf = list_first_entry(&sc->tx.txbuf, | ||
876 | struct ath_buf, list); | ||
877 | list_del(&tbf->list); | ||
878 | spin_unlock_bh(&sc->tx.txbuflock); | ||
879 | |||
880 | ATH_TXBUF_RESET(tbf); | ||
881 | |||
882 | /* copy descriptor content */ | ||
883 | tbf->bf_mpdu = bf_last->bf_mpdu; | ||
884 | tbf->bf_buf_addr = bf_last->bf_buf_addr; | ||
885 | *(tbf->bf_desc) = *(bf_last->bf_desc); | ||
886 | |||
887 | /* link it to the frame */ | ||
888 | if (bf_lastq) { | ||
889 | bf_lastq->bf_desc->ds_link = | ||
890 | tbf->bf_daddr; | ||
891 | bf->bf_lastfrm = tbf; | ||
892 | ath9k_hw_cleartxdesc(sc->sc_ah, | ||
893 | bf->bf_lastfrm->bf_desc); | ||
894 | } else { | ||
895 | tbf->bf_state = bf_last->bf_state; | ||
896 | tbf->bf_lastfrm = tbf; | ||
897 | ath9k_hw_cleartxdesc(sc->sc_ah, | ||
898 | tbf->bf_lastfrm->bf_desc); | ||
899 | |||
900 | /* copy the DMA context */ | ||
901 | tbf->bf_dmacontext = | ||
902 | bf_last->bf_dmacontext; | ||
903 | } | ||
904 | list_add_tail(&tbf->list, &bf_head); | 373 | list_add_tail(&tbf->list, &bf_head); |
905 | } else { | 374 | } else { |
906 | /* | 375 | /* |
907 | * Clear descriptor status words for | 376 | * Clear descriptor status words for |
908 | * software retry | 377 | * software retry |
909 | */ | 378 | */ |
910 | ath9k_hw_cleartxdesc(sc->sc_ah, | 379 | ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc); |
911 | bf->bf_lastfrm->bf_desc); | ||
912 | } | 380 | } |
913 | 381 | ||
914 | /* | 382 | /* |
@@ -922,332 +390,33 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, | |||
922 | } | 390 | } |
923 | 391 | ||
924 | if (tid->state & AGGR_CLEANUP) { | 392 | if (tid->state & AGGR_CLEANUP) { |
925 | /* check to see if we're done with cleaning the h/w queue */ | ||
926 | spin_lock_bh(&txq->axq_lock); | ||
927 | |||
928 | if (tid->baw_head == tid->baw_tail) { | 393 | if (tid->baw_head == tid->baw_tail) { |
929 | tid->state &= ~AGGR_ADDBA_COMPLETE; | 394 | tid->state &= ~AGGR_ADDBA_COMPLETE; |
930 | tid->addba_exchangeattempts = 0; | 395 | tid->addba_exchangeattempts = 0; |
931 | spin_unlock_bh(&txq->axq_lock); | ||
932 | |||
933 | tid->state &= ~AGGR_CLEANUP; | 396 | tid->state &= ~AGGR_CLEANUP; |
934 | 397 | ||
935 | /* send buffered frames as singles */ | 398 | /* send buffered frames as singles */ |
936 | ath_tx_flush_tid(sc, tid); | 399 | ath_tx_flush_tid(sc, tid); |
937 | } else | 400 | } |
938 | spin_unlock_bh(&txq->axq_lock); | 401 | rcu_read_unlock(); |
939 | |||
940 | return; | 402 | return; |
941 | } | 403 | } |
942 | 404 | ||
943 | /* | 405 | /* prepend un-acked frames to the beginning of the pending frame queue */ |
944 | * prepend un-acked frames to the beginning of the pending frame queue | ||
945 | */ | ||
946 | if (!list_empty(&bf_pending)) { | 406 | if (!list_empty(&bf_pending)) { |
947 | spin_lock_bh(&txq->axq_lock); | 407 | spin_lock_bh(&txq->axq_lock); |
948 | /* Note: we _prepend_, we _do_not_ at to | ||
949 | * the end of the queue ! */ | ||
950 | list_splice(&bf_pending, &tid->buf_q); | 408 | list_splice(&bf_pending, &tid->buf_q); |
951 | ath_tx_queue_tid(txq, tid); | 409 | ath_tx_queue_tid(txq, tid); |
952 | spin_unlock_bh(&txq->axq_lock); | 410 | spin_unlock_bh(&txq->axq_lock); |
953 | } | 411 | } |
954 | 412 | ||
413 | rcu_read_unlock(); | ||
414 | |||
955 | if (needreset) | 415 | if (needreset) |
956 | ath_reset(sc, false); | 416 | ath_reset(sc, false); |
957 | |||
958 | return; | ||
959 | } | ||
960 | |||
961 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad) | ||
962 | { | ||
963 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; | ||
964 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
965 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
966 | |||
967 | tx_info_priv->update_rc = false; | ||
968 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | ||
969 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
970 | |||
971 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | ||
972 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { | ||
973 | if (bf_isdata(bf)) { | ||
974 | memcpy(&tx_info_priv->tx, &ds->ds_txstat, | ||
975 | sizeof(tx_info_priv->tx)); | ||
976 | tx_info_priv->n_frames = bf->bf_nframes; | ||
977 | tx_info_priv->n_bad_frames = nbad; | ||
978 | tx_info_priv->update_rc = true; | ||
979 | } | ||
980 | } | ||
981 | } | 417 | } |
982 | 418 | ||
983 | /* Process completed xmit descriptors from the specified queue */ | 419 | static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, |
984 | |||
985 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | ||
986 | { | ||
987 | struct ath_hal *ah = sc->sc_ah; | ||
988 | struct ath_buf *bf, *lastbf, *bf_held = NULL; | ||
989 | struct list_head bf_head; | ||
990 | struct ath_desc *ds; | ||
991 | int txok, nbad = 0; | ||
992 | int status; | ||
993 | |||
994 | DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | ||
995 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | ||
996 | txq->axq_link); | ||
997 | |||
998 | for (;;) { | ||
999 | spin_lock_bh(&txq->axq_lock); | ||
1000 | if (list_empty(&txq->axq_q)) { | ||
1001 | txq->axq_link = NULL; | ||
1002 | txq->axq_linkbuf = NULL; | ||
1003 | spin_unlock_bh(&txq->axq_lock); | ||
1004 | break; | ||
1005 | } | ||
1006 | bf = list_first_entry(&txq->axq_q, struct ath_buf, list); | ||
1007 | |||
1008 | /* | ||
1009 | * There is a race condition that a BH gets scheduled | ||
1010 | * after sw writes TxE and before hw re-load the last | ||
1011 | * descriptor to get the newly chained one. | ||
1012 | * Software must keep the last DONE descriptor as a | ||
1013 | * holding descriptor - software does so by marking | ||
1014 | * it with the STALE flag. | ||
1015 | */ | ||
1016 | bf_held = NULL; | ||
1017 | if (bf->bf_status & ATH_BUFSTATUS_STALE) { | ||
1018 | bf_held = bf; | ||
1019 | if (list_is_last(&bf_held->list, &txq->axq_q)) { | ||
1020 | /* FIXME: | ||
1021 | * The holding descriptor is the last | ||
1022 | * descriptor in queue. It's safe to remove | ||
1023 | * the last holding descriptor in BH context. | ||
1024 | */ | ||
1025 | spin_unlock_bh(&txq->axq_lock); | ||
1026 | break; | ||
1027 | } else { | ||
1028 | /* Lets work with the next buffer now */ | ||
1029 | bf = list_entry(bf_held->list.next, | ||
1030 | struct ath_buf, list); | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | lastbf = bf->bf_lastbf; | ||
1035 | ds = lastbf->bf_desc; /* NB: last decriptor */ | ||
1036 | |||
1037 | status = ath9k_hw_txprocdesc(ah, ds); | ||
1038 | if (status == -EINPROGRESS) { | ||
1039 | spin_unlock_bh(&txq->axq_lock); | ||
1040 | break; | ||
1041 | } | ||
1042 | if (bf->bf_desc == txq->axq_lastdsWithCTS) | ||
1043 | txq->axq_lastdsWithCTS = NULL; | ||
1044 | if (ds == txq->axq_gatingds) | ||
1045 | txq->axq_gatingds = NULL; | ||
1046 | |||
1047 | /* | ||
1048 | * Remove ath_buf's of the same transmit unit from txq, | ||
1049 | * however leave the last descriptor back as the holding | ||
1050 | * descriptor for hw. | ||
1051 | */ | ||
1052 | lastbf->bf_status |= ATH_BUFSTATUS_STALE; | ||
1053 | INIT_LIST_HEAD(&bf_head); | ||
1054 | |||
1055 | if (!list_is_singular(&lastbf->list)) | ||
1056 | list_cut_position(&bf_head, | ||
1057 | &txq->axq_q, lastbf->list.prev); | ||
1058 | |||
1059 | txq->axq_depth--; | ||
1060 | |||
1061 | if (bf_isaggr(bf)) | ||
1062 | txq->axq_aggr_depth--; | ||
1063 | |||
1064 | txok = (ds->ds_txstat.ts_status == 0); | ||
1065 | |||
1066 | spin_unlock_bh(&txq->axq_lock); | ||
1067 | |||
1068 | if (bf_held) { | ||
1069 | list_del(&bf_held->list); | ||
1070 | spin_lock_bh(&sc->tx.txbuflock); | ||
1071 | list_add_tail(&bf_held->list, &sc->tx.txbuf); | ||
1072 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1073 | } | ||
1074 | |||
1075 | if (!bf_isampdu(bf)) { | ||
1076 | /* | ||
1077 | * This frame is sent out as a single frame. | ||
1078 | * Use hardware retry status for this frame. | ||
1079 | */ | ||
1080 | bf->bf_retries = ds->ds_txstat.ts_longretry; | ||
1081 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) | ||
1082 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
1083 | nbad = 0; | ||
1084 | } else { | ||
1085 | nbad = ath_tx_num_badfrms(sc, bf, txok); | ||
1086 | } | ||
1087 | |||
1088 | ath_tx_rc_status(bf, ds, nbad); | ||
1089 | |||
1090 | /* | ||
1091 | * Complete this transmit unit | ||
1092 | */ | ||
1093 | if (bf_isampdu(bf)) | ||
1094 | ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok); | ||
1095 | else | ||
1096 | ath_tx_complete_buf(sc, bf, &bf_head, txok, 0); | ||
1097 | |||
1098 | /* Wake up mac80211 queue */ | ||
1099 | |||
1100 | spin_lock_bh(&txq->axq_lock); | ||
1101 | if (txq->stopped && ath_txq_depth(sc, txq->axq_qnum) <= | ||
1102 | (ATH_TXBUF - 20)) { | ||
1103 | int qnum; | ||
1104 | qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); | ||
1105 | if (qnum != -1) { | ||
1106 | ieee80211_wake_queue(sc->hw, qnum); | ||
1107 | txq->stopped = 0; | ||
1108 | } | ||
1109 | |||
1110 | } | ||
1111 | |||
1112 | /* | ||
1113 | * schedule any pending packets if aggregation is enabled | ||
1114 | */ | ||
1115 | if (sc->sc_flags & SC_OP_TXAGGR) | ||
1116 | ath_txq_schedule(sc, txq); | ||
1117 | spin_unlock_bh(&txq->axq_lock); | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1121 | static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq) | ||
1122 | { | ||
1123 | struct ath_hal *ah = sc->sc_ah; | ||
1124 | |||
1125 | (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum); | ||
1126 | DPRINTF(sc, ATH_DBG_XMIT, "tx queue [%u] %x, link %p\n", | ||
1127 | txq->axq_qnum, ath9k_hw_gettxbuf(ah, txq->axq_qnum), | ||
1128 | txq->axq_link); | ||
1129 | } | ||
1130 | |||
1131 | /* Drain only the data queues */ | ||
1132 | |||
1133 | static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) | ||
1134 | { | ||
1135 | struct ath_hal *ah = sc->sc_ah; | ||
1136 | int i, status, npend = 0; | ||
1137 | |||
1138 | if (!(sc->sc_flags & SC_OP_INVALID)) { | ||
1139 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1140 | if (ATH_TXQ_SETUP(sc, i)) { | ||
1141 | ath_tx_stopdma(sc, &sc->tx.txq[i]); | ||
1142 | /* The TxDMA may not really be stopped. | ||
1143 | * Double check the hal tx pending count */ | ||
1144 | npend += ath9k_hw_numtxpending(ah, | ||
1145 | sc->tx.txq[i].axq_qnum); | ||
1146 | } | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | if (npend) { | ||
1151 | /* TxDMA not stopped, reset the hal */ | ||
1152 | DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n"); | ||
1153 | |||
1154 | spin_lock_bh(&sc->sc_resetlock); | ||
1155 | if (!ath9k_hw_reset(ah, | ||
1156 | sc->sc_ah->ah_curchan, | ||
1157 | sc->tx_chan_width, | ||
1158 | sc->sc_tx_chainmask, sc->sc_rx_chainmask, | ||
1159 | sc->sc_ht_extprotspacing, true, &status)) { | ||
1160 | |||
1161 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1162 | "Unable to reset hardware; hal status %u\n", | ||
1163 | status); | ||
1164 | } | ||
1165 | spin_unlock_bh(&sc->sc_resetlock); | ||
1166 | } | ||
1167 | |||
1168 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1169 | if (ATH_TXQ_SETUP(sc, i)) | ||
1170 | ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx); | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1174 | /* Add a sub-frame to block ack window */ | ||
1175 | |||
1176 | static void ath_tx_addto_baw(struct ath_softc *sc, | ||
1177 | struct ath_atx_tid *tid, | ||
1178 | struct ath_buf *bf) | ||
1179 | { | ||
1180 | int index, cindex; | ||
1181 | |||
1182 | if (bf_isretried(bf)) | ||
1183 | return; | ||
1184 | |||
1185 | index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); | ||
1186 | cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); | ||
1187 | |||
1188 | ASSERT(tid->tx_buf[cindex] == NULL); | ||
1189 | tid->tx_buf[cindex] = bf; | ||
1190 | |||
1191 | if (index >= ((tid->baw_tail - tid->baw_head) & | ||
1192 | (ATH_TID_MAX_BUFS - 1))) { | ||
1193 | tid->baw_tail = cindex; | ||
1194 | INCR(tid->baw_tail, ATH_TID_MAX_BUFS); | ||
1195 | } | ||
1196 | } | ||
1197 | |||
1198 | /* | ||
1199 | * Function to send an A-MPDU | ||
1200 | * NB: must be called with txq lock held | ||
1201 | */ | ||
1202 | static int ath_tx_send_ampdu(struct ath_softc *sc, | ||
1203 | struct ath_atx_tid *tid, | ||
1204 | struct list_head *bf_head, | ||
1205 | struct ath_tx_control *txctl) | ||
1206 | { | ||
1207 | struct ath_buf *bf; | ||
1208 | |||
1209 | BUG_ON(list_empty(bf_head)); | ||
1210 | |||
1211 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1212 | bf->bf_state.bf_type |= BUF_AMPDU; | ||
1213 | |||
1214 | /* | ||
1215 | * Do not queue to h/w when any of the following conditions is true: | ||
1216 | * - there are pending frames in software queue | ||
1217 | * - the TID is currently paused for ADDBA/BAR request | ||
1218 | * - seqno is not within block-ack window | ||
1219 | * - h/w queue depth exceeds low water mark | ||
1220 | */ | ||
1221 | if (!list_empty(&tid->buf_q) || tid->paused || | ||
1222 | !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) || | ||
1223 | txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { | ||
1224 | /* | ||
1225 | * Add this frame to software queue for scheduling later | ||
1226 | * for aggregation. | ||
1227 | */ | ||
1228 | list_splice_tail_init(bf_head, &tid->buf_q); | ||
1229 | ath_tx_queue_tid(txctl->txq, tid); | ||
1230 | return 0; | ||
1231 | } | ||
1232 | |||
1233 | /* Add sub-frame to BAW */ | ||
1234 | ath_tx_addto_baw(sc, tid, bf); | ||
1235 | |||
1236 | /* Queue to h/w without aggregation */ | ||
1237 | bf->bf_nframes = 1; | ||
1238 | bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */ | ||
1239 | ath_buf_set_rate(sc, bf); | ||
1240 | ath_tx_txqaddbuf(sc, txctl->txq, bf_head); | ||
1241 | |||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | /* | ||
1246 | * looks up the rate | ||
1247 | * returns aggr limit based on lowest of the rates | ||
1248 | */ | ||
1249 | static u32 ath_lookup_rate(struct ath_softc *sc, | ||
1250 | struct ath_buf *bf, | ||
1251 | struct ath_atx_tid *tid) | 420 | struct ath_atx_tid *tid) |
1252 | { | 421 | { |
1253 | struct ath_rate_table *rate_table = sc->cur_rate_table; | 422 | struct ath_rate_table *rate_table = sc->cur_rate_table; |
@@ -1255,15 +424,14 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1255 | struct ieee80211_tx_info *tx_info; | 424 | struct ieee80211_tx_info *tx_info; |
1256 | struct ieee80211_tx_rate *rates; | 425 | struct ieee80211_tx_rate *rates; |
1257 | struct ath_tx_info_priv *tx_info_priv; | 426 | struct ath_tx_info_priv *tx_info_priv; |
1258 | u32 max_4ms_framelen, frame_length; | 427 | u32 max_4ms_framelen, frmlen; |
1259 | u16 aggr_limit, legacy = 0, maxampdu; | 428 | u16 aggr_limit, legacy = 0, maxampdu; |
1260 | int i; | 429 | int i; |
1261 | 430 | ||
1262 | skb = (struct sk_buff *)bf->bf_mpdu; | 431 | skb = (struct sk_buff *)bf->bf_mpdu; |
1263 | tx_info = IEEE80211_SKB_CB(skb); | 432 | tx_info = IEEE80211_SKB_CB(skb); |
1264 | rates = tx_info->control.rates; | 433 | rates = tx_info->control.rates; |
1265 | tx_info_priv = | 434 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; |
1266 | (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; | ||
1267 | 435 | ||
1268 | /* | 436 | /* |
1269 | * Find the lowest frame length among the rate series that will have a | 437 | * Find the lowest frame length among the rate series that will have a |
@@ -1279,9 +447,8 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1279 | break; | 447 | break; |
1280 | } | 448 | } |
1281 | 449 | ||
1282 | frame_length = | 450 | frmlen = rate_table->info[rates[i].idx].max_4ms_framelen; |
1283 | rate_table->info[rates[i].idx].max_4ms_framelen; | 451 | max_4ms_framelen = min(max_4ms_framelen, frmlen); |
1284 | max_4ms_framelen = min(max_4ms_framelen, frame_length); | ||
1285 | } | 452 | } |
1286 | } | 453 | } |
1287 | 454 | ||
@@ -1293,8 +460,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1293 | if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) | 460 | if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) |
1294 | return 0; | 461 | return 0; |
1295 | 462 | ||
1296 | aggr_limit = min(max_4ms_framelen, | 463 | aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT); |
1297 | (u32)ATH_AMPDU_LIMIT_DEFAULT); | ||
1298 | 464 | ||
1299 | /* | 465 | /* |
1300 | * h/w can accept aggregates upto 16 bit lengths (65535). | 466 | * h/w can accept aggregates upto 16 bit lengths (65535). |
@@ -1309,14 +475,12 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1309 | } | 475 | } |
1310 | 476 | ||
1311 | /* | 477 | /* |
1312 | * returns the number of delimiters to be added to | 478 | * Returns the number of delimiters to be added to |
1313 | * meet the minimum required mpdudensity. | 479 | * meet the minimum required mpdudensity. |
1314 | * caller should make sure that the rate is HT rate . | 480 | * caller should make sure that the rate is HT rate . |
1315 | */ | 481 | */ |
1316 | static int ath_compute_num_delims(struct ath_softc *sc, | 482 | static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, |
1317 | struct ath_atx_tid *tid, | 483 | struct ath_buf *bf, u16 frmlen) |
1318 | struct ath_buf *bf, | ||
1319 | u16 frmlen) | ||
1320 | { | 484 | { |
1321 | struct ath_rate_table *rt = sc->cur_rate_table; | 485 | struct ath_rate_table *rt = sc->cur_rate_table; |
1322 | struct sk_buff *skb = bf->bf_mpdu; | 486 | struct sk_buff *skb = bf->bf_mpdu; |
@@ -1370,9 +534,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1370 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; | 534 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; |
1371 | minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; | 535 | minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; |
1372 | 536 | ||
1373 | /* Is frame shorter than required minimum length? */ | ||
1374 | if (frmlen < minlen) { | 537 | if (frmlen < minlen) { |
1375 | /* Get the minimum number of delimiters required. */ | ||
1376 | mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ; | 538 | mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ; |
1377 | ndelim = max(mindelim, ndelim); | 539 | ndelim = max(mindelim, ndelim); |
1378 | } | 540 | } |
@@ -1380,37 +542,23 @@ static int ath_compute_num_delims(struct ath_softc *sc, | |||
1380 | return ndelim; | 542 | return ndelim; |
1381 | } | 543 | } |
1382 | 544 | ||
1383 | /* | ||
1384 | * For aggregation from software buffer queue. | ||
1385 | * NB: must be called with txq lock held | ||
1386 | */ | ||
1387 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | 545 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, |
1388 | struct ath_atx_tid *tid, | 546 | struct ath_atx_tid *tid, |
1389 | struct list_head *bf_q, | 547 | struct list_head *bf_q) |
1390 | struct ath_buf **bf_last, | ||
1391 | struct aggr_rifs_param *param, | ||
1392 | int *prev_frames) | ||
1393 | { | 548 | { |
1394 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) | 549 | #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) |
1395 | struct ath_buf *bf, *tbf, *bf_first, *bf_prev = NULL; | 550 | struct ath_buf *bf, *bf_first, *bf_prev = NULL; |
1396 | struct list_head bf_head; | 551 | int rl = 0, nframes = 0, ndelim, prev_al = 0; |
1397 | int rl = 0, nframes = 0, ndelim; | ||
1398 | u16 aggr_limit = 0, al = 0, bpad = 0, | 552 | u16 aggr_limit = 0, al = 0, bpad = 0, |
1399 | al_delta, h_baw = tid->baw_size / 2; | 553 | al_delta, h_baw = tid->baw_size / 2; |
1400 | enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; | 554 | enum ATH_AGGR_STATUS status = ATH_AGGR_DONE; |
1401 | int prev_al = 0; | ||
1402 | INIT_LIST_HEAD(&bf_head); | ||
1403 | |||
1404 | BUG_ON(list_empty(&tid->buf_q)); | ||
1405 | 555 | ||
1406 | bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); | 556 | bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list); |
1407 | 557 | ||
1408 | do { | 558 | do { |
1409 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | 559 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); |
1410 | 560 | ||
1411 | /* | 561 | /* do not step over block-ack window */ |
1412 | * do not step over block-ack window | ||
1413 | */ | ||
1414 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) { | 562 | if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) { |
1415 | status = ATH_AGGR_BAW_CLOSED; | 563 | status = ATH_AGGR_BAW_CLOSED; |
1416 | break; | 564 | break; |
@@ -1421,29 +569,23 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
1421 | rl = 1; | 569 | rl = 1; |
1422 | } | 570 | } |
1423 | 571 | ||
1424 | /* | 572 | /* do not exceed aggregation limit */ |
1425 | * do not exceed aggregation limit | ||
1426 | */ | ||
1427 | al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen; | 573 | al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen; |
1428 | 574 | ||
1429 | if (nframes && (aggr_limit < | 575 | if (nframes && |
1430 | (al + bpad + al_delta + prev_al))) { | 576 | (aggr_limit < (al + bpad + al_delta + prev_al))) { |
1431 | status = ATH_AGGR_LIMITED; | 577 | status = ATH_AGGR_LIMITED; |
1432 | break; | 578 | break; |
1433 | } | 579 | } |
1434 | 580 | ||
1435 | /* | 581 | /* do not exceed subframe limit */ |
1436 | * do not exceed subframe limit | 582 | if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) { |
1437 | */ | ||
1438 | if ((nframes + *prev_frames) >= | ||
1439 | min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) { | ||
1440 | status = ATH_AGGR_LIMITED; | 583 | status = ATH_AGGR_LIMITED; |
1441 | break; | 584 | break; |
1442 | } | 585 | } |
586 | nframes++; | ||
1443 | 587 | ||
1444 | /* | 588 | /* add padding for previous frame to aggregation length */ |
1445 | * add padding for previous frame to aggregation length | ||
1446 | */ | ||
1447 | al += bpad + al_delta; | 589 | al += bpad + al_delta; |
1448 | 590 | ||
1449 | /* | 591 | /* |
@@ -1451,69 +593,35 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
1451 | * density for this node. | 593 | * density for this node. |
1452 | */ | 594 | */ |
1453 | ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen); | 595 | ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen); |
1454 | |||
1455 | bpad = PADBYTES(al_delta) + (ndelim << 2); | 596 | bpad = PADBYTES(al_delta) + (ndelim << 2); |
1456 | 597 | ||
1457 | bf->bf_next = NULL; | 598 | bf->bf_next = NULL; |
1458 | bf->bf_lastfrm->bf_desc->ds_link = 0; | 599 | bf->bf_desc->ds_link = 0; |
1459 | 600 | ||
1460 | /* | 601 | /* link buffers of this frame to the aggregate */ |
1461 | * this packet is part of an aggregate | ||
1462 | * - remove all descriptors belonging to this frame from | ||
1463 | * software queue | ||
1464 | * - add it to block ack window | ||
1465 | * - set up descriptors for aggregation | ||
1466 | */ | ||
1467 | list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list); | ||
1468 | ath_tx_addto_baw(sc, tid, bf); | 602 | ath_tx_addto_baw(sc, tid, bf); |
1469 | 603 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); | |
1470 | list_for_each_entry(tbf, &bf_head, list) { | 604 | list_move_tail(&bf->list, bf_q); |
1471 | ath9k_hw_set11n_aggr_middle(sc->sc_ah, | ||
1472 | tbf->bf_desc, ndelim); | ||
1473 | } | ||
1474 | |||
1475 | /* | ||
1476 | * link buffers of this frame to the aggregate | ||
1477 | */ | ||
1478 | list_splice_tail_init(&bf_head, bf_q); | ||
1479 | nframes++; | ||
1480 | |||
1481 | if (bf_prev) { | 605 | if (bf_prev) { |
1482 | bf_prev->bf_next = bf; | 606 | bf_prev->bf_next = bf; |
1483 | bf_prev->bf_lastfrm->bf_desc->ds_link = bf->bf_daddr; | 607 | bf_prev->bf_desc->ds_link = bf->bf_daddr; |
1484 | } | 608 | } |
1485 | bf_prev = bf; | 609 | bf_prev = bf; |
1486 | |||
1487 | #ifdef AGGR_NOSHORT | ||
1488 | /* | ||
1489 | * terminate aggregation on a small packet boundary | ||
1490 | */ | ||
1491 | if (bf->bf_frmlen < ATH_AGGR_MINPLEN) { | ||
1492 | status = ATH_AGGR_SHORTPKT; | ||
1493 | break; | ||
1494 | } | ||
1495 | #endif | ||
1496 | } while (!list_empty(&tid->buf_q)); | 610 | } while (!list_empty(&tid->buf_q)); |
1497 | 611 | ||
1498 | bf_first->bf_al = al; | 612 | bf_first->bf_al = al; |
1499 | bf_first->bf_nframes = nframes; | 613 | bf_first->bf_nframes = nframes; |
1500 | *bf_last = bf_prev; | 614 | |
1501 | return status; | 615 | return status; |
1502 | #undef PADBYTES | 616 | #undef PADBYTES |
1503 | } | 617 | } |
1504 | 618 | ||
1505 | /* | 619 | static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, |
1506 | * process pending frames possibly doing a-mpdu aggregation | 620 | struct ath_atx_tid *tid) |
1507 | * NB: must be called with txq lock held | ||
1508 | */ | ||
1509 | static void ath_tx_sched_aggr(struct ath_softc *sc, | ||
1510 | struct ath_txq *txq, struct ath_atx_tid *tid) | ||
1511 | { | 621 | { |
1512 | struct ath_buf *bf, *tbf, *bf_last, *bf_lastaggr = NULL; | 622 | struct ath_buf *bf; |
1513 | enum ATH_AGGR_STATUS status; | 623 | enum ATH_AGGR_STATUS status; |
1514 | struct list_head bf_q; | 624 | struct list_head bf_q; |
1515 | struct aggr_rifs_param param = {0, 0, 0, 0, NULL}; | ||
1516 | int prev_frames = 0; | ||
1517 | 625 | ||
1518 | do { | 626 | do { |
1519 | if (list_empty(&tid->buf_q)) | 627 | if (list_empty(&tid->buf_q)) |
@@ -1521,379 +629,183 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, | |||
1521 | 629 | ||
1522 | INIT_LIST_HEAD(&bf_q); | 630 | INIT_LIST_HEAD(&bf_q); |
1523 | 631 | ||
1524 | status = ath_tx_form_aggr(sc, tid, &bf_q, &bf_lastaggr, ¶m, | 632 | status = ath_tx_form_aggr(sc, tid, &bf_q); |
1525 | &prev_frames); | ||
1526 | 633 | ||
1527 | /* | 634 | /* |
1528 | * no frames picked up to be aggregated; block-ack | 635 | * no frames picked up to be aggregated; |
1529 | * window is not open | 636 | * block-ack window is not open. |
1530 | */ | 637 | */ |
1531 | if (list_empty(&bf_q)) | 638 | if (list_empty(&bf_q)) |
1532 | break; | 639 | break; |
1533 | 640 | ||
1534 | bf = list_first_entry(&bf_q, struct ath_buf, list); | 641 | bf = list_first_entry(&bf_q, struct ath_buf, list); |
1535 | bf_last = list_entry(bf_q.prev, struct ath_buf, list); | 642 | bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); |
1536 | bf->bf_lastbf = bf_last; | ||
1537 | 643 | ||
1538 | /* | 644 | /* if only one frame, send as non-aggregate */ |
1539 | * if only one frame, send as non-aggregate | ||
1540 | */ | ||
1541 | if (bf->bf_nframes == 1) { | 645 | if (bf->bf_nframes == 1) { |
1542 | ASSERT(bf->bf_lastfrm == bf_last); | ||
1543 | |||
1544 | bf->bf_state.bf_type &= ~BUF_AGGR; | 646 | bf->bf_state.bf_type &= ~BUF_AGGR; |
1545 | /* | 647 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); |
1546 | * clear aggr bits for every descriptor | ||
1547 | * XXX TODO: is there a way to optimize it? | ||
1548 | */ | ||
1549 | list_for_each_entry(tbf, &bf_q, list) { | ||
1550 | ath9k_hw_clr11n_aggr(sc->sc_ah, tbf->bf_desc); | ||
1551 | } | ||
1552 | |||
1553 | ath_buf_set_rate(sc, bf); | 648 | ath_buf_set_rate(sc, bf); |
1554 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 649 | ath_tx_txqaddbuf(sc, txq, &bf_q); |
1555 | continue; | 650 | continue; |
1556 | } | 651 | } |
1557 | 652 | ||
1558 | /* | 653 | /* setup first desc of aggregate */ |
1559 | * setup first desc with rate and aggr info | ||
1560 | */ | ||
1561 | bf->bf_state.bf_type |= BUF_AGGR; | 654 | bf->bf_state.bf_type |= BUF_AGGR; |
1562 | ath_buf_set_rate(sc, bf); | 655 | ath_buf_set_rate(sc, bf); |
1563 | ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al); | 656 | ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al); |
1564 | 657 | ||
1565 | /* | 658 | /* anchor last desc of aggregate */ |
1566 | * anchor last frame of aggregate correctly | 659 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); |
1567 | */ | ||
1568 | ASSERT(bf_lastaggr); | ||
1569 | ASSERT(bf_lastaggr->bf_lastfrm == bf_last); | ||
1570 | tbf = bf_lastaggr; | ||
1571 | ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc); | ||
1572 | |||
1573 | /* XXX: We don't enter into this loop, consider removing this */ | ||
1574 | while (!list_empty(&bf_q) && !list_is_last(&tbf->list, &bf_q)) { | ||
1575 | tbf = list_entry(tbf->list.next, struct ath_buf, list); | ||
1576 | ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc); | ||
1577 | } | ||
1578 | 660 | ||
1579 | txq->axq_aggr_depth++; | 661 | txq->axq_aggr_depth++; |
1580 | |||
1581 | /* | ||
1582 | * Normal aggregate, queue to hardware | ||
1583 | */ | ||
1584 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 662 | ath_tx_txqaddbuf(sc, txq, &bf_q); |
1585 | 663 | ||
1586 | } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH && | 664 | } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH && |
1587 | status != ATH_AGGR_BAW_CLOSED); | 665 | status != ATH_AGGR_BAW_CLOSED); |
1588 | } | 666 | } |
1589 | 667 | ||
1590 | /* Called with txq lock held */ | 668 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
1591 | 669 | u16 tid, u16 *ssn) | |
1592 | static void ath_tid_drain(struct ath_softc *sc, | ||
1593 | struct ath_txq *txq, | ||
1594 | struct ath_atx_tid *tid) | ||
1595 | |||
1596 | { | ||
1597 | struct ath_buf *bf; | ||
1598 | struct list_head bf_head; | ||
1599 | INIT_LIST_HEAD(&bf_head); | ||
1600 | |||
1601 | for (;;) { | ||
1602 | if (list_empty(&tid->buf_q)) | ||
1603 | break; | ||
1604 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | ||
1605 | |||
1606 | list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list); | ||
1607 | |||
1608 | /* update baw for software retried frame */ | ||
1609 | if (bf_isretried(bf)) | ||
1610 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | ||
1611 | |||
1612 | /* | ||
1613 | * do not indicate packets while holding txq spinlock. | ||
1614 | * unlock is intentional here | ||
1615 | */ | ||
1616 | spin_unlock(&txq->axq_lock); | ||
1617 | |||
1618 | /* complete this sub-frame */ | ||
1619 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); | ||
1620 | |||
1621 | spin_lock(&txq->axq_lock); | ||
1622 | } | ||
1623 | |||
1624 | /* | ||
1625 | * TODO: For frame(s) that are in the retry state, we will reuse the | ||
1626 | * sequence number(s) without setting the retry bit. The | ||
1627 | * alternative is to give up on these and BAR the receiver's window | ||
1628 | * forward. | ||
1629 | */ | ||
1630 | tid->seq_next = tid->seq_start; | ||
1631 | tid->baw_tail = tid->baw_head; | ||
1632 | } | ||
1633 | |||
1634 | /* | ||
1635 | * Drain all pending buffers | ||
1636 | * NB: must be called with txq lock held | ||
1637 | */ | ||
1638 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | ||
1639 | struct ath_txq *txq) | ||
1640 | { | ||
1641 | struct ath_atx_ac *ac, *ac_tmp; | ||
1642 | struct ath_atx_tid *tid, *tid_tmp; | ||
1643 | |||
1644 | list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { | ||
1645 | list_del(&ac->list); | ||
1646 | ac->sched = false; | ||
1647 | list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { | ||
1648 | list_del(&tid->list); | ||
1649 | tid->sched = false; | ||
1650 | ath_tid_drain(sc, txq, tid); | ||
1651 | } | ||
1652 | } | ||
1653 | } | ||
1654 | |||
1655 | static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, | ||
1656 | struct sk_buff *skb, | ||
1657 | struct ath_tx_control *txctl) | ||
1658 | { | 670 | { |
1659 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 671 | struct ath_atx_tid *txtid; |
1660 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 672 | struct ath_node *an; |
1661 | struct ath_tx_info_priv *tx_info_priv; | ||
1662 | int hdrlen; | ||
1663 | __le16 fc; | ||
1664 | |||
1665 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | ||
1666 | if (unlikely(!tx_info_priv)) | ||
1667 | return -ENOMEM; | ||
1668 | tx_info->rate_driver_data[0] = tx_info_priv; | ||
1669 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1670 | fc = hdr->frame_control; | ||
1671 | |||
1672 | ATH_TXBUF_RESET(bf); | ||
1673 | |||
1674 | /* Frame type */ | ||
1675 | |||
1676 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | ||
1677 | |||
1678 | ieee80211_is_data(fc) ? | ||
1679 | (bf->bf_state.bf_type |= BUF_DATA) : | ||
1680 | (bf->bf_state.bf_type &= ~BUF_DATA); | ||
1681 | ieee80211_is_back_req(fc) ? | ||
1682 | (bf->bf_state.bf_type |= BUF_BAR) : | ||
1683 | (bf->bf_state.bf_type &= ~BUF_BAR); | ||
1684 | ieee80211_is_pspoll(fc) ? | ||
1685 | (bf->bf_state.bf_type |= BUF_PSPOLL) : | ||
1686 | (bf->bf_state.bf_type &= ~BUF_PSPOLL); | ||
1687 | (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ? | ||
1688 | (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) : | ||
1689 | (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE); | ||
1690 | (sc->hw->conf.ht.enabled && !is_pae(skb) && | ||
1691 | (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) ? | ||
1692 | (bf->bf_state.bf_type |= BUF_HT) : | ||
1693 | (bf->bf_state.bf_type &= ~BUF_HT); | ||
1694 | |||
1695 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); | ||
1696 | |||
1697 | /* Crypto */ | ||
1698 | |||
1699 | bf->bf_keytype = get_hw_crypto_keytype(skb); | ||
1700 | |||
1701 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { | ||
1702 | bf->bf_frmlen += tx_info->control.hw_key->icv_len; | ||
1703 | bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; | ||
1704 | } else { | ||
1705 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | ||
1706 | } | ||
1707 | |||
1708 | /* Assign seqno, tidno */ | ||
1709 | |||
1710 | if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) | ||
1711 | assign_aggr_tid_seqno(skb, bf); | ||
1712 | 673 | ||
1713 | /* DMA setup */ | 674 | an = (struct ath_node *)sta->drv_priv; |
1714 | bf->bf_mpdu = skb; | ||
1715 | 675 | ||
1716 | bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, | 676 | if (sc->sc_flags & SC_OP_TXAGGR) { |
1717 | skb->len, PCI_DMA_TODEVICE); | 677 | txtid = ATH_AN_2_TID(an, tid); |
1718 | if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) { | 678 | txtid->state |= AGGR_ADDBA_PROGRESS; |
1719 | bf->bf_mpdu = NULL; | 679 | ath_tx_pause_tid(sc, txtid); |
1720 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
1721 | "pci_dma_mapping_error() on TX\n"); | ||
1722 | return -ENOMEM; | ||
1723 | } | 680 | } |
1724 | 681 | ||
1725 | bf->bf_buf_addr = bf->bf_dmacontext; | ||
1726 | return 0; | 682 | return 0; |
1727 | } | 683 | } |
1728 | 684 | ||
1729 | /* FIXME: tx power */ | 685 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
1730 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | ||
1731 | struct ath_tx_control *txctl) | ||
1732 | { | 686 | { |
1733 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; | 687 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
1734 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 688 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); |
1735 | struct ath_node *an = NULL; | 689 | struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; |
690 | struct ath_buf *bf; | ||
1736 | struct list_head bf_head; | 691 | struct list_head bf_head; |
1737 | struct ath_desc *ds; | ||
1738 | struct ath_atx_tid *tid; | ||
1739 | struct ath_hal *ah = sc->sc_ah; | ||
1740 | int frm_type; | ||
1741 | |||
1742 | frm_type = get_hw_packet_type(skb); | ||
1743 | |||
1744 | INIT_LIST_HEAD(&bf_head); | 692 | INIT_LIST_HEAD(&bf_head); |
1745 | list_add_tail(&bf->list, &bf_head); | ||
1746 | |||
1747 | /* setup descriptor */ | ||
1748 | |||
1749 | ds = bf->bf_desc; | ||
1750 | ds->ds_link = 0; | ||
1751 | ds->ds_data = bf->bf_buf_addr; | ||
1752 | |||
1753 | /* Formulate first tx descriptor with tx controls */ | ||
1754 | |||
1755 | ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, | ||
1756 | bf->bf_keyix, bf->bf_keytype, bf->bf_flags); | ||
1757 | |||
1758 | ath9k_hw_filltxdesc(ah, ds, | ||
1759 | skb->len, /* segment length */ | ||
1760 | true, /* first segment */ | ||
1761 | true, /* last segment */ | ||
1762 | ds); /* first descriptor */ | ||
1763 | 693 | ||
1764 | bf->bf_lastfrm = bf; | 694 | if (txtid->state & AGGR_CLEANUP) |
695 | return 0; | ||
1765 | 696 | ||
1766 | spin_lock_bh(&txctl->txq->axq_lock); | 697 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { |
698 | txtid->addba_exchangeattempts = 0; | ||
699 | return 0; | ||
700 | } | ||
1767 | 701 | ||
1768 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && | 702 | ath_tx_pause_tid(sc, txtid); |
1769 | tx_info->control.sta) { | ||
1770 | an = (struct ath_node *)tx_info->control.sta->drv_priv; | ||
1771 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
1772 | 703 | ||
1773 | if (ath_aggr_query(sc, an, bf->bf_tidno)) { | 704 | /* drop all software retried frames and mark this TID */ |
1774 | /* | 705 | spin_lock_bh(&txq->axq_lock); |
1775 | * Try aggregation if it's a unicast data frame | 706 | while (!list_empty(&txtid->buf_q)) { |
1776 | * and the destination is HT capable. | 707 | bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); |
1777 | */ | 708 | if (!bf_isretried(bf)) { |
1778 | ath_tx_send_ampdu(sc, tid, &bf_head, txctl); | ||
1779 | } else { | ||
1780 | /* | 709 | /* |
1781 | * Send this frame as regular when ADDBA | 710 | * NB: it's based on the assumption that |
1782 | * exchange is neither complete nor pending. | 711 | * software retried frame will always stay |
712 | * at the head of software queue. | ||
1783 | */ | 713 | */ |
1784 | ath_tx_send_normal(sc, txctl->txq, | 714 | break; |
1785 | tid, &bf_head); | ||
1786 | } | 715 | } |
1787 | } else { | 716 | list_move_tail(&bf->list, &bf_head); |
1788 | bf->bf_lastbf = bf; | 717 | ath_tx_update_baw(sc, txtid, bf->bf_seqno); |
1789 | bf->bf_nframes = 1; | 718 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); |
719 | } | ||
720 | spin_unlock_bh(&txq->axq_lock); | ||
1790 | 721 | ||
1791 | ath_buf_set_rate(sc, bf); | 722 | if (txtid->baw_head != txtid->baw_tail) { |
1792 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); | 723 | txtid->state |= AGGR_CLEANUP; |
724 | } else { | ||
725 | txtid->state &= ~AGGR_ADDBA_COMPLETE; | ||
726 | txtid->addba_exchangeattempts = 0; | ||
727 | ath_tx_flush_tid(sc, txtid); | ||
1793 | } | 728 | } |
1794 | 729 | ||
1795 | spin_unlock_bh(&txctl->txq->axq_lock); | 730 | return 0; |
1796 | } | 731 | } |
1797 | 732 | ||
1798 | /* Upon failure caller should free skb */ | 733 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
1799 | int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, | ||
1800 | struct ath_tx_control *txctl) | ||
1801 | { | 734 | { |
1802 | struct ath_buf *bf; | 735 | struct ath_atx_tid *txtid; |
1803 | int r; | 736 | struct ath_node *an; |
1804 | 737 | ||
1805 | /* Check if a tx buffer is available */ | 738 | an = (struct ath_node *)sta->drv_priv; |
1806 | 739 | ||
1807 | bf = ath_tx_get_buffer(sc); | 740 | if (sc->sc_flags & SC_OP_TXAGGR) { |
1808 | if (!bf) { | 741 | txtid = ATH_AN_2_TID(an, tid); |
1809 | DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n"); | 742 | txtid->baw_size = |
1810 | return -1; | 743 | IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; |
744 | txtid->state |= AGGR_ADDBA_COMPLETE; | ||
745 | txtid->state &= ~AGGR_ADDBA_PROGRESS; | ||
746 | ath_tx_resume_tid(sc, txtid); | ||
1811 | } | 747 | } |
748 | } | ||
1812 | 749 | ||
1813 | r = ath_tx_setup_buffer(sc, bf, skb, txctl); | 750 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) |
1814 | if (unlikely(r)) { | 751 | { |
1815 | struct ath_txq *txq = txctl->txq; | 752 | struct ath_atx_tid *txtid; |
1816 | |||
1817 | DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n"); | ||
1818 | 753 | ||
1819 | /* upon ath_tx_processq() this TX queue will be resumed, we | 754 | if (!(sc->sc_flags & SC_OP_TXAGGR)) |
1820 | * guarantee this will happen by knowing beforehand that | 755 | return false; |
1821 | * we will at least have to run TX completionon one buffer | ||
1822 | * on the queue */ | ||
1823 | spin_lock_bh(&txq->axq_lock); | ||
1824 | if (ath_txq_depth(sc, txq->axq_qnum) > 1) { | ||
1825 | ieee80211_stop_queue(sc->hw, | ||
1826 | skb_get_queue_mapping(skb)); | ||
1827 | txq->stopped = 1; | ||
1828 | } | ||
1829 | spin_unlock_bh(&txq->axq_lock); | ||
1830 | 756 | ||
1831 | spin_lock_bh(&sc->tx.txbuflock); | 757 | txtid = ATH_AN_2_TID(an, tidno); |
1832 | list_add_tail(&bf->list, &sc->tx.txbuf); | ||
1833 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1834 | 758 | ||
1835 | return r; | 759 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { |
760 | if (!(txtid->state & AGGR_ADDBA_PROGRESS) && | ||
761 | (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) { | ||
762 | txtid->addba_exchangeattempts++; | ||
763 | return true; | ||
764 | } | ||
1836 | } | 765 | } |
1837 | 766 | ||
1838 | ath_tx_start_dma(sc, bf, txctl); | 767 | return false; |
1839 | |||
1840 | return 0; | ||
1841 | } | 768 | } |
1842 | 769 | ||
1843 | /* Initialize TX queue and h/w */ | 770 | /********************/ |
771 | /* Queue Management */ | ||
772 | /********************/ | ||
1844 | 773 | ||
1845 | int ath_tx_init(struct ath_softc *sc, int nbufs) | 774 | static u32 ath_txq_depth(struct ath_softc *sc, int qnum) |
1846 | { | 775 | { |
1847 | int error = 0; | 776 | return sc->tx.txq[qnum].axq_depth; |
1848 | 777 | } | |
1849 | do { | ||
1850 | spin_lock_init(&sc->tx.txbuflock); | ||
1851 | |||
1852 | /* Setup tx descriptors */ | ||
1853 | error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, | ||
1854 | "tx", nbufs, 1); | ||
1855 | if (error != 0) { | ||
1856 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1857 | "Failed to allocate tx descriptors: %d\n", | ||
1858 | error); | ||
1859 | break; | ||
1860 | } | ||
1861 | |||
1862 | /* XXX allocate beacon state together with vap */ | ||
1863 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, | ||
1864 | "beacon", ATH_BCBUF, 1); | ||
1865 | if (error != 0) { | ||
1866 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1867 | "Failed to allocate beacon descriptors: %d\n", | ||
1868 | error); | ||
1869 | break; | ||
1870 | } | ||
1871 | 778 | ||
1872 | } while (0); | 779 | static void ath_get_beaconconfig(struct ath_softc *sc, int if_id, |
780 | struct ath_beacon_config *conf) | ||
781 | { | ||
782 | struct ieee80211_hw *hw = sc->hw; | ||
1873 | 783 | ||
1874 | if (error != 0) | 784 | /* fill in beacon config data */ |
1875 | ath_tx_cleanup(sc); | ||
1876 | 785 | ||
1877 | return error; | 786 | conf->beacon_interval = hw->conf.beacon_int; |
787 | conf->listen_interval = 100; | ||
788 | conf->dtim_count = 1; | ||
789 | conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; | ||
1878 | } | 790 | } |
1879 | 791 | ||
1880 | /* Reclaim all tx queue resources */ | 792 | static void ath_txq_drain_pending_buffers(struct ath_softc *sc, |
1881 | 793 | struct ath_txq *txq) | |
1882 | int ath_tx_cleanup(struct ath_softc *sc) | ||
1883 | { | 794 | { |
1884 | /* cleanup beacon descriptors */ | 795 | struct ath_atx_ac *ac, *ac_tmp; |
1885 | if (sc->beacon.bdma.dd_desc_len != 0) | 796 | struct ath_atx_tid *tid, *tid_tmp; |
1886 | ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf); | ||
1887 | |||
1888 | /* cleanup tx descriptors */ | ||
1889 | if (sc->tx.txdma.dd_desc_len != 0) | ||
1890 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); | ||
1891 | 797 | ||
1892 | return 0; | 798 | list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { |
799 | list_del(&ac->list); | ||
800 | ac->sched = false; | ||
801 | list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { | ||
802 | list_del(&tid->list); | ||
803 | tid->sched = false; | ||
804 | ath_tid_drain(sc, txq, tid); | ||
805 | } | ||
806 | } | ||
1893 | } | 807 | } |
1894 | 808 | ||
1895 | /* Setup a h/w transmit queue */ | ||
1896 | |||
1897 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | 809 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) |
1898 | { | 810 | { |
1899 | struct ath_hal *ah = sc->sc_ah; | 811 | struct ath_hal *ah = sc->sc_ah; |
@@ -1959,43 +871,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
1959 | return &sc->tx.txq[qnum]; | 871 | return &sc->tx.txq[qnum]; |
1960 | } | 872 | } |
1961 | 873 | ||
1962 | /* Reclaim resources for a setup queue */ | 874 | static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) |
1963 | |||
1964 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | ||
1965 | { | ||
1966 | ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum); | ||
1967 | sc->tx.txqsetup &= ~(1<<txq->axq_qnum); | ||
1968 | } | ||
1969 | |||
1970 | /* | ||
1971 | * Setup a hardware data transmit queue for the specified | ||
1972 | * access control. The hal may not support all requested | ||
1973 | * queues in which case it will return a reference to a | ||
1974 | * previously setup queue. We record the mapping from ac's | ||
1975 | * to h/w queues for use by ath_tx_start and also track | ||
1976 | * the set of h/w queues being used to optimize work in the | ||
1977 | * transmit interrupt handler and related routines. | ||
1978 | */ | ||
1979 | |||
1980 | int ath_tx_setup(struct ath_softc *sc, int haltype) | ||
1981 | { | ||
1982 | struct ath_txq *txq; | ||
1983 | |||
1984 | if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { | ||
1985 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1986 | "HAL AC %u out of range, max %zu!\n", | ||
1987 | haltype, ARRAY_SIZE(sc->tx.hwq_map)); | ||
1988 | return 0; | ||
1989 | } | ||
1990 | txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); | ||
1991 | if (txq != NULL) { | ||
1992 | sc->tx.hwq_map[haltype] = txq->axq_qnum; | ||
1993 | return 1; | ||
1994 | } else | ||
1995 | return 0; | ||
1996 | } | ||
1997 | |||
1998 | int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) | ||
1999 | { | 875 | { |
2000 | int qnum; | 876 | int qnum; |
2001 | 877 | ||
@@ -2021,8 +897,6 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) | |||
2021 | return qnum; | 897 | return qnum; |
2022 | } | 898 | } |
2023 | 899 | ||
2024 | /* Get a transmit queue, if available */ | ||
2025 | |||
2026 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) | 900 | struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) |
2027 | { | 901 | { |
2028 | struct ath_txq *txq = NULL; | 902 | struct ath_txq *txq = NULL; |
@@ -2033,7 +907,6 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) | |||
2033 | 907 | ||
2034 | spin_lock_bh(&txq->axq_lock); | 908 | spin_lock_bh(&txq->axq_lock); |
2035 | 909 | ||
2036 | /* Try to avoid running out of descriptors */ | ||
2037 | if (txq->axq_depth >= (ATH_TXBUF - 20)) { | 910 | if (txq->axq_depth >= (ATH_TXBUF - 20)) { |
2038 | DPRINTF(sc, ATH_DBG_FATAL, | 911 | DPRINTF(sc, ATH_DBG_FATAL, |
2039 | "TX queue: %d is full, depth: %d\n", | 912 | "TX queue: %d is full, depth: %d\n", |
@@ -2049,8 +922,6 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) | |||
2049 | return txq; | 922 | return txq; |
2050 | } | 923 | } |
2051 | 924 | ||
2052 | /* Update parameters for a transmit queue */ | ||
2053 | |||
2054 | int ath_txq_update(struct ath_softc *sc, int qnum, | 925 | int ath_txq_update(struct ath_softc *sc, int qnum, |
2055 | struct ath9k_tx_queue_info *qinfo) | 926 | struct ath9k_tx_queue_info *qinfo) |
2056 | { | 927 | { |
@@ -2082,7 +953,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, | |||
2082 | "Unable to update hardware queue %u!\n", qnum); | 953 | "Unable to update hardware queue %u!\n", qnum); |
2083 | error = -EIO; | 954 | error = -EIO; |
2084 | } else { | 955 | } else { |
2085 | ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */ | 956 | ath9k_hw_resettxqueue(ah, qnum); |
2086 | } | 957 | } |
2087 | 958 | ||
2088 | return error; | 959 | return error; |
@@ -2111,36 +982,19 @@ int ath_cabq_update(struct ath_softc *sc) | |||
2111 | return 0; | 982 | return 0; |
2112 | } | 983 | } |
2113 | 984 | ||
2114 | /* Deferred processing of transmit interrupt */ | 985 | /* |
2115 | 986 | * Drain a given TX queue (could be Beacon or Data) | |
2116 | void ath_tx_tasklet(struct ath_softc *sc) | 987 | * |
2117 | { | 988 | * This assumes output has been stopped and |
2118 | int i; | 989 | * we do not need to block ath_tx_tasklet. |
2119 | u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); | 990 | */ |
2120 | 991 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |
2121 | ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); | ||
2122 | |||
2123 | /* | ||
2124 | * Process each active queue. | ||
2125 | */ | ||
2126 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2127 | if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) | ||
2128 | ath_tx_processq(sc, &sc->tx.txq[i]); | ||
2129 | } | ||
2130 | } | ||
2131 | |||
2132 | void ath_tx_draintxq(struct ath_softc *sc, | ||
2133 | struct ath_txq *txq, bool retry_tx) | ||
2134 | { | 992 | { |
2135 | struct ath_buf *bf, *lastbf; | 993 | struct ath_buf *bf, *lastbf; |
2136 | struct list_head bf_head; | 994 | struct list_head bf_head; |
2137 | 995 | ||
2138 | INIT_LIST_HEAD(&bf_head); | 996 | INIT_LIST_HEAD(&bf_head); |
2139 | 997 | ||
2140 | /* | ||
2141 | * NB: this assumes output has been stopped and | ||
2142 | * we do not need to block ath_tx_tasklet | ||
2143 | */ | ||
2144 | for (;;) { | 998 | for (;;) { |
2145 | spin_lock_bh(&txq->axq_lock); | 999 | spin_lock_bh(&txq->axq_lock); |
2146 | 1000 | ||
@@ -2175,7 +1029,7 @@ void ath_tx_draintxq(struct ath_softc *sc, | |||
2175 | spin_unlock_bh(&txq->axq_lock); | 1029 | spin_unlock_bh(&txq->axq_lock); |
2176 | 1030 | ||
2177 | if (bf_isampdu(bf)) | 1031 | if (bf_isampdu(bf)) |
2178 | ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0); | 1032 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); |
2179 | else | 1033 | else |
2180 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); | 1034 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); |
2181 | } | 1035 | } |
@@ -2190,44 +1044,272 @@ void ath_tx_draintxq(struct ath_softc *sc, | |||
2190 | } | 1044 | } |
2191 | } | 1045 | } |
2192 | 1046 | ||
2193 | /* Drain the transmit queues and reclaim resources */ | 1047 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
1048 | { | ||
1049 | struct ath_hal *ah = sc->sc_ah; | ||
1050 | struct ath_txq *txq; | ||
1051 | int i, npend = 0; | ||
1052 | |||
1053 | if (sc->sc_flags & SC_OP_INVALID) | ||
1054 | return; | ||
1055 | |||
1056 | /* Stop beacon queue */ | ||
1057 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
1058 | |||
1059 | /* Stop data queues */ | ||
1060 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1061 | if (ATH_TXQ_SETUP(sc, i)) { | ||
1062 | txq = &sc->tx.txq[i]; | ||
1063 | ath9k_hw_stoptxdma(ah, txq->axq_qnum); | ||
1064 | npend += ath9k_hw_numtxpending(ah, txq->axq_qnum); | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | if (npend) { | ||
1069 | int r; | ||
1070 | |||
1071 | DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n"); | ||
1072 | |||
1073 | spin_lock_bh(&sc->sc_resetlock); | ||
1074 | r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, true); | ||
1075 | if (r) | ||
1076 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1077 | "Unable to reset hardware; reset status %u\n", | ||
1078 | r); | ||
1079 | spin_unlock_bh(&sc->sc_resetlock); | ||
1080 | } | ||
1081 | |||
1082 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
1083 | if (ATH_TXQ_SETUP(sc, i)) | ||
1084 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | ||
1085 | } | ||
1086 | } | ||
1087 | |||
1088 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | ||
1089 | { | ||
1090 | ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum); | ||
1091 | sc->tx.txqsetup &= ~(1<<txq->axq_qnum); | ||
1092 | } | ||
2194 | 1093 | ||
2195 | void ath_draintxq(struct ath_softc *sc, bool retry_tx) | 1094 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) |
2196 | { | 1095 | { |
2197 | /* stop beacon queue. The beacon will be freed when | 1096 | struct ath_atx_ac *ac; |
2198 | * we go to INIT state */ | 1097 | struct ath_atx_tid *tid; |
2199 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 1098 | |
2200 | (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1099 | if (list_empty(&txq->axq_acq)) |
2201 | DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n", | 1100 | return; |
2202 | ath9k_hw_gettxbuf(sc->sc_ah, sc->beacon.beaconq)); | 1101 | |
1102 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); | ||
1103 | list_del(&ac->list); | ||
1104 | ac->sched = false; | ||
1105 | |||
1106 | do { | ||
1107 | if (list_empty(&ac->tid_q)) | ||
1108 | return; | ||
1109 | |||
1110 | tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list); | ||
1111 | list_del(&tid->list); | ||
1112 | tid->sched = false; | ||
1113 | |||
1114 | if (tid->paused) | ||
1115 | continue; | ||
1116 | |||
1117 | if ((txq->axq_depth % 2) == 0) | ||
1118 | ath_tx_sched_aggr(sc, txq, tid); | ||
1119 | |||
1120 | /* | ||
1121 | * add tid to round-robin queue if more frames | ||
1122 | * are pending for the tid | ||
1123 | */ | ||
1124 | if (!list_empty(&tid->buf_q)) | ||
1125 | ath_tx_queue_tid(txq, tid); | ||
1126 | |||
1127 | break; | ||
1128 | } while (!list_empty(&ac->tid_q)); | ||
1129 | |||
1130 | if (!list_empty(&ac->tid_q)) { | ||
1131 | if (!ac->sched) { | ||
1132 | ac->sched = true; | ||
1133 | list_add_tail(&ac->list, &txq->axq_acq); | ||
1134 | } | ||
2203 | } | 1135 | } |
1136 | } | ||
2204 | 1137 | ||
2205 | ath_drain_txdataq(sc, retry_tx); | 1138 | int ath_tx_setup(struct ath_softc *sc, int haltype) |
1139 | { | ||
1140 | struct ath_txq *txq; | ||
1141 | |||
1142 | if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { | ||
1143 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1144 | "HAL AC %u out of range, max %zu!\n", | ||
1145 | haltype, ARRAY_SIZE(sc->tx.hwq_map)); | ||
1146 | return 0; | ||
1147 | } | ||
1148 | txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); | ||
1149 | if (txq != NULL) { | ||
1150 | sc->tx.hwq_map[haltype] = txq->axq_qnum; | ||
1151 | return 1; | ||
1152 | } else | ||
1153 | return 0; | ||
2206 | } | 1154 | } |
2207 | 1155 | ||
2208 | u32 ath_txq_depth(struct ath_softc *sc, int qnum) | 1156 | /***********/ |
1157 | /* TX, DMA */ | ||
1158 | /***********/ | ||
1159 | |||
1160 | /* | ||
1161 | * Insert a chain of ath_buf (descriptors) on a txq and | ||
1162 | * assume the descriptors are already chained together by caller. | ||
1163 | */ | ||
1164 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | ||
1165 | struct list_head *head) | ||
2209 | { | 1166 | { |
2210 | return sc->tx.txq[qnum].axq_depth; | 1167 | struct ath_hal *ah = sc->sc_ah; |
1168 | struct ath_buf *bf; | ||
1169 | |||
1170 | /* | ||
1171 | * Insert the frame on the outbound list and | ||
1172 | * pass it on to the hardware. | ||
1173 | */ | ||
1174 | |||
1175 | if (list_empty(head)) | ||
1176 | return; | ||
1177 | |||
1178 | bf = list_first_entry(head, struct ath_buf, list); | ||
1179 | |||
1180 | list_splice_tail_init(head, &txq->axq_q); | ||
1181 | txq->axq_depth++; | ||
1182 | txq->axq_totalqueued++; | ||
1183 | txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); | ||
1184 | |||
1185 | DPRINTF(sc, ATH_DBG_QUEUE, | ||
1186 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | ||
1187 | |||
1188 | if (txq->axq_link == NULL) { | ||
1189 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | ||
1190 | DPRINTF(sc, ATH_DBG_XMIT, | ||
1191 | "TXDP[%u] = %llx (%p)\n", | ||
1192 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | ||
1193 | } else { | ||
1194 | *txq->axq_link = bf->bf_daddr; | ||
1195 | DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n", | ||
1196 | txq->axq_qnum, txq->axq_link, | ||
1197 | ito64(bf->bf_daddr), bf->bf_desc); | ||
1198 | } | ||
1199 | txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link); | ||
1200 | ath9k_hw_txstart(ah, txq->axq_qnum); | ||
2211 | } | 1201 | } |
2212 | 1202 | ||
2213 | u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum) | 1203 | static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) |
2214 | { | 1204 | { |
2215 | return sc->tx.txq[qnum].axq_aggr_depth; | 1205 | struct ath_buf *bf = NULL; |
1206 | |||
1207 | spin_lock_bh(&sc->tx.txbuflock); | ||
1208 | |||
1209 | if (unlikely(list_empty(&sc->tx.txbuf))) { | ||
1210 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1211 | return NULL; | ||
1212 | } | ||
1213 | |||
1214 | bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | ||
1215 | list_del(&bf->list); | ||
1216 | |||
1217 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1218 | |||
1219 | return bf; | ||
2216 | } | 1220 | } |
2217 | 1221 | ||
2218 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) | 1222 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, |
1223 | struct list_head *bf_head, | ||
1224 | struct ath_tx_control *txctl) | ||
2219 | { | 1225 | { |
2220 | struct ath_atx_tid *txtid; | 1226 | struct ath_buf *bf; |
2221 | 1227 | ||
2222 | if (!(sc->sc_flags & SC_OP_TXAGGR)) | 1228 | bf = list_first_entry(bf_head, struct ath_buf, list); |
2223 | return false; | 1229 | bf->bf_state.bf_type |= BUF_AMPDU; |
2224 | 1230 | ||
2225 | txtid = ATH_AN_2_TID(an, tidno); | 1231 | /* |
1232 | * Do not queue to h/w when any of the following conditions is true: | ||
1233 | * - there are pending frames in software queue | ||
1234 | * - the TID is currently paused for ADDBA/BAR request | ||
1235 | * - seqno is not within block-ack window | ||
1236 | * - h/w queue depth exceeds low water mark | ||
1237 | */ | ||
1238 | if (!list_empty(&tid->buf_q) || tid->paused || | ||
1239 | !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) || | ||
1240 | txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) { | ||
1241 | /* | ||
1242 | * Add this frame to software queue for scheduling later | ||
1243 | * for aggregation. | ||
1244 | */ | ||
1245 | list_move_tail(&bf->list, &tid->buf_q); | ||
1246 | ath_tx_queue_tid(txctl->txq, tid); | ||
1247 | return; | ||
1248 | } | ||
2226 | 1249 | ||
2227 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | 1250 | /* Add sub-frame to BAW */ |
2228 | if (!(txtid->state & AGGR_ADDBA_PROGRESS) && | 1251 | ath_tx_addto_baw(sc, tid, bf); |
2229 | (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) { | 1252 | |
2230 | txtid->addba_exchangeattempts++; | 1253 | /* Queue to h/w without aggregation */ |
1254 | bf->bf_nframes = 1; | ||
1255 | bf->bf_lastbf = bf; | ||
1256 | ath_buf_set_rate(sc, bf); | ||
1257 | ath_tx_txqaddbuf(sc, txctl->txq, bf_head); | ||
1258 | } | ||
1259 | |||
1260 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | ||
1261 | struct ath_atx_tid *tid, | ||
1262 | struct list_head *bf_head) | ||
1263 | { | ||
1264 | struct ath_buf *bf; | ||
1265 | |||
1266 | bf = list_first_entry(bf_head, struct ath_buf, list); | ||
1267 | bf->bf_state.bf_type &= ~BUF_AMPDU; | ||
1268 | |||
1269 | /* update starting sequence number for subsequent ADDBA request */ | ||
1270 | INCR(tid->seq_start, IEEE80211_SEQ_MAX); | ||
1271 | |||
1272 | bf->bf_nframes = 1; | ||
1273 | bf->bf_lastbf = bf; | ||
1274 | ath_buf_set_rate(sc, bf); | ||
1275 | ath_tx_txqaddbuf(sc, txq, bf_head); | ||
1276 | } | ||
1277 | |||
1278 | static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | ||
1279 | { | ||
1280 | struct ieee80211_hdr *hdr; | ||
1281 | enum ath9k_pkt_type htype; | ||
1282 | __le16 fc; | ||
1283 | |||
1284 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1285 | fc = hdr->frame_control; | ||
1286 | |||
1287 | if (ieee80211_is_beacon(fc)) | ||
1288 | htype = ATH9K_PKT_TYPE_BEACON; | ||
1289 | else if (ieee80211_is_probe_resp(fc)) | ||
1290 | htype = ATH9K_PKT_TYPE_PROBE_RESP; | ||
1291 | else if (ieee80211_is_atim(fc)) | ||
1292 | htype = ATH9K_PKT_TYPE_ATIM; | ||
1293 | else if (ieee80211_is_pspoll(fc)) | ||
1294 | htype = ATH9K_PKT_TYPE_PSPOLL; | ||
1295 | else | ||
1296 | htype = ATH9K_PKT_TYPE_NORMAL; | ||
1297 | |||
1298 | return htype; | ||
1299 | } | ||
1300 | |||
1301 | static bool is_pae(struct sk_buff *skb) | ||
1302 | { | ||
1303 | struct ieee80211_hdr *hdr; | ||
1304 | __le16 fc; | ||
1305 | |||
1306 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1307 | fc = hdr->frame_control; | ||
1308 | |||
1309 | if (ieee80211_is_data(fc)) { | ||
1310 | if (ieee80211_is_nullfunc(fc) || | ||
1311 | /* Port Access Entity (IEEE 802.1X) */ | ||
1312 | (skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
2231 | return true; | 1313 | return true; |
2232 | } | 1314 | } |
2233 | } | 1315 | } |
@@ -2235,175 +1317,803 @@ bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) | |||
2235 | return false; | 1317 | return false; |
2236 | } | 1318 | } |
2237 | 1319 | ||
2238 | /* Start TX aggregation */ | 1320 | static int get_hw_crypto_keytype(struct sk_buff *skb) |
1321 | { | ||
1322 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
2239 | 1323 | ||
2240 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 1324 | if (tx_info->control.hw_key) { |
2241 | u16 tid, u16 *ssn) | 1325 | if (tx_info->control.hw_key->alg == ALG_WEP) |
1326 | return ATH9K_KEY_TYPE_WEP; | ||
1327 | else if (tx_info->control.hw_key->alg == ALG_TKIP) | ||
1328 | return ATH9K_KEY_TYPE_TKIP; | ||
1329 | else if (tx_info->control.hw_key->alg == ALG_CCMP) | ||
1330 | return ATH9K_KEY_TYPE_AES; | ||
1331 | } | ||
1332 | |||
1333 | return ATH9K_KEY_TYPE_CLEAR; | ||
1334 | } | ||
1335 | |||
1336 | static void assign_aggr_tid_seqno(struct sk_buff *skb, | ||
1337 | struct ath_buf *bf) | ||
2242 | { | 1338 | { |
2243 | struct ath_atx_tid *txtid; | 1339 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1340 | struct ieee80211_hdr *hdr; | ||
2244 | struct ath_node *an; | 1341 | struct ath_node *an; |
1342 | struct ath_atx_tid *tid; | ||
1343 | __le16 fc; | ||
1344 | u8 *qc; | ||
2245 | 1345 | ||
2246 | an = (struct ath_node *)sta->drv_priv; | 1346 | if (!tx_info->control.sta) |
1347 | return; | ||
2247 | 1348 | ||
2248 | if (sc->sc_flags & SC_OP_TXAGGR) { | 1349 | an = (struct ath_node *)tx_info->control.sta->drv_priv; |
2249 | txtid = ATH_AN_2_TID(an, tid); | 1350 | hdr = (struct ieee80211_hdr *)skb->data; |
2250 | txtid->state |= AGGR_ADDBA_PROGRESS; | 1351 | fc = hdr->frame_control; |
2251 | ath_tx_pause_tid(sc, txtid); | 1352 | |
1353 | if (ieee80211_is_data_qos(fc)) { | ||
1354 | qc = ieee80211_get_qos_ctl(hdr); | ||
1355 | bf->bf_tidno = qc[0] & 0xf; | ||
2252 | } | 1356 | } |
2253 | 1357 | ||
2254 | return 0; | 1358 | /* |
1359 | * For HT capable stations, we save tidno for later use. | ||
1360 | * We also override seqno set by upper layer with the one | ||
1361 | * in tx aggregation state. | ||
1362 | * | ||
1363 | * If fragmentation is on, the sequence number is | ||
1364 | * not overridden, since it has been | ||
1365 | * incremented by the fragmentation routine. | ||
1366 | * | ||
1367 | * FIXME: check if the fragmentation threshold exceeds | ||
1368 | * IEEE80211 max. | ||
1369 | */ | ||
1370 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
1371 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << | ||
1372 | IEEE80211_SEQ_SEQ_SHIFT); | ||
1373 | bf->bf_seqno = tid->seq_next; | ||
1374 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | ||
2255 | } | 1375 | } |
2256 | 1376 | ||
2257 | /* Stop tx aggregation */ | 1377 | static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, |
2258 | 1378 | struct ath_txq *txq) | |
2259 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | ||
2260 | { | 1379 | { |
2261 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | 1380 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1381 | int flags = 0; | ||
2262 | 1382 | ||
2263 | ath_tx_aggr_teardown(sc, an, tid); | 1383 | flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ |
2264 | return 0; | 1384 | flags |= ATH9K_TXDESC_INTREQ; |
1385 | |||
1386 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
1387 | flags |= ATH9K_TXDESC_NOACK; | ||
1388 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
1389 | flags |= ATH9K_TXDESC_RTSENA; | ||
1390 | |||
1391 | return flags; | ||
2265 | } | 1392 | } |
2266 | 1393 | ||
2267 | /* Resume tx aggregation */ | 1394 | /* |
1395 | * rix - rate index | ||
1396 | * pktlen - total bytes (delims + data + fcs + pads + pad delims) | ||
1397 | * width - 0 for 20 MHz, 1 for 40 MHz | ||
1398 | * half_gi - to use 4us v/s 3.6 us for symbol time | ||
1399 | */ | ||
1400 | static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | ||
1401 | int width, int half_gi, bool shortPreamble) | ||
1402 | { | ||
1403 | struct ath_rate_table *rate_table = sc->cur_rate_table; | ||
1404 | u32 nbits, nsymbits, duration, nsymbols; | ||
1405 | u8 rc; | ||
1406 | int streams, pktlen; | ||
2268 | 1407 | ||
2269 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 1408 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; |
1409 | rc = rate_table->info[rix].ratecode; | ||
1410 | |||
1411 | /* for legacy rates, use old function to compute packet duration */ | ||
1412 | if (!IS_HT_RATE(rc)) | ||
1413 | return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen, | ||
1414 | rix, shortPreamble); | ||
1415 | |||
1416 | /* find number of symbols: PLCP + data */ | ||
1417 | nbits = (pktlen << 3) + OFDM_PLCP_BITS; | ||
1418 | nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width]; | ||
1419 | nsymbols = (nbits + nsymbits - 1) / nsymbits; | ||
1420 | |||
1421 | if (!half_gi) | ||
1422 | duration = SYMBOL_TIME(nsymbols); | ||
1423 | else | ||
1424 | duration = SYMBOL_TIME_HALFGI(nsymbols); | ||
1425 | |||
1426 | /* addup duration for legacy/ht training and signal fields */ | ||
1427 | streams = HT_RC_2_STREAMS(rc); | ||
1428 | duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | ||
1429 | |||
1430 | return duration; | ||
1431 | } | ||
1432 | |||
1433 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | ||
2270 | { | 1434 | { |
2271 | struct ath_atx_tid *txtid; | 1435 | struct ath_hal *ah = sc->sc_ah; |
2272 | struct ath_node *an; | 1436 | struct ath_rate_table *rt; |
1437 | struct ath_desc *ds = bf->bf_desc; | ||
1438 | struct ath_desc *lastds = bf->bf_lastbf->bf_desc; | ||
1439 | struct ath9k_11n_rate_series series[4]; | ||
1440 | struct sk_buff *skb; | ||
1441 | struct ieee80211_tx_info *tx_info; | ||
1442 | struct ieee80211_tx_rate *rates; | ||
1443 | struct ieee80211_hdr *hdr; | ||
1444 | struct ieee80211_hw *hw = sc->hw; | ||
1445 | int i, flags, rtsctsena = 0, enable_g_protection = 0; | ||
1446 | u32 ctsduration = 0; | ||
1447 | u8 rix = 0, cix, ctsrate = 0; | ||
1448 | __le16 fc; | ||
2273 | 1449 | ||
2274 | an = (struct ath_node *)sta->drv_priv; | 1450 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); |
2275 | 1451 | ||
2276 | if (sc->sc_flags & SC_OP_TXAGGR) { | 1452 | skb = (struct sk_buff *)bf->bf_mpdu; |
2277 | txtid = ATH_AN_2_TID(an, tid); | 1453 | hdr = (struct ieee80211_hdr *)skb->data; |
2278 | txtid->baw_size = | 1454 | fc = hdr->frame_control; |
2279 | IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; | 1455 | tx_info = IEEE80211_SKB_CB(skb); |
2280 | txtid->state |= AGGR_ADDBA_COMPLETE; | 1456 | rates = tx_info->control.rates; |
2281 | txtid->state &= ~AGGR_ADDBA_PROGRESS; | 1457 | |
2282 | ath_tx_resume_tid(sc, txtid); | 1458 | if (ieee80211_has_morefrags(fc) || |
1459 | (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) { | ||
1460 | rates[1].count = rates[2].count = rates[3].count = 0; | ||
1461 | rates[1].idx = rates[2].idx = rates[3].idx = 0; | ||
1462 | rates[0].count = ATH_TXMAXTRY; | ||
1463 | } | ||
1464 | |||
1465 | /* get the cix for the lowest valid rix */ | ||
1466 | rt = sc->cur_rate_table; | ||
1467 | for (i = 3; i >= 0; i--) { | ||
1468 | if (rates[i].count && (rates[i].idx >= 0)) { | ||
1469 | rix = rates[i].idx; | ||
1470 | break; | ||
1471 | } | ||
1472 | } | ||
1473 | |||
1474 | flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)); | ||
1475 | cix = rt->info[rix].ctrl_rate; | ||
1476 | |||
1477 | /* All protection frames are transmited at 2Mb/s for 802.11g, | ||
1478 | * otherwise we transmit them at 1Mb/s */ | ||
1479 | if (hw->conf.channel->band == IEEE80211_BAND_2GHZ && | ||
1480 | !conf_is_ht(&hw->conf)) | ||
1481 | enable_g_protection = 1; | ||
1482 | |||
1483 | /* | ||
1484 | * If 802.11g protection is enabled, determine whether to use RTS/CTS or | ||
1485 | * just CTS. Note that this is only done for OFDM/HT unicast frames. | ||
1486 | */ | ||
1487 | if (sc->sc_protmode != PROT_M_NONE && !(bf->bf_flags & ATH9K_TXDESC_NOACK) | ||
1488 | && (rt->info[rix].phy == WLAN_RC_PHY_OFDM || | ||
1489 | WLAN_RC_PHY_HT(rt->info[rix].phy))) { | ||
1490 | if (sc->sc_protmode == PROT_M_RTSCTS) | ||
1491 | flags = ATH9K_TXDESC_RTSENA; | ||
1492 | else if (sc->sc_protmode == PROT_M_CTSONLY) | ||
1493 | flags = ATH9K_TXDESC_CTSENA; | ||
1494 | |||
1495 | cix = rt->info[enable_g_protection].ctrl_rate; | ||
1496 | rtsctsena = 1; | ||
1497 | } | ||
1498 | |||
1499 | /* For 11n, the default behavior is to enable RTS for hw retried frames. | ||
1500 | * We enable the global flag here and let rate series flags determine | ||
1501 | * which rates will actually use RTS. | ||
1502 | */ | ||
1503 | if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) { | ||
1504 | /* 802.11g protection not needed, use our default behavior */ | ||
1505 | if (!rtsctsena) | ||
1506 | flags = ATH9K_TXDESC_RTSENA; | ||
1507 | } | ||
1508 | |||
1509 | /* Set protection if aggregate protection on */ | ||
1510 | if (sc->sc_config.ath_aggr_prot && | ||
1511 | (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { | ||
1512 | flags = ATH9K_TXDESC_RTSENA; | ||
1513 | cix = rt->info[enable_g_protection].ctrl_rate; | ||
1514 | rtsctsena = 1; | ||
1515 | } | ||
1516 | |||
1517 | /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ | ||
1518 | if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) | ||
1519 | flags &= ~(ATH9K_TXDESC_RTSENA); | ||
1520 | |||
1521 | /* | ||
1522 | * CTS transmit rate is derived from the transmit rate by looking in the | ||
1523 | * h/w rate table. We must also factor in whether or not a short | ||
1524 | * preamble is to be used. NB: cix is set above where RTS/CTS is enabled | ||
1525 | */ | ||
1526 | ctsrate = rt->info[cix].ratecode | | ||
1527 | (bf_isshpreamble(bf) ? rt->info[cix].short_preamble : 0); | ||
1528 | |||
1529 | for (i = 0; i < 4; i++) { | ||
1530 | if (!rates[i].count || (rates[i].idx < 0)) | ||
1531 | continue; | ||
1532 | |||
1533 | rix = rates[i].idx; | ||
1534 | |||
1535 | series[i].Rate = rt->info[rix].ratecode | | ||
1536 | (bf_isshpreamble(bf) ? rt->info[rix].short_preamble : 0); | ||
1537 | |||
1538 | series[i].Tries = rates[i].count; | ||
1539 | |||
1540 | series[i].RateFlags = ( | ||
1541 | (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) ? | ||
1542 | ATH9K_RATESERIES_RTS_CTS : 0) | | ||
1543 | ((rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? | ||
1544 | ATH9K_RATESERIES_2040 : 0) | | ||
1545 | ((rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ? | ||
1546 | ATH9K_RATESERIES_HALFGI : 0); | ||
1547 | |||
1548 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, | ||
1549 | (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0, | ||
1550 | (rates[i].flags & IEEE80211_TX_RC_SHORT_GI), | ||
1551 | bf_isshpreamble(bf)); | ||
1552 | |||
1553 | series[i].ChSel = sc->sc_tx_chainmask; | ||
1554 | |||
1555 | if (rtsctsena) | ||
1556 | series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; | ||
2283 | } | 1557 | } |
1558 | |||
1559 | /* set dur_update_en for l-sig computation except for PS-Poll frames */ | ||
1560 | ath9k_hw_set11n_ratescenario(ah, ds, lastds, !bf_ispspoll(bf), | ||
1561 | ctsrate, ctsduration, | ||
1562 | series, 4, flags); | ||
1563 | |||
1564 | if (sc->sc_config.ath_aggr_prot && flags) | ||
1565 | ath9k_hw_set11n_burstduration(ah, ds, 8192); | ||
2284 | } | 1566 | } |
2285 | 1567 | ||
2286 | /* | 1568 | static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, |
2287 | * Performs transmit side cleanup when TID changes from aggregated to | 1569 | struct sk_buff *skb, |
2288 | * unaggregated. | 1570 | struct ath_tx_control *txctl) |
2289 | * - Pause the TID and mark cleanup in progress | 1571 | { |
2290 | * - Discard all retry frames from the s/w queue. | 1572 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
2291 | */ | 1573 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1574 | struct ath_tx_info_priv *tx_info_priv; | ||
1575 | int hdrlen; | ||
1576 | __le16 fc; | ||
1577 | |||
1578 | tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | ||
1579 | if (unlikely(!tx_info_priv)) | ||
1580 | return -ENOMEM; | ||
1581 | tx_info->rate_driver_data[0] = tx_info_priv; | ||
1582 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1583 | fc = hdr->frame_control; | ||
1584 | |||
1585 | ATH_TXBUF_RESET(bf); | ||
1586 | |||
1587 | bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3); | ||
1588 | |||
1589 | if (ieee80211_is_data(fc)) | ||
1590 | bf->bf_state.bf_type |= BUF_DATA; | ||
1591 | if (ieee80211_is_back_req(fc)) | ||
1592 | bf->bf_state.bf_type |= BUF_BAR; | ||
1593 | if (ieee80211_is_pspoll(fc)) | ||
1594 | bf->bf_state.bf_type |= BUF_PSPOLL; | ||
1595 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | ||
1596 | bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE; | ||
1597 | if ((conf_is_ht(&sc->hw->conf) && !is_pae(skb) && | ||
1598 | (tx_info->flags & IEEE80211_TX_CTL_AMPDU))) | ||
1599 | bf->bf_state.bf_type |= BUF_HT; | ||
1600 | |||
1601 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); | ||
1602 | |||
1603 | bf->bf_keytype = get_hw_crypto_keytype(skb); | ||
1604 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { | ||
1605 | bf->bf_frmlen += tx_info->control.hw_key->icv_len; | ||
1606 | bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; | ||
1607 | } else { | ||
1608 | bf->bf_keyix = ATH9K_TXKEYIX_INVALID; | ||
1609 | } | ||
1610 | |||
1611 | if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR)) | ||
1612 | assign_aggr_tid_seqno(skb, bf); | ||
1613 | |||
1614 | bf->bf_mpdu = skb; | ||
1615 | |||
1616 | bf->bf_dmacontext = dma_map_single(sc->dev, skb->data, | ||
1617 | skb->len, DMA_TO_DEVICE); | ||
1618 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { | ||
1619 | bf->bf_mpdu = NULL; | ||
1620 | DPRINTF(sc, ATH_DBG_CONFIG, | ||
1621 | "dma_mapping_error() on TX\n"); | ||
1622 | return -ENOMEM; | ||
1623 | } | ||
1624 | |||
1625 | bf->bf_buf_addr = bf->bf_dmacontext; | ||
1626 | return 0; | ||
1627 | } | ||
2292 | 1628 | ||
2293 | void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) | 1629 | /* FIXME: tx power */ |
1630 | static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | ||
1631 | struct ath_tx_control *txctl) | ||
2294 | { | 1632 | { |
2295 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); | 1633 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; |
2296 | struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; | 1634 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
2297 | struct ath_buf *bf; | 1635 | struct ath_node *an = NULL; |
2298 | struct list_head bf_head; | 1636 | struct list_head bf_head; |
1637 | struct ath_desc *ds; | ||
1638 | struct ath_atx_tid *tid; | ||
1639 | struct ath_hal *ah = sc->sc_ah; | ||
1640 | int frm_type; | ||
1641 | |||
1642 | frm_type = get_hw_packet_type(skb); | ||
1643 | |||
2299 | INIT_LIST_HEAD(&bf_head); | 1644 | INIT_LIST_HEAD(&bf_head); |
1645 | list_add_tail(&bf->list, &bf_head); | ||
2300 | 1646 | ||
2301 | if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */ | 1647 | ds = bf->bf_desc; |
2302 | return; | 1648 | ds->ds_link = 0; |
1649 | ds->ds_data = bf->bf_buf_addr; | ||
2303 | 1650 | ||
2304 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | 1651 | ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, |
2305 | txtid->addba_exchangeattempts = 0; | 1652 | bf->bf_keyix, bf->bf_keytype, bf->bf_flags); |
2306 | return; | ||
2307 | } | ||
2308 | 1653 | ||
2309 | /* TID must be paused first */ | 1654 | ath9k_hw_filltxdesc(ah, ds, |
2310 | ath_tx_pause_tid(sc, txtid); | 1655 | skb->len, /* segment length */ |
1656 | true, /* first segment */ | ||
1657 | true, /* last segment */ | ||
1658 | ds); /* first descriptor */ | ||
2311 | 1659 | ||
2312 | /* drop all software retried frames and mark this TID */ | 1660 | spin_lock_bh(&txctl->txq->axq_lock); |
2313 | spin_lock_bh(&txq->axq_lock); | 1661 | |
2314 | while (!list_empty(&txtid->buf_q)) { | 1662 | if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && |
2315 | bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); | 1663 | tx_info->control.sta) { |
2316 | if (!bf_isretried(bf)) { | 1664 | an = (struct ath_node *)tx_info->control.sta->drv_priv; |
1665 | tid = ATH_AN_2_TID(an, bf->bf_tidno); | ||
1666 | |||
1667 | if (ath_aggr_query(sc, an, bf->bf_tidno)) { | ||
2317 | /* | 1668 | /* |
2318 | * NB: it's based on the assumption that | 1669 | * Try aggregation if it's a unicast data frame |
2319 | * software retried frame will always stay | 1670 | * and the destination is HT capable. |
2320 | * at the head of software queue. | ||
2321 | */ | 1671 | */ |
2322 | break; | 1672 | ath_tx_send_ampdu(sc, tid, &bf_head, txctl); |
1673 | } else { | ||
1674 | /* | ||
1675 | * Send this frame as regular when ADDBA | ||
1676 | * exchange is neither complete nor pending. | ||
1677 | */ | ||
1678 | ath_tx_send_normal(sc, txctl->txq, | ||
1679 | tid, &bf_head); | ||
2323 | } | 1680 | } |
2324 | list_cut_position(&bf_head, | 1681 | } else { |
2325 | &txtid->buf_q, &bf->bf_lastfrm->list); | 1682 | bf->bf_lastbf = bf; |
2326 | ath_tx_update_baw(sc, txtid, bf->bf_seqno); | 1683 | bf->bf_nframes = 1; |
2327 | 1684 | ||
2328 | /* complete this sub-frame */ | 1685 | ath_buf_set_rate(sc, bf); |
2329 | ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); | 1686 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); |
2330 | } | 1687 | } |
2331 | 1688 | ||
2332 | if (txtid->baw_head != txtid->baw_tail) { | 1689 | spin_unlock_bh(&txctl->txq->axq_lock); |
2333 | spin_unlock_bh(&txq->axq_lock); | 1690 | } |
2334 | txtid->state |= AGGR_CLEANUP; | 1691 | |
2335 | } else { | 1692 | /* Upon failure caller should free skb */ |
2336 | txtid->state &= ~AGGR_ADDBA_COMPLETE; | 1693 | int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, |
2337 | txtid->addba_exchangeattempts = 0; | 1694 | struct ath_tx_control *txctl) |
1695 | { | ||
1696 | struct ath_buf *bf; | ||
1697 | int r; | ||
1698 | |||
1699 | bf = ath_tx_get_buffer(sc); | ||
1700 | if (!bf) { | ||
1701 | DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n"); | ||
1702 | return -1; | ||
1703 | } | ||
1704 | |||
1705 | r = ath_tx_setup_buffer(sc, bf, skb, txctl); | ||
1706 | if (unlikely(r)) { | ||
1707 | struct ath_txq *txq = txctl->txq; | ||
1708 | |||
1709 | DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n"); | ||
1710 | |||
1711 | /* upon ath_tx_processq() this TX queue will be resumed, we | ||
1712 | * guarantee this will happen by knowing beforehand that | ||
1713 | * we will at least have to run TX completionon one buffer | ||
1714 | * on the queue */ | ||
1715 | spin_lock_bh(&txq->axq_lock); | ||
1716 | if (ath_txq_depth(sc, txq->axq_qnum) > 1) { | ||
1717 | ieee80211_stop_queue(sc->hw, | ||
1718 | skb_get_queue_mapping(skb)); | ||
1719 | txq->stopped = 1; | ||
1720 | } | ||
2338 | spin_unlock_bh(&txq->axq_lock); | 1721 | spin_unlock_bh(&txq->axq_lock); |
2339 | ath_tx_flush_tid(sc, txtid); | 1722 | |
1723 | spin_lock_bh(&sc->tx.txbuflock); | ||
1724 | list_add_tail(&bf->list, &sc->tx.txbuf); | ||
1725 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1726 | |||
1727 | return r; | ||
2340 | } | 1728 | } |
2341 | } | ||
2342 | 1729 | ||
2343 | /* | 1730 | ath_tx_start_dma(sc, bf, txctl); |
2344 | * Tx scheduling logic | ||
2345 | * NB: must be called with txq lock held | ||
2346 | */ | ||
2347 | 1731 | ||
2348 | void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | 1732 | return 0; |
1733 | } | ||
1734 | |||
1735 | void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) | ||
2349 | { | 1736 | { |
2350 | struct ath_atx_ac *ac; | 1737 | int hdrlen, padsize; |
2351 | struct ath_atx_tid *tid; | 1738 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1739 | struct ath_tx_control txctl; | ||
2352 | 1740 | ||
2353 | /* nothing to schedule */ | 1741 | memset(&txctl, 0, sizeof(struct ath_tx_control)); |
2354 | if (list_empty(&txq->axq_acq)) | ||
2355 | return; | ||
2356 | /* | ||
2357 | * get the first node/ac pair on the queue | ||
2358 | */ | ||
2359 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); | ||
2360 | list_del(&ac->list); | ||
2361 | ac->sched = false; | ||
2362 | 1742 | ||
2363 | /* | 1743 | /* |
2364 | * process a single tid per destination | 1744 | * As a temporary workaround, assign seq# here; this will likely need |
1745 | * to be cleaned up to work better with Beacon transmission and virtual | ||
1746 | * BSSes. | ||
2365 | */ | 1747 | */ |
2366 | do { | 1748 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
2367 | /* nothing to schedule */ | 1749 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
2368 | if (list_empty(&ac->tid_q)) | 1750 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
1751 | sc->tx.seq_no += 0x10; | ||
1752 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
1753 | hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); | ||
1754 | } | ||
1755 | |||
1756 | /* Add the padding after the header if this is not already done */ | ||
1757 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1758 | if (hdrlen & 3) { | ||
1759 | padsize = hdrlen % 4; | ||
1760 | if (skb_headroom(skb) < padsize) { | ||
1761 | DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n"); | ||
1762 | dev_kfree_skb_any(skb); | ||
2369 | return; | 1763 | return; |
1764 | } | ||
1765 | skb_push(skb, padsize); | ||
1766 | memmove(skb->data, skb->data + padsize, hdrlen); | ||
1767 | } | ||
2370 | 1768 | ||
2371 | tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list); | 1769 | txctl.txq = sc->beacon.cabq; |
2372 | list_del(&tid->list); | ||
2373 | tid->sched = false; | ||
2374 | 1770 | ||
2375 | if (tid->paused) /* check next tid to keep h/w busy */ | 1771 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb); |
2376 | continue; | ||
2377 | 1772 | ||
2378 | if ((txq->axq_depth % 2) == 0) | 1773 | if (ath_tx_start(sc, skb, &txctl) != 0) { |
2379 | ath_tx_sched_aggr(sc, txq, tid); | 1774 | DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n"); |
1775 | goto exit; | ||
1776 | } | ||
1777 | |||
1778 | return; | ||
1779 | exit: | ||
1780 | dev_kfree_skb_any(skb); | ||
1781 | } | ||
1782 | |||
1783 | /*****************/ | ||
1784 | /* TX Completion */ | ||
1785 | /*****************/ | ||
1786 | |||
1787 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | ||
1788 | struct ath_xmit_status *tx_status) | ||
1789 | { | ||
1790 | struct ieee80211_hw *hw = sc->hw; | ||
1791 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1792 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1793 | int hdrlen, padsize; | ||
1794 | |||
1795 | DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | ||
1796 | |||
1797 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | ||
1798 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
1799 | kfree(tx_info_priv); | ||
1800 | tx_info->rate_driver_data[0] = NULL; | ||
1801 | } | ||
1802 | |||
1803 | if (tx_status->flags & ATH_TX_BAR) { | ||
1804 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | ||
1805 | tx_status->flags &= ~ATH_TX_BAR; | ||
1806 | } | ||
1807 | |||
1808 | if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { | ||
1809 | /* Frame was ACKed */ | ||
1810 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | ||
1811 | } | ||
2380 | 1812 | ||
1813 | tx_info->status.rates[0].count = tx_status->retries + 1; | ||
1814 | |||
1815 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
1816 | padsize = hdrlen & 3; | ||
1817 | if (padsize && hdrlen >= 24) { | ||
2381 | /* | 1818 | /* |
2382 | * add tid to round-robin queue if more frames | 1819 | * Remove MAC header padding before giving the frame back to |
2383 | * are pending for the tid | 1820 | * mac80211. |
2384 | */ | 1821 | */ |
2385 | if (!list_empty(&tid->buf_q)) | 1822 | memmove(skb->data + padsize, skb->data, hdrlen); |
2386 | ath_tx_queue_tid(txq, tid); | 1823 | skb_pull(skb, padsize); |
1824 | } | ||
2387 | 1825 | ||
2388 | /* only schedule one TID at a time */ | 1826 | ieee80211_tx_status(hw, skb); |
2389 | break; | 1827 | } |
2390 | } while (!list_empty(&ac->tid_q)); | 1828 | |
1829 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | ||
1830 | struct list_head *bf_q, | ||
1831 | int txok, int sendbar) | ||
1832 | { | ||
1833 | struct sk_buff *skb = bf->bf_mpdu; | ||
1834 | struct ath_xmit_status tx_status; | ||
1835 | unsigned long flags; | ||
2391 | 1836 | ||
2392 | /* | 1837 | /* |
2393 | * schedule AC if more TIDs need processing | 1838 | * Set retry information. |
1839 | * NB: Don't use the information in the descriptor, because the frame | ||
1840 | * could be software retried. | ||
2394 | */ | 1841 | */ |
2395 | if (!list_empty(&ac->tid_q)) { | 1842 | tx_status.retries = bf->bf_retries; |
1843 | tx_status.flags = 0; | ||
1844 | |||
1845 | if (sendbar) | ||
1846 | tx_status.flags = ATH_TX_BAR; | ||
1847 | |||
1848 | if (!txok) { | ||
1849 | tx_status.flags |= ATH_TX_ERROR; | ||
1850 | |||
1851 | if (bf_isxretried(bf)) | ||
1852 | tx_status.flags |= ATH_TX_XRETRY; | ||
1853 | } | ||
1854 | |||
1855 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | ||
1856 | ath_tx_complete(sc, skb, &tx_status); | ||
1857 | |||
1858 | /* | ||
1859 | * Return the list of ath_buf of this mpdu to free queue | ||
1860 | */ | ||
1861 | spin_lock_irqsave(&sc->tx.txbuflock, flags); | ||
1862 | list_splice_tail_init(bf_q, &sc->tx.txbuf); | ||
1863 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); | ||
1864 | } | ||
1865 | |||
1866 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | ||
1867 | int txok) | ||
1868 | { | ||
1869 | struct ath_buf *bf_last = bf->bf_lastbf; | ||
1870 | struct ath_desc *ds = bf_last->bf_desc; | ||
1871 | u16 seq_st = 0; | ||
1872 | u32 ba[WME_BA_BMP_SIZE >> 5]; | ||
1873 | int ba_index; | ||
1874 | int nbad = 0; | ||
1875 | int isaggr = 0; | ||
1876 | |||
1877 | if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) | ||
1878 | return 0; | ||
1879 | |||
1880 | isaggr = bf_isaggr(bf); | ||
1881 | if (isaggr) { | ||
1882 | seq_st = ATH_DS_BA_SEQ(ds); | ||
1883 | memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); | ||
1884 | } | ||
1885 | |||
1886 | while (bf) { | ||
1887 | ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno); | ||
1888 | if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index))) | ||
1889 | nbad++; | ||
1890 | |||
1891 | bf = bf->bf_next; | ||
1892 | } | ||
1893 | |||
1894 | return nbad; | ||
1895 | } | ||
1896 | |||
1897 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad) | ||
1898 | { | ||
1899 | struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; | ||
1900 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
1901 | struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); | ||
1902 | |||
1903 | tx_info_priv->update_rc = false; | ||
1904 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | ||
1905 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
1906 | |||
1907 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | ||
1908 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { | ||
1909 | if (bf_isdata(bf)) { | ||
1910 | memcpy(&tx_info_priv->tx, &ds->ds_txstat, | ||
1911 | sizeof(tx_info_priv->tx)); | ||
1912 | tx_info_priv->n_frames = bf->bf_nframes; | ||
1913 | tx_info_priv->n_bad_frames = nbad; | ||
1914 | tx_info_priv->update_rc = true; | ||
1915 | } | ||
1916 | } | ||
1917 | } | ||
1918 | |||
1919 | static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | ||
1920 | { | ||
1921 | int qnum; | ||
1922 | |||
1923 | spin_lock_bh(&txq->axq_lock); | ||
1924 | if (txq->stopped && | ||
1925 | ath_txq_depth(sc, txq->axq_qnum) <= (ATH_TXBUF - 20)) { | ||
1926 | qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); | ||
1927 | if (qnum != -1) { | ||
1928 | ieee80211_wake_queue(sc->hw, qnum); | ||
1929 | txq->stopped = 0; | ||
1930 | } | ||
1931 | } | ||
1932 | spin_unlock_bh(&txq->axq_lock); | ||
1933 | } | ||
1934 | |||
1935 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | ||
1936 | { | ||
1937 | struct ath_hal *ah = sc->sc_ah; | ||
1938 | struct ath_buf *bf, *lastbf, *bf_held = NULL; | ||
1939 | struct list_head bf_head; | ||
1940 | struct ath_desc *ds; | ||
1941 | int txok, nbad = 0; | ||
1942 | int status; | ||
1943 | |||
1944 | DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | ||
1945 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | ||
1946 | txq->axq_link); | ||
1947 | |||
1948 | for (;;) { | ||
1949 | spin_lock_bh(&txq->axq_lock); | ||
1950 | if (list_empty(&txq->axq_q)) { | ||
1951 | txq->axq_link = NULL; | ||
1952 | txq->axq_linkbuf = NULL; | ||
1953 | spin_unlock_bh(&txq->axq_lock); | ||
1954 | break; | ||
1955 | } | ||
1956 | bf = list_first_entry(&txq->axq_q, struct ath_buf, list); | ||
1957 | |||
2396 | /* | 1958 | /* |
2397 | * add dest ac to txq if not already added | 1959 | * There is a race condition that a BH gets scheduled |
1960 | * after sw writes TxE and before hw re-load the last | ||
1961 | * descriptor to get the newly chained one. | ||
1962 | * Software must keep the last DONE descriptor as a | ||
1963 | * holding descriptor - software does so by marking | ||
1964 | * it with the STALE flag. | ||
2398 | */ | 1965 | */ |
2399 | if (!ac->sched) { | 1966 | bf_held = NULL; |
2400 | ac->sched = true; | 1967 | if (bf->bf_status & ATH_BUFSTATUS_STALE) { |
2401 | list_add_tail(&ac->list, &txq->axq_acq); | 1968 | bf_held = bf; |
1969 | if (list_is_last(&bf_held->list, &txq->axq_q)) { | ||
1970 | txq->axq_link = NULL; | ||
1971 | txq->axq_linkbuf = NULL; | ||
1972 | spin_unlock_bh(&txq->axq_lock); | ||
1973 | |||
1974 | /* | ||
1975 | * The holding descriptor is the last | ||
1976 | * descriptor in queue. It's safe to remove | ||
1977 | * the last holding descriptor in BH context. | ||
1978 | */ | ||
1979 | spin_lock_bh(&sc->tx.txbuflock); | ||
1980 | list_move_tail(&bf_held->list, &sc->tx.txbuf); | ||
1981 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1982 | |||
1983 | break; | ||
1984 | } else { | ||
1985 | bf = list_entry(bf_held->list.next, | ||
1986 | struct ath_buf, list); | ||
1987 | } | ||
1988 | } | ||
1989 | |||
1990 | lastbf = bf->bf_lastbf; | ||
1991 | ds = lastbf->bf_desc; | ||
1992 | |||
1993 | status = ath9k_hw_txprocdesc(ah, ds); | ||
1994 | if (status == -EINPROGRESS) { | ||
1995 | spin_unlock_bh(&txq->axq_lock); | ||
1996 | break; | ||
2402 | } | 1997 | } |
1998 | if (bf->bf_desc == txq->axq_lastdsWithCTS) | ||
1999 | txq->axq_lastdsWithCTS = NULL; | ||
2000 | if (ds == txq->axq_gatingds) | ||
2001 | txq->axq_gatingds = NULL; | ||
2002 | |||
2003 | /* | ||
2004 | * Remove ath_buf's of the same transmit unit from txq, | ||
2005 | * however leave the last descriptor back as the holding | ||
2006 | * descriptor for hw. | ||
2007 | */ | ||
2008 | lastbf->bf_status |= ATH_BUFSTATUS_STALE; | ||
2009 | INIT_LIST_HEAD(&bf_head); | ||
2010 | if (!list_is_singular(&lastbf->list)) | ||
2011 | list_cut_position(&bf_head, | ||
2012 | &txq->axq_q, lastbf->list.prev); | ||
2013 | |||
2014 | txq->axq_depth--; | ||
2015 | if (bf_isaggr(bf)) | ||
2016 | txq->axq_aggr_depth--; | ||
2017 | |||
2018 | txok = (ds->ds_txstat.ts_status == 0); | ||
2019 | spin_unlock_bh(&txq->axq_lock); | ||
2020 | |||
2021 | if (bf_held) { | ||
2022 | spin_lock_bh(&sc->tx.txbuflock); | ||
2023 | list_move_tail(&bf_held->list, &sc->tx.txbuf); | ||
2024 | spin_unlock_bh(&sc->tx.txbuflock); | ||
2025 | } | ||
2026 | |||
2027 | if (!bf_isampdu(bf)) { | ||
2028 | /* | ||
2029 | * This frame is sent out as a single frame. | ||
2030 | * Use hardware retry status for this frame. | ||
2031 | */ | ||
2032 | bf->bf_retries = ds->ds_txstat.ts_longretry; | ||
2033 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) | ||
2034 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
2035 | nbad = 0; | ||
2036 | } else { | ||
2037 | nbad = ath_tx_num_badfrms(sc, bf, txok); | ||
2038 | } | ||
2039 | |||
2040 | ath_tx_rc_status(bf, ds, nbad); | ||
2041 | |||
2042 | if (bf_isampdu(bf)) | ||
2043 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); | ||
2044 | else | ||
2045 | ath_tx_complete_buf(sc, bf, &bf_head, txok, 0); | ||
2046 | |||
2047 | ath_wake_mac80211_queue(sc, txq); | ||
2048 | |||
2049 | spin_lock_bh(&txq->axq_lock); | ||
2050 | if (sc->sc_flags & SC_OP_TXAGGR) | ||
2051 | ath_txq_schedule(sc, txq); | ||
2052 | spin_unlock_bh(&txq->axq_lock); | ||
2053 | } | ||
2054 | } | ||
2055 | |||
2056 | |||
2057 | void ath_tx_tasklet(struct ath_softc *sc) | ||
2058 | { | ||
2059 | int i; | ||
2060 | u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); | ||
2061 | |||
2062 | ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); | ||
2063 | |||
2064 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2065 | if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) | ||
2066 | ath_tx_processq(sc, &sc->tx.txq[i]); | ||
2403 | } | 2067 | } |
2404 | } | 2068 | } |
2405 | 2069 | ||
2406 | /* Initialize per-node transmit state */ | 2070 | /*****************/ |
2071 | /* Init, Cleanup */ | ||
2072 | /*****************/ | ||
2073 | |||
2074 | int ath_tx_init(struct ath_softc *sc, int nbufs) | ||
2075 | { | ||
2076 | int error = 0; | ||
2077 | |||
2078 | do { | ||
2079 | spin_lock_init(&sc->tx.txbuflock); | ||
2080 | |||
2081 | error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, | ||
2082 | "tx", nbufs, 1); | ||
2083 | if (error != 0) { | ||
2084 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2085 | "Failed to allocate tx descriptors: %d\n", | ||
2086 | error); | ||
2087 | break; | ||
2088 | } | ||
2089 | |||
2090 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, | ||
2091 | "beacon", ATH_BCBUF, 1); | ||
2092 | if (error != 0) { | ||
2093 | DPRINTF(sc, ATH_DBG_FATAL, | ||
2094 | "Failed to allocate beacon descriptors: %d\n", | ||
2095 | error); | ||
2096 | break; | ||
2097 | } | ||
2098 | |||
2099 | } while (0); | ||
2100 | |||
2101 | if (error != 0) | ||
2102 | ath_tx_cleanup(sc); | ||
2103 | |||
2104 | return error; | ||
2105 | } | ||
2106 | |||
2107 | int ath_tx_cleanup(struct ath_softc *sc) | ||
2108 | { | ||
2109 | if (sc->beacon.bdma.dd_desc_len != 0) | ||
2110 | ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf); | ||
2111 | |||
2112 | if (sc->tx.txdma.dd_desc_len != 0) | ||
2113 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); | ||
2114 | |||
2115 | return 0; | ||
2116 | } | ||
2407 | 2117 | ||
2408 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | 2118 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) |
2409 | { | 2119 | { |
@@ -2411,9 +2121,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2411 | struct ath_atx_ac *ac; | 2121 | struct ath_atx_ac *ac; |
2412 | int tidno, acno; | 2122 | int tidno, acno; |
2413 | 2123 | ||
2414 | /* | ||
2415 | * Init per tid tx state | ||
2416 | */ | ||
2417 | for (tidno = 0, tid = &an->tid[tidno]; | 2124 | for (tidno = 0, tid = &an->tid[tidno]; |
2418 | tidno < WME_NUM_TID; | 2125 | tidno < WME_NUM_TID; |
2419 | tidno++, tid++) { | 2126 | tidno++, tid++) { |
@@ -2423,22 +2130,16 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2423 | tid->baw_size = WME_MAX_BA; | 2130 | tid->baw_size = WME_MAX_BA; |
2424 | tid->baw_head = tid->baw_tail = 0; | 2131 | tid->baw_head = tid->baw_tail = 0; |
2425 | tid->sched = false; | 2132 | tid->sched = false; |
2426 | tid->paused = false; | 2133 | tid->paused = false; |
2427 | tid->state &= ~AGGR_CLEANUP; | 2134 | tid->state &= ~AGGR_CLEANUP; |
2428 | INIT_LIST_HEAD(&tid->buf_q); | 2135 | INIT_LIST_HEAD(&tid->buf_q); |
2429 | |||
2430 | acno = TID_TO_WME_AC(tidno); | 2136 | acno = TID_TO_WME_AC(tidno); |
2431 | tid->ac = &an->ac[acno]; | 2137 | tid->ac = &an->ac[acno]; |
2432 | |||
2433 | /* ADDBA state */ | ||
2434 | tid->state &= ~AGGR_ADDBA_COMPLETE; | 2138 | tid->state &= ~AGGR_ADDBA_COMPLETE; |
2435 | tid->state &= ~AGGR_ADDBA_PROGRESS; | 2139 | tid->state &= ~AGGR_ADDBA_PROGRESS; |
2436 | tid->addba_exchangeattempts = 0; | 2140 | tid->addba_exchangeattempts = 0; |
2437 | } | 2141 | } |
2438 | 2142 | ||
2439 | /* | ||
2440 | * Init per ac tx state | ||
2441 | */ | ||
2442 | for (acno = 0, ac = &an->ac[acno]; | 2143 | for (acno = 0, ac = &an->ac[acno]; |
2443 | acno < WME_NUM_AC; acno++, ac++) { | 2144 | acno < WME_NUM_AC; acno++, ac++) { |
2444 | ac->sched = false; | 2145 | ac->sched = false; |
@@ -2465,14 +2166,13 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2465 | } | 2166 | } |
2466 | } | 2167 | } |
2467 | 2168 | ||
2468 | /* Cleanupthe pending buffers for the node. */ | ||
2469 | |||
2470 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | 2169 | void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) |
2471 | { | 2170 | { |
2472 | int i; | 2171 | int i; |
2473 | struct ath_atx_ac *ac, *ac_tmp; | 2172 | struct ath_atx_ac *ac, *ac_tmp; |
2474 | struct ath_atx_tid *tid, *tid_tmp; | 2173 | struct ath_atx_tid *tid, *tid_tmp; |
2475 | struct ath_txq *txq; | 2174 | struct ath_txq *txq; |
2175 | |||
2476 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 2176 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
2477 | if (ATH_TXQ_SETUP(sc, i)) { | 2177 | if (ATH_TXQ_SETUP(sc, i)) { |
2478 | txq = &sc->tx.txq[i]; | 2178 | txq = &sc->tx.txq[i]; |
@@ -2503,51 +2203,3 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | |||
2503 | } | 2203 | } |
2504 | } | 2204 | } |
2505 | } | 2205 | } |
2506 | |||
2507 | void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) | ||
2508 | { | ||
2509 | int hdrlen, padsize; | ||
2510 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2511 | struct ath_tx_control txctl; | ||
2512 | |||
2513 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | ||
2514 | |||
2515 | /* | ||
2516 | * As a temporary workaround, assign seq# here; this will likely need | ||
2517 | * to be cleaned up to work better with Beacon transmission and virtual | ||
2518 | * BSSes. | ||
2519 | */ | ||
2520 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
2521 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
2522 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
2523 | sc->tx.seq_no += 0x10; | ||
2524 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
2525 | hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); | ||
2526 | } | ||
2527 | |||
2528 | /* Add the padding after the header if this is not already done */ | ||
2529 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
2530 | if (hdrlen & 3) { | ||
2531 | padsize = hdrlen % 4; | ||
2532 | if (skb_headroom(skb) < padsize) { | ||
2533 | DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n"); | ||
2534 | dev_kfree_skb_any(skb); | ||
2535 | return; | ||
2536 | } | ||
2537 | skb_push(skb, padsize); | ||
2538 | memmove(skb->data, skb->data + padsize, hdrlen); | ||
2539 | } | ||
2540 | |||
2541 | txctl.txq = sc->beacon.cabq; | ||
2542 | |||
2543 | DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb); | ||
2544 | |||
2545 | if (ath_tx_start(sc, skb, &txctl) != 0) { | ||
2546 | DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n"); | ||
2547 | goto exit; | ||
2548 | } | ||
2549 | |||
2550 | return; | ||
2551 | exit: | ||
2552 | dev_kfree_skb_any(skb); | ||
2553 | } | ||
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 4223672c4432..91930a2c3c6b 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -2204,9 +2204,6 @@ static int atmel_get_frag(struct net_device *dev, | |||
2204 | return 0; | 2204 | return 0; |
2205 | } | 2205 | } |
2206 | 2206 | ||
2207 | static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
2208 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; | ||
2209 | |||
2210 | static int atmel_set_freq(struct net_device *dev, | 2207 | static int atmel_set_freq(struct net_device *dev, |
2211 | struct iw_request_info *info, | 2208 | struct iw_request_info *info, |
2212 | struct iw_freq *fwrq, | 2209 | struct iw_freq *fwrq, |
@@ -2216,16 +2213,12 @@ static int atmel_set_freq(struct net_device *dev, | |||
2216 | int rc = -EINPROGRESS; /* Call commit handler */ | 2213 | int rc = -EINPROGRESS; /* Call commit handler */ |
2217 | 2214 | ||
2218 | /* If setting by frequency, convert to a channel */ | 2215 | /* If setting by frequency, convert to a channel */ |
2219 | if ((fwrq->e == 1) && | 2216 | if (fwrq->e == 1) { |
2220 | (fwrq->m >= (int) 241200000) && | ||
2221 | (fwrq->m <= (int) 248700000)) { | ||
2222 | int f = fwrq->m / 100000; | 2217 | int f = fwrq->m / 100000; |
2223 | int c = 0; | 2218 | |
2224 | while ((c < 14) && (f != frequency_list[c])) | ||
2225 | c++; | ||
2226 | /* Hack to fall through... */ | 2219 | /* Hack to fall through... */ |
2227 | fwrq->e = 0; | 2220 | fwrq->e = 0; |
2228 | fwrq->m = c + 1; | 2221 | fwrq->m = ieee80211_freq_to_dsss_chan(f); |
2229 | } | 2222 | } |
2230 | /* Setting by channel number */ | 2223 | /* Setting by channel number */ |
2231 | if ((fwrq->m > 1000) || (fwrq->e > 0)) | 2224 | if ((fwrq->m > 1000) || (fwrq->e > 0)) |
@@ -2384,8 +2377,11 @@ static int atmel_get_range(struct net_device *dev, | |||
2384 | if (range->num_channels != 0) { | 2377 | if (range->num_channels != 0) { |
2385 | for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) { | 2378 | for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) { |
2386 | range->freq[k].i = i; /* List index */ | 2379 | range->freq[k].i = i; /* List index */ |
2387 | range->freq[k].m = frequency_list[i - 1] * 100000; | 2380 | |
2388 | range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */ | 2381 | /* Values in MHz -> * 10^5 * 10 */ |
2382 | range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) * | ||
2383 | 100000); | ||
2384 | range->freq[k++].e = 1; | ||
2389 | } | 2385 | } |
2390 | range->num_frequency = k; | 2386 | range->num_frequency = k; |
2391 | } | 2387 | } |
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 1f81d36f87c5..aab71a70ba78 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -110,10 +110,18 @@ config B43_DEBUG | |||
110 | bool "Broadcom 43xx debugging" | 110 | bool "Broadcom 43xx debugging" |
111 | depends on B43 | 111 | depends on B43 |
112 | ---help--- | 112 | ---help--- |
113 | Broadcom 43xx debugging messages. | 113 | Broadcom 43xx debugging. |
114 | 114 | ||
115 | Say Y, if you want to find out why the driver does not | 115 | This adds additional runtime sanity checks and statistics to the driver. |
116 | work for you. | 116 | These checks and statistics might me expensive and hurt runtime performance |
117 | of your system. | ||
118 | This also adds the b43 debugfs interface. | ||
119 | |||
120 | Do not enable this, unless you are debugging the driver. | ||
121 | |||
122 | Say N, if you are a distributor or user building a release kernel | ||
123 | for production use. | ||
124 | Only say Y, if you are debugging a problem in the b43 driver sourcecode. | ||
117 | 125 | ||
118 | config B43_FORCE_PIO | 126 | config B43_FORCE_PIO |
119 | bool "Force usage of PIO instead of DMA" | 127 | bool "Force usage of PIO instead of DMA" |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index a53c378e7484..e9d60f0910be 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -655,10 +655,39 @@ struct b43_wl { | |||
655 | struct work_struct txpower_adjust_work; | 655 | struct work_struct txpower_adjust_work; |
656 | }; | 656 | }; |
657 | 657 | ||
658 | /* The type of the firmware file. */ | ||
659 | enum b43_firmware_file_type { | ||
660 | B43_FWTYPE_PROPRIETARY, | ||
661 | B43_FWTYPE_OPENSOURCE, | ||
662 | B43_NR_FWTYPES, | ||
663 | }; | ||
664 | |||
665 | /* Context data for fetching firmware. */ | ||
666 | struct b43_request_fw_context { | ||
667 | /* The device we are requesting the fw for. */ | ||
668 | struct b43_wldev *dev; | ||
669 | /* The type of firmware to request. */ | ||
670 | enum b43_firmware_file_type req_type; | ||
671 | /* Error messages for each firmware type. */ | ||
672 | char errors[B43_NR_FWTYPES][128]; | ||
673 | /* Temporary buffer for storing the firmware name. */ | ||
674 | char fwname[64]; | ||
675 | /* A fatal error occured while requesting. Firmware reqest | ||
676 | * can not continue, as any other reqest will also fail. */ | ||
677 | int fatal_failure; | ||
678 | }; | ||
679 | |||
658 | /* In-memory representation of a cached microcode file. */ | 680 | /* In-memory representation of a cached microcode file. */ |
659 | struct b43_firmware_file { | 681 | struct b43_firmware_file { |
660 | const char *filename; | 682 | const char *filename; |
661 | const struct firmware *data; | 683 | const struct firmware *data; |
684 | /* Type of the firmware file name. Note that this does only indicate | ||
685 | * the type by the firmware name. NOT the file contents. | ||
686 | * If you want to check for proprietary vs opensource, use (struct b43_firmware)->opensource | ||
687 | * instead! The (struct b43_firmware)->opensource flag is derived from the actual firmware | ||
688 | * binary code, not just the filename. | ||
689 | */ | ||
690 | enum b43_firmware_file_type type; | ||
662 | }; | 691 | }; |
663 | 692 | ||
664 | /* Pointers to the firmware data and meta information about it. */ | 693 | /* Pointers to the firmware data and meta information about it. */ |
@@ -677,7 +706,8 @@ struct b43_firmware { | |||
677 | /* Firmware patchlevel */ | 706 | /* Firmware patchlevel */ |
678 | u16 patch; | 707 | u16 patch; |
679 | 708 | ||
680 | /* Set to true, if we are using an opensource firmware. */ | 709 | /* Set to true, if we are using an opensource firmware. |
710 | * Use this to check for proprietary vs opensource. */ | ||
681 | bool opensource; | 711 | bool opensource; |
682 | /* Set to true, if the core needs a PCM firmware, but | 712 | /* Set to true, if the core needs a PCM firmware, but |
683 | * we failed to load one. This is always false for | 713 | * we failed to load one. This is always false for |
@@ -848,12 +878,9 @@ void b43err(struct b43_wl *wl, const char *fmt, ...) | |||
848 | __attribute__ ((format(printf, 2, 3))); | 878 | __attribute__ ((format(printf, 2, 3))); |
849 | void b43warn(struct b43_wl *wl, const char *fmt, ...) | 879 | void b43warn(struct b43_wl *wl, const char *fmt, ...) |
850 | __attribute__ ((format(printf, 2, 3))); | 880 | __attribute__ ((format(printf, 2, 3))); |
851 | #if B43_DEBUG | ||
852 | void b43dbg(struct b43_wl *wl, const char *fmt, ...) | 881 | void b43dbg(struct b43_wl *wl, const char *fmt, ...) |
853 | __attribute__ ((format(printf, 2, 3))); | 882 | __attribute__ ((format(printf, 2, 3))); |
854 | #else /* DEBUG */ | 883 | |
855 | # define b43dbg(wl, fmt...) do { /* nothing */ } while (0) | ||
856 | #endif /* DEBUG */ | ||
857 | 884 | ||
858 | /* A WARN_ON variant that vanishes when b43 debugging is disabled. | 885 | /* A WARN_ON variant that vanishes when b43 debugging is disabled. |
859 | * This _also_ evaluates the arg with debugging disabled. */ | 886 | * This _also_ evaluates the arg with debugging disabled. */ |
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index e04fc91f569e..bc2767da46e8 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c | |||
@@ -367,34 +367,6 @@ static int mmio32write__write_file(struct b43_wldev *dev, | |||
367 | return 0; | 367 | return 0; |
368 | } | 368 | } |
369 | 369 | ||
370 | /* wl->irq_lock is locked */ | ||
371 | static ssize_t tsf_read_file(struct b43_wldev *dev, | ||
372 | char *buf, size_t bufsize) | ||
373 | { | ||
374 | ssize_t count = 0; | ||
375 | u64 tsf; | ||
376 | |||
377 | b43_tsf_read(dev, &tsf); | ||
378 | fappend("0x%08x%08x\n", | ||
379 | (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32), | ||
380 | (unsigned int)(tsf & 0xFFFFFFFFULL)); | ||
381 | |||
382 | return count; | ||
383 | } | ||
384 | |||
385 | /* wl->irq_lock is locked */ | ||
386 | static int tsf_write_file(struct b43_wldev *dev, | ||
387 | const char *buf, size_t count) | ||
388 | { | ||
389 | u64 tsf; | ||
390 | |||
391 | if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1) | ||
392 | return -EINVAL; | ||
393 | b43_tsf_write(dev, tsf); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static ssize_t txstat_read_file(struct b43_wldev *dev, | 370 | static ssize_t txstat_read_file(struct b43_wldev *dev, |
399 | char *buf, size_t bufsize) | 371 | char *buf, size_t bufsize) |
400 | { | 372 | { |
@@ -691,15 +663,23 @@ B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1); | |||
691 | B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); | 663 | B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); |
692 | B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); | 664 | B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); |
693 | B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1); | 665 | B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1); |
694 | B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1); | ||
695 | B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); | 666 | B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); |
696 | B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); | 667 | B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); |
697 | B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0); | 668 | B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0); |
698 | 669 | ||
699 | 670 | ||
700 | int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature) | 671 | bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature) |
701 | { | 672 | { |
702 | return !!(dev->dfsentry && dev->dfsentry->dyn_debug[feature]); | 673 | bool enabled; |
674 | |||
675 | enabled = (dev->dfsentry && dev->dfsentry->dyn_debug[feature]); | ||
676 | if (unlikely(enabled)) { | ||
677 | /* Force full debugging messages, if the user enabled | ||
678 | * some dynamic debugging feature. */ | ||
679 | b43_modparam_verbose = B43_VERBOSITY_MAX; | ||
680 | } | ||
681 | |||
682 | return enabled; | ||
703 | } | 683 | } |
704 | 684 | ||
705 | static void b43_remove_dynamic_debug(struct b43_wldev *dev) | 685 | static void b43_remove_dynamic_debug(struct b43_wldev *dev) |
@@ -805,7 +785,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev) | |||
805 | ADD_FILE(mmio16write, 0200); | 785 | ADD_FILE(mmio16write, 0200); |
806 | ADD_FILE(mmio32read, 0600); | 786 | ADD_FILE(mmio32read, 0600); |
807 | ADD_FILE(mmio32write, 0200); | 787 | ADD_FILE(mmio32write, 0200); |
808 | ADD_FILE(tsf, 0600); | ||
809 | ADD_FILE(txstat, 0400); | 788 | ADD_FILE(txstat, 0400); |
810 | ADD_FILE(restart, 0200); | 789 | ADD_FILE(restart, 0200); |
811 | ADD_FILE(loctls, 0400); | 790 | ADD_FILE(loctls, 0400); |
@@ -834,7 +813,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev) | |||
834 | debugfs_remove(e->file_mmio16write.dentry); | 813 | debugfs_remove(e->file_mmio16write.dentry); |
835 | debugfs_remove(e->file_mmio32read.dentry); | 814 | debugfs_remove(e->file_mmio32read.dentry); |
836 | debugfs_remove(e->file_mmio32write.dentry); | 815 | debugfs_remove(e->file_mmio32write.dentry); |
837 | debugfs_remove(e->file_tsf.dentry); | ||
838 | debugfs_remove(e->file_txstat.dentry); | 816 | debugfs_remove(e->file_txstat.dentry); |
839 | debugfs_remove(e->file_restart.dentry); | 817 | debugfs_remove(e->file_restart.dentry); |
840 | debugfs_remove(e->file_loctls.dentry); | 818 | debugfs_remove(e->file_loctls.dentry); |
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h index 7886cbe2d1d1..b9d4de4a979c 100644 --- a/drivers/net/wireless/b43/debugfs.h +++ b/drivers/net/wireless/b43/debugfs.h | |||
@@ -46,7 +46,6 @@ struct b43_dfsentry { | |||
46 | struct b43_dfs_file file_mmio16write; | 46 | struct b43_dfs_file file_mmio16write; |
47 | struct b43_dfs_file file_mmio32read; | 47 | struct b43_dfs_file file_mmio32read; |
48 | struct b43_dfs_file file_mmio32write; | 48 | struct b43_dfs_file file_mmio32write; |
49 | struct b43_dfs_file file_tsf; | ||
50 | struct b43_dfs_file file_txstat; | 49 | struct b43_dfs_file file_txstat; |
51 | struct b43_dfs_file file_txpower_g; | 50 | struct b43_dfs_file file_txpower_g; |
52 | struct b43_dfs_file file_restart; | 51 | struct b43_dfs_file file_restart; |
@@ -72,7 +71,7 @@ struct b43_dfsentry { | |||
72 | struct dentry *dyn_debug_dentries[__B43_NR_DYNDBG]; | 71 | struct dentry *dyn_debug_dentries[__B43_NR_DYNDBG]; |
73 | }; | 72 | }; |
74 | 73 | ||
75 | int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature); | 74 | bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature); |
76 | 75 | ||
77 | void b43_debugfs_init(void); | 76 | void b43_debugfs_init(void); |
78 | void b43_debugfs_exit(void); | 77 | void b43_debugfs_exit(void); |
@@ -83,7 +82,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev, | |||
83 | 82 | ||
84 | #else /* CONFIG_B43_DEBUG */ | 83 | #else /* CONFIG_B43_DEBUG */ |
85 | 84 | ||
86 | static inline int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature) | 85 | static inline bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature) |
87 | { | 86 | { |
88 | return 0; | 87 | return 0; |
89 | } | 88 | } |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c788bad10661..dbb8765506e8 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | Copyright (c) 2005 Martin Langer <martin-langer@gmx.de> | 5 | Copyright (c) 2005 Martin Langer <martin-langer@gmx.de> |
6 | Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it> | 6 | Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it> |
7 | Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de> | 7 | Copyright (c) 2005-2009 Michael Buesch <mb@bu3sch.de> |
8 | Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> | 8 | Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org> |
9 | Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> | 9 | Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> |
10 | 10 | ||
@@ -88,6 +88,10 @@ static int modparam_btcoex = 1; | |||
88 | module_param_named(btcoex, modparam_btcoex, int, 0444); | 88 | module_param_named(btcoex, modparam_btcoex, int, 0444); |
89 | MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)"); | 89 | MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)"); |
90 | 90 | ||
91 | int b43_modparam_verbose = B43_VERBOSITY_DEFAULT; | ||
92 | module_param_named(verbose, b43_modparam_verbose, int, 0644); | ||
93 | MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug"); | ||
94 | |||
91 | 95 | ||
92 | static const struct ssb_device_id b43_ssb_tbl[] = { | 96 | static const struct ssb_device_id b43_ssb_tbl[] = { |
93 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), | 97 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), |
@@ -97,6 +101,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = { | |||
97 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), | 101 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), |
98 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11), | 102 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11), |
99 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), | 103 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), |
104 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15), | ||
105 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), | ||
100 | SSB_DEVTABLE_END | 106 | SSB_DEVTABLE_END |
101 | }; | 107 | }; |
102 | 108 | ||
@@ -298,6 +304,8 @@ void b43info(struct b43_wl *wl, const char *fmt, ...) | |||
298 | { | 304 | { |
299 | va_list args; | 305 | va_list args; |
300 | 306 | ||
307 | if (b43_modparam_verbose < B43_VERBOSITY_INFO) | ||
308 | return; | ||
301 | if (!b43_ratelimit(wl)) | 309 | if (!b43_ratelimit(wl)) |
302 | return; | 310 | return; |
303 | va_start(args, fmt); | 311 | va_start(args, fmt); |
@@ -311,6 +319,8 @@ void b43err(struct b43_wl *wl, const char *fmt, ...) | |||
311 | { | 319 | { |
312 | va_list args; | 320 | va_list args; |
313 | 321 | ||
322 | if (b43_modparam_verbose < B43_VERBOSITY_ERROR) | ||
323 | return; | ||
314 | if (!b43_ratelimit(wl)) | 324 | if (!b43_ratelimit(wl)) |
315 | return; | 325 | return; |
316 | va_start(args, fmt); | 326 | va_start(args, fmt); |
@@ -324,6 +334,8 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...) | |||
324 | { | 334 | { |
325 | va_list args; | 335 | va_list args; |
326 | 336 | ||
337 | if (b43_modparam_verbose < B43_VERBOSITY_WARN) | ||
338 | return; | ||
327 | if (!b43_ratelimit(wl)) | 339 | if (!b43_ratelimit(wl)) |
328 | return; | 340 | return; |
329 | va_start(args, fmt); | 341 | va_start(args, fmt); |
@@ -333,18 +345,18 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...) | |||
333 | va_end(args); | 345 | va_end(args); |
334 | } | 346 | } |
335 | 347 | ||
336 | #if B43_DEBUG | ||
337 | void b43dbg(struct b43_wl *wl, const char *fmt, ...) | 348 | void b43dbg(struct b43_wl *wl, const char *fmt, ...) |
338 | { | 349 | { |
339 | va_list args; | 350 | va_list args; |
340 | 351 | ||
352 | if (b43_modparam_verbose < B43_VERBOSITY_DEBUG) | ||
353 | return; | ||
341 | va_start(args, fmt); | 354 | va_start(args, fmt); |
342 | printk(KERN_DEBUG "b43-%s debug: ", | 355 | printk(KERN_DEBUG "b43-%s debug: ", |
343 | (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); | 356 | (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan"); |
344 | vprintk(fmt, args); | 357 | vprintk(fmt, args); |
345 | va_end(args); | 358 | va_end(args); |
346 | } | 359 | } |
347 | #endif /* DEBUG */ | ||
348 | 360 | ||
349 | static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val) | 361 | static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val) |
350 | { | 362 | { |
@@ -526,52 +538,20 @@ void b43_hf_write(struct b43_wldev *dev, u64 value) | |||
526 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); | 538 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); |
527 | } | 539 | } |
528 | 540 | ||
529 | void b43_tsf_read(struct b43_wldev *dev, u64 * tsf) | 541 | void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) |
530 | { | 542 | { |
531 | /* We need to be careful. As we read the TSF from multiple | 543 | u32 low, high; |
532 | * registers, we should take care of register overflows. | ||
533 | * In theory, the whole tsf read process should be atomic. | ||
534 | * We try to be atomic here, by restaring the read process, | ||
535 | * if any of the high registers changed (overflew). | ||
536 | */ | ||
537 | if (dev->dev->id.revision >= 3) { | ||
538 | u32 low, high, high2; | ||
539 | 544 | ||
540 | do { | 545 | B43_WARN_ON(dev->dev->id.revision < 3); |
541 | high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH); | ||
542 | low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW); | ||
543 | high2 = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH); | ||
544 | } while (unlikely(high != high2)); | ||
545 | 546 | ||
546 | *tsf = high; | 547 | /* The hardware guarantees us an atomic read, if we |
547 | *tsf <<= 32; | 548 | * read the low register first. */ |
548 | *tsf |= low; | 549 | low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW); |
549 | } else { | 550 | high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH); |
550 | u64 tmp; | ||
551 | u16 v0, v1, v2, v3; | ||
552 | u16 test1, test2, test3; | ||
553 | |||
554 | do { | ||
555 | v3 = b43_read16(dev, B43_MMIO_TSF_3); | ||
556 | v2 = b43_read16(dev, B43_MMIO_TSF_2); | ||
557 | v1 = b43_read16(dev, B43_MMIO_TSF_1); | ||
558 | v0 = b43_read16(dev, B43_MMIO_TSF_0); | ||
559 | 551 | ||
560 | test3 = b43_read16(dev, B43_MMIO_TSF_3); | 552 | *tsf = high; |
561 | test2 = b43_read16(dev, B43_MMIO_TSF_2); | 553 | *tsf <<= 32; |
562 | test1 = b43_read16(dev, B43_MMIO_TSF_1); | 554 | *tsf |= low; |
563 | } while (v3 != test3 || v2 != test2 || v1 != test1); | ||
564 | |||
565 | *tsf = v3; | ||
566 | *tsf <<= 48; | ||
567 | tmp = v2; | ||
568 | tmp <<= 32; | ||
569 | *tsf |= tmp; | ||
570 | tmp = v1; | ||
571 | tmp <<= 16; | ||
572 | *tsf |= tmp; | ||
573 | *tsf |= v0; | ||
574 | } | ||
575 | } | 555 | } |
576 | 556 | ||
577 | static void b43_time_lock(struct b43_wldev *dev) | 557 | static void b43_time_lock(struct b43_wldev *dev) |
@@ -598,35 +578,18 @@ static void b43_time_unlock(struct b43_wldev *dev) | |||
598 | 578 | ||
599 | static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) | 579 | static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) |
600 | { | 580 | { |
601 | /* Be careful with the in-progress timer. | 581 | u32 low, high; |
602 | * First zero out the low register, so we have a full | ||
603 | * register-overflow duration to complete the operation. | ||
604 | */ | ||
605 | if (dev->dev->id.revision >= 3) { | ||
606 | u32 lo = (tsf & 0x00000000FFFFFFFFULL); | ||
607 | u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32; | ||
608 | 582 | ||
609 | b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, 0); | 583 | B43_WARN_ON(dev->dev->id.revision < 3); |
610 | mmiowb(); | ||
611 | b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, hi); | ||
612 | mmiowb(); | ||
613 | b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, lo); | ||
614 | } else { | ||
615 | u16 v0 = (tsf & 0x000000000000FFFFULL); | ||
616 | u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16; | ||
617 | u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32; | ||
618 | u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48; | ||
619 | 584 | ||
620 | b43_write16(dev, B43_MMIO_TSF_0, 0); | 585 | low = tsf; |
621 | mmiowb(); | 586 | high = (tsf >> 32); |
622 | b43_write16(dev, B43_MMIO_TSF_3, v3); | 587 | /* The hardware guarantees us an atomic write, if we |
623 | mmiowb(); | 588 | * write the low register first. */ |
624 | b43_write16(dev, B43_MMIO_TSF_2, v2); | 589 | b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, low); |
625 | mmiowb(); | 590 | mmiowb(); |
626 | b43_write16(dev, B43_MMIO_TSF_1, v1); | 591 | b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, high); |
627 | mmiowb(); | 592 | mmiowb(); |
628 | b43_write16(dev, B43_MMIO_TSF_0, v0); | ||
629 | } | ||
630 | } | 593 | } |
631 | 594 | ||
632 | void b43_tsf_write(struct b43_wldev *dev, u64 tsf) | 595 | void b43_tsf_write(struct b43_wldev *dev, u64 tsf) |
@@ -937,8 +900,7 @@ static int b43_key_write(struct b43_wldev *dev, | |||
937 | B43_WARN_ON(dev->key[i].keyconf == keyconf); | 900 | B43_WARN_ON(dev->key[i].keyconf == keyconf); |
938 | } | 901 | } |
939 | if (index < 0) { | 902 | if (index < 0) { |
940 | /* Either pairwise key or address is 00:00:00:00:00:00 | 903 | /* Pairwise key. Get an empty slot for the key. */ |
941 | * for transmit-only keys. Search the index. */ | ||
942 | if (b43_new_kidx_api(dev)) | 904 | if (b43_new_kidx_api(dev)) |
943 | sta_keys_start = 4; | 905 | sta_keys_start = 4; |
944 | else | 906 | else |
@@ -951,7 +913,7 @@ static int b43_key_write(struct b43_wldev *dev, | |||
951 | } | 913 | } |
952 | } | 914 | } |
953 | if (index < 0) { | 915 | if (index < 0) { |
954 | b43err(dev->wl, "Out of hardware key memory\n"); | 916 | b43warn(dev->wl, "Out of hardware key memory\n"); |
955 | return -ENOSPC; | 917 | return -ENOSPC; |
956 | } | 918 | } |
957 | } else | 919 | } else |
@@ -1982,7 +1944,7 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id) | |||
1982 | return ret; | 1944 | return ret; |
1983 | } | 1945 | } |
1984 | 1946 | ||
1985 | static void do_release_fw(struct b43_firmware_file *fw) | 1947 | void b43_do_release_fw(struct b43_firmware_file *fw) |
1986 | { | 1948 | { |
1987 | release_firmware(fw->data); | 1949 | release_firmware(fw->data); |
1988 | fw->data = NULL; | 1950 | fw->data = NULL; |
@@ -1991,10 +1953,10 @@ static void do_release_fw(struct b43_firmware_file *fw) | |||
1991 | 1953 | ||
1992 | static void b43_release_firmware(struct b43_wldev *dev) | 1954 | static void b43_release_firmware(struct b43_wldev *dev) |
1993 | { | 1955 | { |
1994 | do_release_fw(&dev->fw.ucode); | 1956 | b43_do_release_fw(&dev->fw.ucode); |
1995 | do_release_fw(&dev->fw.pcm); | 1957 | b43_do_release_fw(&dev->fw.pcm); |
1996 | do_release_fw(&dev->fw.initvals); | 1958 | b43_do_release_fw(&dev->fw.initvals); |
1997 | do_release_fw(&dev->fw.initvals_band); | 1959 | b43_do_release_fw(&dev->fw.initvals_band); |
1998 | } | 1960 | } |
1999 | 1961 | ||
2000 | static void b43_print_fw_helptext(struct b43_wl *wl, bool error) | 1962 | static void b43_print_fw_helptext(struct b43_wl *wl, bool error) |
@@ -2002,20 +1964,19 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error) | |||
2002 | const char *text; | 1964 | const char *text; |
2003 | 1965 | ||
2004 | text = "You must go to " | 1966 | text = "You must go to " |
2005 | "http://linuxwireless.org/en/users/Drivers/b43#devicefirmware " | 1967 | "http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " |
2006 | "and download the latest firmware (version 4).\n"; | 1968 | "and download the correct firmware for this driver version. " |
1969 | "Please carefully read all instructions on this website.\n"; | ||
2007 | if (error) | 1970 | if (error) |
2008 | b43err(wl, text); | 1971 | b43err(wl, text); |
2009 | else | 1972 | else |
2010 | b43warn(wl, text); | 1973 | b43warn(wl, text); |
2011 | } | 1974 | } |
2012 | 1975 | ||
2013 | static int do_request_fw(struct b43_wldev *dev, | 1976 | int b43_do_request_fw(struct b43_request_fw_context *ctx, |
2014 | const char *name, | 1977 | const char *name, |
2015 | struct b43_firmware_file *fw, | 1978 | struct b43_firmware_file *fw) |
2016 | bool silent) | ||
2017 | { | 1979 | { |
2018 | char path[sizeof(modparam_fwpostfix) + 32]; | ||
2019 | const struct firmware *blob; | 1980 | const struct firmware *blob; |
2020 | struct b43_fw_header *hdr; | 1981 | struct b43_fw_header *hdr; |
2021 | u32 size; | 1982 | u32 size; |
@@ -2023,29 +1984,49 @@ static int do_request_fw(struct b43_wldev *dev, | |||
2023 | 1984 | ||
2024 | if (!name) { | 1985 | if (!name) { |
2025 | /* Don't fetch anything. Free possibly cached firmware. */ | 1986 | /* Don't fetch anything. Free possibly cached firmware. */ |
2026 | do_release_fw(fw); | 1987 | /* FIXME: We should probably keep it anyway, to save some headache |
1988 | * on suspend/resume with multiband devices. */ | ||
1989 | b43_do_release_fw(fw); | ||
2027 | return 0; | 1990 | return 0; |
2028 | } | 1991 | } |
2029 | if (fw->filename) { | 1992 | if (fw->filename) { |
2030 | if (strcmp(fw->filename, name) == 0) | 1993 | if ((fw->type == ctx->req_type) && |
1994 | (strcmp(fw->filename, name) == 0)) | ||
2031 | return 0; /* Already have this fw. */ | 1995 | return 0; /* Already have this fw. */ |
2032 | /* Free the cached firmware first. */ | 1996 | /* Free the cached firmware first. */ |
2033 | do_release_fw(fw); | 1997 | /* FIXME: We should probably do this later after we successfully |
1998 | * got the new fw. This could reduce headache with multiband devices. | ||
1999 | * We could also redesign this to cache the firmware for all possible | ||
2000 | * bands all the time. */ | ||
2001 | b43_do_release_fw(fw); | ||
2002 | } | ||
2003 | |||
2004 | switch (ctx->req_type) { | ||
2005 | case B43_FWTYPE_PROPRIETARY: | ||
2006 | snprintf(ctx->fwname, sizeof(ctx->fwname), | ||
2007 | "b43%s/%s.fw", | ||
2008 | modparam_fwpostfix, name); | ||
2009 | break; | ||
2010 | case B43_FWTYPE_OPENSOURCE: | ||
2011 | snprintf(ctx->fwname, sizeof(ctx->fwname), | ||
2012 | "b43-open%s/%s.fw", | ||
2013 | modparam_fwpostfix, name); | ||
2014 | break; | ||
2015 | default: | ||
2016 | B43_WARN_ON(1); | ||
2017 | return -ENOSYS; | ||
2034 | } | 2018 | } |
2035 | 2019 | err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); | |
2036 | snprintf(path, ARRAY_SIZE(path), | ||
2037 | "b43%s/%s.fw", | ||
2038 | modparam_fwpostfix, name); | ||
2039 | err = request_firmware(&blob, path, dev->dev->dev); | ||
2040 | if (err == -ENOENT) { | 2020 | if (err == -ENOENT) { |
2041 | if (!silent) { | 2021 | snprintf(ctx->errors[ctx->req_type], |
2042 | b43err(dev->wl, "Firmware file \"%s\" not found\n", | 2022 | sizeof(ctx->errors[ctx->req_type]), |
2043 | path); | 2023 | "Firmware file \"%s\" not found\n", ctx->fwname); |
2044 | } | ||
2045 | return err; | 2024 | return err; |
2046 | } else if (err) { | 2025 | } else if (err) { |
2047 | b43err(dev->wl, "Firmware file \"%s\" request failed (err=%d)\n", | 2026 | snprintf(ctx->errors[ctx->req_type], |
2048 | path, err); | 2027 | sizeof(ctx->errors[ctx->req_type]), |
2028 | "Firmware file \"%s\" request failed (err=%d)\n", | ||
2029 | ctx->fwname, err); | ||
2049 | return err; | 2030 | return err; |
2050 | } | 2031 | } |
2051 | if (blob->size < sizeof(struct b43_fw_header)) | 2032 | if (blob->size < sizeof(struct b43_fw_header)) |
@@ -2068,20 +2049,24 @@ static int do_request_fw(struct b43_wldev *dev, | |||
2068 | 2049 | ||
2069 | fw->data = blob; | 2050 | fw->data = blob; |
2070 | fw->filename = name; | 2051 | fw->filename = name; |
2052 | fw->type = ctx->req_type; | ||
2071 | 2053 | ||
2072 | return 0; | 2054 | return 0; |
2073 | 2055 | ||
2074 | err_format: | 2056 | err_format: |
2075 | b43err(dev->wl, "Firmware file \"%s\" format error.\n", path); | 2057 | snprintf(ctx->errors[ctx->req_type], |
2058 | sizeof(ctx->errors[ctx->req_type]), | ||
2059 | "Firmware file \"%s\" format error.\n", ctx->fwname); | ||
2076 | release_firmware(blob); | 2060 | release_firmware(blob); |
2077 | 2061 | ||
2078 | return -EPROTO; | 2062 | return -EPROTO; |
2079 | } | 2063 | } |
2080 | 2064 | ||
2081 | static int b43_request_firmware(struct b43_wldev *dev) | 2065 | static int b43_try_request_fw(struct b43_request_fw_context *ctx) |
2082 | { | 2066 | { |
2083 | struct b43_firmware *fw = &dev->fw; | 2067 | struct b43_wldev *dev = ctx->dev; |
2084 | const u8 rev = dev->dev->id.revision; | 2068 | struct b43_firmware *fw = &ctx->dev->fw; |
2069 | const u8 rev = ctx->dev->dev->id.revision; | ||
2085 | const char *filename; | 2070 | const char *filename; |
2086 | u32 tmshigh; | 2071 | u32 tmshigh; |
2087 | int err; | 2072 | int err; |
@@ -2096,7 +2081,7 @@ static int b43_request_firmware(struct b43_wldev *dev) | |||
2096 | filename = "ucode13"; | 2081 | filename = "ucode13"; |
2097 | else | 2082 | else |
2098 | goto err_no_ucode; | 2083 | goto err_no_ucode; |
2099 | err = do_request_fw(dev, filename, &fw->ucode, 0); | 2084 | err = b43_do_request_fw(ctx, filename, &fw->ucode); |
2100 | if (err) | 2085 | if (err) |
2101 | goto err_load; | 2086 | goto err_load; |
2102 | 2087 | ||
@@ -2108,7 +2093,7 @@ static int b43_request_firmware(struct b43_wldev *dev) | |||
2108 | else | 2093 | else |
2109 | goto err_no_pcm; | 2094 | goto err_no_pcm; |
2110 | fw->pcm_request_failed = 0; | 2095 | fw->pcm_request_failed = 0; |
2111 | err = do_request_fw(dev, filename, &fw->pcm, 1); | 2096 | err = b43_do_request_fw(ctx, filename, &fw->pcm); |
2112 | if (err == -ENOENT) { | 2097 | if (err == -ENOENT) { |
2113 | /* We did not find a PCM file? Not fatal, but | 2098 | /* We did not find a PCM file? Not fatal, but |
2114 | * core rev <= 10 must do without hwcrypto then. */ | 2099 | * core rev <= 10 must do without hwcrypto then. */ |
@@ -2144,7 +2129,7 @@ static int b43_request_firmware(struct b43_wldev *dev) | |||
2144 | default: | 2129 | default: |
2145 | goto err_no_initvals; | 2130 | goto err_no_initvals; |
2146 | } | 2131 | } |
2147 | err = do_request_fw(dev, filename, &fw->initvals, 0); | 2132 | err = b43_do_request_fw(ctx, filename, &fw->initvals); |
2148 | if (err) | 2133 | if (err) |
2149 | goto err_load; | 2134 | goto err_load; |
2150 | 2135 | ||
@@ -2178,30 +2163,34 @@ static int b43_request_firmware(struct b43_wldev *dev) | |||
2178 | default: | 2163 | default: |
2179 | goto err_no_initvals; | 2164 | goto err_no_initvals; |
2180 | } | 2165 | } |
2181 | err = do_request_fw(dev, filename, &fw->initvals_band, 0); | 2166 | err = b43_do_request_fw(ctx, filename, &fw->initvals_band); |
2182 | if (err) | 2167 | if (err) |
2183 | goto err_load; | 2168 | goto err_load; |
2184 | 2169 | ||
2185 | return 0; | 2170 | return 0; |
2186 | 2171 | ||
2187 | err_load: | ||
2188 | b43_print_fw_helptext(dev->wl, 1); | ||
2189 | goto error; | ||
2190 | |||
2191 | err_no_ucode: | 2172 | err_no_ucode: |
2192 | err = -ENODEV; | 2173 | err = ctx->fatal_failure = -EOPNOTSUPP; |
2193 | b43err(dev->wl, "No microcode available for core rev %u\n", rev); | 2174 | b43err(dev->wl, "The driver does not know which firmware (ucode) " |
2175 | "is required for your device (wl-core rev %u)\n", rev); | ||
2194 | goto error; | 2176 | goto error; |
2195 | 2177 | ||
2196 | err_no_pcm: | 2178 | err_no_pcm: |
2197 | err = -ENODEV; | 2179 | err = ctx->fatal_failure = -EOPNOTSUPP; |
2198 | b43err(dev->wl, "No PCM available for core rev %u\n", rev); | 2180 | b43err(dev->wl, "The driver does not know which firmware (PCM) " |
2181 | "is required for your device (wl-core rev %u)\n", rev); | ||
2199 | goto error; | 2182 | goto error; |
2200 | 2183 | ||
2201 | err_no_initvals: | 2184 | err_no_initvals: |
2202 | err = -ENODEV; | 2185 | err = ctx->fatal_failure = -EOPNOTSUPP; |
2203 | b43err(dev->wl, "No Initial Values firmware file for PHY %u, " | 2186 | b43err(dev->wl, "The driver does not know which firmware (initvals) " |
2204 | "core rev %u\n", dev->phy.type, rev); | 2187 | "is required for your device (wl-core rev %u)\n", rev); |
2188 | goto error; | ||
2189 | |||
2190 | err_load: | ||
2191 | /* We failed to load this firmware image. The error message | ||
2192 | * already is in ctx->errors. Return and let our caller decide | ||
2193 | * what to do. */ | ||
2205 | goto error; | 2194 | goto error; |
2206 | 2195 | ||
2207 | error: | 2196 | error: |
@@ -2209,6 +2198,48 @@ error: | |||
2209 | return err; | 2198 | return err; |
2210 | } | 2199 | } |
2211 | 2200 | ||
2201 | static int b43_request_firmware(struct b43_wldev *dev) | ||
2202 | { | ||
2203 | struct b43_request_fw_context *ctx; | ||
2204 | unsigned int i; | ||
2205 | int err; | ||
2206 | const char *errmsg; | ||
2207 | |||
2208 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
2209 | if (!ctx) | ||
2210 | return -ENOMEM; | ||
2211 | ctx->dev = dev; | ||
2212 | |||
2213 | ctx->req_type = B43_FWTYPE_PROPRIETARY; | ||
2214 | err = b43_try_request_fw(ctx); | ||
2215 | if (!err) | ||
2216 | goto out; /* Successfully loaded it. */ | ||
2217 | err = ctx->fatal_failure; | ||
2218 | if (err) | ||
2219 | goto out; | ||
2220 | |||
2221 | ctx->req_type = B43_FWTYPE_OPENSOURCE; | ||
2222 | err = b43_try_request_fw(ctx); | ||
2223 | if (!err) | ||
2224 | goto out; /* Successfully loaded it. */ | ||
2225 | err = ctx->fatal_failure; | ||
2226 | if (err) | ||
2227 | goto out; | ||
2228 | |||
2229 | /* Could not find a usable firmware. Print the errors. */ | ||
2230 | for (i = 0; i < B43_NR_FWTYPES; i++) { | ||
2231 | errmsg = ctx->errors[i]; | ||
2232 | if (strlen(errmsg)) | ||
2233 | b43err(dev->wl, errmsg); | ||
2234 | } | ||
2235 | b43_print_fw_helptext(dev->wl, 1); | ||
2236 | err = -ENOENT; | ||
2237 | |||
2238 | out: | ||
2239 | kfree(ctx); | ||
2240 | return err; | ||
2241 | } | ||
2242 | |||
2212 | static int b43_upload_microcode(struct b43_wldev *dev) | 2243 | static int b43_upload_microcode(struct b43_wldev *dev) |
2213 | { | 2244 | { |
2214 | const size_t hdr_len = sizeof(struct b43_fw_header); | 2245 | const size_t hdr_len = sizeof(struct b43_fw_header); |
@@ -2319,8 +2350,11 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2319 | } | 2350 | } |
2320 | 2351 | ||
2321 | if (b43_is_old_txhdr_format(dev)) { | 2352 | if (b43_is_old_txhdr_format(dev)) { |
2353 | /* We're over the deadline, but we keep support for old fw | ||
2354 | * until it turns out to be in major conflict with something new. */ | ||
2322 | b43warn(dev->wl, "You are using an old firmware image. " | 2355 | b43warn(dev->wl, "You are using an old firmware image. " |
2323 | "Support for old firmware will be removed in July 2008.\n"); | 2356 | "Support for old firmware will be removed soon " |
2357 | "(official deadline was July 2008).\n"); | ||
2324 | b43_print_fw_helptext(dev->wl, 0); | 2358 | b43_print_fw_helptext(dev->wl, 0); |
2325 | } | 2359 | } |
2326 | 2360 | ||
@@ -3221,6 +3255,43 @@ static int b43_op_get_stats(struct ieee80211_hw *hw, | |||
3221 | return 0; | 3255 | return 0; |
3222 | } | 3256 | } |
3223 | 3257 | ||
3258 | static u64 b43_op_get_tsf(struct ieee80211_hw *hw) | ||
3259 | { | ||
3260 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
3261 | struct b43_wldev *dev; | ||
3262 | u64 tsf; | ||
3263 | |||
3264 | mutex_lock(&wl->mutex); | ||
3265 | spin_lock_irq(&wl->irq_lock); | ||
3266 | dev = wl->current_dev; | ||
3267 | |||
3268 | if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) | ||
3269 | b43_tsf_read(dev, &tsf); | ||
3270 | else | ||
3271 | tsf = 0; | ||
3272 | |||
3273 | spin_unlock_irq(&wl->irq_lock); | ||
3274 | mutex_unlock(&wl->mutex); | ||
3275 | |||
3276 | return tsf; | ||
3277 | } | ||
3278 | |||
3279 | static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) | ||
3280 | { | ||
3281 | struct b43_wl *wl = hw_to_b43_wl(hw); | ||
3282 | struct b43_wldev *dev; | ||
3283 | |||
3284 | mutex_lock(&wl->mutex); | ||
3285 | spin_lock_irq(&wl->irq_lock); | ||
3286 | dev = wl->current_dev; | ||
3287 | |||
3288 | if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) | ||
3289 | b43_tsf_write(dev, tsf); | ||
3290 | |||
3291 | spin_unlock_irq(&wl->irq_lock); | ||
3292 | mutex_unlock(&wl->mutex); | ||
3293 | } | ||
3294 | |||
3224 | static void b43_put_phy_into_reset(struct b43_wldev *dev) | 3295 | static void b43_put_phy_into_reset(struct b43_wldev *dev) |
3225 | { | 3296 | { |
3226 | struct ssb_device *sdev = dev->dev; | 3297 | struct ssb_device *sdev = dev->dev; |
@@ -3442,7 +3513,7 @@ out_unlock_mutex: | |||
3442 | return err; | 3513 | return err; |
3443 | } | 3514 | } |
3444 | 3515 | ||
3445 | static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates) | 3516 | static void b43_update_basic_rates(struct b43_wldev *dev, u32 brates) |
3446 | { | 3517 | { |
3447 | struct ieee80211_supported_band *sband = | 3518 | struct ieee80211_supported_band *sband = |
3448 | dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)]; | 3519 | dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)]; |
@@ -3520,21 +3591,29 @@ out_unlock_mutex: | |||
3520 | } | 3591 | } |
3521 | 3592 | ||
3522 | static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 3593 | static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
3523 | const u8 *local_addr, const u8 *addr, | 3594 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
3524 | struct ieee80211_key_conf *key) | 3595 | struct ieee80211_key_conf *key) |
3525 | { | 3596 | { |
3526 | struct b43_wl *wl = hw_to_b43_wl(hw); | 3597 | struct b43_wl *wl = hw_to_b43_wl(hw); |
3527 | struct b43_wldev *dev; | 3598 | struct b43_wldev *dev; |
3528 | unsigned long flags; | ||
3529 | u8 algorithm; | 3599 | u8 algorithm; |
3530 | u8 index; | 3600 | u8 index; |
3531 | int err; | 3601 | int err; |
3602 | static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
3532 | 3603 | ||
3533 | if (modparam_nohwcrypt) | 3604 | if (modparam_nohwcrypt) |
3534 | return -ENOSPC; /* User disabled HW-crypto */ | 3605 | return -ENOSPC; /* User disabled HW-crypto */ |
3535 | 3606 | ||
3536 | mutex_lock(&wl->mutex); | 3607 | mutex_lock(&wl->mutex); |
3537 | spin_lock_irqsave(&wl->irq_lock, flags); | 3608 | spin_lock_irq(&wl->irq_lock); |
3609 | write_lock(&wl->tx_lock); | ||
3610 | /* Why do we need all this locking here? | ||
3611 | * mutex -> Every config operation must take it. | ||
3612 | * irq_lock -> We modify the dev->key array, which is accessed | ||
3613 | * in the IRQ handlers. | ||
3614 | * tx_lock -> We modify the dev->key array, which is accessed | ||
3615 | * in the TX handler. | ||
3616 | */ | ||
3538 | 3617 | ||
3539 | dev = wl->current_dev; | 3618 | dev = wl->current_dev; |
3540 | err = -ENODEV; | 3619 | err = -ENODEV; |
@@ -3551,7 +3630,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3551 | err = -EINVAL; | 3630 | err = -EINVAL; |
3552 | switch (key->alg) { | 3631 | switch (key->alg) { |
3553 | case ALG_WEP: | 3632 | case ALG_WEP: |
3554 | if (key->keylen == 5) | 3633 | if (key->keylen == LEN_WEP40) |
3555 | algorithm = B43_SEC_ALGO_WEP40; | 3634 | algorithm = B43_SEC_ALGO_WEP40; |
3556 | else | 3635 | else |
3557 | algorithm = B43_SEC_ALGO_WEP104; | 3636 | algorithm = B43_SEC_ALGO_WEP104; |
@@ -3578,17 +3657,19 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3578 | goto out_unlock; | 3657 | goto out_unlock; |
3579 | } | 3658 | } |
3580 | 3659 | ||
3581 | if (is_broadcast_ether_addr(addr)) { | 3660 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { |
3582 | /* addr is FF:FF:FF:FF:FF:FF for default keys */ | 3661 | if (WARN_ON(!sta)) { |
3662 | err = -EOPNOTSUPP; | ||
3663 | goto out_unlock; | ||
3664 | } | ||
3665 | /* Pairwise key with an assigned MAC address. */ | ||
3666 | err = b43_key_write(dev, -1, algorithm, | ||
3667 | key->key, key->keylen, | ||
3668 | sta->addr, key); | ||
3669 | } else { | ||
3670 | /* Group key */ | ||
3583 | err = b43_key_write(dev, index, algorithm, | 3671 | err = b43_key_write(dev, index, algorithm, |
3584 | key->key, key->keylen, NULL, key); | 3672 | key->key, key->keylen, NULL, key); |
3585 | } else { | ||
3586 | /* | ||
3587 | * either pairwise key or address is 00:00:00:00:00:00 | ||
3588 | * for transmit-only keys | ||
3589 | */ | ||
3590 | err = b43_key_write(dev, -1, algorithm, | ||
3591 | key->key, key->keylen, addr, key); | ||
3592 | } | 3673 | } |
3593 | if (err) | 3674 | if (err) |
3594 | goto out_unlock; | 3675 | goto out_unlock; |
@@ -3617,10 +3698,11 @@ out_unlock: | |||
3617 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " | 3698 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " |
3618 | "mac: %pM\n", | 3699 | "mac: %pM\n", |
3619 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, | 3700 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, |
3620 | addr); | 3701 | sta ? sta->addr : bcast_addr); |
3621 | b43_dump_keymemory(dev); | 3702 | b43_dump_keymemory(dev); |
3622 | } | 3703 | } |
3623 | spin_unlock_irqrestore(&wl->irq_lock, flags); | 3704 | write_unlock(&wl->tx_lock); |
3705 | spin_unlock_irq(&wl->irq_lock); | ||
3624 | mutex_unlock(&wl->mutex); | 3706 | mutex_unlock(&wl->mutex); |
3625 | 3707 | ||
3626 | return err; | 3708 | return err; |
@@ -3796,6 +3878,12 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
3796 | break; | 3878 | break; |
3797 | #ifdef CONFIG_B43_NPHY | 3879 | #ifdef CONFIG_B43_NPHY |
3798 | case B43_PHYTYPE_N: | 3880 | case B43_PHYTYPE_N: |
3881 | if (phy_rev > 4) | ||
3882 | unsupported = 1; | ||
3883 | break; | ||
3884 | #endif | ||
3885 | #ifdef CONFIG_B43_PHY_LP | ||
3886 | case B43_PHYTYPE_LP: | ||
3799 | if (phy_rev > 1) | 3887 | if (phy_rev > 1) |
3800 | unsupported = 1; | 3888 | unsupported = 1; |
3801 | break; | 3889 | break; |
@@ -3849,7 +3937,11 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
3849 | unsupported = 1; | 3937 | unsupported = 1; |
3850 | break; | 3938 | break; |
3851 | case B43_PHYTYPE_N: | 3939 | case B43_PHYTYPE_N: |
3852 | if (radio_ver != 0x2055) | 3940 | if (radio_ver != 0x2055 && radio_ver != 0x2056) |
3941 | unsupported = 1; | ||
3942 | break; | ||
3943 | case B43_PHYTYPE_LP: | ||
3944 | if (radio_ver != 0x2062) | ||
3853 | unsupported = 1; | 3945 | unsupported = 1; |
3854 | break; | 3946 | break; |
3855 | default: | 3947 | default: |
@@ -4317,6 +4409,8 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4317 | .set_key = b43_op_set_key, | 4409 | .set_key = b43_op_set_key, |
4318 | .get_stats = b43_op_get_stats, | 4410 | .get_stats = b43_op_get_stats, |
4319 | .get_tx_stats = b43_op_get_tx_stats, | 4411 | .get_tx_stats = b43_op_get_tx_stats, |
4412 | .get_tsf = b43_op_get_tsf, | ||
4413 | .set_tsf = b43_op_set_tsf, | ||
4320 | .start = b43_op_start, | 4414 | .start = b43_op_start, |
4321 | .stop = b43_op_stop, | 4415 | .stop = b43_op_stop, |
4322 | .set_tim = b43_op_beacon_set_tim, | 4416 | .set_tim = b43_op_beacon_set_tim, |
@@ -4446,6 +4540,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4446 | break; | 4540 | break; |
4447 | case B43_PHYTYPE_G: | 4541 | case B43_PHYTYPE_G: |
4448 | case B43_PHYTYPE_N: | 4542 | case B43_PHYTYPE_N: |
4543 | case B43_PHYTYPE_LP: | ||
4449 | have_2ghz_phy = 1; | 4544 | have_2ghz_phy = 1; |
4450 | break; | 4545 | break; |
4451 | default: | 4546 | default: |
@@ -4657,9 +4752,10 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4657 | INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); | 4752 | INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); |
4658 | 4753 | ||
4659 | ssb_set_devtypedata(dev, wl); | 4754 | ssb_set_devtypedata(dev, wl); |
4660 | b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); | 4755 | b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", |
4756 | dev->bus->chip_id, dev->id.revision); | ||
4661 | err = 0; | 4757 | err = 0; |
4662 | out: | 4758 | out: |
4663 | return err; | 4759 | return err; |
4664 | } | 4760 | } |
4665 | 4761 | ||
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index f871a252cb55..40abcf5d1b43 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
@@ -40,6 +40,24 @@ | |||
40 | 40 | ||
41 | 41 | ||
42 | extern int b43_modparam_qos; | 42 | extern int b43_modparam_qos; |
43 | extern int b43_modparam_verbose; | ||
44 | |||
45 | /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if | ||
46 | * you add or remove levels. */ | ||
47 | enum b43_verbosity { | ||
48 | B43_VERBOSITY_ERROR, | ||
49 | B43_VERBOSITY_WARN, | ||
50 | B43_VERBOSITY_INFO, | ||
51 | B43_VERBOSITY_DEBUG, | ||
52 | __B43_VERBOSITY_AFTERLAST, /* keep last */ | ||
53 | |||
54 | B43_VERBOSITY_MAX = __B43_VERBOSITY_AFTERLAST - 1, | ||
55 | #if B43_DEBUG | ||
56 | B43_VERBOSITY_DEFAULT = B43_VERBOSITY_DEBUG, | ||
57 | #else | ||
58 | B43_VERBOSITY_DEFAULT = B43_VERBOSITY_INFO, | ||
59 | #endif | ||
60 | }; | ||
43 | 61 | ||
44 | 62 | ||
45 | /* Lightweight function to convert a frequency (in Mhz) to a channel number. */ | 63 | /* Lightweight function to convert a frequency (in Mhz) to a channel number. */ |
@@ -121,4 +139,11 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags); | |||
121 | void b43_mac_suspend(struct b43_wldev *dev); | 139 | void b43_mac_suspend(struct b43_wldev *dev); |
122 | void b43_mac_enable(struct b43_wldev *dev); | 140 | void b43_mac_enable(struct b43_wldev *dev); |
123 | 141 | ||
142 | |||
143 | struct b43_request_fw_context; | ||
144 | int b43_do_request_fw(struct b43_request_fw_context *ctx, | ||
145 | const char *name, | ||
146 | struct b43_firmware_file *fw); | ||
147 | void b43_do_release_fw(struct b43_firmware_file *fw); | ||
148 | |||
124 | #endif /* B43_MAIN_H_ */ | 149 | #endif /* B43_MAIN_H_ */ |
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index caac4a45f0bf..88bb303ae9d5 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c | |||
@@ -3191,6 +3191,7 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, | |||
3191 | * Baseband attennuation. Subtract it. */ | 3191 | * Baseband attennuation. Subtract it. */ |
3192 | bbatt_delta -= 4 * rfatt_delta; | 3192 | bbatt_delta -= 4 * rfatt_delta; |
3193 | 3193 | ||
3194 | #if B43_DEBUG | ||
3194 | if (b43_debug(dev, B43_DBG_XMITPOWER)) { | 3195 | if (b43_debug(dev, B43_DBG_XMITPOWER)) { |
3195 | int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust; | 3196 | int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust; |
3196 | b43dbg(dev->wl, | 3197 | b43dbg(dev->wl, |
@@ -3199,6 +3200,8 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, | |||
3199 | (pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm), | 3200 | (pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm), |
3200 | bbatt_delta, rfatt_delta); | 3201 | bbatt_delta, rfatt_delta); |
3201 | } | 3202 | } |
3203 | #endif /* DEBUG */ | ||
3204 | |||
3202 | /* So do we finally need to adjust something in hardware? */ | 3205 | /* So do we finally need to adjust something in hardware? */ |
3203 | if ((rfatt_delta == 0) && (bbatt_delta == 0)) | 3206 | if ((rfatt_delta == 0) && (bbatt_delta == 0)) |
3204 | goto no_adjustment_needed; | 3207 | goto no_adjustment_needed; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index fb996c27a19b..879edc786713 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -2650,7 +2650,7 @@ out_unlock_mutex: | |||
2650 | return err; | 2650 | return err; |
2651 | } | 2651 | } |
2652 | 2652 | ||
2653 | static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates) | 2653 | static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u32 brates) |
2654 | { | 2654 | { |
2655 | struct ieee80211_supported_band *sband = | 2655 | struct ieee80211_supported_band *sband = |
2656 | dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; | 2656 | dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 47bee0ee0a7c..7b3bad1796c7 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -1,25 +1,26 @@ | |||
1 | config IWLWIFI | 1 | config IWLWIFI |
2 | tristate | 2 | bool "Intel Wireless Wifi" |
3 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | ||
4 | default y | ||
3 | 5 | ||
4 | config IWLCORE | 6 | config IWLCORE |
5 | tristate "Intel Wireless Wifi Core" | 7 | tristate "Intel Wireless Wifi Core" |
6 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | 8 | depends on IWLWIFI |
7 | select LIB80211 | 9 | select LIB80211 |
8 | select IWLWIFI | ||
9 | select MAC80211_LEDS if IWLWIFI_LEDS | 10 | select MAC80211_LEDS if IWLWIFI_LEDS |
10 | select LEDS_CLASS if IWLWIFI_LEDS | 11 | select LEDS_CLASS if IWLWIFI_LEDS |
11 | select RFKILL if IWLWIFI_RFKILL | 12 | select RFKILL if IWLWIFI_RFKILL |
12 | 13 | ||
13 | config IWLWIFI_LEDS | 14 | config IWLWIFI_LEDS |
14 | bool | 15 | bool "Enable LED support in iwlagn driver" |
15 | default n | 16 | depends on IWLCORE |
16 | 17 | ||
17 | config IWLWIFI_RFKILL | 18 | config IWLWIFI_RFKILL |
18 | boolean "Iwlwifi RF kill support" | 19 | bool "Enable RF kill support in iwlagn driver" |
19 | depends on IWLCORE | 20 | depends on IWLCORE |
20 | 21 | ||
21 | config IWLWIFI_DEBUG | 22 | config IWLWIFI_DEBUG |
22 | bool "Enable full debugging output in iwlagn driver" | 23 | bool "Enable full debugging output in iwlagn and iwl3945 drivers" |
23 | depends on IWLCORE | 24 | depends on IWLCORE |
24 | ---help--- | 25 | ---help--- |
25 | This option will enable debug tracing output for the iwlwifi drivers | 26 | This option will enable debug tracing output for the iwlwifi drivers |
@@ -51,7 +52,7 @@ config IWLWIFI_DEBUGFS | |||
51 | 52 | ||
52 | config IWLAGN | 53 | config IWLAGN |
53 | tristate "Intel Wireless WiFi Next Gen AGN" | 54 | tristate "Intel Wireless WiFi Next Gen AGN" |
54 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | 55 | depends on IWLWIFI |
55 | select FW_LOADER | 56 | select FW_LOADER |
56 | select IWLCORE | 57 | select IWLCORE |
57 | ---help--- | 58 | ---help--- |
@@ -104,13 +105,12 @@ config IWL5000 | |||
104 | 105 | ||
105 | config IWL3945 | 106 | config IWL3945 |
106 | tristate "Intel PRO/Wireless 3945ABG/BG Network Connection" | 107 | tristate "Intel PRO/Wireless 3945ABG/BG Network Connection" |
107 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | 108 | depends on IWLWIFI |
108 | select FW_LOADER | 109 | select FW_LOADER |
109 | select LIB80211 | 110 | select LIB80211 |
110 | select IWLWIFI | ||
111 | select MAC80211_LEDS if IWL3945_LEDS | 111 | select MAC80211_LEDS if IWL3945_LEDS |
112 | select LEDS_CLASS if IWL3945_LEDS | 112 | select LEDS_CLASS if IWL3945_LEDS |
113 | select RFKILL if IWL3945_RFKILL | 113 | select RFKILL if IWLWIFI_RFKILL |
114 | ---help--- | 114 | ---help--- |
115 | Select to build the driver supporting the: | 115 | Select to build the driver supporting the: |
116 | 116 | ||
@@ -133,10 +133,6 @@ config IWL3945 | |||
133 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 133 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
134 | module will be called iwl3945.ko. | 134 | module will be called iwl3945.ko. |
135 | 135 | ||
136 | config IWL3945_RFKILL | ||
137 | bool "Enable RF kill support in iwl3945 drivers" | ||
138 | depends on IWL3945 | ||
139 | |||
140 | config IWL3945_SPECTRUM_MEASUREMENT | 136 | config IWL3945_SPECTRUM_MEASUREMENT |
141 | bool "Enable Spectrum Measurement in iwl3945 drivers" | 137 | bool "Enable Spectrum Measurement in iwl3945 drivers" |
142 | depends on IWL3945 | 138 | depends on IWL3945 |
@@ -148,30 +144,3 @@ config IWL3945_LEDS | |||
148 | depends on IWL3945 | 144 | depends on IWL3945 |
149 | ---help--- | 145 | ---help--- |
150 | This option enables LEDS for the iwl3945 driver. | 146 | This option enables LEDS for the iwl3945 driver. |
151 | |||
152 | config IWL3945_DEBUG | ||
153 | bool "Enable full debugging output in iwl3945 driver" | ||
154 | depends on IWL3945 | ||
155 | ---help--- | ||
156 | This option will enable debug tracing output for the iwl3945 | ||
157 | driver. | ||
158 | |||
159 | This will result in the kernel module being ~100k larger. You can | ||
160 | control which debug output is sent to the kernel log by setting the | ||
161 | value in | ||
162 | |||
163 | /sys/bus/pci/drivers/${DRIVER}/debug_level | ||
164 | |||
165 | This entry will only exist if this option is enabled. | ||
166 | |||
167 | To set a value, simply echo an 8-byte hex value to the same file: | ||
168 | |||
169 | % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level | ||
170 | |||
171 | You can find the list of debug mask values in: | ||
172 | drivers/net/wireless/iwlwifi/iwl-3945-debug.h | ||
173 | |||
174 | If this is your first time using this driver, you should say Y here | ||
175 | as the debug information can assist others in helping you resolve | ||
176 | any problems you may encounter. | ||
177 | |||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 0be9e6b66aa0..fec2fbf8dc02 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -12,6 +12,8 @@ iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-hcmd-check.o | |||
12 | 12 | ||
13 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o | 13 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o |
14 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o | 14 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o |
15 | iwlagn-$(CONFIG_IWL5000) += iwl-6000.o | ||
16 | iwlagn-$(CONFIG_IWL5000) += iwl-100.o | ||
15 | 17 | ||
16 | obj-$(CONFIG_IWL3945) += iwl3945.o | 18 | obj-$(CONFIG_IWL3945) += iwl3945.o |
17 | iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o | 19 | iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-100.c b/drivers/net/wireless/iwlwifi/iwl-100.c new file mode 100644 index 000000000000..dbadaf44f570 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-100.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
24 | * | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/pci.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/skbuff.h> | ||
34 | #include <linux/netdevice.h> | ||
35 | #include <linux/wireless.h> | ||
36 | #include <net/mac80211.h> | ||
37 | #include <linux/etherdevice.h> | ||
38 | #include <asm/unaligned.h> | ||
39 | |||
40 | #include "iwl-eeprom.h" | ||
41 | #include "iwl-dev.h" | ||
42 | #include "iwl-core.h" | ||
43 | #include "iwl-io.h" | ||
44 | #include "iwl-sta.h" | ||
45 | #include "iwl-helpers.h" | ||
46 | #include "iwl-5000-hw.h" | ||
47 | |||
48 | /* Highest firmware API version supported */ | ||
49 | #define IWL100_UCODE_API_MAX 1 | ||
50 | |||
51 | /* Lowest firmware API version supported */ | ||
52 | #define IWL100_UCODE_API_MIN 1 | ||
53 | |||
54 | #define IWL100_FW_PRE "iwlwifi-100-" | ||
55 | #define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" | ||
56 | #define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api) | ||
57 | |||
58 | struct iwl_cfg iwl100_bgn_cfg = { | ||
59 | .name = "100 Series BGN", | ||
60 | .fw_name_pre = IWL100_FW_PRE, | ||
61 | .ucode_api_max = IWL100_UCODE_API_MAX, | ||
62 | .ucode_api_min = IWL100_UCODE_API_MIN, | ||
63 | .sku = IWL_SKU_G|IWL_SKU_N, | ||
64 | .ops = &iwl5000_ops, | ||
65 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
66 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | ||
67 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
68 | .mod_params = &iwl50_mod_params, | ||
69 | }; | ||
70 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h deleted file mode 100644 index c6f4eb54a2b1..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h +++ /dev/null | |||
@@ -1,1702 +0,0 @@ | |||
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 | * Intel Linux Wireless <ilw@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 - 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 | * Please use this file (iwl-3945-commands.h) only for uCode API definitions. | ||
65 | * Please use iwl-3945-hw.h for hardware-related definitions. | ||
66 | * Please use iwl-3945.h for driver implementation definitions. | ||
67 | */ | ||
68 | |||
69 | #ifndef __iwl_3945_commands_h__ | ||
70 | #define __iwl_3945_commands_h__ | ||
71 | |||
72 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | ||
73 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | ||
74 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | ||
75 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | ||
76 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | ||
77 | |||
78 | enum { | ||
79 | REPLY_ALIVE = 0x1, | ||
80 | REPLY_ERROR = 0x2, | ||
81 | |||
82 | /* RXON and QOS commands */ | ||
83 | REPLY_RXON = 0x10, | ||
84 | REPLY_RXON_ASSOC = 0x11, | ||
85 | REPLY_QOS_PARAM = 0x13, | ||
86 | REPLY_RXON_TIMING = 0x14, | ||
87 | |||
88 | /* Multi-Station support */ | ||
89 | REPLY_ADD_STA = 0x18, | ||
90 | REPLY_REMOVE_STA = 0x19, /* not used */ | ||
91 | REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ | ||
92 | |||
93 | /* RX, TX, LEDs */ | ||
94 | REPLY_3945_RX = 0x1b, /* 3945 only */ | ||
95 | REPLY_TX = 0x1c, | ||
96 | REPLY_RATE_SCALE = 0x47, /* 3945 only */ | ||
97 | REPLY_LEDS_CMD = 0x48, | ||
98 | REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */ | ||
99 | |||
100 | /* 802.11h related */ | ||
101 | RADAR_NOTIFICATION = 0x70, /* not used */ | ||
102 | REPLY_QUIET_CMD = 0x71, /* not used */ | ||
103 | REPLY_CHANNEL_SWITCH = 0x72, | ||
104 | CHANNEL_SWITCH_NOTIFICATION = 0x73, | ||
105 | REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74, | ||
106 | SPECTRUM_MEASURE_NOTIFICATION = 0x75, | ||
107 | |||
108 | /* Power Management */ | ||
109 | POWER_TABLE_CMD = 0x77, | ||
110 | PM_SLEEP_NOTIFICATION = 0x7A, | ||
111 | PM_DEBUG_STATISTIC_NOTIFIC = 0x7B, | ||
112 | |||
113 | /* Scan commands and notifications */ | ||
114 | REPLY_SCAN_CMD = 0x80, | ||
115 | REPLY_SCAN_ABORT_CMD = 0x81, | ||
116 | SCAN_START_NOTIFICATION = 0x82, | ||
117 | SCAN_RESULTS_NOTIFICATION = 0x83, | ||
118 | SCAN_COMPLETE_NOTIFICATION = 0x84, | ||
119 | |||
120 | /* IBSS/AP commands */ | ||
121 | BEACON_NOTIFICATION = 0x90, | ||
122 | REPLY_TX_BEACON = 0x91, | ||
123 | WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */ | ||
124 | |||
125 | /* Miscellaneous commands */ | ||
126 | QUIET_NOTIFICATION = 0x96, /* not used */ | ||
127 | REPLY_TX_PWR_TABLE_CMD = 0x97, | ||
128 | MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ | ||
129 | |||
130 | /* Bluetooth device coexistence config command */ | ||
131 | REPLY_BT_CONFIG = 0x9b, | ||
132 | |||
133 | /* Statistics */ | ||
134 | REPLY_STATISTICS_CMD = 0x9c, | ||
135 | STATISTICS_NOTIFICATION = 0x9d, | ||
136 | |||
137 | /* RF-KILL commands and notifications */ | ||
138 | REPLY_CARD_STATE_CMD = 0xa0, | ||
139 | CARD_STATE_NOTIFICATION = 0xa1, | ||
140 | |||
141 | /* Missed beacons notification */ | ||
142 | MISSED_BEACONS_NOTIFICATION = 0xa2, | ||
143 | |||
144 | REPLY_MAX = 0xff | ||
145 | }; | ||
146 | |||
147 | /****************************************************************************** | ||
148 | * (0) | ||
149 | * Commonly used structures and definitions: | ||
150 | * Command header, txpower | ||
151 | * | ||
152 | *****************************************************************************/ | ||
153 | |||
154 | /* iwl3945_cmd_header flags value */ | ||
155 | #define IWL_CMD_FAILED_MSK 0x40 | ||
156 | |||
157 | /** | ||
158 | * struct iwl3945_cmd_header | ||
159 | * | ||
160 | * This header format appears in the beginning of each command sent from the | ||
161 | * driver, and each response/notification received from uCode. | ||
162 | */ | ||
163 | struct iwl3945_cmd_header { | ||
164 | u8 cmd; /* Command ID: REPLY_RXON, etc. */ | ||
165 | u8 flags; /* IWL_CMD_* */ | ||
166 | /* | ||
167 | * The driver sets up the sequence number to values of its choosing. | ||
168 | * uCode does not use this value, but passes it back to the driver | ||
169 | * when sending the response to each driver-originated command, so | ||
170 | * the driver can match the response to the command. Since the values | ||
171 | * don't get used by uCode, the driver may set up an arbitrary format. | ||
172 | * | ||
173 | * There is one exception: uCode sets bit 15 when it originates | ||
174 | * the response/notification, i.e. when the response/notification | ||
175 | * is not a direct response to a command sent by the driver. For | ||
176 | * example, uCode issues REPLY_3945_RX when it sends a received frame | ||
177 | * to the driver; it is not a direct response to any driver command. | ||
178 | * | ||
179 | * The Linux driver uses the following format: | ||
180 | * | ||
181 | * 0:7 index/position within Tx queue | ||
182 | * 8:13 Tx queue selection | ||
183 | * 14:14 driver sets this to indicate command is in the 'huge' | ||
184 | * storage at the end of the command buffers, i.e. scan cmd | ||
185 | * 15:15 uCode sets this in uCode-originated response/notification | ||
186 | */ | ||
187 | __le16 sequence; | ||
188 | |||
189 | /* command or response/notification data follows immediately */ | ||
190 | u8 data[0]; | ||
191 | } __attribute__ ((packed)); | ||
192 | |||
193 | /** | ||
194 | * struct iwl3945_tx_power | ||
195 | * | ||
196 | * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH | ||
197 | * | ||
198 | * Each entry contains two values: | ||
199 | * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained | ||
200 | * linear value that multiplies the output of the digital signal processor, | ||
201 | * before being sent to the analog radio. | ||
202 | * 2) Radio gain. This sets the analog gain of the radio Tx path. | ||
203 | * It is a coarser setting, and behaves in a logarithmic (dB) fashion. | ||
204 | * | ||
205 | * Driver obtains values from struct iwl3945_tx_power power_gain_table[][]. | ||
206 | */ | ||
207 | struct iwl3945_tx_power { | ||
208 | u8 tx_gain; /* gain for analog radio */ | ||
209 | u8 dsp_atten; /* gain for DSP */ | ||
210 | } __attribute__ ((packed)); | ||
211 | |||
212 | /** | ||
213 | * struct iwl3945_power_per_rate | ||
214 | * | ||
215 | * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH | ||
216 | */ | ||
217 | struct iwl3945_power_per_rate { | ||
218 | u8 rate; /* plcp */ | ||
219 | struct iwl3945_tx_power tpc; | ||
220 | u8 reserved; | ||
221 | } __attribute__ ((packed)); | ||
222 | |||
223 | /****************************************************************************** | ||
224 | * (0a) | ||
225 | * Alive and Error Commands & Responses: | ||
226 | * | ||
227 | *****************************************************************************/ | ||
228 | |||
229 | #define UCODE_VALID_OK cpu_to_le32(0x1) | ||
230 | #define INITIALIZE_SUBTYPE (9) | ||
231 | |||
232 | /* | ||
233 | * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command) | ||
234 | * | ||
235 | * uCode issues this "initialize alive" notification once the initialization | ||
236 | * uCode image has completed its work, and is ready to load the runtime image. | ||
237 | * This is the *first* "alive" notification that the driver will receive after | ||
238 | * rebooting uCode; the "initialize" alive is indicated by subtype field == 9. | ||
239 | * | ||
240 | * See comments documenting "BSM" (bootstrap state machine). | ||
241 | */ | ||
242 | struct iwl3945_init_alive_resp { | ||
243 | u8 ucode_minor; | ||
244 | u8 ucode_major; | ||
245 | __le16 reserved1; | ||
246 | u8 sw_rev[8]; | ||
247 | u8 ver_type; | ||
248 | u8 ver_subtype; /* "9" for initialize alive */ | ||
249 | __le16 reserved2; | ||
250 | __le32 log_event_table_ptr; | ||
251 | __le32 error_event_table_ptr; | ||
252 | __le32 timestamp; | ||
253 | __le32 is_valid; | ||
254 | } __attribute__ ((packed)); | ||
255 | |||
256 | |||
257 | /** | ||
258 | * REPLY_ALIVE = 0x1 (response only, not a command) | ||
259 | * | ||
260 | * uCode issues this "alive" notification once the runtime image is ready | ||
261 | * to receive commands from the driver. This is the *second* "alive" | ||
262 | * notification that the driver will receive after rebooting uCode; | ||
263 | * this "alive" is indicated by subtype field != 9. | ||
264 | * | ||
265 | * See comments documenting "BSM" (bootstrap state machine). | ||
266 | * | ||
267 | * This response includes two pointers to structures within the device's | ||
268 | * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging: | ||
269 | * | ||
270 | * 1) log_event_table_ptr indicates base of the event log. This traces | ||
271 | * a 256-entry history of uCode execution within a circular buffer. | ||
272 | * | ||
273 | * 2) error_event_table_ptr indicates base of the error log. This contains | ||
274 | * information about any uCode error that occurs. | ||
275 | * | ||
276 | * The Linux driver can print both logs to the system log when a uCode error | ||
277 | * occurs. | ||
278 | */ | ||
279 | struct iwl3945_alive_resp { | ||
280 | u8 ucode_minor; | ||
281 | u8 ucode_major; | ||
282 | __le16 reserved1; | ||
283 | u8 sw_rev[8]; | ||
284 | u8 ver_type; | ||
285 | u8 ver_subtype; /* not "9" for runtime alive */ | ||
286 | __le16 reserved2; | ||
287 | __le32 log_event_table_ptr; /* SRAM address for event log */ | ||
288 | __le32 error_event_table_ptr; /* SRAM address for error log */ | ||
289 | __le32 timestamp; | ||
290 | __le32 is_valid; | ||
291 | } __attribute__ ((packed)); | ||
292 | |||
293 | union tsf { | ||
294 | u8 byte[8]; | ||
295 | __le16 word[4]; | ||
296 | __le32 dw[2]; | ||
297 | }; | ||
298 | |||
299 | /* | ||
300 | * REPLY_ERROR = 0x2 (response only, not a command) | ||
301 | */ | ||
302 | struct iwl3945_error_resp { | ||
303 | __le32 error_type; | ||
304 | u8 cmd_id; | ||
305 | u8 reserved1; | ||
306 | __le16 bad_cmd_seq_num; | ||
307 | __le16 reserved2; | ||
308 | __le32 error_info; | ||
309 | union tsf timestamp; | ||
310 | } __attribute__ ((packed)); | ||
311 | |||
312 | /****************************************************************************** | ||
313 | * (1) | ||
314 | * RXON Commands & Responses: | ||
315 | * | ||
316 | *****************************************************************************/ | ||
317 | |||
318 | /* | ||
319 | * Rx config defines & structure | ||
320 | */ | ||
321 | /* rx_config device types */ | ||
322 | enum { | ||
323 | RXON_DEV_TYPE_AP = 1, | ||
324 | RXON_DEV_TYPE_ESS = 3, | ||
325 | RXON_DEV_TYPE_IBSS = 4, | ||
326 | RXON_DEV_TYPE_SNIFFER = 6, | ||
327 | }; | ||
328 | |||
329 | /* rx_config flags */ | ||
330 | /* band & modulation selection */ | ||
331 | #define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0) | ||
332 | #define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1) | ||
333 | /* auto detection enable */ | ||
334 | #define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2) | ||
335 | /* TGg protection when tx */ | ||
336 | #define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3) | ||
337 | /* cck short slot & preamble */ | ||
338 | #define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4) | ||
339 | #define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5) | ||
340 | /* antenna selection */ | ||
341 | #define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7) | ||
342 | #define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00) | ||
343 | #define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8) | ||
344 | #define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9) | ||
345 | /* radar detection enable */ | ||
346 | #define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12) | ||
347 | #define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13) | ||
348 | /* rx response to host with 8-byte TSF | ||
349 | * (according to ON_AIR deassertion) */ | ||
350 | #define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15) | ||
351 | |||
352 | /* rx_config filter flags */ | ||
353 | /* accept all data frames */ | ||
354 | #define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0) | ||
355 | /* pass control & management to host */ | ||
356 | #define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1) | ||
357 | /* accept multi-cast */ | ||
358 | #define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2) | ||
359 | /* don't decrypt uni-cast frames */ | ||
360 | #define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3) | ||
361 | /* don't decrypt multi-cast frames */ | ||
362 | #define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4) | ||
363 | /* STA is associated */ | ||
364 | #define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5) | ||
365 | /* transfer to host non bssid beacons in associated state */ | ||
366 | #define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6) | ||
367 | |||
368 | /** | ||
369 | * REPLY_RXON = 0x10 (command, has simple generic response) | ||
370 | * | ||
371 | * RXON tunes the radio tuner to a service channel, and sets up a number | ||
372 | * of parameters that are used primarily for Rx, but also for Tx operations. | ||
373 | * | ||
374 | * NOTE: When tuning to a new channel, driver must set the | ||
375 | * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent | ||
376 | * info within the device, including the station tables, tx retry | ||
377 | * rate tables, and txpower tables. Driver must build a new station | ||
378 | * table and txpower table before transmitting anything on the RXON | ||
379 | * channel. | ||
380 | * | ||
381 | * NOTE: All RXONs wipe clean the internal txpower table. Driver must | ||
382 | * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), | ||
383 | * regardless of whether RXON_FILTER_ASSOC_MSK is set. | ||
384 | */ | ||
385 | struct iwl3945_rxon_cmd { | ||
386 | u8 node_addr[6]; | ||
387 | __le16 reserved1; | ||
388 | u8 bssid_addr[6]; | ||
389 | __le16 reserved2; | ||
390 | u8 wlap_bssid_addr[6]; | ||
391 | __le16 reserved3; | ||
392 | u8 dev_type; | ||
393 | u8 air_propagation; | ||
394 | __le16 reserved4; | ||
395 | u8 ofdm_basic_rates; | ||
396 | u8 cck_basic_rates; | ||
397 | __le16 assoc_id; | ||
398 | __le32 flags; | ||
399 | __le32 filter_flags; | ||
400 | __le16 channel; | ||
401 | __le16 reserved5; | ||
402 | } __attribute__ ((packed)); | ||
403 | |||
404 | /* | ||
405 | * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) | ||
406 | */ | ||
407 | struct iwl3945_rxon_assoc_cmd { | ||
408 | __le32 flags; | ||
409 | __le32 filter_flags; | ||
410 | u8 ofdm_basic_rates; | ||
411 | u8 cck_basic_rates; | ||
412 | __le16 reserved; | ||
413 | } __attribute__ ((packed)); | ||
414 | |||
415 | /* | ||
416 | * REPLY_RXON_TIMING = 0x14 (command, has simple generic response) | ||
417 | */ | ||
418 | struct iwl3945_rxon_time_cmd { | ||
419 | union tsf timestamp; | ||
420 | __le16 beacon_interval; | ||
421 | __le16 atim_window; | ||
422 | __le32 beacon_init_val; | ||
423 | __le16 listen_interval; | ||
424 | __le16 reserved; | ||
425 | } __attribute__ ((packed)); | ||
426 | |||
427 | /* | ||
428 | * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) | ||
429 | */ | ||
430 | struct iwl3945_channel_switch_cmd { | ||
431 | u8 band; | ||
432 | u8 expect_beacon; | ||
433 | __le16 channel; | ||
434 | __le32 rxon_flags; | ||
435 | __le32 rxon_filter_flags; | ||
436 | __le32 switch_time; | ||
437 | struct iwl3945_power_per_rate power[IWL_MAX_RATES]; | ||
438 | } __attribute__ ((packed)); | ||
439 | |||
440 | /* | ||
441 | * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) | ||
442 | */ | ||
443 | struct iwl3945_csa_notification { | ||
444 | __le16 band; | ||
445 | __le16 channel; | ||
446 | __le32 status; /* 0 - OK, 1 - fail */ | ||
447 | } __attribute__ ((packed)); | ||
448 | |||
449 | /****************************************************************************** | ||
450 | * (2) | ||
451 | * Quality-of-Service (QOS) Commands & Responses: | ||
452 | * | ||
453 | *****************************************************************************/ | ||
454 | |||
455 | /** | ||
456 | * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM | ||
457 | * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd | ||
458 | * | ||
459 | * @cw_min: Contention window, start value in numbers of slots. | ||
460 | * Should be a power-of-2, minus 1. Device's default is 0x0f. | ||
461 | * @cw_max: Contention window, max value in numbers of slots. | ||
462 | * Should be a power-of-2, minus 1. Device's default is 0x3f. | ||
463 | * @aifsn: Number of slots in Arbitration Interframe Space (before | ||
464 | * performing random backoff timing prior to Tx). Device default 1. | ||
465 | * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0. | ||
466 | * | ||
467 | * Device will automatically increase contention window by (2*CW) + 1 for each | ||
468 | * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW | ||
469 | * value, to cap the CW value. | ||
470 | */ | ||
471 | struct iwl3945_ac_qos { | ||
472 | __le16 cw_min; | ||
473 | __le16 cw_max; | ||
474 | u8 aifsn; | ||
475 | u8 reserved1; | ||
476 | __le16 edca_txop; | ||
477 | } __attribute__ ((packed)); | ||
478 | |||
479 | /* QoS flags defines */ | ||
480 | #define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01) | ||
481 | #define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02) | ||
482 | #define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10) | ||
483 | |||
484 | /* Number of Access Categories (AC) (EDCA), queues 0..3 */ | ||
485 | #define AC_NUM 4 | ||
486 | |||
487 | /* | ||
488 | * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) | ||
489 | * | ||
490 | * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs | ||
491 | * 0: Background, 1: Best Effort, 2: Video, 3: Voice. | ||
492 | */ | ||
493 | struct iwl3945_qosparam_cmd { | ||
494 | __le32 qos_flags; | ||
495 | struct iwl3945_ac_qos ac[AC_NUM]; | ||
496 | } __attribute__ ((packed)); | ||
497 | |||
498 | /****************************************************************************** | ||
499 | * (3) | ||
500 | * Add/Modify Stations Commands & Responses: | ||
501 | * | ||
502 | *****************************************************************************/ | ||
503 | /* | ||
504 | * Multi station support | ||
505 | */ | ||
506 | |||
507 | /* Special, dedicated locations within device's station table */ | ||
508 | #define IWL_AP_ID 0 | ||
509 | #define IWL_MULTICAST_ID 1 | ||
510 | #define IWL_STA_ID 2 | ||
511 | #define IWL3945_BROADCAST_ID 24 | ||
512 | #define IWL3945_STATION_COUNT 25 | ||
513 | |||
514 | #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ | ||
515 | #define IWL_INVALID_STATION 255 | ||
516 | |||
517 | #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2); | ||
518 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); | ||
519 | |||
520 | /* Use in mode field. 1: modify existing entry, 0: add new station entry */ | ||
521 | #define STA_CONTROL_MODIFY_MSK 0x01 | ||
522 | |||
523 | /* key flags __le16*/ | ||
524 | #define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007) | ||
525 | #define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000) | ||
526 | #define STA_KEY_FLG_WEP cpu_to_le16(0x0001) | ||
527 | #define STA_KEY_FLG_CCMP cpu_to_le16(0x0002) | ||
528 | #define STA_KEY_FLG_TKIP cpu_to_le16(0x0003) | ||
529 | |||
530 | #define STA_KEY_FLG_KEYID_POS 8 | ||
531 | #define STA_KEY_FLG_INVALID cpu_to_le16(0x0800) | ||
532 | /* wep key is either from global key (0) or from station info array (1) */ | ||
533 | #define STA_KEY_FLG_WEP_KEY_MAP_MSK cpu_to_le16(0x0008) | ||
534 | |||
535 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | ||
536 | #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) | ||
537 | #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) | ||
538 | |||
539 | /* Flags indicate whether to modify vs. don't change various station params */ | ||
540 | #define STA_MODIFY_KEY_MASK 0x01 | ||
541 | #define STA_MODIFY_TID_DISABLE_TX 0x02 | ||
542 | #define STA_MODIFY_TX_RATE_MSK 0x04 | ||
543 | |||
544 | /* | ||
545 | * Antenna masks: | ||
546 | * bit14:15 01 B inactive, A active | ||
547 | * 10 B active, A inactive | ||
548 | * 11 Both active | ||
549 | */ | ||
550 | #define RATE_MCS_ANT_A_POS 14 | ||
551 | #define RATE_MCS_ANT_B_POS 15 | ||
552 | #define RATE_MCS_ANT_A_MSK 0x4000 | ||
553 | #define RATE_MCS_ANT_B_MSK 0x8000 | ||
554 | #define RATE_MCS_ANT_AB_MSK 0xc000 | ||
555 | |||
556 | struct iwl3945_keyinfo { | ||
557 | __le16 key_flags; | ||
558 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ | ||
559 | u8 reserved1; | ||
560 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ | ||
561 | u8 key_offset; | ||
562 | u8 reserved2; | ||
563 | u8 key[16]; /* 16-byte unicast decryption key */ | ||
564 | } __attribute__ ((packed)); | ||
565 | |||
566 | /** | ||
567 | * struct sta_id_modify | ||
568 | * @addr[ETH_ALEN]: station's MAC address | ||
569 | * @sta_id: index of station in uCode's station table | ||
570 | * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change | ||
571 | * | ||
572 | * Driver selects unused table index when adding new station, | ||
573 | * or the index to a pre-existing station entry when modifying that station. | ||
574 | * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP). | ||
575 | * | ||
576 | * modify_mask flags select which parameters to modify vs. leave alone. | ||
577 | */ | ||
578 | struct sta_id_modify { | ||
579 | u8 addr[ETH_ALEN]; | ||
580 | __le16 reserved1; | ||
581 | u8 sta_id; | ||
582 | u8 modify_mask; | ||
583 | __le16 reserved2; | ||
584 | } __attribute__ ((packed)); | ||
585 | |||
586 | /* | ||
587 | * REPLY_ADD_STA = 0x18 (command) | ||
588 | * | ||
589 | * The device contains an internal table of per-station information, | ||
590 | * with info on security keys, aggregation parameters, and Tx rates for | ||
591 | * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD, | ||
592 | * 3945 uses REPLY_RATE_SCALE to set up rate tables). | ||
593 | * | ||
594 | * REPLY_ADD_STA sets up the table entry for one station, either creating | ||
595 | * a new entry, or modifying a pre-existing one. | ||
596 | * | ||
597 | * NOTE: RXON command (without "associated" bit set) wipes the station table | ||
598 | * clean. Moving into RF_KILL state does this also. Driver must set up | ||
599 | * new station table before transmitting anything on the RXON channel | ||
600 | * (except active scans or active measurements; those commands carry | ||
601 | * their own txpower/rate setup data). | ||
602 | * | ||
603 | * When getting started on a new channel, driver must set up the | ||
604 | * IWL_BROADCAST_ID entry (last entry in the table). For a client | ||
605 | * station in a BSS, once an AP is selected, driver sets up the AP STA | ||
606 | * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP | ||
607 | * are all that are needed for a BSS client station. If the device is | ||
608 | * used as AP, or in an IBSS network, driver must set up station table | ||
609 | * entries for all STAs in network, starting with index IWL_STA_ID. | ||
610 | */ | ||
611 | struct iwl3945_addsta_cmd { | ||
612 | u8 mode; /* 1: modify existing, 0: add new station */ | ||
613 | u8 reserved[3]; | ||
614 | struct sta_id_modify sta; | ||
615 | struct iwl3945_keyinfo key; | ||
616 | __le32 station_flags; /* STA_FLG_* */ | ||
617 | __le32 station_flags_msk; /* STA_FLG_* */ | ||
618 | |||
619 | /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) | ||
620 | * corresponding to bit (e.g. bit 5 controls TID 5). | ||
621 | * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ | ||
622 | __le16 tid_disable_tx; | ||
623 | |||
624 | __le16 rate_n_flags; | ||
625 | |||
626 | /* TID for which to add block-ack support. | ||
627 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | ||
628 | u8 add_immediate_ba_tid; | ||
629 | |||
630 | /* TID for which to remove block-ack support. | ||
631 | * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ | ||
632 | u8 remove_immediate_ba_tid; | ||
633 | |||
634 | /* Starting Sequence Number for added block-ack support. | ||
635 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | ||
636 | __le16 add_immediate_ba_ssn; | ||
637 | } __attribute__ ((packed)); | ||
638 | |||
639 | #define ADD_STA_SUCCESS_MSK 0x1 | ||
640 | #define ADD_STA_NO_ROOM_IN_TABLE 0x2 | ||
641 | #define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 | ||
642 | /* | ||
643 | * REPLY_ADD_STA = 0x18 (response) | ||
644 | */ | ||
645 | struct iwl3945_add_sta_resp { | ||
646 | u8 status; /* ADD_STA_* */ | ||
647 | } __attribute__ ((packed)); | ||
648 | |||
649 | |||
650 | /****************************************************************************** | ||
651 | * (4) | ||
652 | * Rx Responses: | ||
653 | * | ||
654 | *****************************************************************************/ | ||
655 | |||
656 | struct iwl3945_rx_frame_stats { | ||
657 | u8 phy_count; | ||
658 | u8 id; | ||
659 | u8 rssi; | ||
660 | u8 agc; | ||
661 | __le16 sig_avg; | ||
662 | __le16 noise_diff; | ||
663 | u8 payload[0]; | ||
664 | } __attribute__ ((packed)); | ||
665 | |||
666 | struct iwl3945_rx_frame_hdr { | ||
667 | __le16 channel; | ||
668 | __le16 phy_flags; | ||
669 | u8 reserved1; | ||
670 | u8 rate; | ||
671 | __le16 len; | ||
672 | u8 payload[0]; | ||
673 | } __attribute__ ((packed)); | ||
674 | |||
675 | #define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0) | ||
676 | #define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1) | ||
677 | |||
678 | #define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0) | ||
679 | #define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) | ||
680 | #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) | ||
681 | #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) | ||
682 | #define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0) | ||
683 | |||
684 | #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) | ||
685 | #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) | ||
686 | #define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) | ||
687 | #define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) | ||
688 | #define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) | ||
689 | |||
690 | #define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) | ||
691 | #define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) | ||
692 | #define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) | ||
693 | #define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) | ||
694 | #define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) | ||
695 | |||
696 | struct iwl3945_rx_frame_end { | ||
697 | __le32 status; | ||
698 | __le64 timestamp; | ||
699 | __le32 beacon_timestamp; | ||
700 | } __attribute__ ((packed)); | ||
701 | |||
702 | /* | ||
703 | * REPLY_3945_RX = 0x1b (response only, not a command) | ||
704 | * | ||
705 | * NOTE: DO NOT dereference from casts to this structure | ||
706 | * It is provided only for calculating minimum data set size. | ||
707 | * The actual offsets of the hdr and end are dynamic based on | ||
708 | * stats.phy_count | ||
709 | */ | ||
710 | struct iwl3945_rx_frame { | ||
711 | struct iwl3945_rx_frame_stats stats; | ||
712 | struct iwl3945_rx_frame_hdr hdr; | ||
713 | struct iwl3945_rx_frame_end end; | ||
714 | } __attribute__ ((packed)); | ||
715 | |||
716 | /****************************************************************************** | ||
717 | * (5) | ||
718 | * Tx Commands & Responses: | ||
719 | * | ||
720 | * Driver must place each REPLY_TX command into one of the prioritized Tx | ||
721 | * queues in host DRAM, shared between driver and device. When the device's | ||
722 | * Tx scheduler and uCode are preparing to transmit, the device pulls the | ||
723 | * Tx command over the PCI bus via one of the device's Tx DMA channels, | ||
724 | * to fill an internal FIFO from which data will be transmitted. | ||
725 | * | ||
726 | * uCode handles all timing and protocol related to control frames | ||
727 | * (RTS/CTS/ACK), based on flags in the Tx command. | ||
728 | * | ||
729 | * uCode handles retrying Tx when an ACK is expected but not received. | ||
730 | * This includes trying lower data rates than the one requested in the Tx | ||
731 | * command, as set up by the REPLY_RATE_SCALE (for 3945) or | ||
732 | * REPLY_TX_LINK_QUALITY_CMD (4965). | ||
733 | * | ||
734 | * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD. | ||
735 | * This command must be executed after every RXON command, before Tx can occur. | ||
736 | *****************************************************************************/ | ||
737 | |||
738 | /* REPLY_TX Tx flags field */ | ||
739 | |||
740 | /* 1: Use Request-To-Send protocol before this frame. | ||
741 | * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ | ||
742 | #define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1) | ||
743 | |||
744 | /* 1: Transmit Clear-To-Send to self before this frame. | ||
745 | * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. | ||
746 | * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ | ||
747 | #define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2) | ||
748 | |||
749 | /* 1: Expect ACK from receiving station | ||
750 | * 0: Don't expect ACK (MAC header's duration field s/b 0) | ||
751 | * Set this for unicast frames, but not broadcast/multicast. */ | ||
752 | #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) | ||
753 | |||
754 | /* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). | ||
755 | * Tx command's initial_rate_index indicates first rate to try; | ||
756 | * uCode walks through table for additional Tx attempts. | ||
757 | * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. | ||
758 | * This rate will be used for all Tx attempts; it will not be scaled. */ | ||
759 | #define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4) | ||
760 | |||
761 | /* 1: Expect immediate block-ack. | ||
762 | * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ | ||
763 | #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6) | ||
764 | |||
765 | /* 1: Frame requires full Tx-Op protection. | ||
766 | * Set this if either RTS or CTS Tx Flag gets set. */ | ||
767 | #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) | ||
768 | |||
769 | /* Tx antenna selection field; used only for 3945, reserved (0) for 4965. | ||
770 | * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ | ||
771 | #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) | ||
772 | #define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8) | ||
773 | #define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9) | ||
774 | |||
775 | /* 1: Ignore Bluetooth priority for this frame. | ||
776 | * 0: Delay Tx until Bluetooth device is done (normal usage). */ | ||
777 | #define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12) | ||
778 | |||
779 | /* 1: uCode overrides sequence control field in MAC header. | ||
780 | * 0: Driver provides sequence control field in MAC header. | ||
781 | * Set this for management frames, non-QOS data frames, non-unicast frames, | ||
782 | * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ | ||
783 | #define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13) | ||
784 | |||
785 | /* 1: This frame is non-last MPDU; more fragments are coming. | ||
786 | * 0: Last fragment, or not using fragmentation. */ | ||
787 | #define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14) | ||
788 | |||
789 | /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. | ||
790 | * 0: No TSF required in outgoing frame. | ||
791 | * Set this for transmitting beacons and probe responses. */ | ||
792 | #define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16) | ||
793 | |||
794 | /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword | ||
795 | * alignment of frame's payload data field. | ||
796 | * 0: No pad | ||
797 | * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 | ||
798 | * field (but not both). Driver must align frame data (i.e. data following | ||
799 | * MAC header) to DWORD boundary. */ | ||
800 | #define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20) | ||
801 | |||
802 | /* HCCA-AP - disable duration overwriting. */ | ||
803 | #define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25) | ||
804 | |||
805 | /* | ||
806 | * TX command security control | ||
807 | */ | ||
808 | #define TX_CMD_SEC_WEP 0x01 | ||
809 | #define TX_CMD_SEC_CCM 0x02 | ||
810 | #define TX_CMD_SEC_TKIP 0x03 | ||
811 | #define TX_CMD_SEC_MSK 0x03 | ||
812 | #define TX_CMD_SEC_SHIFT 6 | ||
813 | #define TX_CMD_SEC_KEY128 0x08 | ||
814 | |||
815 | /* | ||
816 | * REPLY_TX = 0x1c (command) | ||
817 | */ | ||
818 | struct iwl3945_tx_cmd { | ||
819 | /* | ||
820 | * MPDU byte count: | ||
821 | * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, | ||
822 | * + 8 byte IV for CCM or TKIP (not used for WEP) | ||
823 | * + Data payload | ||
824 | * + 8-byte MIC (not used for CCM/WEP) | ||
825 | * NOTE: Does not include Tx command bytes, post-MAC pad bytes, | ||
826 | * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i | ||
827 | * Range: 14-2342 bytes. | ||
828 | */ | ||
829 | __le16 len; | ||
830 | |||
831 | /* | ||
832 | * MPDU or MSDU byte count for next frame. | ||
833 | * Used for fragmentation and bursting, but not 11n aggregation. | ||
834 | * Same as "len", but for next frame. Set to 0 if not applicable. | ||
835 | */ | ||
836 | __le16 next_frame_len; | ||
837 | |||
838 | __le32 tx_flags; /* TX_CMD_FLG_* */ | ||
839 | |||
840 | u8 rate; | ||
841 | |||
842 | /* Index of recipient station in uCode's station table */ | ||
843 | u8 sta_id; | ||
844 | u8 tid_tspec; | ||
845 | u8 sec_ctl; | ||
846 | u8 key[16]; | ||
847 | union { | ||
848 | u8 byte[8]; | ||
849 | __le16 word[4]; | ||
850 | __le32 dw[2]; | ||
851 | } tkip_mic; | ||
852 | __le32 next_frame_info; | ||
853 | union { | ||
854 | __le32 life_time; | ||
855 | __le32 attempt; | ||
856 | } stop_time; | ||
857 | u8 supp_rates[2]; | ||
858 | u8 rts_retry_limit; /*byte 50 */ | ||
859 | u8 data_retry_limit; /*byte 51 */ | ||
860 | union { | ||
861 | __le16 pm_frame_timeout; | ||
862 | __le16 attempt_duration; | ||
863 | } timeout; | ||
864 | |||
865 | /* | ||
866 | * Duration of EDCA burst Tx Opportunity, in 32-usec units. | ||
867 | * Set this if txop time is not specified by HCCA protocol (e.g. by AP). | ||
868 | */ | ||
869 | __le16 driver_txop; | ||
870 | |||
871 | /* | ||
872 | * MAC header goes here, followed by 2 bytes padding if MAC header | ||
873 | * length is 26 or 30 bytes, followed by payload data | ||
874 | */ | ||
875 | u8 payload[0]; | ||
876 | struct ieee80211_hdr hdr[0]; | ||
877 | } __attribute__ ((packed)); | ||
878 | |||
879 | /* TX command response is sent after *all* transmission attempts. | ||
880 | * | ||
881 | * NOTES: | ||
882 | * | ||
883 | * TX_STATUS_FAIL_NEXT_FRAG | ||
884 | * | ||
885 | * If the fragment flag in the MAC header for the frame being transmitted | ||
886 | * is set and there is insufficient time to transmit the next frame, the | ||
887 | * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'. | ||
888 | * | ||
889 | * TX_STATUS_FIFO_UNDERRUN | ||
890 | * | ||
891 | * Indicates the host did not provide bytes to the FIFO fast enough while | ||
892 | * a TX was in progress. | ||
893 | * | ||
894 | * TX_STATUS_FAIL_MGMNT_ABORT | ||
895 | * | ||
896 | * This status is only possible if the ABORT ON MGMT RX parameter was | ||
897 | * set to true with the TX command. | ||
898 | * | ||
899 | * If the MSB of the status parameter is set then an abort sequence is | ||
900 | * required. This sequence consists of the host activating the TX Abort | ||
901 | * control line, and then waiting for the TX Abort command response. This | ||
902 | * indicates that a the device is no longer in a transmit state, and that the | ||
903 | * command FIFO has been cleared. The host must then deactivate the TX Abort | ||
904 | * control line. Receiving is still allowed in this case. | ||
905 | */ | ||
906 | enum { | ||
907 | TX_STATUS_SUCCESS = 0x01, | ||
908 | TX_STATUS_DIRECT_DONE = 0x02, | ||
909 | TX_STATUS_FAIL_SHORT_LIMIT = 0x82, | ||
910 | TX_STATUS_FAIL_LONG_LIMIT = 0x83, | ||
911 | TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, | ||
912 | TX_STATUS_FAIL_MGMNT_ABORT = 0x85, | ||
913 | TX_STATUS_FAIL_NEXT_FRAG = 0x86, | ||
914 | TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, | ||
915 | TX_STATUS_FAIL_DEST_PS = 0x88, | ||
916 | TX_STATUS_FAIL_ABORTED = 0x89, | ||
917 | TX_STATUS_FAIL_BT_RETRY = 0x8a, | ||
918 | TX_STATUS_FAIL_STA_INVALID = 0x8b, | ||
919 | TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, | ||
920 | TX_STATUS_FAIL_TID_DISABLE = 0x8d, | ||
921 | TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e, | ||
922 | TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, | ||
923 | TX_STATUS_FAIL_TX_LOCKED = 0x90, | ||
924 | TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, | ||
925 | }; | ||
926 | |||
927 | #define TX_PACKET_MODE_REGULAR 0x0000 | ||
928 | #define TX_PACKET_MODE_BURST_SEQ 0x0100 | ||
929 | #define TX_PACKET_MODE_BURST_FIRST 0x0200 | ||
930 | |||
931 | enum { | ||
932 | TX_POWER_PA_NOT_ACTIVE = 0x0, | ||
933 | }; | ||
934 | |||
935 | enum { | ||
936 | TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ | ||
937 | TX_STATUS_DELAY_MSK = 0x00000040, | ||
938 | TX_STATUS_ABORT_MSK = 0x00000080, | ||
939 | TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ | ||
940 | TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ | ||
941 | TX_RESERVED = 0x00780000, /* bits 19:22 */ | ||
942 | TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ | ||
943 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ | ||
944 | }; | ||
945 | |||
946 | /* | ||
947 | * REPLY_TX = 0x1c (response) | ||
948 | */ | ||
949 | struct iwl3945_tx_resp { | ||
950 | u8 failure_rts; | ||
951 | u8 failure_frame; | ||
952 | u8 bt_kill_count; | ||
953 | u8 rate; | ||
954 | __le32 wireless_media_time; | ||
955 | __le32 status; /* TX status */ | ||
956 | } __attribute__ ((packed)); | ||
957 | |||
958 | /* | ||
959 | * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) | ||
960 | */ | ||
961 | struct iwl3945_txpowertable_cmd { | ||
962 | u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ | ||
963 | u8 reserved; | ||
964 | __le16 channel; | ||
965 | struct iwl3945_power_per_rate power[IWL_MAX_RATES]; | ||
966 | } __attribute__ ((packed)); | ||
967 | |||
968 | struct iwl3945_rate_scaling_info { | ||
969 | __le16 rate_n_flags; | ||
970 | u8 try_cnt; | ||
971 | u8 next_rate_index; | ||
972 | } __attribute__ ((packed)); | ||
973 | |||
974 | /** | ||
975 | * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response | ||
976 | * | ||
977 | * REPLY_RATE_SCALE = 0x47 (command, has simple generic response) | ||
978 | * | ||
979 | * NOTE: The table of rates passed to the uCode via the | ||
980 | * RATE_SCALE command sets up the corresponding order of | ||
981 | * rates used for all related commands, including rate | ||
982 | * masks, etc. | ||
983 | * | ||
984 | * For example, if you set 9MB (PLCP 0x0f) as the first | ||
985 | * rate in the rate table, the bit mask for that rate | ||
986 | * when passed through ofdm_basic_rates on the REPLY_RXON | ||
987 | * command would be bit 0 (1 << 0) | ||
988 | */ | ||
989 | struct iwl3945_rate_scaling_cmd { | ||
990 | u8 table_id; | ||
991 | u8 reserved[3]; | ||
992 | struct iwl3945_rate_scaling_info table[IWL_MAX_RATES]; | ||
993 | } __attribute__ ((packed)); | ||
994 | |||
995 | /* | ||
996 | * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) | ||
997 | * | ||
998 | * 3945 and 4965 support hardware handshake with Bluetooth device on | ||
999 | * same platform. Bluetooth device alerts wireless device when it will Tx; | ||
1000 | * wireless device can delay or kill its own Tx to accommodate. | ||
1001 | */ | ||
1002 | struct iwl3945_bt_cmd { | ||
1003 | u8 flags; | ||
1004 | u8 lead_time; | ||
1005 | u8 max_kill; | ||
1006 | u8 reserved; | ||
1007 | __le32 kill_ack_mask; | ||
1008 | __le32 kill_cts_mask; | ||
1009 | } __attribute__ ((packed)); | ||
1010 | |||
1011 | /****************************************************************************** | ||
1012 | * (6) | ||
1013 | * Spectrum Management (802.11h) Commands, Responses, Notifications: | ||
1014 | * | ||
1015 | *****************************************************************************/ | ||
1016 | |||
1017 | /* | ||
1018 | * Spectrum Management | ||
1019 | */ | ||
1020 | #define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \ | ||
1021 | RXON_FILTER_CTL2HOST_MSK | \ | ||
1022 | RXON_FILTER_ACCEPT_GRP_MSK | \ | ||
1023 | RXON_FILTER_DIS_DECRYPT_MSK | \ | ||
1024 | RXON_FILTER_DIS_GRP_DECRYPT_MSK | \ | ||
1025 | RXON_FILTER_ASSOC_MSK | \ | ||
1026 | RXON_FILTER_BCON_AWARE_MSK) | ||
1027 | |||
1028 | struct iwl3945_measure_channel { | ||
1029 | __le32 duration; /* measurement duration in extended beacon | ||
1030 | * format */ | ||
1031 | u8 channel; /* channel to measure */ | ||
1032 | u8 type; /* see enum iwl3945_measure_type */ | ||
1033 | __le16 reserved; | ||
1034 | } __attribute__ ((packed)); | ||
1035 | |||
1036 | /* | ||
1037 | * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) | ||
1038 | */ | ||
1039 | struct iwl3945_spectrum_cmd { | ||
1040 | __le16 len; /* number of bytes starting from token */ | ||
1041 | u8 token; /* token id */ | ||
1042 | u8 id; /* measurement id -- 0 or 1 */ | ||
1043 | u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */ | ||
1044 | u8 periodic; /* 1 = periodic */ | ||
1045 | __le16 path_loss_timeout; | ||
1046 | __le32 start_time; /* start time in extended beacon format */ | ||
1047 | __le32 reserved2; | ||
1048 | __le32 flags; /* rxon flags */ | ||
1049 | __le32 filter_flags; /* rxon filter flags */ | ||
1050 | __le16 channel_count; /* minimum 1, maximum 10 */ | ||
1051 | __le16 reserved3; | ||
1052 | struct iwl3945_measure_channel channels[10]; | ||
1053 | } __attribute__ ((packed)); | ||
1054 | |||
1055 | /* | ||
1056 | * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) | ||
1057 | */ | ||
1058 | struct iwl3945_spectrum_resp { | ||
1059 | u8 token; | ||
1060 | u8 id; /* id of the prior command replaced, or 0xff */ | ||
1061 | __le16 status; /* 0 - command will be handled | ||
1062 | * 1 - cannot handle (conflicts with another | ||
1063 | * measurement) */ | ||
1064 | } __attribute__ ((packed)); | ||
1065 | |||
1066 | enum iwl3945_measurement_state { | ||
1067 | IWL_MEASUREMENT_START = 0, | ||
1068 | IWL_MEASUREMENT_STOP = 1, | ||
1069 | }; | ||
1070 | |||
1071 | enum iwl3945_measurement_status { | ||
1072 | IWL_MEASUREMENT_OK = 0, | ||
1073 | IWL_MEASUREMENT_CONCURRENT = 1, | ||
1074 | IWL_MEASUREMENT_CSA_CONFLICT = 2, | ||
1075 | IWL_MEASUREMENT_TGH_CONFLICT = 3, | ||
1076 | /* 4-5 reserved */ | ||
1077 | IWL_MEASUREMENT_STOPPED = 6, | ||
1078 | IWL_MEASUREMENT_TIMEOUT = 7, | ||
1079 | IWL_MEASUREMENT_PERIODIC_FAILED = 8, | ||
1080 | }; | ||
1081 | |||
1082 | #define NUM_ELEMENTS_IN_HISTOGRAM 8 | ||
1083 | |||
1084 | struct iwl3945_measurement_histogram { | ||
1085 | __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ | ||
1086 | __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ | ||
1087 | } __attribute__ ((packed)); | ||
1088 | |||
1089 | /* clear channel availability counters */ | ||
1090 | struct iwl3945_measurement_cca_counters { | ||
1091 | __le32 ofdm; | ||
1092 | __le32 cck; | ||
1093 | } __attribute__ ((packed)); | ||
1094 | |||
1095 | enum iwl3945_measure_type { | ||
1096 | IWL_MEASURE_BASIC = (1 << 0), | ||
1097 | IWL_MEASURE_CHANNEL_LOAD = (1 << 1), | ||
1098 | IWL_MEASURE_HISTOGRAM_RPI = (1 << 2), | ||
1099 | IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3), | ||
1100 | IWL_MEASURE_FRAME = (1 << 4), | ||
1101 | /* bits 5:6 are reserved */ | ||
1102 | IWL_MEASURE_IDLE = (1 << 7), | ||
1103 | }; | ||
1104 | |||
1105 | /* | ||
1106 | * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command) | ||
1107 | */ | ||
1108 | struct iwl3945_spectrum_notification { | ||
1109 | u8 id; /* measurement id -- 0 or 1 */ | ||
1110 | u8 token; | ||
1111 | u8 channel_index; /* index in measurement channel list */ | ||
1112 | u8 state; /* 0 - start, 1 - stop */ | ||
1113 | __le32 start_time; /* lower 32-bits of TSF */ | ||
1114 | u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */ | ||
1115 | u8 channel; | ||
1116 | u8 type; /* see enum iwl3945_measurement_type */ | ||
1117 | u8 reserved1; | ||
1118 | /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only | ||
1119 | * valid if applicable for measurement type requested. */ | ||
1120 | __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ | ||
1121 | __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ | ||
1122 | __le32 cca_time; /* channel load time in usecs */ | ||
1123 | u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 - | ||
1124 | * unidentified */ | ||
1125 | u8 reserved2[3]; | ||
1126 | struct iwl3945_measurement_histogram histogram; | ||
1127 | __le32 stop_time; /* lower 32-bits of TSF */ | ||
1128 | __le32 status; /* see iwl3945_measurement_status */ | ||
1129 | } __attribute__ ((packed)); | ||
1130 | |||
1131 | /****************************************************************************** | ||
1132 | * (7) | ||
1133 | * Power Management Commands, Responses, Notifications: | ||
1134 | * | ||
1135 | *****************************************************************************/ | ||
1136 | |||
1137 | /** | ||
1138 | * struct iwl3945_powertable_cmd - Power Table Command | ||
1139 | * @flags: See below: | ||
1140 | * | ||
1141 | * POWER_TABLE_CMD = 0x77 (command, has simple generic response) | ||
1142 | * | ||
1143 | * PM allow: | ||
1144 | * bit 0 - '0' Driver not allow power management | ||
1145 | * '1' Driver allow PM (use rest of parameters) | ||
1146 | * uCode send sleep notifications: | ||
1147 | * bit 1 - '0' Don't send sleep notification | ||
1148 | * '1' send sleep notification (SEND_PM_NOTIFICATION) | ||
1149 | * Sleep over DTIM | ||
1150 | * bit 2 - '0' PM have to walk up every DTIM | ||
1151 | * '1' PM could sleep over DTIM till listen Interval. | ||
1152 | * PCI power managed | ||
1153 | * bit 3 - '0' (PCI_LINK_CTRL & 0x1) | ||
1154 | * '1' !(PCI_LINK_CTRL & 0x1) | ||
1155 | * Force sleep Modes | ||
1156 | * bit 31/30- '00' use both mac/xtal sleeps | ||
1157 | * '01' force Mac sleep | ||
1158 | * '10' force xtal sleep | ||
1159 | * '11' Illegal set | ||
1160 | * | ||
1161 | * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then | ||
1162 | * ucode assume sleep over DTIM is allowed and we don't need to wakeup | ||
1163 | * for every DTIM. | ||
1164 | */ | ||
1165 | #define IWL_POWER_VEC_SIZE 5 | ||
1166 | |||
1167 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le32(1 << 0) | ||
1168 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le32(1 << 2) | ||
1169 | #define IWL_POWER_PCI_PM_MSK cpu_to_le32(1 << 3) | ||
1170 | struct iwl3945_powertable_cmd { | ||
1171 | __le32 flags; | ||
1172 | __le32 rx_data_timeout; | ||
1173 | __le32 tx_data_timeout; | ||
1174 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; | ||
1175 | } __attribute__((packed)); | ||
1176 | |||
1177 | /* | ||
1178 | * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) | ||
1179 | * 3945 and 4965 identical. | ||
1180 | */ | ||
1181 | struct iwl3945_sleep_notification { | ||
1182 | u8 pm_sleep_mode; | ||
1183 | u8 pm_wakeup_src; | ||
1184 | __le16 reserved; | ||
1185 | __le32 sleep_time; | ||
1186 | __le32 tsf_low; | ||
1187 | __le32 bcon_timer; | ||
1188 | } __attribute__ ((packed)); | ||
1189 | |||
1190 | /* Sleep states. 3945 and 4965 identical. */ | ||
1191 | enum { | ||
1192 | IWL_PM_NO_SLEEP = 0, | ||
1193 | IWL_PM_SLP_MAC = 1, | ||
1194 | IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2, | ||
1195 | IWL_PM_SLP_FULL_MAC_CARD_STATE = 3, | ||
1196 | IWL_PM_SLP_PHY = 4, | ||
1197 | IWL_PM_SLP_REPENT = 5, | ||
1198 | IWL_PM_WAKEUP_BY_TIMER = 6, | ||
1199 | IWL_PM_WAKEUP_BY_DRIVER = 7, | ||
1200 | IWL_PM_WAKEUP_BY_RFKILL = 8, | ||
1201 | /* 3 reserved */ | ||
1202 | IWL_PM_NUM_OF_MODES = 12, | ||
1203 | }; | ||
1204 | |||
1205 | /* | ||
1206 | * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response) | ||
1207 | */ | ||
1208 | #define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */ | ||
1209 | #define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */ | ||
1210 | #define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */ | ||
1211 | struct iwl3945_card_state_cmd { | ||
1212 | __le32 status; /* CARD_STATE_CMD_* request new power state */ | ||
1213 | } __attribute__ ((packed)); | ||
1214 | |||
1215 | /* | ||
1216 | * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) | ||
1217 | */ | ||
1218 | struct iwl3945_card_state_notif { | ||
1219 | __le32 flags; | ||
1220 | } __attribute__ ((packed)); | ||
1221 | |||
1222 | #define HW_CARD_DISABLED 0x01 | ||
1223 | #define SW_CARD_DISABLED 0x02 | ||
1224 | #define RF_CARD_DISABLED 0x04 | ||
1225 | #define RXON_CARD_DISABLED 0x10 | ||
1226 | |||
1227 | struct iwl3945_ct_kill_config { | ||
1228 | __le32 reserved; | ||
1229 | __le32 critical_temperature_M; | ||
1230 | __le32 critical_temperature_R; | ||
1231 | } __attribute__ ((packed)); | ||
1232 | |||
1233 | /****************************************************************************** | ||
1234 | * (8) | ||
1235 | * Scan Commands, Responses, Notifications: | ||
1236 | * | ||
1237 | *****************************************************************************/ | ||
1238 | |||
1239 | /** | ||
1240 | * struct iwl3945_scan_channel - entry in REPLY_SCAN_CMD channel table | ||
1241 | * | ||
1242 | * One for each channel in the scan list. | ||
1243 | * Each channel can independently select: | ||
1244 | * 1) SSID for directed active scans | ||
1245 | * 2) Txpower setting (for rate specified within Tx command) | ||
1246 | * 3) How long to stay on-channel (behavior may be modified by quiet_time, | ||
1247 | * quiet_plcp_th, good_CRC_th) | ||
1248 | * | ||
1249 | * To avoid uCode errors, make sure the following are true (see comments | ||
1250 | * under struct iwl3945_scan_cmd about max_out_time and quiet_time): | ||
1251 | * 1) If using passive_dwell (i.e. passive_dwell != 0): | ||
1252 | * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) | ||
1253 | * 2) quiet_time <= active_dwell | ||
1254 | * 3) If restricting off-channel time (i.e. max_out_time !=0): | ||
1255 | * passive_dwell < max_out_time | ||
1256 | * active_dwell < max_out_time | ||
1257 | */ | ||
1258 | struct iwl3945_scan_channel { | ||
1259 | /* | ||
1260 | * type is defined as: | ||
1261 | * 0:0 1 = active, 0 = passive | ||
1262 | * 1:4 SSID direct bit map; if a bit is set, then corresponding | ||
1263 | * SSID IE is transmitted in probe request. | ||
1264 | * 5:7 reserved | ||
1265 | */ | ||
1266 | u8 type; | ||
1267 | u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */ | ||
1268 | struct iwl3945_tx_power tpc; | ||
1269 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ | ||
1270 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ | ||
1271 | } __attribute__ ((packed)); | ||
1272 | |||
1273 | /** | ||
1274 | * struct iwl3945_ssid_ie - directed scan network information element | ||
1275 | * | ||
1276 | * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field | ||
1277 | * in struct iwl3945_scan_channel; each channel may select different ssids from | ||
1278 | * among the 4 entries. SSID IEs get transmitted in reverse order of entry. | ||
1279 | */ | ||
1280 | struct iwl3945_ssid_ie { | ||
1281 | u8 id; | ||
1282 | u8 len; | ||
1283 | u8 ssid[32]; | ||
1284 | } __attribute__ ((packed)); | ||
1285 | |||
1286 | #define PROBE_OPTION_MAX 0x4 | ||
1287 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) | ||
1288 | #define IWL_GOOD_CRC_TH cpu_to_le16(1) | ||
1289 | #define IWL_MAX_SCAN_SIZE 1024 | ||
1290 | |||
1291 | /* | ||
1292 | * REPLY_SCAN_CMD = 0x80 (command) | ||
1293 | * | ||
1294 | * The hardware scan command is very powerful; the driver can set it up to | ||
1295 | * maintain (relatively) normal network traffic while doing a scan in the | ||
1296 | * background. The max_out_time and suspend_time control the ratio of how | ||
1297 | * long the device stays on an associated network channel ("service channel") | ||
1298 | * vs. how long it's away from the service channel, tuned to other channels | ||
1299 | * for scanning. | ||
1300 | * | ||
1301 | * max_out_time is the max time off-channel (in usec), and suspend_time | ||
1302 | * is how long (in "extended beacon" format) that the scan is "suspended" | ||
1303 | * after returning to the service channel. That is, suspend_time is the | ||
1304 | * time that we stay on the service channel, doing normal work, between | ||
1305 | * scan segments. The driver may set these parameters differently to support | ||
1306 | * scanning when associated vs. not associated, and light vs. heavy traffic | ||
1307 | * loads when associated. | ||
1308 | * | ||
1309 | * After receiving this command, the device's scan engine does the following; | ||
1310 | * | ||
1311 | * 1) Sends SCAN_START notification to driver | ||
1312 | * 2) Checks to see if it has time to do scan for one channel | ||
1313 | * 3) Sends NULL packet, with power-save (PS) bit set to 1, | ||
1314 | * to tell AP that we're going off-channel | ||
1315 | * 4) Tunes to first channel in scan list, does active or passive scan | ||
1316 | * 5) Sends SCAN_RESULT notification to driver | ||
1317 | * 6) Checks to see if it has time to do scan on *next* channel in list | ||
1318 | * 7) Repeats 4-6 until it no longer has time to scan the next channel | ||
1319 | * before max_out_time expires | ||
1320 | * 8) Returns to service channel | ||
1321 | * 9) Sends NULL packet with PS=0 to tell AP that we're back | ||
1322 | * 10) Stays on service channel until suspend_time expires | ||
1323 | * 11) Repeats entire process 2-10 until list is complete | ||
1324 | * 12) Sends SCAN_COMPLETE notification | ||
1325 | * | ||
1326 | * For fast, efficient scans, the scan command also has support for staying on | ||
1327 | * a channel for just a short time, if doing active scanning and getting no | ||
1328 | * responses to the transmitted probe request. This time is controlled by | ||
1329 | * quiet_time, and the number of received packets below which a channel is | ||
1330 | * considered "quiet" is controlled by quiet_plcp_threshold. | ||
1331 | * | ||
1332 | * For active scanning on channels that have regulatory restrictions against | ||
1333 | * blindly transmitting, the scan can listen before transmitting, to make sure | ||
1334 | * that there is already legitimate activity on the channel. If enough | ||
1335 | * packets are cleanly received on the channel (controlled by good_CRC_th, | ||
1336 | * typical value 1), the scan engine starts transmitting probe requests. | ||
1337 | * | ||
1338 | * Driver must use separate scan commands for 2.4 vs. 5 GHz bands. | ||
1339 | * | ||
1340 | * To avoid uCode errors, see timing restrictions described under | ||
1341 | * struct iwl3945_scan_channel. | ||
1342 | */ | ||
1343 | struct iwl3945_scan_cmd { | ||
1344 | __le16 len; | ||
1345 | u8 reserved0; | ||
1346 | u8 channel_count; /* # channels in channel list */ | ||
1347 | __le16 quiet_time; /* dwell only this # millisecs on quiet channel | ||
1348 | * (only for active scan) */ | ||
1349 | __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ | ||
1350 | __le16 good_CRC_th; /* passive -> active promotion threshold */ | ||
1351 | __le16 reserved1; | ||
1352 | __le32 max_out_time; /* max usec to be away from associated (service) | ||
1353 | * channel */ | ||
1354 | __le32 suspend_time; /* pause scan this long (in "extended beacon | ||
1355 | * format") when returning to service channel: | ||
1356 | * 3945; 31:24 # beacons, 19:0 additional usec, | ||
1357 | * 4965; 31:22 # beacons, 21:0 additional usec. | ||
1358 | */ | ||
1359 | __le32 flags; /* RXON_FLG_* */ | ||
1360 | __le32 filter_flags; /* RXON_FILTER_* */ | ||
1361 | |||
1362 | /* For active scans (set to all-0s for passive scans). | ||
1363 | * Does not include payload. Must specify Tx rate; no rate scaling. */ | ||
1364 | struct iwl3945_tx_cmd tx_cmd; | ||
1365 | |||
1366 | /* For directed active scans (set to all-0s otherwise) */ | ||
1367 | struct iwl3945_ssid_ie direct_scan[PROBE_OPTION_MAX]; | ||
1368 | |||
1369 | /* | ||
1370 | * Probe request frame, followed by channel list. | ||
1371 | * | ||
1372 | * Size of probe request frame is specified by byte count in tx_cmd. | ||
1373 | * Channel list follows immediately after probe request frame. | ||
1374 | * Number of channels in list is specified by channel_count. | ||
1375 | * Each channel in list is of type: | ||
1376 | * | ||
1377 | * struct iwl3945_scan_channel channels[0]; | ||
1378 | * | ||
1379 | * NOTE: Only one band of channels can be scanned per pass. You | ||
1380 | * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait | ||
1381 | * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) | ||
1382 | * before requesting another scan. | ||
1383 | */ | ||
1384 | u8 data[0]; | ||
1385 | } __attribute__ ((packed)); | ||
1386 | |||
1387 | /* Can abort will notify by complete notification with abort status. */ | ||
1388 | #define CAN_ABORT_STATUS cpu_to_le32(0x1) | ||
1389 | /* complete notification statuses */ | ||
1390 | #define ABORT_STATUS 0x2 | ||
1391 | |||
1392 | /* | ||
1393 | * REPLY_SCAN_CMD = 0x80 (response) | ||
1394 | */ | ||
1395 | struct iwl3945_scanreq_notification { | ||
1396 | __le32 status; /* 1: okay, 2: cannot fulfill request */ | ||
1397 | } __attribute__ ((packed)); | ||
1398 | |||
1399 | /* | ||
1400 | * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) | ||
1401 | */ | ||
1402 | struct iwl3945_scanstart_notification { | ||
1403 | __le32 tsf_low; | ||
1404 | __le32 tsf_high; | ||
1405 | __le32 beacon_timer; | ||
1406 | u8 channel; | ||
1407 | u8 band; | ||
1408 | u8 reserved[2]; | ||
1409 | __le32 status; | ||
1410 | } __attribute__ ((packed)); | ||
1411 | |||
1412 | #define SCAN_OWNER_STATUS 0x1; | ||
1413 | #define MEASURE_OWNER_STATUS 0x2; | ||
1414 | |||
1415 | #define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ | ||
1416 | /* | ||
1417 | * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) | ||
1418 | */ | ||
1419 | struct iwl3945_scanresults_notification { | ||
1420 | u8 channel; | ||
1421 | u8 band; | ||
1422 | u8 reserved[2]; | ||
1423 | __le32 tsf_low; | ||
1424 | __le32 tsf_high; | ||
1425 | __le32 statistics[NUMBER_OF_STATISTICS]; | ||
1426 | } __attribute__ ((packed)); | ||
1427 | |||
1428 | /* | ||
1429 | * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) | ||
1430 | */ | ||
1431 | struct iwl3945_scancomplete_notification { | ||
1432 | u8 scanned_channels; | ||
1433 | u8 status; | ||
1434 | u8 reserved; | ||
1435 | u8 last_channel; | ||
1436 | __le32 tsf_low; | ||
1437 | __le32 tsf_high; | ||
1438 | } __attribute__ ((packed)); | ||
1439 | |||
1440 | |||
1441 | /****************************************************************************** | ||
1442 | * (9) | ||
1443 | * IBSS/AP Commands and Notifications: | ||
1444 | * | ||
1445 | *****************************************************************************/ | ||
1446 | |||
1447 | /* | ||
1448 | * BEACON_NOTIFICATION = 0x90 (notification only, not a command) | ||
1449 | */ | ||
1450 | struct iwl3945_beacon_notif { | ||
1451 | struct iwl3945_tx_resp beacon_notify_hdr; | ||
1452 | __le32 low_tsf; | ||
1453 | __le32 high_tsf; | ||
1454 | __le32 ibss_mgr_status; | ||
1455 | } __attribute__ ((packed)); | ||
1456 | |||
1457 | /* | ||
1458 | * REPLY_TX_BEACON = 0x91 (command, has simple generic response) | ||
1459 | */ | ||
1460 | struct iwl3945_tx_beacon_cmd { | ||
1461 | struct iwl3945_tx_cmd tx; | ||
1462 | __le16 tim_idx; | ||
1463 | u8 tim_size; | ||
1464 | u8 reserved1; | ||
1465 | struct ieee80211_hdr frame[0]; /* beacon frame */ | ||
1466 | } __attribute__ ((packed)); | ||
1467 | |||
1468 | /****************************************************************************** | ||
1469 | * (10) | ||
1470 | * Statistics Commands and Notifications: | ||
1471 | * | ||
1472 | *****************************************************************************/ | ||
1473 | |||
1474 | #define IWL_TEMP_CONVERT 260 | ||
1475 | |||
1476 | #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 | ||
1477 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 | ||
1478 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 | ||
1479 | |||
1480 | /* Used for passing to driver number of successes and failures per rate */ | ||
1481 | struct rate_histogram { | ||
1482 | union { | ||
1483 | __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; | ||
1484 | __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; | ||
1485 | __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; | ||
1486 | } success; | ||
1487 | union { | ||
1488 | __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; | ||
1489 | __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; | ||
1490 | __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; | ||
1491 | } failed; | ||
1492 | } __attribute__ ((packed)); | ||
1493 | |||
1494 | /* statistics command response */ | ||
1495 | |||
1496 | struct statistics_rx_phy { | ||
1497 | __le32 ina_cnt; | ||
1498 | __le32 fina_cnt; | ||
1499 | __le32 plcp_err; | ||
1500 | __le32 crc32_err; | ||
1501 | __le32 overrun_err; | ||
1502 | __le32 early_overrun_err; | ||
1503 | __le32 crc32_good; | ||
1504 | __le32 false_alarm_cnt; | ||
1505 | __le32 fina_sync_err_cnt; | ||
1506 | __le32 sfd_timeout; | ||
1507 | __le32 fina_timeout; | ||
1508 | __le32 unresponded_rts; | ||
1509 | __le32 rxe_frame_limit_overrun; | ||
1510 | __le32 sent_ack_cnt; | ||
1511 | __le32 sent_cts_cnt; | ||
1512 | } __attribute__ ((packed)); | ||
1513 | |||
1514 | struct statistics_rx_non_phy { | ||
1515 | __le32 bogus_cts; /* CTS received when not expecting CTS */ | ||
1516 | __le32 bogus_ack; /* ACK received when not expecting ACK */ | ||
1517 | __le32 non_bssid_frames; /* number of frames with BSSID that | ||
1518 | * doesn't belong to the STA BSSID */ | ||
1519 | __le32 filtered_frames; /* count frames that were dumped in the | ||
1520 | * filtering process */ | ||
1521 | __le32 non_channel_beacons; /* beacons with our bss id but not on | ||
1522 | * our serving channel */ | ||
1523 | } __attribute__ ((packed)); | ||
1524 | |||
1525 | struct statistics_rx { | ||
1526 | struct statistics_rx_phy ofdm; | ||
1527 | struct statistics_rx_phy cck; | ||
1528 | struct statistics_rx_non_phy general; | ||
1529 | } __attribute__ ((packed)); | ||
1530 | |||
1531 | struct statistics_tx { | ||
1532 | __le32 preamble_cnt; | ||
1533 | __le32 rx_detected_cnt; | ||
1534 | __le32 bt_prio_defer_cnt; | ||
1535 | __le32 bt_prio_kill_cnt; | ||
1536 | __le32 few_bytes_cnt; | ||
1537 | __le32 cts_timeout; | ||
1538 | __le32 ack_timeout; | ||
1539 | __le32 expected_ack_cnt; | ||
1540 | __le32 actual_ack_cnt; | ||
1541 | } __attribute__ ((packed)); | ||
1542 | |||
1543 | struct statistics_dbg { | ||
1544 | __le32 burst_check; | ||
1545 | __le32 burst_count; | ||
1546 | __le32 reserved[4]; | ||
1547 | } __attribute__ ((packed)); | ||
1548 | |||
1549 | struct statistics_div { | ||
1550 | __le32 tx_on_a; | ||
1551 | __le32 tx_on_b; | ||
1552 | __le32 exec_time; | ||
1553 | __le32 probe_time; | ||
1554 | } __attribute__ ((packed)); | ||
1555 | |||
1556 | struct statistics_general { | ||
1557 | __le32 temperature; | ||
1558 | struct statistics_dbg dbg; | ||
1559 | __le32 sleep_time; | ||
1560 | __le32 slots_out; | ||
1561 | __le32 slots_idle; | ||
1562 | __le32 ttl_timestamp; | ||
1563 | struct statistics_div div; | ||
1564 | } __attribute__ ((packed)); | ||
1565 | |||
1566 | /* | ||
1567 | * REPLY_STATISTICS_CMD = 0x9c, | ||
1568 | * 3945 and 4965 identical. | ||
1569 | * | ||
1570 | * This command triggers an immediate response containing uCode statistics. | ||
1571 | * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. | ||
1572 | * | ||
1573 | * If the CLEAR_STATS configuration flag is set, uCode will clear its | ||
1574 | * internal copy of the statistics (counters) after issuing the response. | ||
1575 | * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below). | ||
1576 | * | ||
1577 | * If the DISABLE_NOTIF configuration flag is set, uCode will not issue | ||
1578 | * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag | ||
1579 | * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. | ||
1580 | */ | ||
1581 | #define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */ | ||
1582 | #define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */ | ||
1583 | struct iwl3945_statistics_cmd { | ||
1584 | __le32 configuration_flags; /* IWL_STATS_CONF_* */ | ||
1585 | } __attribute__ ((packed)); | ||
1586 | |||
1587 | /* | ||
1588 | * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) | ||
1589 | * | ||
1590 | * By default, uCode issues this notification after receiving a beacon | ||
1591 | * while associated. To disable this behavior, set DISABLE_NOTIF flag in the | ||
1592 | * REPLY_STATISTICS_CMD 0x9c, above. | ||
1593 | * | ||
1594 | * Statistics counters continue to increment beacon after beacon, but are | ||
1595 | * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD | ||
1596 | * 0x9c with CLEAR_STATS bit set (see above). | ||
1597 | * | ||
1598 | * uCode also issues this notification during scans. uCode clears statistics | ||
1599 | * appropriately so that each notification contains statistics for only the | ||
1600 | * one channel that has just been scanned. | ||
1601 | */ | ||
1602 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) | ||
1603 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8) | ||
1604 | struct iwl3945_notif_statistics { | ||
1605 | __le32 flag; | ||
1606 | struct statistics_rx rx; | ||
1607 | struct statistics_tx tx; | ||
1608 | struct statistics_general general; | ||
1609 | } __attribute__ ((packed)); | ||
1610 | |||
1611 | |||
1612 | /* | ||
1613 | * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) | ||
1614 | */ | ||
1615 | /* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, | ||
1616 | * then this notification will be sent. */ | ||
1617 | #define CONSECUTIVE_MISSED_BCONS_TH 20 | ||
1618 | |||
1619 | struct iwl3945_missed_beacon_notif { | ||
1620 | __le32 consequtive_missed_beacons; | ||
1621 | __le32 total_missed_becons; | ||
1622 | __le32 num_expected_beacons; | ||
1623 | __le32 num_recvd_beacons; | ||
1624 | } __attribute__ ((packed)); | ||
1625 | |||
1626 | /****************************************************************************** | ||
1627 | * (11) | ||
1628 | * Rx Calibration Commands: | ||
1629 | * | ||
1630 | *****************************************************************************/ | ||
1631 | |||
1632 | #define PHY_CALIBRATE_DIFF_GAIN_CMD (7) | ||
1633 | #define HD_TABLE_SIZE (11) | ||
1634 | |||
1635 | struct iwl3945_sensitivity_cmd { | ||
1636 | __le16 control; | ||
1637 | __le16 table[HD_TABLE_SIZE]; | ||
1638 | } __attribute__ ((packed)); | ||
1639 | |||
1640 | struct iwl3945_calibration_cmd { | ||
1641 | u8 opCode; | ||
1642 | u8 flags; | ||
1643 | __le16 reserved; | ||
1644 | s8 diff_gain_a; | ||
1645 | s8 diff_gain_b; | ||
1646 | s8 diff_gain_c; | ||
1647 | u8 reserved1; | ||
1648 | } __attribute__ ((packed)); | ||
1649 | |||
1650 | /****************************************************************************** | ||
1651 | * (12) | ||
1652 | * Miscellaneous Commands: | ||
1653 | * | ||
1654 | *****************************************************************************/ | ||
1655 | |||
1656 | /* | ||
1657 | * LEDs Command & Response | ||
1658 | * REPLY_LEDS_CMD = 0x48 (command, has simple generic response) | ||
1659 | * | ||
1660 | * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), | ||
1661 | * this command turns it on or off, or sets up a periodic blinking cycle. | ||
1662 | */ | ||
1663 | struct iwl3945_led_cmd { | ||
1664 | __le32 interval; /* "interval" in uSec */ | ||
1665 | u8 id; /* 1: Activity, 2: Link, 3: Tech */ | ||
1666 | u8 off; /* # intervals off while blinking; | ||
1667 | * "0", with >0 "on" value, turns LED on */ | ||
1668 | u8 on; /* # intervals on while blinking; | ||
1669 | * "0", regardless of "off", turns LED off */ | ||
1670 | u8 reserved; | ||
1671 | } __attribute__ ((packed)); | ||
1672 | |||
1673 | /****************************************************************************** | ||
1674 | * (13) | ||
1675 | * Union of all expected notifications/responses: | ||
1676 | * | ||
1677 | *****************************************************************************/ | ||
1678 | |||
1679 | struct iwl3945_rx_packet { | ||
1680 | __le32 len; | ||
1681 | struct iwl3945_cmd_header hdr; | ||
1682 | union { | ||
1683 | struct iwl3945_alive_resp alive_frame; | ||
1684 | struct iwl3945_rx_frame rx_frame; | ||
1685 | struct iwl3945_tx_resp tx_resp; | ||
1686 | struct iwl3945_spectrum_notification spectrum_notif; | ||
1687 | struct iwl3945_csa_notification csa_notif; | ||
1688 | struct iwl3945_error_resp err_resp; | ||
1689 | struct iwl3945_card_state_notif card_state_notif; | ||
1690 | struct iwl3945_beacon_notif beacon_status; | ||
1691 | struct iwl3945_add_sta_resp add_sta; | ||
1692 | struct iwl3945_sleep_notification sleep_notif; | ||
1693 | struct iwl3945_spectrum_resp spectrum; | ||
1694 | struct iwl3945_notif_statistics stats; | ||
1695 | __le32 status; | ||
1696 | u8 raw[0]; | ||
1697 | } u; | ||
1698 | } __attribute__ ((packed)); | ||
1699 | |||
1700 | #define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame)) | ||
1701 | |||
1702 | #endif /* __iwl3945_3945_commands_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h deleted file mode 100644 index 85eb778f9df1..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h +++ /dev/null | |||
@@ -1,167 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution in the | ||
21 | * file called LICENSE. | ||
22 | * | ||
23 | * Contact Information: | ||
24 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
25 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
26 | * | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #ifndef __iwl3945_debug_h__ | ||
30 | #define __iwl3945_debug_h__ | ||
31 | |||
32 | #ifdef CONFIG_IWL3945_DEBUG | ||
33 | extern u32 iwl3945_debug_level; | ||
34 | #define IWL_DEBUG(level, fmt, args...) \ | ||
35 | do { if (iwl3945_debug_level & (level)) \ | ||
36 | printk(KERN_ERR DRV_NAME": %c %s " fmt, \ | ||
37 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) | ||
38 | |||
39 | #define IWL_DEBUG_LIMIT(level, fmt, args...) \ | ||
40 | do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \ | ||
41 | printk(KERN_ERR DRV_NAME": %c %s " fmt, \ | ||
42 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) | ||
43 | |||
44 | static 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 | } | ||
52 | #else | ||
53 | static inline void IWL_DEBUG(int level, const char *fmt, ...) | ||
54 | { | ||
55 | } | ||
56 | static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) | ||
57 | { | ||
58 | } | ||
59 | static inline void iwl3945_print_hex_dump(int level, void *p, u32 len) | ||
60 | { | ||
61 | } | ||
62 | #endif /* CONFIG_IWL3945_DEBUG */ | ||
63 | |||
64 | |||
65 | |||
66 | /* | ||
67 | * To use the debug system; | ||
68 | * | ||
69 | * If you are defining a new debug classification, simply add it to the #define | ||
70 | * list here in the form of: | ||
71 | * | ||
72 | * #define IWL_DL_xxxx VALUE | ||
73 | * | ||
74 | * shifting value to the left one bit from the previous entry. xxxx should be | ||
75 | * the name of the classification (for example, WEP) | ||
76 | * | ||
77 | * You then need to either add a IWL_xxxx_DEBUG() macro definition for your | ||
78 | * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want | ||
79 | * to send output to that classification. | ||
80 | * | ||
81 | * To add your debug level to the list of levels seen when you perform | ||
82 | * | ||
83 | * % cat /proc/net/iwl/debug_level | ||
84 | * | ||
85 | * you simply need to add your entry to the iwl3945_debug_levels array. | ||
86 | * | ||
87 | * If you do not see debug_level in /proc/net/iwl then you do not have | ||
88 | * CONFIG_IWL3945_DEBUG defined in your kernel configuration | ||
89 | * | ||
90 | */ | ||
91 | |||
92 | #define IWL_DL_INFO (1 << 0) | ||
93 | #define IWL_DL_MAC80211 (1 << 1) | ||
94 | #define IWL_DL_HOST_COMMAND (1 << 2) | ||
95 | #define IWL_DL_STATE (1 << 3) | ||
96 | |||
97 | #define IWL_DL_RADIO (1 << 7) | ||
98 | #define IWL_DL_POWER (1 << 8) | ||
99 | #define IWL_DL_TEMP (1 << 9) | ||
100 | |||
101 | #define IWL_DL_NOTIF (1 << 10) | ||
102 | #define IWL_DL_SCAN (1 << 11) | ||
103 | #define IWL_DL_ASSOC (1 << 12) | ||
104 | #define IWL_DL_DROP (1 << 13) | ||
105 | |||
106 | #define IWL_DL_TXPOWER (1 << 14) | ||
107 | |||
108 | #define IWL_DL_AP (1 << 15) | ||
109 | |||
110 | #define IWL_DL_FW (1 << 16) | ||
111 | #define IWL_DL_RF_KILL (1 << 17) | ||
112 | #define IWL_DL_FW_ERRORS (1 << 18) | ||
113 | |||
114 | #define IWL_DL_LED (1 << 19) | ||
115 | |||
116 | #define IWL_DL_RATE (1 << 20) | ||
117 | |||
118 | #define IWL_DL_CALIB (1 << 21) | ||
119 | #define IWL_DL_WEP (1 << 22) | ||
120 | #define IWL_DL_TX (1 << 23) | ||
121 | #define IWL_DL_RX (1 << 24) | ||
122 | #define IWL_DL_ISR (1 << 25) | ||
123 | #define IWL_DL_HT (1 << 26) | ||
124 | #define IWL_DL_IO (1 << 27) | ||
125 | #define IWL_DL_11H (1 << 28) | ||
126 | |||
127 | #define IWL_DL_STATS (1 << 29) | ||
128 | #define IWL_DL_TX_REPLY (1 << 30) | ||
129 | #define IWL_DL_QOS (1 << 31) | ||
130 | |||
131 | #define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) | ||
132 | #define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) | ||
133 | #define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a) | ||
134 | |||
135 | #define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a) | ||
136 | #define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a) | ||
137 | #define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a) | ||
138 | #define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a) | ||
139 | #define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a) | ||
140 | #define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a) | ||
141 | #define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a) | ||
142 | #define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a) | ||
143 | #define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a) | ||
144 | #define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a) | ||
145 | #define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a) | ||
146 | #define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a) | ||
147 | #define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a) | ||
148 | #define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a) | ||
149 | #define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a) | ||
150 | #define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a) | ||
151 | #define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a) | ||
152 | #define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a) | ||
153 | #define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a) | ||
154 | #define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a) | ||
155 | #define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) | ||
156 | #define IWL_DEBUG_ASSOC_LIMIT(f, a...) \ | ||
157 | IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) | ||
158 | #define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, 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) | ||
161 | #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) | ||
162 | #define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) | ||
163 | #define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) | ||
164 | #define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) | ||
165 | #define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a) | ||
166 | |||
167 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h new file mode 100644 index 000000000000..08ce259a0e60 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h | |||
@@ -0,0 +1,188 @@ | |||
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 - 2009 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 | * Intel Linux Wireless <ilw@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 - 2009 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_fh_h__ | ||
64 | #define __iwl_3945_fh_h__ | ||
65 | |||
66 | /************************************/ | ||
67 | /* iwl3945 Flow Handler Definitions */ | ||
68 | /************************************/ | ||
69 | |||
70 | /** | ||
71 | * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) | ||
72 | * Addresses are offsets from device's PCI hardware base address. | ||
73 | */ | ||
74 | #define FH39_MEM_LOWER_BOUND (0x0800) | ||
75 | #define FH39_MEM_UPPER_BOUND (0x1000) | ||
76 | |||
77 | #define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140) | ||
78 | #define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180) | ||
79 | #define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400) | ||
80 | #define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0) | ||
81 | #define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500) | ||
82 | #define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680) | ||
83 | |||
84 | /* TFDB (Transmit Frame Buffer Descriptor) */ | ||
85 | #define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \ | ||
86 | ((_ch) * 2 + (buf)) * 0x28) | ||
87 | #define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch)) | ||
88 | |||
89 | /* CBCC channel is [0,2] */ | ||
90 | #define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8) | ||
91 | #define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00) | ||
92 | #define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04) | ||
93 | |||
94 | /* RCSR channel is [0,2] */ | ||
95 | #define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40) | ||
96 | #define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00) | ||
97 | #define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04) | ||
98 | #define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20) | ||
99 | #define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24) | ||
100 | |||
101 | #define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0)) | ||
102 | |||
103 | /* RSSR */ | ||
104 | #define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000) | ||
105 | #define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004) | ||
106 | |||
107 | /* TCSR */ | ||
108 | #define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20) | ||
109 | #define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00) | ||
110 | #define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04) | ||
111 | #define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08) | ||
112 | |||
113 | /* TSSR */ | ||
114 | #define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000) | ||
115 | #define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008) | ||
116 | #define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010) | ||
117 | |||
118 | |||
119 | /* DBM */ | ||
120 | |||
121 | #define FH39_SRVC_CHNL (6) | ||
122 | |||
123 | #define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) | ||
124 | #define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) | ||
125 | |||
126 | #define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) | ||
127 | |||
128 | #define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) | ||
129 | |||
130 | #define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) | ||
131 | |||
132 | #define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) | ||
133 | |||
134 | #define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) | ||
135 | |||
136 | #define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) | ||
137 | |||
138 | #define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) | ||
139 | #define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) | ||
140 | |||
141 | #define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) | ||
142 | #define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) | ||
143 | |||
144 | #define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) | ||
145 | |||
146 | #define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) | ||
147 | |||
148 | #define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) | ||
149 | #define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) | ||
150 | |||
151 | #define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) | ||
152 | |||
153 | #define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) | ||
154 | |||
155 | #define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) | ||
156 | #define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) | ||
157 | |||
158 | #define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) | ||
159 | |||
160 | #define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) | ||
161 | #define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) | ||
162 | |||
163 | #define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) | ||
164 | #define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) | ||
165 | |||
166 | #define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24) | ||
167 | #define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16) | ||
168 | |||
169 | #define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \ | ||
170 | (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \ | ||
171 | FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch)) | ||
172 | |||
173 | #define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) | ||
174 | |||
175 | struct iwl3945_tfd_tb { | ||
176 | __le32 addr; | ||
177 | __le32 len; | ||
178 | } __attribute__ ((packed)); | ||
179 | |||
180 | struct iwl3945_tfd { | ||
181 | __le32 control_flags; | ||
182 | struct iwl3945_tfd_tb tbs[4]; | ||
183 | u8 __pad[28]; | ||
184 | } __attribute__ ((packed)); | ||
185 | |||
186 | |||
187 | #endif /* __iwl_3945_fh_h__ */ | ||
188 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 94ea0e60c410..1327b2ac1c53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -69,77 +69,26 @@ | |||
69 | #ifndef __iwl_3945_hw__ | 69 | #ifndef __iwl_3945_hw__ |
70 | #define __iwl_3945_hw__ | 70 | #define __iwl_3945_hw__ |
71 | 71 | ||
72 | #include "iwl-eeprom.h" | ||
73 | |||
72 | /* | 74 | /* |
73 | * uCode queue management definitions ... | 75 | * uCode queue management definitions ... |
74 | * Queue #4 is the command queue for 3945 and 4965. | 76 | * Queue #4 is the command queue for 3945 and 4965. |
75 | */ | 77 | */ |
76 | #define IWL_CMD_QUEUE_NUM 4 | 78 | #define IWL_CMD_QUEUE_NUM 4 |
77 | |||
78 | /* Tx rates */ | ||
79 | #define IWL_CCK_RATES 4 | ||
80 | #define IWL_OFDM_RATES 8 | ||
81 | #define IWL_HT_RATES 0 | ||
82 | #define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES) | ||
83 | 79 | ||
84 | /* Time constants */ | 80 | /* Time constants */ |
85 | #define SHORT_SLOT_TIME 9 | 81 | #define SHORT_SLOT_TIME 9 |
86 | #define LONG_SLOT_TIME 20 | 82 | #define LONG_SLOT_TIME 20 |
87 | 83 | ||
88 | /* RSSI to dBm */ | 84 | /* RSSI to dBm */ |
89 | #define IWL_RSSI_OFFSET 95 | 85 | #define IWL39_RSSI_OFFSET 95 |
90 | 86 | ||
91 | /* | 87 | /* |
92 | * EEPROM related constants, enums, and structures. | 88 | * EEPROM related constants, enums, and structures. |
93 | */ | 89 | */ |
94 | |||
95 | /* | ||
96 | * EEPROM access time values: | ||
97 | * | ||
98 | * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG, | ||
99 | * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit | ||
100 | * CSR_EEPROM_REG_BIT_CMD (0x2). | ||
101 | * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). | ||
102 | * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. | ||
103 | * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. | ||
104 | */ | ||
105 | #define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ | ||
106 | |||
107 | /* | ||
108 | * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags. | ||
109 | * | ||
110 | * IBSS and/or AP operation is allowed *only* on those channels with | ||
111 | * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because | ||
112 | * RADAR detection is not supported by the 3945 driver, but is a | ||
113 | * requirement for establishing a new network for legal operation on channels | ||
114 | * requiring RADAR detection or restricting ACTIVE scanning. | ||
115 | * | ||
116 | * NOTE: "WIDE" flag indicates that 20 MHz channel is supported; | ||
117 | * 3945 does not support FAT 40 MHz-wide channels. | ||
118 | * | ||
119 | * NOTE: Using a channel inappropriately will result in a uCode error! | ||
120 | */ | ||
121 | enum { | ||
122 | EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ | ||
123 | EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ | ||
124 | /* Bit 2 Reserved */ | ||
125 | EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ | ||
126 | EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ | ||
127 | EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */ | ||
128 | /* Bit 6 Reserved (was Narrow Channel) */ | ||
129 | EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ | ||
130 | }; | ||
131 | |||
132 | /* SKU Capabilities */ | ||
133 | #define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) | ||
134 | #define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) | ||
135 | #define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) | 90 | #define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) |
136 | 91 | ||
137 | /* *regulatory* channel data from eeprom, one for each channel */ | ||
138 | struct iwl3945_eeprom_channel { | ||
139 | u8 flags; /* flags copied from EEPROM */ | ||
140 | s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ | ||
141 | } __attribute__ ((packed)); | ||
142 | |||
143 | /* | 92 | /* |
144 | * Mapping of a Tx power level, at factory calibration temperature, | 93 | * Mapping of a Tx power level, at factory calibration temperature, |
145 | * to a radio/DSP gain table index. | 94 | * to a radio/DSP gain table index. |
@@ -233,7 +182,7 @@ struct iwl3945_eeprom { | |||
233 | * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 | 182 | * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 |
234 | */ | 183 | */ |
235 | u16 band_1_count; /* abs.ofs: 196 */ | 184 | u16 band_1_count; /* abs.ofs: 196 */ |
236 | struct iwl3945_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */ | 185 | struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */ |
237 | 186 | ||
238 | /* | 187 | /* |
239 | * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, | 188 | * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, |
@@ -241,28 +190,28 @@ struct iwl3945_eeprom { | |||
241 | * (4915-5080MHz) (none of these is ever supported) | 190 | * (4915-5080MHz) (none of these is ever supported) |
242 | */ | 191 | */ |
243 | u16 band_2_count; /* abs.ofs: 226 */ | 192 | u16 band_2_count; /* abs.ofs: 226 */ |
244 | struct iwl3945_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ | 193 | struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ |
245 | 194 | ||
246 | /* | 195 | /* |
247 | * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 | 196 | * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 |
248 | * (5170-5320MHz) | 197 | * (5170-5320MHz) |
249 | */ | 198 | */ |
250 | u16 band_3_count; /* abs.ofs: 254 */ | 199 | u16 band_3_count; /* abs.ofs: 254 */ |
251 | struct iwl3945_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ | 200 | struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ |
252 | 201 | ||
253 | /* | 202 | /* |
254 | * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 | 203 | * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 |
255 | * (5500-5700MHz) | 204 | * (5500-5700MHz) |
256 | */ | 205 | */ |
257 | u16 band_4_count; /* abs.ofs: 280 */ | 206 | u16 band_4_count; /* abs.ofs: 280 */ |
258 | struct iwl3945_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ | 207 | struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ |
259 | 208 | ||
260 | /* | 209 | /* |
261 | * 5.7 GHz channels 145, 149, 153, 157, 161, 165 | 210 | * 5.7 GHz channels 145, 149, 153, 157, 161, 165 |
262 | * (5725-5825MHz) | 211 | * (5725-5825MHz) |
263 | */ | 212 | */ |
264 | u16 band_5_count; /* abs.ofs: 304 */ | 213 | u16 band_5_count; /* abs.ofs: 304 */ |
265 | struct iwl3945_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ | 214 | struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ |
266 | 215 | ||
267 | u8 reserved9[194]; | 216 | u8 reserved9[194]; |
268 | 217 | ||
@@ -276,125 +225,21 @@ struct iwl3945_eeprom { | |||
276 | u8 reserved16[172]; /* fill out to full 1024 byte block */ | 225 | u8 reserved16[172]; /* fill out to full 1024 byte block */ |
277 | } __attribute__ ((packed)); | 226 | } __attribute__ ((packed)); |
278 | 227 | ||
279 | #define IWL_EEPROM_IMAGE_SIZE 1024 | 228 | #define IWL3945_EEPROM_IMG_SIZE 1024 |
280 | 229 | ||
281 | /* End of EEPROM */ | 230 | /* End of EEPROM */ |
282 | 231 | ||
283 | 232 | ||
284 | #include "iwl-3945-commands.h" | ||
285 | |||
286 | #define PCI_LINK_CTRL 0x0F0 | 233 | #define PCI_LINK_CTRL 0x0F0 |
287 | #define PCI_POWER_SOURCE 0x0C8 | 234 | #define PCI_POWER_SOURCE 0x0C8 |
288 | #define PCI_REG_WUM8 0x0E8 | 235 | #define PCI_REG_WUM8 0x0E8 |
289 | #define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) | 236 | #define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) |
290 | 237 | ||
291 | /*=== FH (data Flow Handler) ===*/ | ||
292 | #define FH_BASE (0x800) | ||
293 | |||
294 | #define FH_CBCC_TABLE (FH_BASE+0x140) | ||
295 | #define FH_TFDB_TABLE (FH_BASE+0x180) | ||
296 | #define FH_RCSR_TABLE (FH_BASE+0x400) | ||
297 | #define FH_RSSR_TABLE (FH_BASE+0x4c0) | ||
298 | #define FH_TCSR_TABLE (FH_BASE+0x500) | ||
299 | #define FH_TSSR_TABLE (FH_BASE+0x680) | ||
300 | |||
301 | /* TFDB (Transmit Frame Buffer Descriptor) */ | ||
302 | #define FH_TFDB(_channel, buf) \ | ||
303 | (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28) | ||
304 | #define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \ | ||
305 | (FH_TFDB_TABLE + 0x50 * _channel) | ||
306 | /* CBCC _channel is [0,2] */ | ||
307 | #define FH_CBCC(_channel) (FH_CBCC_TABLE+(_channel)*0x8) | ||
308 | #define FH_CBCC_CTRL(_channel) (FH_CBCC(_channel)+0x00) | ||
309 | #define FH_CBCC_BASE(_channel) (FH_CBCC(_channel)+0x04) | ||
310 | |||
311 | /* RCSR _channel is [0,2] */ | ||
312 | #define FH_RCSR(_channel) (FH_RCSR_TABLE+(_channel)*0x40) | ||
313 | #define FH_RCSR_CONFIG(_channel) (FH_RCSR(_channel)+0x00) | ||
314 | #define FH_RCSR_RBD_BASE(_channel) (FH_RCSR(_channel)+0x04) | ||
315 | #define FH_RCSR_WPTR(_channel) (FH_RCSR(_channel)+0x20) | ||
316 | #define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24) | ||
317 | |||
318 | #define FH_RSCSR_CHNL0_WPTR (FH_RCSR_WPTR(0)) | ||
319 | |||
320 | /* RSSR */ | ||
321 | #define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000) | ||
322 | #define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004) | ||
323 | #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) | ||
324 | /* TCSR */ | ||
325 | #define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20) | ||
326 | #define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00) | ||
327 | #define FH_TCSR_CREDIT(_channel) (FH_TCSR(_channel)+0x04) | ||
328 | #define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08) | ||
329 | /* TSSR */ | ||
330 | #define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000) | ||
331 | #define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008) | ||
332 | #define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010) | ||
333 | |||
334 | |||
335 | /* DBM */ | ||
336 | |||
337 | #define ALM_FH_SRVC_CHNL (6) | ||
338 | |||
339 | #define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) | ||
340 | #define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) | ||
341 | |||
342 | #define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) | ||
343 | |||
344 | #define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) | ||
345 | |||
346 | #define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) | ||
347 | |||
348 | #define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) | ||
349 | |||
350 | #define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) | ||
351 | |||
352 | #define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) | ||
353 | |||
354 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) | ||
355 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) | ||
356 | |||
357 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) | ||
358 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) | ||
359 | |||
360 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) | ||
361 | |||
362 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) | ||
363 | |||
364 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) | ||
365 | #define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) | ||
366 | |||
367 | #define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) | ||
368 | |||
369 | #define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) | ||
370 | |||
371 | #define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) | ||
372 | #define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) | ||
373 | |||
374 | #define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) | ||
375 | |||
376 | #define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) | ||
377 | #define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) | ||
378 | |||
379 | #define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) | ||
380 | #define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) | ||
381 | |||
382 | #define ALM_TB_MAX_BYTES_COUNT (0xFFF0) | ||
383 | |||
384 | #define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \ | ||
385 | ((1LU << _channel) << 24) | ||
386 | #define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \ | ||
387 | ((1LU << _channel) << 16) | ||
388 | |||
389 | #define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \ | ||
390 | (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \ | ||
391 | ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel)) | ||
392 | #define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ | 238 | #define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ |
393 | #define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ | 239 | #define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ |
394 | 240 | ||
395 | #define TFD_QUEUE_MIN 0 | 241 | #define TFD_QUEUE_MIN 0 |
396 | #define TFD_QUEUE_MAX 6 | 242 | #define TFD_QUEUE_MAX 6 |
397 | #define TFD_QUEUE_SIZE_MAX (256) | ||
398 | 243 | ||
399 | #define IWL_NUM_SCAN_RATES (2) | 244 | #define IWL_NUM_SCAN_RATES (2) |
400 | 245 | ||
@@ -416,12 +261,6 @@ struct iwl3945_eeprom { | |||
416 | #define TFD_CTL_PAD_SET(n) (n << 28) | 261 | #define TFD_CTL_PAD_SET(n) (n << 28) |
417 | #define TFD_CTL_PAD_GET(ctl) (ctl >> 28) | 262 | #define TFD_CTL_PAD_GET(ctl) (ctl >> 28) |
418 | 263 | ||
419 | #define TFD_TX_CMD_SLOTS 256 | ||
420 | #define TFD_CMD_SLOTS 32 | ||
421 | |||
422 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \ | ||
423 | sizeof(struct iwl3945_cmd_meta)) | ||
424 | |||
425 | /* | 264 | /* |
426 | * RX related structures and functions | 265 | * RX related structures and functions |
427 | */ | 266 | */ |
@@ -430,45 +269,35 @@ struct iwl3945_eeprom { | |||
430 | 269 | ||
431 | /* Sizes and addresses for instruction and data memory (SRAM) in | 270 | /* Sizes and addresses for instruction and data memory (SRAM) in |
432 | * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ | 271 | * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ |
433 | #define RTC_INST_LOWER_BOUND (0x000000) | 272 | #define IWL39_RTC_INST_LOWER_BOUND (0x000000) |
434 | #define ALM_RTC_INST_UPPER_BOUND (0x014000) | 273 | #define IWL39_RTC_INST_UPPER_BOUND (0x014000) |
435 | 274 | ||
436 | #define RTC_DATA_LOWER_BOUND (0x800000) | 275 | #define IWL39_RTC_DATA_LOWER_BOUND (0x800000) |
437 | #define ALM_RTC_DATA_UPPER_BOUND (0x808000) | 276 | #define IWL39_RTC_DATA_UPPER_BOUND (0x808000) |
438 | 277 | ||
439 | #define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND) | 278 | #define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \ |
440 | #define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND) | 279 | IWL39_RTC_INST_LOWER_BOUND) |
280 | #define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \ | ||
281 | IWL39_RTC_DATA_LOWER_BOUND) | ||
441 | 282 | ||
442 | #define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE | 283 | #define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE |
443 | #define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE | 284 | #define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE |
444 | 285 | ||
445 | /* Size of uCode instruction memory in bootstrap state machine */ | 286 | /* Size of uCode instruction memory in bootstrap state machine */ |
446 | #define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE | 287 | #define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE |
447 | 288 | ||
448 | #define IWL39_MAX_NUM_QUEUES 8 | 289 | #define IWL39_MAX_NUM_QUEUES 8 |
449 | 290 | ||
450 | static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) | 291 | static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) |
451 | { | 292 | { |
452 | return (addr >= RTC_DATA_LOWER_BOUND) && | 293 | return (addr >= IWL39_RTC_DATA_LOWER_BOUND) && |
453 | (addr < ALM_RTC_DATA_UPPER_BOUND); | 294 | (addr < IWL39_RTC_DATA_UPPER_BOUND); |
454 | } | 295 | } |
455 | 296 | ||
456 | /* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE | 297 | /* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE |
457 | * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ | 298 | * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ |
458 | struct iwl3945_shared { | 299 | struct iwl3945_shared { |
459 | __le32 tx_base_ptr[8]; | 300 | __le32 tx_base_ptr[8]; |
460 | __le32 rx_read_ptr[3]; | ||
461 | } __attribute__ ((packed)); | ||
462 | |||
463 | struct iwl3945_tfd_frame_data { | ||
464 | __le32 addr; | ||
465 | __le32 len; | ||
466 | } __attribute__ ((packed)); | ||
467 | |||
468 | struct iwl3945_tfd_frame { | ||
469 | __le32 control_flags; | ||
470 | struct iwl3945_tfd_frame_data pa[4]; | ||
471 | u8 reserved[28]; | ||
472 | } __attribute__ ((packed)); | 301 | } __attribute__ ((packed)); |
473 | 302 | ||
474 | static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) | 303 | static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h deleted file mode 100644 index 2440fd664dd5..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h +++ /dev/null | |||
@@ -1,404 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
19 | * | ||
20 | * The full GNU General Public License is included in this distribution in the | ||
21 | * file called LICENSE. | ||
22 | * | ||
23 | * Contact Information: | ||
24 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
25 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
26 | * | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #ifndef __iwl3945_io_h__ | ||
30 | #define __iwl3945_io_h__ | ||
31 | |||
32 | #include <linux/io.h> | ||
33 | |||
34 | #include "iwl-3945-debug.h" | ||
35 | |||
36 | /* | ||
37 | * IO, register, and NIC memory access functions | ||
38 | * | ||
39 | * NOTE on naming convention and macro usage for these | ||
40 | * | ||
41 | * A single _ prefix before a an access function means that no state | ||
42 | * check or debug information is printed when that function is called. | ||
43 | * | ||
44 | * A double __ prefix before an access function means that state is checked | ||
45 | * and the current line number is printed in addition to any other debug output. | ||
46 | * | ||
47 | * The non-prefixed name is the #define that maps the caller into a | ||
48 | * #define that provides the caller's __LINE__ to the double prefix version. | ||
49 | * | ||
50 | * If you wish to call the function without any debug or state checking, | ||
51 | * you should use the single _ prefix version (as is used by dependent IO | ||
52 | * routines, for example _iwl3945_read_direct32 calls the non-check version of | ||
53 | * _iwl3945_read32.) | ||
54 | * | ||
55 | * These declarations are *extremely* useful in quickly isolating code deltas | ||
56 | * which result in misconfiguration of the hardware I/O. In combination with | ||
57 | * git-bisect and the IO debug level you can quickly determine the specific | ||
58 | * commit which breaks the IO sequence to the hardware. | ||
59 | * | ||
60 | */ | ||
61 | |||
62 | #define _iwl3945_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs)) | ||
63 | #ifdef CONFIG_IWL3945_DEBUG | ||
64 | static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv, | ||
65 | u32 ofs, u32 val) | ||
66 | { | ||
67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); | ||
68 | _iwl3945_write32(priv, ofs, val); | ||
69 | } | ||
70 | #define iwl3945_write32(priv, ofs, val) \ | ||
71 | __iwl3945_write32(__FILE__, __LINE__, priv, ofs, val) | ||
72 | #else | ||
73 | #define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val) | ||
74 | #endif | ||
75 | |||
76 | #define _iwl3945_read32(priv, ofs) ioread32((priv)->hw_base + (ofs)) | ||
77 | #ifdef CONFIG_IWL3945_DEBUG | ||
78 | static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs) | ||
79 | { | ||
80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); | ||
81 | return _iwl3945_read32(priv, ofs); | ||
82 | } | ||
83 | #define iwl3945_read32(priv, ofs)__iwl3945_read32(__FILE__, __LINE__, priv, ofs) | ||
84 | #else | ||
85 | #define iwl3945_read32(p, o) _iwl3945_read32(p, o) | ||
86 | #endif | ||
87 | |||
88 | static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr, | ||
89 | u32 bits, u32 mask, int timeout) | ||
90 | { | ||
91 | int i = 0; | ||
92 | |||
93 | do { | ||
94 | if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask)) | ||
95 | return i; | ||
96 | udelay(10); | ||
97 | i += 10; | ||
98 | } while (i < timeout); | ||
99 | |||
100 | return -ETIMEDOUT; | ||
101 | } | ||
102 | #ifdef CONFIG_IWL3945_DEBUG | ||
103 | static inline int __iwl3945_poll_bit(const char *f, u32 l, | ||
104 | struct iwl3945_priv *priv, u32 addr, | ||
105 | u32 bits, u32 mask, int timeout) | ||
106 | { | ||
107 | int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout); | ||
108 | IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", | ||
109 | addr, bits, mask, | ||
110 | unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l); | ||
111 | return ret; | ||
112 | } | ||
113 | #define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \ | ||
114 | __iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) | ||
115 | #else | ||
116 | #define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t) | ||
117 | #endif | ||
118 | |||
119 | static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask) | ||
120 | { | ||
121 | _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask); | ||
122 | } | ||
123 | #ifdef CONFIG_IWL3945_DEBUG | ||
124 | static inline void __iwl3945_set_bit(const char *f, u32 l, | ||
125 | struct iwl3945_priv *priv, u32 reg, u32 mask) | ||
126 | { | ||
127 | u32 val = _iwl3945_read32(priv, reg) | mask; | ||
128 | IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); | ||
129 | _iwl3945_write32(priv, reg, val); | ||
130 | } | ||
131 | #define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m) | ||
132 | #else | ||
133 | #define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m) | ||
134 | #endif | ||
135 | |||
136 | static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask) | ||
137 | { | ||
138 | _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask); | ||
139 | } | ||
140 | #ifdef CONFIG_IWL3945_DEBUG | ||
141 | static inline void __iwl3945_clear_bit(const char *f, u32 l, | ||
142 | struct iwl3945_priv *priv, u32 reg, u32 mask) | ||
143 | { | ||
144 | u32 val = _iwl3945_read32(priv, reg) & ~mask; | ||
145 | IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); | ||
146 | _iwl3945_write32(priv, reg, val); | ||
147 | } | ||
148 | #define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m) | ||
149 | #else | ||
150 | #define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m) | ||
151 | #endif | ||
152 | |||
153 | static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv) | ||
154 | { | ||
155 | int ret; | ||
156 | #ifdef CONFIG_IWL3945_DEBUG | ||
157 | if (atomic_read(&priv->restrict_refcnt)) | ||
158 | return 0; | ||
159 | #endif | ||
160 | /* this bit wakes up the NIC */ | ||
161 | _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
162 | ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL, | ||
163 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | ||
164 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | ||
165 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50); | ||
166 | if (ret < 0) { | ||
167 | IWL_ERROR("MAC is in deep sleep!\n"); | ||
168 | return -EIO; | ||
169 | } | ||
170 | |||
171 | #ifdef CONFIG_IWL3945_DEBUG | ||
172 | atomic_inc(&priv->restrict_refcnt); | ||
173 | #endif | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | #ifdef CONFIG_IWL3945_DEBUG | ||
178 | static inline int __iwl3945_grab_nic_access(const char *f, u32 l, | ||
179 | struct iwl3945_priv *priv) | ||
180 | { | ||
181 | if (atomic_read(&priv->restrict_refcnt)) | ||
182 | IWL_DEBUG_INFO("Grabbing access while already held at " | ||
183 | "line %d.\n", l); | ||
184 | |||
185 | IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l); | ||
186 | return _iwl3945_grab_nic_access(priv); | ||
187 | } | ||
188 | #define iwl3945_grab_nic_access(priv) \ | ||
189 | __iwl3945_grab_nic_access(__FILE__, __LINE__, priv) | ||
190 | #else | ||
191 | #define iwl3945_grab_nic_access(priv) \ | ||
192 | _iwl3945_grab_nic_access(priv) | ||
193 | #endif | ||
194 | |||
195 | static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv) | ||
196 | { | ||
197 | #ifdef CONFIG_IWL3945_DEBUG | ||
198 | if (atomic_dec_and_test(&priv->restrict_refcnt)) | ||
199 | #endif | ||
200 | _iwl3945_clear_bit(priv, CSR_GP_CNTRL, | ||
201 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
202 | } | ||
203 | #ifdef CONFIG_IWL3945_DEBUG | ||
204 | static inline void __iwl3945_release_nic_access(const char *f, u32 l, | ||
205 | struct iwl3945_priv *priv) | ||
206 | { | ||
207 | if (atomic_read(&priv->restrict_refcnt) <= 0) | ||
208 | IWL_ERROR("Release unheld nic access at line %d.\n", l); | ||
209 | |||
210 | IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l); | ||
211 | _iwl3945_release_nic_access(priv); | ||
212 | } | ||
213 | #define iwl3945_release_nic_access(priv) \ | ||
214 | __iwl3945_release_nic_access(__FILE__, __LINE__, priv) | ||
215 | #else | ||
216 | #define iwl3945_release_nic_access(priv) \ | ||
217 | _iwl3945_release_nic_access(priv) | ||
218 | #endif | ||
219 | |||
220 | static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg) | ||
221 | { | ||
222 | return _iwl3945_read32(priv, reg); | ||
223 | } | ||
224 | #ifdef CONFIG_IWL3945_DEBUG | ||
225 | static inline u32 __iwl3945_read_direct32(const char *f, u32 l, | ||
226 | struct iwl3945_priv *priv, u32 reg) | ||
227 | { | ||
228 | u32 value = _iwl3945_read_direct32(priv, reg); | ||
229 | if (!atomic_read(&priv->restrict_refcnt)) | ||
230 | IWL_ERROR("Nic access not held from %s %d\n", f, l); | ||
231 | IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, | ||
232 | f, l); | ||
233 | return value; | ||
234 | } | ||
235 | #define iwl3945_read_direct32(priv, reg) \ | ||
236 | __iwl3945_read_direct32(__FILE__, __LINE__, priv, reg) | ||
237 | #else | ||
238 | #define iwl3945_read_direct32 _iwl3945_read_direct32 | ||
239 | #endif | ||
240 | |||
241 | static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv, | ||
242 | u32 reg, u32 value) | ||
243 | { | ||
244 | _iwl3945_write32(priv, reg, value); | ||
245 | } | ||
246 | #ifdef CONFIG_IWL3945_DEBUG | ||
247 | static void __iwl3945_write_direct32(u32 line, | ||
248 | struct iwl3945_priv *priv, u32 reg, u32 value) | ||
249 | { | ||
250 | if (!atomic_read(&priv->restrict_refcnt)) | ||
251 | IWL_ERROR("Nic access not held from line %d\n", line); | ||
252 | _iwl3945_write_direct32(priv, reg, value); | ||
253 | } | ||
254 | #define iwl3945_write_direct32(priv, reg, value) \ | ||
255 | __iwl3945_write_direct32(__LINE__, priv, reg, value) | ||
256 | #else | ||
257 | #define iwl3945_write_direct32 _iwl3945_write_direct32 | ||
258 | #endif | ||
259 | |||
260 | static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv, | ||
261 | u32 reg, u32 len, u32 *values) | ||
262 | { | ||
263 | u32 count = sizeof(u32); | ||
264 | |||
265 | if ((priv != NULL) && (values != NULL)) { | ||
266 | for (; 0 < len; len -= count, reg += count, values++) | ||
267 | _iwl3945_write_direct32(priv, reg, *values); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv, | ||
272 | u32 addr, u32 mask, int timeout) | ||
273 | { | ||
274 | return _iwl3945_poll_bit(priv, addr, mask, mask, timeout); | ||
275 | } | ||
276 | |||
277 | #ifdef CONFIG_IWL3945_DEBUG | ||
278 | static inline int __iwl3945_poll_direct_bit(const char *f, u32 l, | ||
279 | struct iwl3945_priv *priv, | ||
280 | u32 addr, u32 mask, int timeout) | ||
281 | { | ||
282 | int ret = _iwl3945_poll_direct_bit(priv, addr, mask, timeout); | ||
283 | |||
284 | if (unlikely(ret == -ETIMEDOUT)) | ||
285 | IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - " | ||
286 | "timedout - %s %d\n", addr, mask, f, l); | ||
287 | else | ||
288 | IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X " | ||
289 | "- %s %d\n", addr, mask, ret, f, l); | ||
290 | return ret; | ||
291 | } | ||
292 | #define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \ | ||
293 | __iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) | ||
294 | #else | ||
295 | #define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit | ||
296 | #endif | ||
297 | |||
298 | static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg) | ||
299 | { | ||
300 | _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); | ||
301 | rmb(); | ||
302 | return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT); | ||
303 | } | ||
304 | #ifdef CONFIG_IWL3945_DEBUG | ||
305 | static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg) | ||
306 | { | ||
307 | if (!atomic_read(&priv->restrict_refcnt)) | ||
308 | IWL_ERROR("Nic access not held from line %d\n", line); | ||
309 | return _iwl3945_read_prph(priv, reg); | ||
310 | } | ||
311 | |||
312 | #define iwl3945_read_prph(priv, reg) \ | ||
313 | __iwl3945_read_prph(__LINE__, priv, reg) | ||
314 | #else | ||
315 | #define iwl3945_read_prph _iwl3945_read_prph | ||
316 | #endif | ||
317 | |||
318 | static inline void _iwl3945_write_prph(struct iwl3945_priv *priv, | ||
319 | u32 addr, u32 val) | ||
320 | { | ||
321 | _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR, | ||
322 | ((addr & 0x0000FFFF) | (3 << 24))); | ||
323 | wmb(); | ||
324 | _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val); | ||
325 | } | ||
326 | #ifdef CONFIG_IWL3945_DEBUG | ||
327 | static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv, | ||
328 | u32 addr, u32 val) | ||
329 | { | ||
330 | if (!atomic_read(&priv->restrict_refcnt)) | ||
331 | IWL_ERROR("Nic access from line %d\n", line); | ||
332 | _iwl3945_write_prph(priv, addr, val); | ||
333 | } | ||
334 | |||
335 | #define iwl3945_write_prph(priv, addr, val) \ | ||
336 | __iwl3945_write_prph(__LINE__, priv, addr, val); | ||
337 | #else | ||
338 | #define iwl3945_write_prph _iwl3945_write_prph | ||
339 | #endif | ||
340 | |||
341 | #define _iwl3945_set_bits_prph(priv, reg, mask) \ | ||
342 | _iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask)) | ||
343 | #ifdef CONFIG_IWL3945_DEBUG | ||
344 | static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv, | ||
345 | u32 reg, u32 mask) | ||
346 | { | ||
347 | if (!atomic_read(&priv->restrict_refcnt)) | ||
348 | IWL_ERROR("Nic access not held from line %d\n", line); | ||
349 | |||
350 | _iwl3945_set_bits_prph(priv, reg, mask); | ||
351 | } | ||
352 | #define iwl3945_set_bits_prph(priv, reg, mask) \ | ||
353 | __iwl3945_set_bits_prph(__LINE__, priv, reg, mask) | ||
354 | #else | ||
355 | #define iwl3945_set_bits_prph _iwl3945_set_bits_prph | ||
356 | #endif | ||
357 | |||
358 | #define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \ | ||
359 | _iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits)) | ||
360 | |||
361 | #ifdef CONFIG_IWL3945_DEBUG | ||
362 | static inline void __iwl3945_set_bits_mask_prph(u32 line, | ||
363 | struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask) | ||
364 | { | ||
365 | if (!atomic_read(&priv->restrict_refcnt)) | ||
366 | IWL_ERROR("Nic access not held from line %d\n", line); | ||
367 | _iwl3945_set_bits_mask_prph(priv, reg, bits, mask); | ||
368 | } | ||
369 | #define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \ | ||
370 | __iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask) | ||
371 | #else | ||
372 | #define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph | ||
373 | #endif | ||
374 | |||
375 | static inline void iwl3945_clear_bits_prph(struct iwl3945_priv | ||
376 | *priv, u32 reg, u32 mask) | ||
377 | { | ||
378 | u32 val = _iwl3945_read_prph(priv, reg); | ||
379 | _iwl3945_write_prph(priv, reg, (val & ~mask)); | ||
380 | } | ||
381 | |||
382 | static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr) | ||
383 | { | ||
384 | iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr); | ||
385 | rmb(); | ||
386 | return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT); | ||
387 | } | ||
388 | |||
389 | static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val) | ||
390 | { | ||
391 | iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); | ||
392 | wmb(); | ||
393 | iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val); | ||
394 | } | ||
395 | |||
396 | static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr, | ||
397 | u32 len, u32 *values) | ||
398 | { | ||
399 | iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); | ||
400 | wmb(); | ||
401 | for (; 0 < len; len -= sizeof(u32), values++) | ||
402 | iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values); | ||
403 | } | ||
404 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index 4c638909a7db..fab137365000 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -38,8 +38,10 @@ | |||
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-commands.h" | ||
41 | #include "iwl-3945.h" | 42 | #include "iwl-3945.h" |
42 | #include "iwl-helpers.h" | 43 | #include "iwl-core.h" |
44 | #include "iwl-dev.h" | ||
43 | 45 | ||
44 | 46 | ||
45 | static const struct { | 47 | static const struct { |
@@ -67,8 +69,8 @@ static const struct { | |||
67 | #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/ | 69 | #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/ |
68 | #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) | 70 | #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) |
69 | 71 | ||
70 | static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv, | 72 | static int iwl3945_led_cmd_callback(struct iwl_priv *priv, |
71 | struct iwl3945_cmd *cmd, | 73 | struct iwl_cmd *cmd, |
72 | struct sk_buff *skb) | 74 | struct sk_buff *skb) |
73 | { | 75 | { |
74 | return 1; | 76 | return 1; |
@@ -80,27 +82,27 @@ static inline int iwl3945_brightness_to_idx(enum led_brightness brightness) | |||
80 | } | 82 | } |
81 | 83 | ||
82 | /* Send led command */ | 84 | /* Send led command */ |
83 | static int iwl_send_led_cmd(struct iwl3945_priv *priv, | 85 | static int iwl_send_led_cmd(struct iwl_priv *priv, |
84 | struct iwl3945_led_cmd *led_cmd) | 86 | struct iwl_led_cmd *led_cmd) |
85 | { | 87 | { |
86 | struct iwl3945_host_cmd cmd = { | 88 | struct iwl_host_cmd cmd = { |
87 | .id = REPLY_LEDS_CMD, | 89 | .id = REPLY_LEDS_CMD, |
88 | .len = sizeof(struct iwl3945_led_cmd), | 90 | .len = sizeof(struct iwl_led_cmd), |
89 | .data = led_cmd, | 91 | .data = led_cmd, |
90 | .meta.flags = CMD_ASYNC, | 92 | .meta.flags = CMD_ASYNC, |
91 | .meta.u.callback = iwl3945_led_cmd_callback, | 93 | .meta.u.callback = iwl3945_led_cmd_callback, |
92 | }; | 94 | }; |
93 | 95 | ||
94 | return iwl3945_send_cmd(priv, &cmd); | 96 | return iwl_send_cmd(priv, &cmd); |
95 | } | 97 | } |
96 | 98 | ||
97 | 99 | ||
98 | 100 | ||
99 | /* Set led on command */ | 101 | /* Set led on command */ |
100 | static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id, | 102 | static int iwl3945_led_pattern(struct iwl_priv *priv, int led_id, |
101 | unsigned int idx) | 103 | unsigned int idx) |
102 | { | 104 | { |
103 | struct iwl3945_led_cmd led_cmd = { | 105 | struct iwl_led_cmd led_cmd = { |
104 | .id = led_id, | 106 | .id = led_id, |
105 | .interval = IWL_DEF_LED_INTRVL | 107 | .interval = IWL_DEF_LED_INTRVL |
106 | }; | 108 | }; |
@@ -114,11 +116,10 @@ static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id, | |||
114 | } | 116 | } |
115 | 117 | ||
116 | 118 | ||
117 | #if 1 | ||
118 | /* Set led on command */ | 119 | /* Set led on command */ |
119 | static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id) | 120 | static int iwl3945_led_on(struct iwl_priv *priv, int led_id) |
120 | { | 121 | { |
121 | struct iwl3945_led_cmd led_cmd = { | 122 | struct iwl_led_cmd led_cmd = { |
122 | .id = led_id, | 123 | .id = led_id, |
123 | .on = IWL_LED_SOLID, | 124 | .on = IWL_LED_SOLID, |
124 | .off = 0, | 125 | .off = 0, |
@@ -128,9 +129,9 @@ static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id) | |||
128 | } | 129 | } |
129 | 130 | ||
130 | /* Set led off command */ | 131 | /* Set led off command */ |
131 | static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) | 132 | static int iwl3945_led_off(struct iwl_priv *priv, int led_id) |
132 | { | 133 | { |
133 | struct iwl3945_led_cmd led_cmd = { | 134 | struct iwl_led_cmd led_cmd = { |
134 | .id = led_id, | 135 | .id = led_id, |
135 | .on = 0, | 136 | .on = 0, |
136 | .off = 0, | 137 | .off = 0, |
@@ -139,13 +140,11 @@ static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id) | |||
139 | IWL_DEBUG_LED("led off %d\n", led_id); | 140 | IWL_DEBUG_LED("led off %d\n", led_id); |
140 | return iwl_send_led_cmd(priv, &led_cmd); | 141 | return iwl_send_led_cmd(priv, &led_cmd); |
141 | } | 142 | } |
142 | #endif | ||
143 | |||
144 | 143 | ||
145 | /* | 144 | /* |
146 | * brightness call back function for Tx/Rx LED | 145 | * brightness call back function for Tx/Rx LED |
147 | */ | 146 | */ |
148 | static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id) | 147 | static int iwl3945_led_associated(struct iwl_priv *priv, int led_id) |
149 | { | 148 | { |
150 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | 149 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
151 | !test_bit(STATUS_READY, &priv->status)) | 150 | !test_bit(STATUS_READY, &priv->status)) |
@@ -166,7 +165,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev, | |||
166 | { | 165 | { |
167 | struct iwl3945_led *led = container_of(led_cdev, | 166 | struct iwl3945_led *led = container_of(led_cdev, |
168 | struct iwl3945_led, led_dev); | 167 | struct iwl3945_led, led_dev); |
169 | struct iwl3945_priv *priv = led->priv; | 168 | struct iwl_priv *priv = led->priv; |
170 | 169 | ||
171 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 170 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
172 | return; | 171 | return; |
@@ -202,7 +201,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev, | |||
202 | /* | 201 | /* |
203 | * Register led class with the system | 202 | * Register led class with the system |
204 | */ | 203 | */ |
205 | static int iwl3945_led_register_led(struct iwl3945_priv *priv, | 204 | static int iwl3945_led_register_led(struct iwl_priv *priv, |
206 | struct iwl3945_led *led, | 205 | struct iwl3945_led *led, |
207 | enum led_type type, u8 set_led, | 206 | enum led_type type, u8 set_led, |
208 | char *trigger) | 207 | char *trigger) |
@@ -219,7 +218,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv, | |||
219 | 218 | ||
220 | ret = led_classdev_register(device, &led->led_dev); | 219 | ret = led_classdev_register(device, &led->led_dev); |
221 | if (ret) { | 220 | if (ret) { |
222 | IWL_ERROR("Error: failed to register led handler.\n"); | 221 | IWL_ERR(priv, "Error: failed to register led handler.\n"); |
223 | return ret; | 222 | return ret; |
224 | } | 223 | } |
225 | 224 | ||
@@ -234,7 +233,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv, | |||
234 | /* | 233 | /* |
235 | * calculate blink rate according to last 2 sec Tx/Rx activities | 234 | * calculate blink rate according to last 2 sec Tx/Rx activities |
236 | */ | 235 | */ |
237 | static inline u8 get_blink_rate(struct iwl3945_priv *priv) | 236 | static inline u8 get_blink_rate(struct iwl_priv *priv) |
238 | { | 237 | { |
239 | int index; | 238 | int index; |
240 | u64 current_tpt = priv->rxtxpackets; | 239 | u64 current_tpt = priv->rxtxpackets; |
@@ -253,7 +252,7 @@ static inline u8 get_blink_rate(struct iwl3945_priv *priv) | |||
253 | return index; | 252 | return index; |
254 | } | 253 | } |
255 | 254 | ||
256 | static inline int is_rf_kill(struct iwl3945_priv *priv) | 255 | static inline int is_rf_kill(struct iwl_priv *priv) |
257 | { | 256 | { |
258 | return test_bit(STATUS_RF_KILL_HW, &priv->status) || | 257 | return test_bit(STATUS_RF_KILL_HW, &priv->status) || |
259 | test_bit(STATUS_RF_KILL_SW, &priv->status); | 258 | test_bit(STATUS_RF_KILL_SW, &priv->status); |
@@ -264,7 +263,7 @@ static inline int is_rf_kill(struct iwl3945_priv *priv) | |||
264 | * happen very frequent we postpone led command to be called from | 263 | * happen very frequent we postpone led command to be called from |
265 | * REPLY handler so we know ucode is up | 264 | * REPLY handler so we know ucode is up |
266 | */ | 265 | */ |
267 | void iwl3945_led_background(struct iwl3945_priv *priv) | 266 | void iwl3945_led_background(struct iwl_priv *priv) |
268 | { | 267 | { |
269 | u8 blink_idx; | 268 | u8 blink_idx; |
270 | 269 | ||
@@ -304,7 +303,7 @@ void iwl3945_led_background(struct iwl3945_priv *priv) | |||
304 | 303 | ||
305 | 304 | ||
306 | /* Register all led handler */ | 305 | /* Register all led handler */ |
307 | int iwl3945_led_register(struct iwl3945_priv *priv) | 306 | int iwl3945_led_register(struct iwl_priv *priv) |
308 | { | 307 | { |
309 | char *trigger; | 308 | char *trigger; |
310 | int ret; | 309 | int ret; |
@@ -316,66 +315,66 @@ int iwl3945_led_register(struct iwl3945_priv *priv) | |||
316 | priv->allow_blinking = 0; | 315 | priv->allow_blinking = 0; |
317 | 316 | ||
318 | trigger = ieee80211_get_radio_led_name(priv->hw); | 317 | trigger = ieee80211_get_radio_led_name(priv->hw); |
319 | snprintf(priv->led[IWL_LED_TRG_RADIO].name, | 318 | snprintf(priv->led39[IWL_LED_TRG_RADIO].name, |
320 | sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio", | 319 | sizeof(priv->led39[IWL_LED_TRG_RADIO].name), "iwl-%s:radio", |
321 | wiphy_name(priv->hw->wiphy)); | 320 | wiphy_name(priv->hw->wiphy)); |
322 | 321 | ||
323 | priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on; | 322 | priv->led39[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on; |
324 | priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off; | 323 | priv->led39[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off; |
325 | priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; | 324 | priv->led39[IWL_LED_TRG_RADIO].led_pattern = NULL; |
326 | 325 | ||
327 | ret = iwl3945_led_register_led(priv, | 326 | ret = iwl3945_led_register_led(priv, |
328 | &priv->led[IWL_LED_TRG_RADIO], | 327 | &priv->led39[IWL_LED_TRG_RADIO], |
329 | IWL_LED_TRG_RADIO, 1, trigger); | 328 | IWL_LED_TRG_RADIO, 1, trigger); |
330 | 329 | ||
331 | if (ret) | 330 | if (ret) |
332 | goto exit_fail; | 331 | goto exit_fail; |
333 | 332 | ||
334 | trigger = ieee80211_get_assoc_led_name(priv->hw); | 333 | trigger = ieee80211_get_assoc_led_name(priv->hw); |
335 | snprintf(priv->led[IWL_LED_TRG_ASSOC].name, | 334 | snprintf(priv->led39[IWL_LED_TRG_ASSOC].name, |
336 | sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc", | 335 | sizeof(priv->led39[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc", |
337 | wiphy_name(priv->hw->wiphy)); | 336 | wiphy_name(priv->hw->wiphy)); |
338 | 337 | ||
339 | ret = iwl3945_led_register_led(priv, | 338 | ret = iwl3945_led_register_led(priv, |
340 | &priv->led[IWL_LED_TRG_ASSOC], | 339 | &priv->led39[IWL_LED_TRG_ASSOC], |
341 | IWL_LED_TRG_ASSOC, 0, trigger); | 340 | IWL_LED_TRG_ASSOC, 0, trigger); |
342 | 341 | ||
343 | /* for assoc always turn led on */ | 342 | /* for assoc always turn led on */ |
344 | priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on; | 343 | priv->led39[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on; |
345 | priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on; | 344 | priv->led39[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on; |
346 | priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL; | 345 | priv->led39[IWL_LED_TRG_ASSOC].led_pattern = NULL; |
347 | 346 | ||
348 | if (ret) | 347 | if (ret) |
349 | goto exit_fail; | 348 | goto exit_fail; |
350 | 349 | ||
351 | trigger = ieee80211_get_rx_led_name(priv->hw); | 350 | trigger = ieee80211_get_rx_led_name(priv->hw); |
352 | snprintf(priv->led[IWL_LED_TRG_RX].name, | 351 | snprintf(priv->led39[IWL_LED_TRG_RX].name, |
353 | sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX", | 352 | sizeof(priv->led39[IWL_LED_TRG_RX].name), "iwl-%s:RX", |
354 | wiphy_name(priv->hw->wiphy)); | 353 | wiphy_name(priv->hw->wiphy)); |
355 | 354 | ||
356 | ret = iwl3945_led_register_led(priv, | 355 | ret = iwl3945_led_register_led(priv, |
357 | &priv->led[IWL_LED_TRG_RX], | 356 | &priv->led39[IWL_LED_TRG_RX], |
358 | IWL_LED_TRG_RX, 0, trigger); | 357 | IWL_LED_TRG_RX, 0, trigger); |
359 | 358 | ||
360 | priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated; | 359 | priv->led39[IWL_LED_TRG_RX].led_on = iwl3945_led_associated; |
361 | priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated; | 360 | priv->led39[IWL_LED_TRG_RX].led_off = iwl3945_led_associated; |
362 | priv->led[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern; | 361 | priv->led39[IWL_LED_TRG_RX].led_pattern = iwl3945_led_pattern; |
363 | 362 | ||
364 | if (ret) | 363 | if (ret) |
365 | goto exit_fail; | 364 | goto exit_fail; |
366 | 365 | ||
367 | trigger = ieee80211_get_tx_led_name(priv->hw); | 366 | trigger = ieee80211_get_tx_led_name(priv->hw); |
368 | snprintf(priv->led[IWL_LED_TRG_TX].name, | 367 | snprintf(priv->led39[IWL_LED_TRG_TX].name, |
369 | sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX", | 368 | sizeof(priv->led39[IWL_LED_TRG_TX].name), "iwl-%s:TX", |
370 | wiphy_name(priv->hw->wiphy)); | 369 | wiphy_name(priv->hw->wiphy)); |
371 | 370 | ||
372 | ret = iwl3945_led_register_led(priv, | 371 | ret = iwl3945_led_register_led(priv, |
373 | &priv->led[IWL_LED_TRG_TX], | 372 | &priv->led39[IWL_LED_TRG_TX], |
374 | IWL_LED_TRG_TX, 0, trigger); | 373 | IWL_LED_TRG_TX, 0, trigger); |
375 | 374 | ||
376 | priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated; | 375 | priv->led39[IWL_LED_TRG_TX].led_on = iwl3945_led_associated; |
377 | priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated; | 376 | priv->led39[IWL_LED_TRG_TX].led_off = iwl3945_led_associated; |
378 | priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern; | 377 | priv->led39[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern; |
379 | 378 | ||
380 | if (ret) | 379 | if (ret) |
381 | goto exit_fail; | 380 | goto exit_fail; |
@@ -402,11 +401,11 @@ static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led) | |||
402 | } | 401 | } |
403 | 402 | ||
404 | /* Unregister all led handlers */ | 403 | /* Unregister all led handlers */ |
405 | void iwl3945_led_unregister(struct iwl3945_priv *priv) | 404 | void iwl3945_led_unregister(struct iwl_priv *priv) |
406 | { | 405 | { |
407 | iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0); | 406 | iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_ASSOC], 0); |
408 | iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0); | 407 | iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RX], 0); |
409 | iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_TX], 0); | 408 | iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_TX], 0); |
410 | iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1); | 409 | iwl3945_led_unregister_led(&priv->led39[IWL_LED_TRG_RADIO], 1); |
411 | } | 410 | } |
412 | 411 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h index 749ac035fd6a..88185a6ccd6a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -27,48 +27,34 @@ | |||
27 | #ifndef IWL3945_LEDS_H | 27 | #ifndef IWL3945_LEDS_H |
28 | #define IWL3945_LEDS_H | 28 | #define IWL3945_LEDS_H |
29 | 29 | ||
30 | struct iwl3945_priv; | 30 | struct iwl_priv; |
31 | 31 | ||
32 | #ifdef CONFIG_IWL3945_LEDS | 32 | #ifdef CONFIG_IWL3945_LEDS |
33 | #define IWL_LED_SOLID 11 | ||
34 | #define IWL_LED_NAME_LEN 31 | ||
35 | #define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000) | ||
36 | 33 | ||
37 | #define IWL_LED_ACTIVITY (0<<1) | 34 | #include "iwl-led.h" |
38 | #define IWL_LED_LINK (1<<1) | ||
39 | |||
40 | enum led_type { | ||
41 | IWL_LED_TRG_TX, | ||
42 | IWL_LED_TRG_RX, | ||
43 | IWL_LED_TRG_ASSOC, | ||
44 | IWL_LED_TRG_RADIO, | ||
45 | IWL_LED_TRG_MAX, | ||
46 | }; | ||
47 | |||
48 | #include <linux/leds.h> | ||
49 | 35 | ||
50 | struct iwl3945_led { | 36 | struct iwl3945_led { |
51 | struct iwl3945_priv *priv; | 37 | struct iwl_priv *priv; |
52 | struct led_classdev led_dev; | 38 | struct led_classdev led_dev; |
53 | char name[32]; | 39 | char name[32]; |
54 | 40 | ||
55 | int (*led_on) (struct iwl3945_priv *priv, int led_id); | 41 | int (*led_on) (struct iwl_priv *priv, int led_id); |
56 | int (*led_off) (struct iwl3945_priv *priv, int led_id); | 42 | int (*led_off) (struct iwl_priv *priv, int led_id); |
57 | int (*led_pattern) (struct iwl3945_priv *priv, int led_id, | 43 | int (*led_pattern) (struct iwl_priv *priv, int led_id, |
58 | unsigned int idx); | 44 | unsigned int idx); |
59 | 45 | ||
60 | enum led_type type; | 46 | enum led_type type; |
61 | unsigned int registered; | 47 | unsigned int registered; |
62 | }; | 48 | }; |
63 | 49 | ||
64 | extern int iwl3945_led_register(struct iwl3945_priv *priv); | 50 | extern int iwl3945_led_register(struct iwl_priv *priv); |
65 | extern void iwl3945_led_unregister(struct iwl3945_priv *priv); | 51 | extern void iwl3945_led_unregister(struct iwl_priv *priv); |
66 | extern void iwl3945_led_background(struct iwl3945_priv *priv); | 52 | extern void iwl3945_led_background(struct iwl_priv *priv); |
67 | 53 | ||
68 | #else | 54 | #else |
69 | static inline int iwl3945_led_register(struct iwl3945_priv *priv) { return 0; } | 55 | static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; } |
70 | static inline void iwl3945_led_unregister(struct iwl3945_priv *priv) {} | 56 | static inline void iwl3945_led_unregister(struct iwl_priv *priv) {} |
71 | static inline void iwl3945_led_background(struct iwl3945_priv *priv) {} | 57 | static inline void iwl3945_led_background(struct iwl_priv *priv) {} |
72 | #endif /* CONFIG_IWL3945_LEDS */ | 58 | #endif /* CONFIG_IWL3945_LEDS */ |
73 | 59 | ||
74 | #endif /* IWL3945_LEDS_H */ | 60 | #endif /* IWL3945_LEDS_H */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 21c841847d88..044abf734eb6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #include <linux/workqueue.h> | 37 | #include <linux/workqueue.h> |
38 | 38 | ||
39 | #include "iwl-commands.h" | ||
39 | #include "iwl-3945.h" | 40 | #include "iwl-3945.h" |
40 | 41 | ||
41 | #define RS_NAME "iwl-3945-rs" | 42 | #define RS_NAME "iwl-3945-rs" |
@@ -51,6 +52,7 @@ struct iwl3945_rate_scale_data { | |||
51 | 52 | ||
52 | struct iwl3945_rs_sta { | 53 | struct iwl3945_rs_sta { |
53 | spinlock_t lock; | 54 | spinlock_t lock; |
55 | struct iwl_priv *priv; | ||
54 | s32 *expected_tpt; | 56 | s32 *expected_tpt; |
55 | unsigned long last_partial_flush; | 57 | unsigned long last_partial_flush; |
56 | unsigned long last_flush; | 58 | unsigned long last_flush; |
@@ -62,7 +64,7 @@ struct iwl3945_rs_sta { | |||
62 | u8 start_rate; | 64 | u8 start_rate; |
63 | u8 ibss_sta_added; | 65 | u8 ibss_sta_added; |
64 | struct timer_list rate_scale_flush; | 66 | struct timer_list rate_scale_flush; |
65 | struct iwl3945_rate_scale_data win[IWL_RATE_COUNT]; | 67 | struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; |
66 | #ifdef CONFIG_MAC80211_DEBUGFS | 68 | #ifdef CONFIG_MAC80211_DEBUGFS |
67 | struct dentry *rs_sta_dbgfs_stats_table_file; | 69 | struct dentry *rs_sta_dbgfs_stats_table_file; |
68 | #endif | 70 | #endif |
@@ -71,19 +73,19 @@ struct iwl3945_rs_sta { | |||
71 | int last_txrate_idx; | 73 | int last_txrate_idx; |
72 | }; | 74 | }; |
73 | 75 | ||
74 | static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT] = { | 76 | static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = { |
75 | 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 | 77 | 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 |
76 | }; | 78 | }; |
77 | 79 | ||
78 | static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT] = { | 80 | static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = { |
79 | 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 | 81 | 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 |
80 | }; | 82 | }; |
81 | 83 | ||
82 | static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT] = { | 84 | static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = { |
83 | 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 | 85 | 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 |
84 | }; | 86 | }; |
85 | 87 | ||
86 | static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT] = { | 88 | static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = { |
87 | 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 | 89 | 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 |
88 | }; | 90 | }; |
89 | 91 | ||
@@ -119,7 +121,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { | |||
119 | #define IWL_RATE_MAX_WINDOW 62 | 121 | #define IWL_RATE_MAX_WINDOW 62 |
120 | #define IWL_RATE_FLUSH (3*HZ) | 122 | #define IWL_RATE_FLUSH (3*HZ) |
121 | #define IWL_RATE_WIN_FLUSH (HZ/2) | 123 | #define IWL_RATE_WIN_FLUSH (HZ/2) |
122 | #define IWL_RATE_HIGH_TH 11520 | 124 | #define IWL39_RATE_HIGH_TH 11520 |
123 | #define IWL_SUCCESS_UP_TH 8960 | 125 | #define IWL_SUCCESS_UP_TH 8960 |
124 | #define IWL_SUCCESS_DOWN_TH 10880 | 126 | #define IWL_SUCCESS_DOWN_TH 10880 |
125 | #define IWL_RATE_MIN_FAILURE_TH 8 | 127 | #define IWL_RATE_MIN_FAILURE_TH 8 |
@@ -165,7 +167,7 @@ static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window) | |||
165 | window->success_counter = 0; | 167 | window->success_counter = 0; |
166 | window->success_ratio = -1; | 168 | window->success_ratio = -1; |
167 | window->counter = 0; | 169 | window->counter = 0; |
168 | window->average_tpt = IWL_INV_TPT; | 170 | window->average_tpt = IWL_INVALID_VALUE; |
169 | window->stamp = 0; | 171 | window->stamp = 0; |
170 | } | 172 | } |
171 | 173 | ||
@@ -181,13 +183,14 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) | |||
181 | int unflushed = 0; | 183 | int unflushed = 0; |
182 | int i; | 184 | int i; |
183 | unsigned long flags; | 185 | unsigned long flags; |
186 | struct iwl_priv *priv = rs_sta->priv; | ||
184 | 187 | ||
185 | /* | 188 | /* |
186 | * For each rate, if we have collected data on that rate | 189 | * For each rate, if we have collected data on that rate |
187 | * and it has been more than IWL_RATE_WIN_FLUSH | 190 | * and it has been more than IWL_RATE_WIN_FLUSH |
188 | * since we flushed, clear out the gathered statistics | 191 | * since we flushed, clear out the gathered statistics |
189 | */ | 192 | */ |
190 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 193 | for (i = 0; i < IWL_RATE_COUNT_3945; i++) { |
191 | if (!rs_sta->win[i].counter) | 194 | if (!rs_sta->win[i].counter) |
192 | continue; | 195 | continue; |
193 | 196 | ||
@@ -213,6 +216,7 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) | |||
213 | static void iwl3945_bg_rate_scale_flush(unsigned long data) | 216 | static void iwl3945_bg_rate_scale_flush(unsigned long data) |
214 | { | 217 | { |
215 | struct iwl3945_rs_sta *rs_sta = (void *)data; | 218 | struct iwl3945_rs_sta *rs_sta = (void *)data; |
219 | struct iwl_priv *priv = rs_sta->priv; | ||
216 | int unflushed = 0; | 220 | int unflushed = 0; |
217 | unsigned long flags; | 221 | unsigned long flags; |
218 | u32 packet_count, duration, pps; | 222 | u32 packet_count, duration, pps; |
@@ -286,6 +290,7 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | |||
286 | { | 290 | { |
287 | unsigned long flags; | 291 | unsigned long flags; |
288 | s32 fail_count; | 292 | s32 fail_count; |
293 | struct iwl_priv *priv = rs_sta->priv; | ||
289 | 294 | ||
290 | if (!retries) { | 295 | if (!retries) { |
291 | IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n"); | 296 | IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n"); |
@@ -329,7 +334,7 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, | |||
329 | window->average_tpt = ((window->success_ratio * | 334 | window->average_tpt = ((window->success_ratio * |
330 | rs_sta->expected_tpt[index] + 64) / 128); | 335 | rs_sta->expected_tpt[index] + 64) / 128); |
331 | else | 336 | else |
332 | window->average_tpt = IWL_INV_TPT; | 337 | window->average_tpt = IWL_INVALID_VALUE; |
333 | 338 | ||
334 | spin_unlock_irqrestore(&rs_sta->lock, flags); | 339 | spin_unlock_irqrestore(&rs_sta->lock, flags); |
335 | 340 | ||
@@ -339,7 +344,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
339 | struct ieee80211_sta *sta, void *priv_sta) | 344 | struct ieee80211_sta *sta, void *priv_sta) |
340 | { | 345 | { |
341 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 346 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
342 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; | 347 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; |
343 | int i; | 348 | int i; |
344 | 349 | ||
345 | IWL_DEBUG_RATE("enter\n"); | 350 | IWL_DEBUG_RATE("enter\n"); |
@@ -379,10 +384,11 @@ static void rs_free(void *priv) | |||
379 | return; | 384 | return; |
380 | } | 385 | } |
381 | 386 | ||
382 | static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | 387 | static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) |
383 | { | 388 | { |
384 | struct iwl3945_rs_sta *rs_sta; | 389 | struct iwl3945_rs_sta *rs_sta; |
385 | struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; | 390 | struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; |
391 | struct iwl_priv *priv = iwl_priv; | ||
386 | int i; | 392 | int i; |
387 | 393 | ||
388 | /* | 394 | /* |
@@ -402,6 +408,8 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
402 | 408 | ||
403 | spin_lock_init(&rs_sta->lock); | 409 | spin_lock_init(&rs_sta->lock); |
404 | 410 | ||
411 | rs_sta->priv = priv; | ||
412 | |||
405 | rs_sta->start_rate = IWL_RATE_INVALID; | 413 | rs_sta->start_rate = IWL_RATE_INVALID; |
406 | 414 | ||
407 | /* default to just 802.11b */ | 415 | /* default to just 802.11b */ |
@@ -417,7 +425,7 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
417 | rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; | 425 | rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; |
418 | rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush; | 426 | rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush; |
419 | 427 | ||
420 | for (i = 0; i < IWL_RATE_COUNT; i++) | 428 | for (i = 0; i < IWL_RATE_COUNT_3945; i++) |
421 | iwl3945_clear_window(&rs_sta->win[i]); | 429 | iwl3945_clear_window(&rs_sta->win[i]); |
422 | 430 | ||
423 | IWL_DEBUG_RATE("leave\n"); | 431 | IWL_DEBUG_RATE("leave\n"); |
@@ -425,11 +433,12 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
425 | return rs_sta; | 433 | return rs_sta; |
426 | } | 434 | } |
427 | 435 | ||
428 | static void rs_free_sta(void *priv, struct ieee80211_sta *sta, | 436 | static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, |
429 | void *priv_sta) | 437 | void *priv_sta) |
430 | { | 438 | { |
431 | struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; | 439 | struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; |
432 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 440 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
441 | struct iwl_priv *priv = rs_sta->priv; | ||
433 | 442 | ||
434 | psta->rs_sta = NULL; | 443 | psta->rs_sta = NULL; |
435 | 444 | ||
@@ -443,7 +452,7 @@ static void rs_free_sta(void *priv, struct ieee80211_sta *sta, | |||
443 | /** | 452 | /** |
444 | * rs_tx_status - Update rate control values based on Tx results | 453 | * rs_tx_status - Update rate control values based on Tx results |
445 | * | 454 | * |
446 | * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by | 455 | * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by |
447 | * the hardware for each rate. | 456 | * the hardware for each rate. |
448 | */ | 457 | */ |
449 | static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, | 458 | static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, |
@@ -453,7 +462,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
453 | s8 retries = 0, current_count; | 462 | s8 retries = 0, current_count; |
454 | int scale_rate_index, first_index, last_index; | 463 | int scale_rate_index, first_index, last_index; |
455 | unsigned long flags; | 464 | unsigned long flags; |
456 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; | 465 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
457 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 466 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
458 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 467 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
459 | 468 | ||
@@ -462,7 +471,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
462 | retries = info->status.rates[0].count; | 471 | retries = info->status.rates[0].count; |
463 | 472 | ||
464 | first_index = sband->bitrates[info->status.rates[0].idx].hw_value; | 473 | first_index = sband->bitrates[info->status.rates[0].idx].hw_value; |
465 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { | 474 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) { |
466 | IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); | 475 | IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); |
467 | return; | 476 | return; |
468 | } | 477 | } |
@@ -547,6 +556,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | |||
547 | { | 556 | { |
548 | u8 high = IWL_RATE_INVALID; | 557 | u8 high = IWL_RATE_INVALID; |
549 | u8 low = IWL_RATE_INVALID; | 558 | u8 low = IWL_RATE_INVALID; |
559 | struct iwl_priv *priv = rs_sta->priv; | ||
550 | 560 | ||
551 | /* 802.11A walks to the next literal adjacent rate in | 561 | /* 802.11A walks to the next literal adjacent rate in |
552 | * the rate table */ | 562 | * the rate table */ |
@@ -565,7 +575,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | |||
565 | 575 | ||
566 | /* Find the next rate that is in the rate mask */ | 576 | /* Find the next rate that is in the rate mask */ |
567 | i = index + 1; | 577 | i = index + 1; |
568 | for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) { | 578 | for (mask = (1 << i); i < IWL_RATE_COUNT_3945; |
579 | i++, mask <<= 1) { | ||
569 | if (rate_mask & mask) { | 580 | if (rate_mask & mask) { |
570 | high = i; | 581 | high = i; |
571 | break; | 582 | break; |
@@ -631,16 +642,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
631 | int index; | 642 | int index; |
632 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 643 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
633 | struct iwl3945_rate_scale_data *window = NULL; | 644 | struct iwl3945_rate_scale_data *window = NULL; |
634 | int current_tpt = IWL_INV_TPT; | 645 | int current_tpt = IWL_INVALID_VALUE; |
635 | int low_tpt = IWL_INV_TPT; | 646 | int low_tpt = IWL_INVALID_VALUE; |
636 | int high_tpt = IWL_INV_TPT; | 647 | int high_tpt = IWL_INVALID_VALUE; |
637 | u32 fail_count; | 648 | u32 fail_count; |
638 | s8 scale_action = 0; | 649 | s8 scale_action = 0; |
639 | unsigned long flags; | 650 | unsigned long flags; |
640 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 651 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
641 | u16 fc; | 652 | u16 fc; |
642 | u16 rate_mask = 0; | 653 | u16 rate_mask = 0; |
643 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; | 654 | s8 max_rate_idx = -1; |
655 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; | ||
644 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 656 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
645 | 657 | ||
646 | IWL_DEBUG_RATE("enter\n"); | 658 | IWL_DEBUG_RATE("enter\n"); |
@@ -664,7 +676,14 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
664 | return; | 676 | return; |
665 | } | 677 | } |
666 | 678 | ||
667 | index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); | 679 | /* get user max rate if set */ |
680 | max_rate_idx = txrc->max_rate_idx; | ||
681 | if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1)) | ||
682 | max_rate_idx += IWL_FIRST_OFDM_RATE; | ||
683 | if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT)) | ||
684 | max_rate_idx = -1; | ||
685 | |||
686 | index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1); | ||
668 | 687 | ||
669 | if (sband->band == IEEE80211_BAND_5GHZ) | 688 | if (sband->band == IEEE80211_BAND_5GHZ) |
670 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; | 689 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; |
@@ -695,6 +714,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
695 | rs_sta->start_rate = IWL_RATE_INVALID; | 714 | rs_sta->start_rate = IWL_RATE_INVALID; |
696 | } | 715 | } |
697 | 716 | ||
717 | /* force user max rate if set by user */ | ||
718 | if ((max_rate_idx != -1) && (max_rate_idx < index)) { | ||
719 | if (rate_mask & (1 << max_rate_idx)) | ||
720 | index = max_rate_idx; | ||
721 | } | ||
722 | |||
698 | window = &(rs_sta->win[index]); | 723 | window = &(rs_sta->win[index]); |
699 | 724 | ||
700 | fail_count = window->counter - window->success_counter; | 725 | fail_count = window->counter - window->success_counter; |
@@ -721,6 +746,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
721 | low = high_low & 0xff; | 746 | low = high_low & 0xff; |
722 | high = (high_low >> 8) & 0xff; | 747 | high = (high_low >> 8) & 0xff; |
723 | 748 | ||
749 | /* If user set max rate, dont allow higher than user constrain */ | ||
750 | if ((max_rate_idx != -1) && (max_rate_idx < high)) | ||
751 | high = IWL_RATE_INVALID; | ||
752 | |||
724 | if (low != IWL_RATE_INVALID) | 753 | if (low != IWL_RATE_INVALID) |
725 | low_tpt = rs_sta->win[low].average_tpt; | 754 | low_tpt = rs_sta->win[low].average_tpt; |
726 | 755 | ||
@@ -734,16 +763,18 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
734 | if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { | 763 | if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) { |
735 | IWL_DEBUG_RATE("decrease rate because of low success_ratio\n"); | 764 | IWL_DEBUG_RATE("decrease rate because of low success_ratio\n"); |
736 | scale_action = -1; | 765 | scale_action = -1; |
737 | } else if ((low_tpt == IWL_INV_TPT) && (high_tpt == IWL_INV_TPT)) | 766 | } else if ((low_tpt == IWL_INVALID_VALUE) && |
767 | (high_tpt == IWL_INVALID_VALUE)) | ||
738 | scale_action = 1; | 768 | scale_action = 1; |
739 | else if ((low_tpt != IWL_INV_TPT) && (high_tpt != IWL_INV_TPT) && | 769 | else if ((low_tpt != IWL_INVALID_VALUE) && |
770 | (high_tpt != IWL_INVALID_VALUE) && | ||
740 | (low_tpt < current_tpt) && (high_tpt < current_tpt)) { | 771 | (low_tpt < current_tpt) && (high_tpt < current_tpt)) { |
741 | IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < " | 772 | IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < " |
742 | "current_tpt [%d]\n", | 773 | "current_tpt [%d]\n", |
743 | low_tpt, high_tpt, current_tpt); | 774 | low_tpt, high_tpt, current_tpt); |
744 | scale_action = 0; | 775 | scale_action = 0; |
745 | } else { | 776 | } else { |
746 | if (high_tpt != IWL_INV_TPT) { | 777 | if (high_tpt != IWL_INVALID_VALUE) { |
747 | if (high_tpt > current_tpt) | 778 | if (high_tpt > current_tpt) |
748 | scale_action = 1; | 779 | scale_action = 1; |
749 | else { | 780 | else { |
@@ -751,7 +782,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, | |||
751 | ("decrease rate because of high tpt\n"); | 782 | ("decrease rate because of high tpt\n"); |
752 | scale_action = -1; | 783 | scale_action = -1; |
753 | } | 784 | } |
754 | } else if (low_tpt != IWL_INV_TPT) { | 785 | } else if (low_tpt != IWL_INVALID_VALUE) { |
755 | if (low_tpt > current_tpt) { | 786 | if (low_tpt > current_tpt) { |
756 | IWL_DEBUG_RATE | 787 | IWL_DEBUG_RATE |
757 | ("decrease rate because of low tpt\n"); | 788 | ("decrease rate because of low tpt\n"); |
@@ -825,7 +856,7 @@ static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file, | |||
825 | lq_sta->tx_packets, | 856 | lq_sta->tx_packets, |
826 | lq_sta->last_txrate_idx, | 857 | lq_sta->last_txrate_idx, |
827 | lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time)); | 858 | lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time)); |
828 | for (j = 0; j < IWL_RATE_COUNT; j++) { | 859 | for (j = 0; j < IWL_RATE_COUNT_3945; j++) { |
829 | desc += sprintf(buff+desc, | 860 | desc += sprintf(buff+desc, |
830 | "counter=%d success=%d %%=%d\n", | 861 | "counter=%d success=%d %%=%d\n", |
831 | lq_sta->win[j].counter, | 862 | lq_sta->win[j].counter, |
@@ -877,7 +908,7 @@ static struct rate_control_ops rs_ops = { | |||
877 | 908 | ||
878 | void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | 909 | void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) |
879 | { | 910 | { |
880 | struct iwl3945_priv *priv = hw->priv; | 911 | struct iwl_priv *priv = hw->priv; |
881 | s32 rssi = 0; | 912 | s32 rssi = 0; |
882 | unsigned long flags; | 913 | unsigned long flags; |
883 | struct iwl3945_rs_sta *rs_sta; | 914 | struct iwl3945_rs_sta *rs_sta; |
@@ -888,7 +919,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
888 | 919 | ||
889 | rcu_read_lock(); | 920 | rcu_read_lock(); |
890 | 921 | ||
891 | sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr); | 922 | sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr); |
892 | if (!sta) { | 923 | if (!sta) { |
893 | rcu_read_unlock(); | 924 | rcu_read_unlock(); |
894 | return; | 925 | return; |
@@ -903,7 +934,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
903 | switch (priv->band) { | 934 | switch (priv->band) { |
904 | case IEEE80211_BAND_2GHZ: | 935 | case IEEE80211_BAND_2GHZ: |
905 | /* TODO: this always does G, not a regression */ | 936 | /* TODO: this always does G, not a regression */ |
906 | if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { | 937 | if (priv->active39_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { |
907 | rs_sta->tgg = 1; | 938 | rs_sta->tgg = 1; |
908 | rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; | 939 | rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; |
909 | } else | 940 | } else |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h deleted file mode 100644 index b5a66135dedd..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h +++ /dev/null | |||
@@ -1,206 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
24 | * | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | #ifndef __iwl_3945_rs_h__ | ||
28 | #define __iwl_3945_rs_h__ | ||
29 | |||
30 | struct iwl3945_rate_info { | ||
31 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ | ||
32 | u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ | ||
33 | u8 prev_ieee; /* previous rate in IEEE speeds */ | ||
34 | u8 next_ieee; /* next rate in IEEE speeds */ | ||
35 | u8 prev_rs; /* previous 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 */ | ||
38 | u8 next_rs_tgg; /* next rate used in TGG rs algo */ | ||
39 | u8 table_rs_index; /* index in rate scale table cmd */ | ||
40 | u8 prev_table_rs; /* prev in rate table cmd */ | ||
41 | }; | ||
42 | |||
43 | /* | ||
44 | * These serve as indexes into | ||
45 | * struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT]; | ||
46 | */ | ||
47 | enum { | ||
48 | IWL_RATE_1M_INDEX = 0, | ||
49 | IWL_RATE_2M_INDEX, | ||
50 | IWL_RATE_5M_INDEX, | ||
51 | IWL_RATE_11M_INDEX, | ||
52 | IWL_RATE_6M_INDEX, | ||
53 | IWL_RATE_9M_INDEX, | ||
54 | IWL_RATE_12M_INDEX, | ||
55 | IWL_RATE_18M_INDEX, | ||
56 | IWL_RATE_24M_INDEX, | ||
57 | IWL_RATE_36M_INDEX, | ||
58 | IWL_RATE_48M_INDEX, | ||
59 | IWL_RATE_54M_INDEX, | ||
60 | IWL_RATE_COUNT, | ||
61 | IWL_RATE_INVM_INDEX, | ||
62 | IWL_RATE_INVALID = IWL_RATE_INVM_INDEX | ||
63 | }; | ||
64 | |||
65 | enum { | ||
66 | IWL_RATE_6M_INDEX_TABLE = 0, | ||
67 | IWL_RATE_9M_INDEX_TABLE, | ||
68 | IWL_RATE_12M_INDEX_TABLE, | ||
69 | IWL_RATE_18M_INDEX_TABLE, | ||
70 | IWL_RATE_24M_INDEX_TABLE, | ||
71 | IWL_RATE_36M_INDEX_TABLE, | ||
72 | IWL_RATE_48M_INDEX_TABLE, | ||
73 | IWL_RATE_54M_INDEX_TABLE, | ||
74 | IWL_RATE_1M_INDEX_TABLE, | ||
75 | IWL_RATE_2M_INDEX_TABLE, | ||
76 | IWL_RATE_5M_INDEX_TABLE, | ||
77 | IWL_RATE_11M_INDEX_TABLE, | ||
78 | IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX, | ||
79 | }; | ||
80 | |||
81 | enum { | ||
82 | IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, | ||
83 | IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, | ||
84 | IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, | ||
85 | IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, | ||
86 | }; | ||
87 | |||
88 | /* #define vs. enum to keep from defaulting to 'large integer' */ | ||
89 | #define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX) | ||
90 | #define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX) | ||
91 | #define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX) | ||
92 | #define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX) | ||
93 | #define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX) | ||
94 | #define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX) | ||
95 | #define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX) | ||
96 | #define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX) | ||
97 | #define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX) | ||
98 | #define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX) | ||
99 | #define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX) | ||
100 | #define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) | ||
101 | |||
102 | /* 3945 uCode API values for (legacy) bit rates, both OFDM and CCK */ | ||
103 | enum { | ||
104 | IWL_RATE_6M_PLCP = 13, | ||
105 | IWL_RATE_9M_PLCP = 15, | ||
106 | IWL_RATE_12M_PLCP = 5, | ||
107 | IWL_RATE_18M_PLCP = 7, | ||
108 | IWL_RATE_24M_PLCP = 9, | ||
109 | IWL_RATE_36M_PLCP = 11, | ||
110 | IWL_RATE_48M_PLCP = 1, | ||
111 | IWL_RATE_54M_PLCP = 3, | ||
112 | IWL_RATE_1M_PLCP = 10, | ||
113 | IWL_RATE_2M_PLCP = 20, | ||
114 | IWL_RATE_5M_PLCP = 55, | ||
115 | IWL_RATE_11M_PLCP = 110, | ||
116 | }; | ||
117 | |||
118 | /* MAC header values for bit rates */ | ||
119 | enum { | ||
120 | IWL_RATE_6M_IEEE = 12, | ||
121 | IWL_RATE_9M_IEEE = 18, | ||
122 | IWL_RATE_12M_IEEE = 24, | ||
123 | IWL_RATE_18M_IEEE = 36, | ||
124 | IWL_RATE_24M_IEEE = 48, | ||
125 | IWL_RATE_36M_IEEE = 72, | ||
126 | IWL_RATE_48M_IEEE = 96, | ||
127 | IWL_RATE_54M_IEEE = 108, | ||
128 | IWL_RATE_1M_IEEE = 2, | ||
129 | IWL_RATE_2M_IEEE = 4, | ||
130 | IWL_RATE_5M_IEEE = 11, | ||
131 | IWL_RATE_11M_IEEE = 22, | ||
132 | }; | ||
133 | |||
134 | #define IWL_CCK_BASIC_RATES_MASK \ | ||
135 | (IWL_RATE_1M_MASK | \ | ||
136 | IWL_RATE_2M_MASK) | ||
137 | |||
138 | #define IWL_CCK_RATES_MASK \ | ||
139 | (IWL_BASIC_RATES_MASK | \ | ||
140 | IWL_RATE_5M_MASK | \ | ||
141 | IWL_RATE_11M_MASK) | ||
142 | |||
143 | #define IWL_OFDM_BASIC_RATES_MASK \ | ||
144 | (IWL_RATE_6M_MASK | \ | ||
145 | IWL_RATE_12M_MASK | \ | ||
146 | IWL_RATE_24M_MASK) | ||
147 | |||
148 | #define IWL_OFDM_RATES_MASK \ | ||
149 | (IWL_OFDM_BASIC_RATES_MASK | \ | ||
150 | IWL_RATE_9M_MASK | \ | ||
151 | IWL_RATE_18M_MASK | \ | ||
152 | IWL_RATE_36M_MASK | \ | ||
153 | IWL_RATE_48M_MASK | \ | ||
154 | IWL_RATE_54M_MASK) | ||
155 | |||
156 | #define IWL_BASIC_RATES_MASK \ | ||
157 | (IWL_OFDM_BASIC_RATES_MASK | \ | ||
158 | IWL_CCK_BASIC_RATES_MASK) | ||
159 | |||
160 | #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) | ||
161 | |||
162 | #define IWL_INV_TPT -1 | ||
163 | |||
164 | #define IWL_MIN_RSSI_VAL -100 | ||
165 | #define IWL_MAX_RSSI_VAL 0 | ||
166 | |||
167 | extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT]; | ||
168 | |||
169 | static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) | ||
170 | { | ||
171 | u8 rate = iwl3945_rates[rate_index].prev_ieee; | ||
172 | |||
173 | if (rate == IWL_RATE_INVALID) | ||
174 | rate = rate_index; | ||
175 | return rate; | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info | ||
180 | * | ||
181 | * The specific throughput table used is based on the type of network | ||
182 | * the associated with, including A, B, G, and G w/ TGG protection | ||
183 | */ | ||
184 | extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); | ||
185 | |||
186 | /** | ||
187 | * iwl3945_rate_control_register - Register the rate control algorithm callbacks | ||
188 | * | ||
189 | * Since the rate control algorithm is hardware specific, there is no need | ||
190 | * or reason to place it as a stand alone module. The driver can call | ||
191 | * iwl3945_rate_control_register in order to register the rate control callbacks | ||
192 | * with the mac80211 subsystem. This should be performed prior to calling | ||
193 | * ieee80211_register_hw | ||
194 | * | ||
195 | */ | ||
196 | extern int iwl3945_rate_control_register(void); | ||
197 | |||
198 | /** | ||
199 | * iwl3945_rate_control_unregister - Unregister the rate control callbacks | ||
200 | * | ||
201 | * This should be called after calling ieee80211_unregister_hw, but before | ||
202 | * the driver is unloaded. | ||
203 | */ | ||
204 | extern void iwl3945_rate_control_unregister(void); | ||
205 | |||
206 | #endif | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 45cfa1cf194a..12f93b6207d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -38,10 +38,15 @@ | |||
38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
39 | #include <net/mac80211.h> | 39 | #include <net/mac80211.h> |
40 | 40 | ||
41 | #include "iwl-3945-core.h" | 41 | #include "iwl-fh.h" |
42 | #include "iwl-3945-fh.h" | ||
43 | #include "iwl-commands.h" | ||
44 | #include "iwl-sta.h" | ||
42 | #include "iwl-3945.h" | 45 | #include "iwl-3945.h" |
46 | #include "iwl-eeprom.h" | ||
43 | #include "iwl-helpers.h" | 47 | #include "iwl-helpers.h" |
44 | #include "iwl-3945-rs.h" | 48 | #include "iwl-core.h" |
49 | #include "iwl-agn-rs.h" | ||
45 | 50 | ||
46 | #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ | 51 | #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ |
47 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ | 52 | [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ |
@@ -63,7 +68,7 @@ | |||
63 | * maps to IWL_RATE_INVALID | 68 | * maps to IWL_RATE_INVALID |
64 | * | 69 | * |
65 | */ | 70 | */ |
66 | const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = { | 71 | const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = { |
67 | IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */ | 72 | IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */ |
68 | IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */ | 73 | IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */ |
69 | IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */ | 74 | IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */ |
@@ -91,7 +96,7 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = { | |||
91 | * Use for only special debugging. This function is just a placeholder as-is, | 96 | * Use for only special debugging. This function is just a placeholder as-is, |
92 | * you'll need to provide the special bits! ... | 97 | * you'll need to provide the special bits! ... |
93 | * ... and set IWL_EVT_DISABLE to 1. */ | 98 | * ... and set IWL_EVT_DISABLE to 1. */ |
94 | void iwl3945_disable_events(struct iwl3945_priv *priv) | 99 | void iwl3945_disable_events(struct iwl_priv *priv) |
95 | { | 100 | { |
96 | int ret; | 101 | int ret; |
97 | int i; | 102 | int i; |
@@ -150,30 +155,30 @@ void iwl3945_disable_events(struct iwl3945_priv *priv) | |||
150 | 155 | ||
151 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 156 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
152 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { | 157 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { |
153 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); | 158 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); |
154 | return; | 159 | return; |
155 | } | 160 | } |
156 | 161 | ||
157 | ret = iwl3945_grab_nic_access(priv); | 162 | ret = iwl_grab_nic_access(priv); |
158 | if (ret) { | 163 | if (ret) { |
159 | IWL_WARNING("Can not read from adapter at this time.\n"); | 164 | IWL_WARN(priv, "Can not read from adapter at this time.\n"); |
160 | return; | 165 | return; |
161 | } | 166 | } |
162 | 167 | ||
163 | disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32))); | 168 | disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32))); |
164 | array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32))); | 169 | array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32))); |
165 | iwl3945_release_nic_access(priv); | 170 | iwl_release_nic_access(priv); |
166 | 171 | ||
167 | if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { | 172 | if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { |
168 | IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n", | 173 | IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n", |
169 | disable_ptr); | 174 | disable_ptr); |
170 | ret = iwl3945_grab_nic_access(priv); | 175 | ret = iwl_grab_nic_access(priv); |
171 | for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) | 176 | for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) |
172 | iwl3945_write_targ_mem(priv, | 177 | iwl_write_targ_mem(priv, |
173 | disable_ptr + (i * sizeof(u32)), | 178 | disable_ptr + (i * sizeof(u32)), |
174 | evt_disable[i]); | 179 | evt_disable[i]); |
175 | 180 | ||
176 | iwl3945_release_nic_access(priv); | 181 | iwl_release_nic_access(priv); |
177 | } else { | 182 | } else { |
178 | IWL_DEBUG_INFO("Selected uCode log events may be disabled\n"); | 183 | IWL_DEBUG_INFO("Selected uCode log events may be disabled\n"); |
179 | IWL_DEBUG_INFO(" by writing \"1\"s into disable bitmap\n"); | 184 | IWL_DEBUG_INFO(" by writing \"1\"s into disable bitmap\n"); |
@@ -193,40 +198,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp) | |||
193 | return -1; | 198 | return -1; |
194 | } | 199 | } |
195 | 200 | ||
196 | /** | 201 | #ifdef CONFIG_IWLWIFI_DEBUG |
197 | * iwl3945_get_antenna_flags - Get antenna flags for RXON command | ||
198 | * @priv: eeprom and antenna fields are used to determine antenna flags | ||
199 | * | ||
200 | * priv->eeprom is used to determine if antenna AUX/MAIN are reversed | ||
201 | * priv->antenna specifies the antenna diversity mode: | ||
202 | * | ||
203 | * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself | ||
204 | * IWL_ANTENNA_MAIN - Force MAIN antenna | ||
205 | * IWL_ANTENNA_AUX - Force AUX antenna | ||
206 | */ | ||
207 | __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv) | ||
208 | { | ||
209 | switch (priv->antenna) { | ||
210 | case IWL_ANTENNA_DIVERSITY: | ||
211 | return 0; | ||
212 | |||
213 | case IWL_ANTENNA_MAIN: | ||
214 | if (priv->eeprom.antenna_switch_type) | ||
215 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; | ||
216 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; | ||
217 | |||
218 | case IWL_ANTENNA_AUX: | ||
219 | if (priv->eeprom.antenna_switch_type) | ||
220 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; | ||
221 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; | ||
222 | } | ||
223 | |||
224 | /* bad antenna selector value */ | ||
225 | IWL_ERROR("Bad antenna selector value (0x%x)\n", priv->antenna); | ||
226 | return 0; /* "diversity" is default if error */ | ||
227 | } | ||
228 | |||
229 | #ifdef CONFIG_IWL3945_DEBUG | ||
230 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 202 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x |
231 | 203 | ||
232 | static const char *iwl3945_get_tx_fail_reason(u32 status) | 204 | static const char *iwl3945_get_tx_fail_reason(u32 status) |
@@ -266,7 +238,7 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status) | |||
266 | * for A and B mode we need to overright prev | 238 | * for A and B mode we need to overright prev |
267 | * value | 239 | * value |
268 | */ | 240 | */ |
269 | int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate) | 241 | int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) |
270 | { | 242 | { |
271 | int next_rate = iwl3945_get_prev_ieee_rate(rate); | 243 | int next_rate = iwl3945_get_prev_ieee_rate(rate); |
272 | 244 | ||
@@ -300,12 +272,12 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate) | |||
300 | * need to be reclaimed. As result, some free space forms. If there is | 272 | * need to be reclaimed. As result, some free space forms. If there is |
301 | * enough free space (> low mark), wake the stack that feeds us. | 273 | * enough free space (> low mark), wake the stack that feeds us. |
302 | */ | 274 | */ |
303 | static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, | 275 | static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, |
304 | int txq_id, int index) | 276 | int txq_id, int index) |
305 | { | 277 | { |
306 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; | 278 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
307 | struct iwl3945_queue *q = &txq->q; | 279 | struct iwl_queue *q = &txq->q; |
308 | struct iwl3945_tx_info *tx_info; | 280 | struct iwl_tx_info *tx_info; |
309 | 281 | ||
310 | BUG_ON(txq_id == IWL_CMD_QUEUE_NUM); | 282 | BUG_ON(txq_id == IWL_CMD_QUEUE_NUM); |
311 | 283 | ||
@@ -315,10 +287,10 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, | |||
315 | tx_info = &txq->txb[txq->q.read_ptr]; | 287 | tx_info = &txq->txb[txq->q.read_ptr]; |
316 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); | 288 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); |
317 | tx_info->skb[0] = NULL; | 289 | tx_info->skb[0] = NULL; |
318 | iwl3945_hw_txq_free_tfd(priv, txq); | 290 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
319 | } | 291 | } |
320 | 292 | ||
321 | if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) && | 293 | if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && |
322 | (txq_id != IWL_CMD_QUEUE_NUM) && | 294 | (txq_id != IWL_CMD_QUEUE_NUM) && |
323 | priv->mac80211_registered) | 295 | priv->mac80211_registered) |
324 | ieee80211_wake_queue(priv->hw, txq_id); | 296 | ieee80211_wake_queue(priv->hw, txq_id); |
@@ -327,22 +299,22 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, | |||
327 | /** | 299 | /** |
328 | * iwl3945_rx_reply_tx - Handle Tx response | 300 | * iwl3945_rx_reply_tx - Handle Tx response |
329 | */ | 301 | */ |
330 | static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | 302 | static void iwl3945_rx_reply_tx(struct iwl_priv *priv, |
331 | struct iwl3945_rx_mem_buffer *rxb) | 303 | struct iwl_rx_mem_buffer *rxb) |
332 | { | 304 | { |
333 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 305 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
334 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 306 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
335 | int txq_id = SEQ_TO_QUEUE(sequence); | 307 | int txq_id = SEQ_TO_QUEUE(sequence); |
336 | int index = SEQ_TO_INDEX(sequence); | 308 | int index = SEQ_TO_INDEX(sequence); |
337 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; | 309 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
338 | struct ieee80211_tx_info *info; | 310 | struct ieee80211_tx_info *info; |
339 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 311 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
340 | u32 status = le32_to_cpu(tx_resp->status); | 312 | u32 status = le32_to_cpu(tx_resp->status); |
341 | int rate_idx; | 313 | int rate_idx; |
342 | int fail; | 314 | int fail; |
343 | 315 | ||
344 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { | 316 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
345 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 317 | IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " |
346 | "is out of range [0-%d] %d %d\n", txq_id, | 318 | "is out of range [0-%d] %d %d\n", txq_id, |
347 | index, txq->q.n_bd, txq->q.write_ptr, | 319 | index, txq->q.n_bd, txq->q.write_ptr, |
348 | txq->q.read_ptr); | 320 | txq->q.read_ptr); |
@@ -374,7 +346,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
374 | iwl3945_tx_queue_reclaim(priv, txq_id, index); | 346 | iwl3945_tx_queue_reclaim(priv, txq_id, index); |
375 | 347 | ||
376 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 348 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
377 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | 349 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
378 | } | 350 | } |
379 | 351 | ||
380 | 352 | ||
@@ -387,14 +359,14 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
387 | * | 359 | * |
388 | *****************************************************************************/ | 360 | *****************************************************************************/ |
389 | 361 | ||
390 | void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb) | 362 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
391 | { | 363 | { |
392 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 364 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
393 | IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n", | 365 | IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n", |
394 | (int)sizeof(struct iwl3945_notif_statistics), | 366 | (int)sizeof(struct iwl3945_notif_statistics), |
395 | le32_to_cpu(pkt->len)); | 367 | le32_to_cpu(pkt->len)); |
396 | 368 | ||
397 | memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics)); | 369 | memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); |
398 | 370 | ||
399 | iwl3945_led_background(priv); | 371 | iwl3945_led_background(priv); |
400 | 372 | ||
@@ -406,7 +378,7 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b | |||
406 | * Misc. internal state and helper functions | 378 | * Misc. internal state and helper functions |
407 | * | 379 | * |
408 | ******************************************************************************/ | 380 | ******************************************************************************/ |
409 | #ifdef CONFIG_IWL3945_DEBUG | 381 | #ifdef CONFIG_IWLWIFI_DEBUG |
410 | 382 | ||
411 | /** | 383 | /** |
412 | * iwl3945_report_frame - dump frame to syslog during debug sessions | 384 | * iwl3945_report_frame - dump frame to syslog during debug sessions |
@@ -415,8 +387,8 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b | |||
415 | * including selective frame dumps. | 387 | * including selective frame dumps. |
416 | * group100 parameter selects whether to show 1 out of 100 good frames. | 388 | * group100 parameter selects whether to show 1 out of 100 good frames. |
417 | */ | 389 | */ |
418 | static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | 390 | static void _iwl3945_dbg_report_frame(struct iwl_priv *priv, |
419 | struct iwl3945_rx_packet *pkt, | 391 | struct iwl_rx_packet *pkt, |
420 | struct ieee80211_hdr *header, int group100) | 392 | struct ieee80211_hdr *header, int group100) |
421 | { | 393 | { |
422 | u32 to_us; | 394 | u32 to_us; |
@@ -540,18 +512,27 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
540 | } | 512 | } |
541 | } | 513 | } |
542 | if (print_dump) | 514 | if (print_dump) |
543 | iwl3945_print_hex_dump(IWL_DL_RX, data, length); | 515 | iwl_print_hex_dump(priv, IWL_DL_RX, data, length); |
516 | } | ||
517 | |||
518 | static void iwl3945_dbg_report_frame(struct iwl_priv *priv, | ||
519 | struct iwl_rx_packet *pkt, | ||
520 | struct ieee80211_hdr *header, int group100) | ||
521 | { | ||
522 | if (priv->debug_level & IWL_DL_RX) | ||
523 | _iwl3945_dbg_report_frame(priv, pkt, header, group100); | ||
544 | } | 524 | } |
525 | |||
545 | #else | 526 | #else |
546 | static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | 527 | static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv, |
547 | struct iwl3945_rx_packet *pkt, | 528 | struct iwl_rx_packet *pkt, |
548 | struct ieee80211_hdr *header, int group100) | 529 | struct ieee80211_hdr *header, int group100) |
549 | { | 530 | { |
550 | } | 531 | } |
551 | #endif | 532 | #endif |
552 | 533 | ||
553 | /* This is necessary only for a number of statistics, see the caller. */ | 534 | /* This is necessary only for a number of statistics, see the caller. */ |
554 | static int iwl3945_is_network_packet(struct iwl3945_priv *priv, | 535 | static int iwl3945_is_network_packet(struct iwl_priv *priv, |
555 | struct ieee80211_hdr *header) | 536 | struct ieee80211_hdr *header) |
556 | { | 537 | { |
557 | /* Filter incoming packets to determine if they are targeted toward | 538 | /* Filter incoming packets to determine if they are targeted toward |
@@ -568,11 +549,11 @@ static int iwl3945_is_network_packet(struct iwl3945_priv *priv, | |||
568 | } | 549 | } |
569 | } | 550 | } |
570 | 551 | ||
571 | static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv, | 552 | static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, |
572 | struct iwl3945_rx_mem_buffer *rxb, | 553 | struct iwl_rx_mem_buffer *rxb, |
573 | struct ieee80211_rx_status *stats) | 554 | struct ieee80211_rx_status *stats) |
574 | { | 555 | { |
575 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; | 556 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
576 | #ifdef CONFIG_IWL3945_LEDS | 557 | #ifdef CONFIG_IWL3945_LEDS |
577 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 558 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
578 | #endif | 559 | #endif |
@@ -581,7 +562,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv, | |||
581 | short len = le16_to_cpu(rx_hdr->len); | 562 | short len = le16_to_cpu(rx_hdr->len); |
582 | 563 | ||
583 | /* We received data from the HW, so stop the watchdog */ | 564 | /* We received data from the HW, so stop the watchdog */ |
584 | if (unlikely((len + IWL_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) { | 565 | if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) { |
585 | IWL_DEBUG_DROP("Corruption detected!\n"); | 566 | IWL_DEBUG_DROP("Corruption detected!\n"); |
586 | return; | 567 | return; |
587 | } | 568 | } |
@@ -597,7 +578,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv, | |||
597 | /* Set the size of the skb to the size of the frame */ | 578 | /* Set the size of the skb to the size of the frame */ |
598 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); | 579 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); |
599 | 580 | ||
600 | if (iwl3945_param_hwcrypto) | 581 | if (!iwl3945_mod_params.sw_crypto) |
601 | iwl3945_set_decrypted_flag(priv, rxb->skb, | 582 | iwl3945_set_decrypted_flag(priv, rxb->skb, |
602 | le32_to_cpu(rx_end->status), stats); | 583 | le32_to_cpu(rx_end->status), stats); |
603 | 584 | ||
@@ -611,12 +592,12 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv, | |||
611 | 592 | ||
612 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | 593 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) |
613 | 594 | ||
614 | static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | 595 | static void iwl3945_rx_reply_rx(struct iwl_priv *priv, |
615 | struct iwl3945_rx_mem_buffer *rxb) | 596 | struct iwl_rx_mem_buffer *rxb) |
616 | { | 597 | { |
617 | struct ieee80211_hdr *header; | 598 | struct ieee80211_hdr *header; |
618 | struct ieee80211_rx_status rx_status; | 599 | struct ieee80211_rx_status rx_status; |
619 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 600 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
620 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | 601 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); |
621 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 602 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
622 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 603 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
@@ -659,7 +640,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
659 | 640 | ||
660 | 641 | ||
661 | /* Convert 3945's rssi indicator to dBm */ | 642 | /* Convert 3945's rssi indicator to dBm */ |
662 | rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET; | 643 | rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET; |
663 | 644 | ||
664 | /* Set default noise value to -127 */ | 645 | /* Set default noise value to -127 */ |
665 | if (priv->last_rx_noise == 0) | 646 | if (priv->last_rx_noise == 0) |
@@ -705,11 +686,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
705 | rx_status.signal, rx_status.signal, | 686 | rx_status.signal, rx_status.signal, |
706 | rx_status.noise, rx_status.rate_idx); | 687 | rx_status.noise, rx_status.rate_idx); |
707 | 688 | ||
708 | #ifdef CONFIG_IWL3945_DEBUG | 689 | /* Set "1" to report good data frames in groups of 100 */ |
709 | if (iwl3945_debug_level & (IWL_DL_RX)) | 690 | iwl3945_dbg_report_frame(priv, pkt, header, 1); |
710 | /* Set "1" to report good data frames in groups of 100 */ | ||
711 | iwl3945_dbg_report_frame(priv, pkt, header, 1); | ||
712 | #endif | ||
713 | 691 | ||
714 | if (network_packet) { | 692 | if (network_packet) { |
715 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); | 693 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); |
@@ -721,24 +699,31 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
721 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); | 699 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); |
722 | } | 700 | } |
723 | 701 | ||
724 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, | 702 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, |
725 | dma_addr_t addr, u16 len) | 703 | struct iwl_tx_queue *txq, |
704 | dma_addr_t addr, u16 len, u8 reset, u8 pad) | ||
726 | { | 705 | { |
727 | int count; | 706 | int count; |
728 | u32 pad; | 707 | struct iwl_queue *q; |
729 | struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr; | 708 | struct iwl3945_tfd *tfd, *tfd_tmp; |
709 | |||
710 | q = &txq->q; | ||
711 | tfd_tmp = (struct iwl3945_tfd *)txq->tfds; | ||
712 | tfd = &tfd_tmp[q->write_ptr]; | ||
713 | |||
714 | if (reset) | ||
715 | memset(tfd, 0, sizeof(*tfd)); | ||
730 | 716 | ||
731 | count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); | 717 | count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); |
732 | pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags)); | ||
733 | 718 | ||
734 | if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { | 719 | if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { |
735 | IWL_ERROR("Error can not send more than %d chunks\n", | 720 | IWL_ERR(priv, "Error can not send more than %d chunks\n", |
736 | NUM_TFD_CHUNKS); | 721 | NUM_TFD_CHUNKS); |
737 | return -EINVAL; | 722 | return -EINVAL; |
738 | } | 723 | } |
739 | 724 | ||
740 | tfd->pa[count].addr = cpu_to_le32(addr); | 725 | tfd->tbs[count].addr = cpu_to_le32(addr); |
741 | tfd->pa[count].len = cpu_to_le32(len); | 726 | tfd->tbs[count].len = cpu_to_le32(len); |
742 | 727 | ||
743 | count++; | 728 | count++; |
744 | 729 | ||
@@ -753,10 +738,10 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, | |||
753 | * | 738 | * |
754 | * Does NOT advance any indexes | 739 | * Does NOT advance any indexes |
755 | */ | 740 | */ |
756 | int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) | 741 | void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) |
757 | { | 742 | { |
758 | struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0]; | 743 | struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds; |
759 | struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; | 744 | struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr]; |
760 | struct pci_dev *dev = priv->pci_dev; | 745 | struct pci_dev *dev = priv->pci_dev; |
761 | int i; | 746 | int i; |
762 | int counter; | 747 | int counter; |
@@ -764,21 +749,21 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue * | |||
764 | /* classify bd */ | 749 | /* classify bd */ |
765 | if (txq->q.id == IWL_CMD_QUEUE_NUM) | 750 | if (txq->q.id == IWL_CMD_QUEUE_NUM) |
766 | /* nothing to cleanup after for host commands */ | 751 | /* nothing to cleanup after for host commands */ |
767 | return 0; | 752 | return; |
768 | 753 | ||
769 | /* sanity check */ | 754 | /* sanity check */ |
770 | counter = TFD_CTL_COUNT_GET(le32_to_cpu(bd->control_flags)); | 755 | counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); |
771 | if (counter > NUM_TFD_CHUNKS) { | 756 | if (counter > NUM_TFD_CHUNKS) { |
772 | IWL_ERROR("Too many chunks: %i\n", counter); | 757 | IWL_ERR(priv, "Too many chunks: %i\n", counter); |
773 | /* @todo issue fatal error, it is quite serious situation */ | 758 | /* @todo issue fatal error, it is quite serious situation */ |
774 | return 0; | 759 | return; |
775 | } | 760 | } |
776 | 761 | ||
777 | /* unmap chunks if any */ | 762 | /* unmap chunks if any */ |
778 | 763 | ||
779 | for (i = 1; i < counter; i++) { | 764 | for (i = 1; i < counter; i++) { |
780 | pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr), | 765 | pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr), |
781 | le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE); | 766 | le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE); |
782 | if (txq->txb[txq->q.read_ptr].skb[0]) { | 767 | if (txq->txb[txq->q.read_ptr].skb[0]) { |
783 | struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0]; | 768 | struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0]; |
784 | if (txq->txb[txq->q.read_ptr].skb[0]) { | 769 | if (txq->txb[txq->q.read_ptr].skb[0]) { |
@@ -788,10 +773,10 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue * | |||
788 | } | 773 | } |
789 | } | 774 | } |
790 | } | 775 | } |
791 | return 0; | 776 | return ; |
792 | } | 777 | } |
793 | 778 | ||
794 | u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) | 779 | u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr) |
795 | { | 780 | { |
796 | int i, start = IWL_AP_ID; | 781 | int i, start = IWL_AP_ID; |
797 | int ret = IWL_INVALID_STATION; | 782 | int ret = IWL_INVALID_STATION; |
@@ -802,13 +787,13 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) | |||
802 | start = IWL_STA_ID; | 787 | start = IWL_STA_ID; |
803 | 788 | ||
804 | if (is_broadcast_ether_addr(addr)) | 789 | if (is_broadcast_ether_addr(addr)) |
805 | return priv->hw_setting.bcast_sta_id; | 790 | return priv->hw_params.bcast_sta_id; |
806 | 791 | ||
807 | spin_lock_irqsave(&priv->sta_lock, flags); | 792 | spin_lock_irqsave(&priv->sta_lock, flags); |
808 | for (i = start; i < priv->hw_setting.max_stations; i++) | 793 | for (i = start; i < priv->hw_params.max_stations; i++) |
809 | if ((priv->stations[i].used) && | 794 | if ((priv->stations_39[i].used) && |
810 | (!compare_ether_addr | 795 | (!compare_ether_addr |
811 | (priv->stations[i].sta.sta.addr, addr))) { | 796 | (priv->stations_39[i].sta.sta.addr, addr))) { |
812 | ret = i; | 797 | ret = i; |
813 | goto out; | 798 | goto out; |
814 | } | 799 | } |
@@ -824,12 +809,10 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) | |||
824 | * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: | 809 | * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: |
825 | * | 810 | * |
826 | */ | 811 | */ |
827 | void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | 812 | void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, |
828 | struct iwl3945_cmd *cmd, | ||
829 | struct ieee80211_tx_info *info, | 813 | struct ieee80211_tx_info *info, |
830 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) | 814 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) |
831 | { | 815 | { |
832 | unsigned long flags; | ||
833 | u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; | 816 | u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; |
834 | u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); | 817 | u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); |
835 | u16 rate_mask; | 818 | u16 rate_mask; |
@@ -838,25 +821,15 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
838 | u8 data_retry_limit; | 821 | u8 data_retry_limit; |
839 | __le32 tx_flags; | 822 | __le32 tx_flags; |
840 | __le16 fc = hdr->frame_control; | 823 | __le16 fc = hdr->frame_control; |
824 | struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; | ||
841 | 825 | ||
842 | rate = iwl3945_rates[rate_index].plcp; | 826 | rate = iwl3945_rates[rate_index].plcp; |
843 | tx_flags = cmd->cmd.tx.tx_flags; | 827 | tx_flags = tx->tx_flags; |
844 | 828 | ||
845 | /* We need to figure out how to get the sta->supp_rates while | 829 | /* We need to figure out how to get the sta->supp_rates while |
846 | * in this running context */ | 830 | * in this running context */ |
847 | rate_mask = IWL_RATES_MASK; | 831 | rate_mask = IWL_RATES_MASK; |
848 | 832 | ||
849 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
850 | |||
851 | priv->stations[sta_id].current_rate.rate_n_flags = rate; | ||
852 | |||
853 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && | ||
854 | (sta_id != priv->hw_setting.bcast_sta_id) && | ||
855 | (sta_id != IWL_MULTICAST_ID)) | ||
856 | priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate; | ||
857 | |||
858 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
859 | |||
860 | if (tx_id >= IWL_CMD_QUEUE_NUM) | 833 | if (tx_id >= IWL_CMD_QUEUE_NUM) |
861 | rts_retry_limit = 3; | 834 | rts_retry_limit = 3; |
862 | else | 835 | else |
@@ -888,25 +861,25 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
888 | } | 861 | } |
889 | } | 862 | } |
890 | 863 | ||
891 | cmd->cmd.tx.rts_retry_limit = rts_retry_limit; | 864 | tx->rts_retry_limit = rts_retry_limit; |
892 | cmd->cmd.tx.data_retry_limit = data_retry_limit; | 865 | tx->data_retry_limit = data_retry_limit; |
893 | cmd->cmd.tx.rate = rate; | 866 | tx->rate = rate; |
894 | cmd->cmd.tx.tx_flags = tx_flags; | 867 | tx->tx_flags = tx_flags; |
895 | 868 | ||
896 | /* OFDM */ | 869 | /* OFDM */ |
897 | cmd->cmd.tx.supp_rates[0] = | 870 | tx->supp_rates[0] = |
898 | ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; | 871 | ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF; |
899 | 872 | ||
900 | /* CCK */ | 873 | /* CCK */ |
901 | cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF); | 874 | tx->supp_rates[1] = (rate_mask & 0xF); |
902 | 875 | ||
903 | IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " | 876 | IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X " |
904 | "cck/ofdm mask: 0x%x/0x%x\n", sta_id, | 877 | "cck/ofdm mask: 0x%x/0x%x\n", sta_id, |
905 | cmd->cmd.tx.rate, le32_to_cpu(cmd->cmd.tx.tx_flags), | 878 | tx->rate, le32_to_cpu(tx->tx_flags), |
906 | cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]); | 879 | tx->supp_rates[1], tx->supp_rates[0]); |
907 | } | 880 | } |
908 | 881 | ||
909 | u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags) | 882 | u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) |
910 | { | 883 | { |
911 | unsigned long flags_spin; | 884 | unsigned long flags_spin; |
912 | struct iwl3945_station_entry *station; | 885 | struct iwl3945_station_entry *station; |
@@ -915,56 +888,56 @@ u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags | |||
915 | return IWL_INVALID_STATION; | 888 | return IWL_INVALID_STATION; |
916 | 889 | ||
917 | spin_lock_irqsave(&priv->sta_lock, flags_spin); | 890 | spin_lock_irqsave(&priv->sta_lock, flags_spin); |
918 | station = &priv->stations[sta_id]; | 891 | station = &priv->stations_39[sta_id]; |
919 | 892 | ||
920 | station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; | 893 | station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; |
921 | station->sta.rate_n_flags = cpu_to_le16(tx_rate); | 894 | station->sta.rate_n_flags = cpu_to_le16(tx_rate); |
922 | station->current_rate.rate_n_flags = tx_rate; | ||
923 | station->sta.mode = STA_CONTROL_MODIFY_MSK; | 895 | station->sta.mode = STA_CONTROL_MODIFY_MSK; |
924 | 896 | ||
925 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 897 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
926 | 898 | ||
927 | iwl3945_send_add_station(priv, &station->sta, flags); | 899 | iwl_send_add_sta(priv, |
900 | (struct iwl_addsta_cmd *)&station->sta, flags); | ||
928 | IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n", | 901 | IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n", |
929 | sta_id, tx_rate); | 902 | sta_id, tx_rate); |
930 | return sta_id; | 903 | return sta_id; |
931 | } | 904 | } |
932 | 905 | ||
933 | static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max) | 906 | static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) |
934 | { | 907 | { |
935 | int rc; | 908 | int rc; |
936 | unsigned long flags; | 909 | unsigned long flags; |
937 | 910 | ||
938 | spin_lock_irqsave(&priv->lock, flags); | 911 | spin_lock_irqsave(&priv->lock, flags); |
939 | rc = iwl3945_grab_nic_access(priv); | 912 | rc = iwl_grab_nic_access(priv); |
940 | if (rc) { | 913 | if (rc) { |
941 | spin_unlock_irqrestore(&priv->lock, flags); | 914 | spin_unlock_irqrestore(&priv->lock, flags); |
942 | return rc; | 915 | return rc; |
943 | } | 916 | } |
944 | 917 | ||
945 | if (!pwr_max) { | 918 | if (src == IWL_PWR_SRC_VAUX) { |
946 | u32 val; | 919 | u32 val; |
947 | 920 | ||
948 | rc = pci_read_config_dword(priv->pci_dev, | 921 | rc = pci_read_config_dword(priv->pci_dev, |
949 | PCI_POWER_SOURCE, &val); | 922 | PCI_POWER_SOURCE, &val); |
950 | if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) { | 923 | if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) { |
951 | iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, | 924 | iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, |
952 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, | 925 | APMG_PS_CTRL_VAL_PWR_SRC_VAUX, |
953 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 926 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
954 | iwl3945_release_nic_access(priv); | 927 | iwl_release_nic_access(priv); |
955 | 928 | ||
956 | iwl3945_poll_bit(priv, CSR_GPIO_IN, | 929 | iwl_poll_bit(priv, CSR_GPIO_IN, |
957 | CSR_GPIO_IN_VAL_VAUX_PWR_SRC, | 930 | CSR_GPIO_IN_VAL_VAUX_PWR_SRC, |
958 | CSR_GPIO_IN_BIT_AUX_POWER, 5000); | 931 | CSR_GPIO_IN_BIT_AUX_POWER, 5000); |
959 | } else | 932 | } else |
960 | iwl3945_release_nic_access(priv); | 933 | iwl_release_nic_access(priv); |
961 | } else { | 934 | } else { |
962 | iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, | 935 | iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, |
963 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, | 936 | APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, |
964 | ~APMG_PS_CTRL_MSK_PWR_SRC); | 937 | ~APMG_PS_CTRL_MSK_PWR_SRC); |
965 | 938 | ||
966 | iwl3945_release_nic_access(priv); | 939 | iwl_release_nic_access(priv); |
967 | iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, | 940 | iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, |
968 | CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ | 941 | CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ |
969 | } | 942 | } |
970 | spin_unlock_irqrestore(&priv->lock, flags); | 943 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -972,81 +945,79 @@ static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max) | |||
972 | return rc; | 945 | return rc; |
973 | } | 946 | } |
974 | 947 | ||
975 | static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq) | 948 | static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) |
976 | { | 949 | { |
977 | int rc; | 950 | int rc; |
978 | unsigned long flags; | 951 | unsigned long flags; |
979 | 952 | ||
980 | spin_lock_irqsave(&priv->lock, flags); | 953 | spin_lock_irqsave(&priv->lock, flags); |
981 | rc = iwl3945_grab_nic_access(priv); | 954 | rc = iwl_grab_nic_access(priv); |
982 | if (rc) { | 955 | if (rc) { |
983 | spin_unlock_irqrestore(&priv->lock, flags); | 956 | spin_unlock_irqrestore(&priv->lock, flags); |
984 | return rc; | 957 | return rc; |
985 | } | 958 | } |
986 | 959 | ||
987 | iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr); | 960 | iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr); |
988 | iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0), | 961 | iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma); |
989 | priv->hw_setting.shared_phys + | 962 | iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0); |
990 | offsetof(struct iwl3945_shared, rx_read_ptr[0])); | 963 | iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), |
991 | iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0); | 964 | FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE | |
992 | iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), | 965 | FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE | |
993 | ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE | | 966 | FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN | |
994 | ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE | | 967 | FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 | |
995 | ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN | | 968 | (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) | |
996 | ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 | | 969 | FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST | |
997 | (RX_QUEUE_SIZE_LOG << ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) | | 970 | (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) | |
998 | ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST | | 971 | FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH); |
999 | (1 << ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) | | ||
1000 | ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH); | ||
1001 | 972 | ||
1002 | /* fake read to flush all prev I/O */ | 973 | /* fake read to flush all prev I/O */ |
1003 | iwl3945_read_direct32(priv, FH_RSSR_CTRL); | 974 | iwl_read_direct32(priv, FH39_RSSR_CTRL); |
1004 | 975 | ||
1005 | iwl3945_release_nic_access(priv); | 976 | iwl_release_nic_access(priv); |
1006 | spin_unlock_irqrestore(&priv->lock, flags); | 977 | spin_unlock_irqrestore(&priv->lock, flags); |
1007 | 978 | ||
1008 | return 0; | 979 | return 0; |
1009 | } | 980 | } |
1010 | 981 | ||
1011 | static int iwl3945_tx_reset(struct iwl3945_priv *priv) | 982 | static int iwl3945_tx_reset(struct iwl_priv *priv) |
1012 | { | 983 | { |
1013 | int rc; | 984 | int rc; |
1014 | unsigned long flags; | 985 | unsigned long flags; |
1015 | 986 | ||
1016 | spin_lock_irqsave(&priv->lock, flags); | 987 | spin_lock_irqsave(&priv->lock, flags); |
1017 | rc = iwl3945_grab_nic_access(priv); | 988 | rc = iwl_grab_nic_access(priv); |
1018 | if (rc) { | 989 | if (rc) { |
1019 | spin_unlock_irqrestore(&priv->lock, flags); | 990 | spin_unlock_irqrestore(&priv->lock, flags); |
1020 | return rc; | 991 | return rc; |
1021 | } | 992 | } |
1022 | 993 | ||
1023 | /* bypass mode */ | 994 | /* bypass mode */ |
1024 | iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2); | 995 | iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2); |
1025 | 996 | ||
1026 | /* RA 0 is active */ | 997 | /* RA 0 is active */ |
1027 | iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01); | 998 | iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01); |
1028 | 999 | ||
1029 | /* all 6 fifo are active */ | 1000 | /* all 6 fifo are active */ |
1030 | iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f); | 1001 | iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f); |
1031 | 1002 | ||
1032 | iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000); | 1003 | iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000); |
1033 | iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002); | 1004 | iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002); |
1034 | iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004); | 1005 | iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004); |
1035 | iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); | 1006 | iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); |
1036 | 1007 | ||
1037 | iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE, | 1008 | iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, |
1038 | priv->hw_setting.shared_phys); | 1009 | priv->shared_phys); |
1039 | 1010 | ||
1040 | iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG, | 1011 | iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, |
1041 | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | | 1012 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | |
1042 | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON | | 1013 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON | |
1043 | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B | | 1014 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B | |
1044 | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON | | 1015 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON | |
1045 | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON | | 1016 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON | |
1046 | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | | 1017 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | |
1047 | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); | 1018 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); |
1048 | 1019 | ||
1049 | iwl3945_release_nic_access(priv); | 1020 | iwl_release_nic_access(priv); |
1050 | spin_unlock_irqrestore(&priv->lock, flags); | 1021 | spin_unlock_irqrestore(&priv->lock, flags); |
1051 | 1022 | ||
1052 | return 0; | 1023 | return 0; |
@@ -1057,7 +1028,7 @@ static int iwl3945_tx_reset(struct iwl3945_priv *priv) | |||
1057 | * | 1028 | * |
1058 | * Destroys all DMA structures and initialize them again | 1029 | * Destroys all DMA structures and initialize them again |
1059 | */ | 1030 | */ |
1060 | static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv) | 1031 | static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) |
1061 | { | 1032 | { |
1062 | int rc; | 1033 | int rc; |
1063 | int txq_id, slots_num; | 1034 | int txq_id, slots_num; |
@@ -1073,10 +1044,10 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv) | |||
1073 | for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) { | 1044 | for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) { |
1074 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? | 1045 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? |
1075 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | 1046 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; |
1076 | rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | 1047 | rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, |
1077 | txq_id); | 1048 | txq_id); |
1078 | if (rc) { | 1049 | if (rc) { |
1079 | IWL_ERROR("Tx %d queue init failed\n", txq_id); | 1050 | IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); |
1080 | goto error; | 1051 | goto error; |
1081 | } | 1052 | } |
1082 | } | 1053 | } |
@@ -1088,111 +1059,140 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv) | |||
1088 | return rc; | 1059 | return rc; |
1089 | } | 1060 | } |
1090 | 1061 | ||
1091 | int iwl3945_hw_nic_init(struct iwl3945_priv *priv) | 1062 | static int iwl3945_apm_init(struct iwl_priv *priv) |
1092 | { | 1063 | { |
1093 | u8 rev_id; | 1064 | int ret = 0; |
1094 | int rc; | ||
1095 | unsigned long flags; | ||
1096 | struct iwl3945_rx_queue *rxq = &priv->rxq; | ||
1097 | 1065 | ||
1098 | iwl3945_power_init_handle(priv); | 1066 | iwl3945_power_init_handle(priv); |
1099 | 1067 | ||
1100 | spin_lock_irqsave(&priv->lock, flags); | 1068 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, |
1101 | iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL); | 1069 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); |
1102 | iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 1070 | |
1103 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | 1071 | /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */ |
1104 | 1072 | iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, | |
1105 | iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 1073 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); |
1106 | rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL, | 1074 | |
1107 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | 1075 | /* set "initialization complete" bit to move adapter |
1108 | if (rc < 0) { | 1076 | * D0U* --> D0A* state */ |
1109 | spin_unlock_irqrestore(&priv->lock, flags); | 1077 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
1078 | |||
1079 | iwl_poll_direct_bit(priv, CSR_GP_CNTRL, | ||
1080 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
1081 | if (ret < 0) { | ||
1110 | IWL_DEBUG_INFO("Failed to init the card\n"); | 1082 | IWL_DEBUG_INFO("Failed to init the card\n"); |
1111 | return rc; | 1083 | goto out; |
1112 | } | 1084 | } |
1113 | 1085 | ||
1114 | rc = iwl3945_grab_nic_access(priv); | 1086 | ret = iwl_grab_nic_access(priv); |
1115 | if (rc) { | 1087 | if (ret) |
1116 | spin_unlock_irqrestore(&priv->lock, flags); | 1088 | goto out; |
1117 | return rc; | 1089 | |
1118 | } | 1090 | /* enable DMA */ |
1119 | iwl3945_write_prph(priv, APMG_CLK_EN_REG, | 1091 | iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT | |
1120 | APMG_CLK_VAL_DMA_CLK_RQT | | 1092 | APMG_CLK_VAL_BSM_CLK_RQT); |
1121 | APMG_CLK_VAL_BSM_CLK_RQT); | 1093 | |
1122 | udelay(20); | 1094 | udelay(20); |
1123 | iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||
1124 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
1125 | iwl3945_release_nic_access(priv); | ||
1126 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1127 | 1095 | ||
1128 | /* Determine HW type */ | 1096 | /* disable L1-Active */ |
1129 | rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); | 1097 | iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, |
1130 | if (rc) | 1098 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
1131 | return rc; | 1099 | |
1132 | IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id); | 1100 | iwl_release_nic_access(priv); |
1101 | out: | ||
1102 | return ret; | ||
1103 | } | ||
1104 | |||
1105 | static void iwl3945_nic_config(struct iwl_priv *priv) | ||
1106 | { | ||
1107 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
1108 | unsigned long flags; | ||
1109 | u8 rev_id = 0; | ||
1133 | 1110 | ||
1134 | iwl3945_nic_set_pwr_src(priv, 1); | ||
1135 | spin_lock_irqsave(&priv->lock, flags); | 1111 | spin_lock_irqsave(&priv->lock, flags); |
1136 | 1112 | ||
1137 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) | 1113 | if (rev_id & PCI_CFG_REV_ID_BIT_RTP) |
1138 | IWL_DEBUG_INFO("RTP type \n"); | 1114 | IWL_DEBUG_INFO("RTP type \n"); |
1139 | else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { | 1115 | else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { |
1140 | IWL_DEBUG_INFO("3945 RADIO-MB type\n"); | 1116 | IWL_DEBUG_INFO("3945 RADIO-MB type\n"); |
1141 | iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1117 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1142 | CSR39_HW_IF_CONFIG_REG_BIT_3945_MB); | 1118 | CSR39_HW_IF_CONFIG_REG_BIT_3945_MB); |
1143 | } else { | 1119 | } else { |
1144 | IWL_DEBUG_INFO("3945 RADIO-MM type\n"); | 1120 | IWL_DEBUG_INFO("3945 RADIO-MM type\n"); |
1145 | iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1121 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1146 | CSR39_HW_IF_CONFIG_REG_BIT_3945_MM); | 1122 | CSR39_HW_IF_CONFIG_REG_BIT_3945_MM); |
1147 | } | 1123 | } |
1148 | 1124 | ||
1149 | if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) { | 1125 | if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) { |
1150 | IWL_DEBUG_INFO("SKU OP mode is mrc\n"); | 1126 | IWL_DEBUG_INFO("SKU OP mode is mrc\n"); |
1151 | iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1127 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1152 | CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC); | 1128 | CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC); |
1153 | } else | 1129 | } else |
1154 | IWL_DEBUG_INFO("SKU OP mode is basic\n"); | 1130 | IWL_DEBUG_INFO("SKU OP mode is basic\n"); |
1155 | 1131 | ||
1156 | if ((priv->eeprom.board_revision & 0xF0) == 0xD0) { | 1132 | if ((eeprom->board_revision & 0xF0) == 0xD0) { |
1157 | IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", | 1133 | IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", |
1158 | priv->eeprom.board_revision); | 1134 | eeprom->board_revision); |
1159 | iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1135 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1160 | CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); | 1136 | CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); |
1161 | } else { | 1137 | } else { |
1162 | IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", | 1138 | IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", |
1163 | priv->eeprom.board_revision); | 1139 | eeprom->board_revision); |
1164 | iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG, | 1140 | iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, |
1165 | CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); | 1141 | CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); |
1166 | } | 1142 | } |
1167 | 1143 | ||
1168 | if (priv->eeprom.almgor_m_version <= 1) { | 1144 | if (eeprom->almgor_m_version <= 1) { |
1169 | iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1145 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1170 | CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); | 1146 | CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); |
1171 | IWL_DEBUG_INFO("Card M type A version is 0x%X\n", | 1147 | IWL_DEBUG_INFO("Card M type A version is 0x%X\n", |
1172 | priv->eeprom.almgor_m_version); | 1148 | eeprom->almgor_m_version); |
1173 | } else { | 1149 | } else { |
1174 | IWL_DEBUG_INFO("Card M type B version is 0x%X\n", | 1150 | IWL_DEBUG_INFO("Card M type B version is 0x%X\n", |
1175 | priv->eeprom.almgor_m_version); | 1151 | eeprom->almgor_m_version); |
1176 | iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, | 1152 | iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
1177 | CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); | 1153 | CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); |
1178 | } | 1154 | } |
1179 | spin_unlock_irqrestore(&priv->lock, flags); | 1155 | spin_unlock_irqrestore(&priv->lock, flags); |
1180 | 1156 | ||
1181 | if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE) | 1157 | if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE) |
1182 | IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n"); | 1158 | IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n"); |
1183 | 1159 | ||
1184 | if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) | 1160 | if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) |
1185 | IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n"); | 1161 | IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n"); |
1162 | } | ||
1163 | |||
1164 | int iwl3945_hw_nic_init(struct iwl_priv *priv) | ||
1165 | { | ||
1166 | u8 rev_id; | ||
1167 | int rc; | ||
1168 | unsigned long flags; | ||
1169 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
1170 | |||
1171 | spin_lock_irqsave(&priv->lock, flags); | ||
1172 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
1173 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1174 | |||
1175 | /* Determine HW type */ | ||
1176 | rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id); | ||
1177 | if (rc) | ||
1178 | return rc; | ||
1179 | IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id); | ||
1180 | |||
1181 | rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | ||
1182 | if(rc) | ||
1183 | return rc; | ||
1184 | |||
1185 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
1186 | 1186 | ||
1187 | /* Allocate the RX queue, or reset if it is already allocated */ | 1187 | /* Allocate the RX queue, or reset if it is already allocated */ |
1188 | if (!rxq->bd) { | 1188 | if (!rxq->bd) { |
1189 | rc = iwl3945_rx_queue_alloc(priv); | 1189 | rc = iwl_rx_queue_alloc(priv); |
1190 | if (rc) { | 1190 | if (rc) { |
1191 | IWL_ERROR("Unable to initialize Rx queue\n"); | 1191 | IWL_ERR(priv, "Unable to initialize Rx queue\n"); |
1192 | return -ENOMEM; | 1192 | return -ENOMEM; |
1193 | } | 1193 | } |
1194 | } else | 1194 | } else |
1195 | iwl3945_rx_queue_reset(priv, rxq); | 1195 | iwl_rx_queue_reset(priv, rxq); |
1196 | 1196 | ||
1197 | iwl3945_rx_replenish(priv); | 1197 | iwl3945_rx_replenish(priv); |
1198 | 1198 | ||
@@ -1202,16 +1202,16 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv) | |||
1202 | 1202 | ||
1203 | /* Look at using this instead: | 1203 | /* Look at using this instead: |
1204 | rxq->need_update = 1; | 1204 | rxq->need_update = 1; |
1205 | iwl3945_rx_queue_update_write_ptr(priv, rxq); | 1205 | iwl_rx_queue_update_write_ptr(priv, rxq); |
1206 | */ | 1206 | */ |
1207 | 1207 | ||
1208 | rc = iwl3945_grab_nic_access(priv); | 1208 | rc = iwl_grab_nic_access(priv); |
1209 | if (rc) { | 1209 | if (rc) { |
1210 | spin_unlock_irqrestore(&priv->lock, flags); | 1210 | spin_unlock_irqrestore(&priv->lock, flags); |
1211 | return rc; | 1211 | return rc; |
1212 | } | 1212 | } |
1213 | iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7); | 1213 | iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7); |
1214 | iwl3945_release_nic_access(priv); | 1214 | iwl_release_nic_access(priv); |
1215 | 1215 | ||
1216 | spin_unlock_irqrestore(&priv->lock, flags); | 1216 | spin_unlock_irqrestore(&priv->lock, flags); |
1217 | 1217 | ||
@@ -1229,116 +1229,121 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv) | |||
1229 | * | 1229 | * |
1230 | * Destroy all TX DMA queues and structures | 1230 | * Destroy all TX DMA queues and structures |
1231 | */ | 1231 | */ |
1232 | void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv) | 1232 | void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) |
1233 | { | 1233 | { |
1234 | int txq_id; | 1234 | int txq_id; |
1235 | 1235 | ||
1236 | /* Tx queues */ | 1236 | /* Tx queues */ |
1237 | for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) | 1237 | for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) |
1238 | iwl3945_tx_queue_free(priv, &priv->txq[txq_id]); | 1238 | iwl_tx_queue_free(priv, txq_id); |
1239 | } | 1239 | } |
1240 | 1240 | ||
1241 | void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv) | 1241 | void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv) |
1242 | { | 1242 | { |
1243 | int queue; | 1243 | int txq_id; |
1244 | unsigned long flags; | 1244 | unsigned long flags; |
1245 | 1245 | ||
1246 | spin_lock_irqsave(&priv->lock, flags); | 1246 | spin_lock_irqsave(&priv->lock, flags); |
1247 | if (iwl3945_grab_nic_access(priv)) { | 1247 | if (iwl_grab_nic_access(priv)) { |
1248 | spin_unlock_irqrestore(&priv->lock, flags); | 1248 | spin_unlock_irqrestore(&priv->lock, flags); |
1249 | iwl3945_hw_txq_ctx_free(priv); | 1249 | iwl3945_hw_txq_ctx_free(priv); |
1250 | return; | 1250 | return; |
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | /* stop SCD */ | 1253 | /* stop SCD */ |
1254 | iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0); | 1254 | iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); |
1255 | 1255 | ||
1256 | /* reset TFD queues */ | 1256 | /* reset TFD queues */ |
1257 | for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) { | 1257 | for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) { |
1258 | iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0); | 1258 | iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0); |
1259 | iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS, | 1259 | iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS, |
1260 | ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue), | 1260 | FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), |
1261 | 1000); | 1261 | 1000); |
1262 | } | 1262 | } |
1263 | 1263 | ||
1264 | iwl3945_release_nic_access(priv); | 1264 | iwl_release_nic_access(priv); |
1265 | spin_unlock_irqrestore(&priv->lock, flags); | 1265 | spin_unlock_irqrestore(&priv->lock, flags); |
1266 | 1266 | ||
1267 | iwl3945_hw_txq_ctx_free(priv); | 1267 | iwl3945_hw_txq_ctx_free(priv); |
1268 | } | 1268 | } |
1269 | 1269 | ||
1270 | int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv) | 1270 | static int iwl3945_apm_stop_master(struct iwl_priv *priv) |
1271 | { | 1271 | { |
1272 | int rc = 0; | 1272 | int ret = 0; |
1273 | u32 reg_val; | ||
1274 | unsigned long flags; | 1273 | unsigned long flags; |
1275 | 1274 | ||
1276 | spin_lock_irqsave(&priv->lock, flags); | 1275 | spin_lock_irqsave(&priv->lock, flags); |
1277 | 1276 | ||
1278 | /* set stop master bit */ | 1277 | /* set stop master bit */ |
1279 | iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); | 1278 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); |
1280 | 1279 | ||
1281 | reg_val = iwl3945_read32(priv, CSR_GP_CNTRL); | 1280 | iwl_poll_direct_bit(priv, CSR_RESET, |
1281 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | ||
1282 | 1282 | ||
1283 | if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE == | 1283 | if (ret < 0) |
1284 | (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE)) | 1284 | goto out; |
1285 | IWL_DEBUG_INFO("Card in power save, master is already " | ||
1286 | "stopped\n"); | ||
1287 | else { | ||
1288 | rc = iwl3945_poll_direct_bit(priv, CSR_RESET, | ||
1289 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | ||
1290 | if (rc < 0) { | ||
1291 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1292 | return rc; | ||
1293 | } | ||
1294 | } | ||
1295 | 1285 | ||
1286 | out: | ||
1296 | spin_unlock_irqrestore(&priv->lock, flags); | 1287 | spin_unlock_irqrestore(&priv->lock, flags); |
1297 | IWL_DEBUG_INFO("stop master\n"); | 1288 | IWL_DEBUG_INFO("stop master\n"); |
1298 | 1289 | ||
1299 | return rc; | 1290 | return ret; |
1291 | } | ||
1292 | |||
1293 | static void iwl3945_apm_stop(struct iwl_priv *priv) | ||
1294 | { | ||
1295 | unsigned long flags; | ||
1296 | |||
1297 | iwl3945_apm_stop_master(priv); | ||
1298 | |||
1299 | spin_lock_irqsave(&priv->lock, flags); | ||
1300 | |||
1301 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
1302 | |||
1303 | udelay(10); | ||
1304 | /* clear "init complete" move adapter D0A* --> D0U state */ | ||
1305 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
1306 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1300 | } | 1307 | } |
1301 | 1308 | ||
1302 | int iwl3945_hw_nic_reset(struct iwl3945_priv *priv) | 1309 | static int iwl3945_apm_reset(struct iwl_priv *priv) |
1303 | { | 1310 | { |
1304 | int rc; | 1311 | int rc; |
1305 | unsigned long flags; | 1312 | unsigned long flags; |
1306 | 1313 | ||
1307 | iwl3945_hw_nic_stop_master(priv); | 1314 | iwl3945_apm_stop_master(priv); |
1308 | 1315 | ||
1309 | spin_lock_irqsave(&priv->lock, flags); | 1316 | spin_lock_irqsave(&priv->lock, flags); |
1310 | 1317 | ||
1311 | iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | 1318 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); |
1319 | udelay(10); | ||
1312 | 1320 | ||
1313 | iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL, | 1321 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
1322 | |||
1323 | iwl_poll_direct_bit(priv, CSR_GP_CNTRL, | ||
1314 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | 1324 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); |
1315 | 1325 | ||
1316 | rc = iwl3945_grab_nic_access(priv); | 1326 | rc = iwl_grab_nic_access(priv); |
1317 | if (!rc) { | 1327 | if (!rc) { |
1318 | iwl3945_write_prph(priv, APMG_CLK_CTRL_REG, | 1328 | iwl_write_prph(priv, APMG_CLK_CTRL_REG, |
1319 | APMG_CLK_VAL_BSM_CLK_RQT); | 1329 | APMG_CLK_VAL_BSM_CLK_RQT); |
1320 | 1330 | ||
1321 | udelay(10); | 1331 | iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); |
1322 | 1332 | iwl_write_prph(priv, APMG_RTC_INT_STT_REG, | |
1323 | iwl3945_set_bit(priv, CSR_GP_CNTRL, | ||
1324 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
1325 | |||
1326 | iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); | ||
1327 | iwl3945_write_prph(priv, APMG_RTC_INT_STT_REG, | ||
1328 | 0xFFFFFFFF); | 1333 | 0xFFFFFFFF); |
1329 | 1334 | ||
1330 | /* enable DMA */ | 1335 | /* enable DMA */ |
1331 | iwl3945_write_prph(priv, APMG_CLK_EN_REG, | 1336 | iwl_write_prph(priv, APMG_CLK_EN_REG, |
1332 | APMG_CLK_VAL_DMA_CLK_RQT | | 1337 | APMG_CLK_VAL_DMA_CLK_RQT | |
1333 | APMG_CLK_VAL_BSM_CLK_RQT); | 1338 | APMG_CLK_VAL_BSM_CLK_RQT); |
1334 | udelay(10); | 1339 | udelay(10); |
1335 | 1340 | ||
1336 | iwl3945_set_bits_prph(priv, APMG_PS_CTRL_REG, | 1341 | iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, |
1337 | APMG_PS_CTRL_VAL_RESET_REQ); | 1342 | APMG_PS_CTRL_VAL_RESET_REQ); |
1338 | udelay(5); | 1343 | udelay(5); |
1339 | iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG, | 1344 | iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, |
1340 | APMG_PS_CTRL_VAL_RESET_REQ); | 1345 | APMG_PS_CTRL_VAL_RESET_REQ); |
1341 | iwl3945_release_nic_access(priv); | 1346 | iwl_release_nic_access(priv); |
1342 | } | 1347 | } |
1343 | 1348 | ||
1344 | /* Clear the 'host command active' bit... */ | 1349 | /* Clear the 'host command active' bit... */ |
@@ -1367,17 +1372,18 @@ static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) | |||
1367 | return ((temperature < -260) || (temperature > 25)) ? 1 : 0; | 1372 | return ((temperature < -260) || (temperature > 25)) ? 1 : 0; |
1368 | } | 1373 | } |
1369 | 1374 | ||
1370 | int iwl3945_hw_get_temperature(struct iwl3945_priv *priv) | 1375 | int iwl3945_hw_get_temperature(struct iwl_priv *priv) |
1371 | { | 1376 | { |
1372 | return iwl3945_read32(priv, CSR_UCODE_DRV_GP2); | 1377 | return iwl_read32(priv, CSR_UCODE_DRV_GP2); |
1373 | } | 1378 | } |
1374 | 1379 | ||
1375 | /** | 1380 | /** |
1376 | * iwl3945_hw_reg_txpower_get_temperature | 1381 | * iwl3945_hw_reg_txpower_get_temperature |
1377 | * get the current temperature by reading from NIC | 1382 | * get the current temperature by reading from NIC |
1378 | */ | 1383 | */ |
1379 | static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv) | 1384 | static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv) |
1380 | { | 1385 | { |
1386 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
1381 | int temperature; | 1387 | int temperature; |
1382 | 1388 | ||
1383 | temperature = iwl3945_hw_get_temperature(priv); | 1389 | temperature = iwl3945_hw_get_temperature(priv); |
@@ -1388,12 +1394,12 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv) | |||
1388 | 1394 | ||
1389 | /* handle insane temp reading */ | 1395 | /* handle insane temp reading */ |
1390 | if (iwl3945_hw_reg_temp_out_of_range(temperature)) { | 1396 | if (iwl3945_hw_reg_temp_out_of_range(temperature)) { |
1391 | IWL_ERROR("Error bad temperature value %d\n", temperature); | 1397 | IWL_ERR(priv, "Error bad temperature value %d\n", temperature); |
1392 | 1398 | ||
1393 | /* if really really hot(?), | 1399 | /* if really really hot(?), |
1394 | * substitute the 3rd band/group's temp measured at factory */ | 1400 | * substitute the 3rd band/group's temp measured at factory */ |
1395 | if (priv->last_temperature > 100) | 1401 | if (priv->last_temperature > 100) |
1396 | temperature = priv->eeprom.groups[2].temperature; | 1402 | temperature = eeprom->groups[2].temperature; |
1397 | else /* else use most recent "sane" value from driver */ | 1403 | else /* else use most recent "sane" value from driver */ |
1398 | temperature = priv->last_temperature; | 1404 | temperature = priv->last_temperature; |
1399 | } | 1405 | } |
@@ -1412,7 +1418,7 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv) | |||
1412 | * records new temperature in tx_mgr->temperature. | 1418 | * records new temperature in tx_mgr->temperature. |
1413 | * replaces tx_mgr->last_temperature *only* if calib needed | 1419 | * replaces tx_mgr->last_temperature *only* if calib needed |
1414 | * (assumes caller will actually do the calibration!). */ | 1420 | * (assumes caller will actually do the calibration!). */ |
1415 | static int is_temp_calib_needed(struct iwl3945_priv *priv) | 1421 | static int is_temp_calib_needed(struct iwl_priv *priv) |
1416 | { | 1422 | { |
1417 | int temp_diff; | 1423 | int temp_diff; |
1418 | 1424 | ||
@@ -1627,9 +1633,9 @@ static inline u8 iwl3945_hw_reg_fix_power_index(int index) | |||
1627 | * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK) | 1633 | * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK) |
1628 | * or 6 Mbit (OFDM) rates. | 1634 | * or 6 Mbit (OFDM) rates. |
1629 | */ | 1635 | */ |
1630 | static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index, | 1636 | static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, |
1631 | s32 rate_index, const s8 *clip_pwrs, | 1637 | s32 rate_index, const s8 *clip_pwrs, |
1632 | struct iwl3945_channel_info *ch_info, | 1638 | struct iwl_channel_info *ch_info, |
1633 | int band_index) | 1639 | int band_index) |
1634 | { | 1640 | { |
1635 | struct iwl3945_scan_power_info *scan_power_info; | 1641 | struct iwl3945_scan_power_info *scan_power_info; |
@@ -1646,7 +1652,7 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb | |||
1646 | /* further limit to user's max power preference. | 1652 | /* further limit to user's max power preference. |
1647 | * FIXME: Other spectrum management power limitations do not | 1653 | * FIXME: Other spectrum management power limitations do not |
1648 | * seem to apply?? */ | 1654 | * seem to apply?? */ |
1649 | power = min(power, priv->user_txpower_limit); | 1655 | power = min(power, priv->tx_power_user_lmt); |
1650 | scan_power_info->requested_power = power; | 1656 | scan_power_info->requested_power = power; |
1651 | 1657 | ||
1652 | /* find difference between new scan *power* and current "normal" | 1658 | /* find difference between new scan *power* and current "normal" |
@@ -1678,27 +1684,27 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb | |||
1678 | } | 1684 | } |
1679 | 1685 | ||
1680 | /** | 1686 | /** |
1681 | * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings | 1687 | * iwl3945_send_tx_power - fill in Tx Power command with gain settings |
1682 | * | 1688 | * |
1683 | * Configures power settings for all rates for the current channel, | 1689 | * Configures power settings for all rates for the current channel, |
1684 | * using values from channel info struct, and send to NIC | 1690 | * using values from channel info struct, and send to NIC |
1685 | */ | 1691 | */ |
1686 | int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) | 1692 | int iwl3945_send_tx_power(struct iwl_priv *priv) |
1687 | { | 1693 | { |
1688 | int rate_idx, i; | 1694 | int rate_idx, i; |
1689 | const struct iwl3945_channel_info *ch_info = NULL; | 1695 | const struct iwl_channel_info *ch_info = NULL; |
1690 | struct iwl3945_txpowertable_cmd txpower = { | 1696 | struct iwl3945_txpowertable_cmd txpower = { |
1691 | .channel = priv->active_rxon.channel, | 1697 | .channel = priv->active39_rxon.channel, |
1692 | }; | 1698 | }; |
1693 | 1699 | ||
1694 | txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; | 1700 | txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; |
1695 | ch_info = iwl3945_get_channel_info(priv, | 1701 | ch_info = iwl_get_channel_info(priv, |
1696 | priv->band, | 1702 | priv->band, |
1697 | le16_to_cpu(priv->active_rxon.channel)); | 1703 | le16_to_cpu(priv->active39_rxon.channel)); |
1698 | if (!ch_info) { | 1704 | if (!ch_info) { |
1699 | IWL_ERROR | 1705 | IWL_ERR(priv, |
1700 | ("Failed to get channel info for channel %d [%d]\n", | 1706 | "Failed to get channel info for channel %d [%d]\n", |
1701 | le16_to_cpu(priv->active_rxon.channel), priv->band); | 1707 | le16_to_cpu(priv->active39_rxon.channel), priv->band); |
1702 | return -EINVAL; | 1708 | return -EINVAL; |
1703 | } | 1709 | } |
1704 | 1710 | ||
@@ -1711,7 +1717,7 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) | |||
1711 | /* fill cmd with power settings for all rates for current channel */ | 1717 | /* fill cmd with power settings for all rates for current channel */ |
1712 | /* Fill OFDM rate */ | 1718 | /* Fill OFDM rate */ |
1713 | for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0; | 1719 | for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0; |
1714 | rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) { | 1720 | rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) { |
1715 | 1721 | ||
1716 | txpower.power[i].tpc = ch_info->power_info[i].tpc; | 1722 | txpower.power[i].tpc = ch_info->power_info[i].tpc; |
1717 | txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; | 1723 | txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; |
@@ -1737,8 +1743,9 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) | |||
1737 | txpower.power[i].rate); | 1743 | txpower.power[i].rate); |
1738 | } | 1744 | } |
1739 | 1745 | ||
1740 | return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, | 1746 | return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, |
1741 | sizeof(struct iwl3945_txpowertable_cmd), &txpower); | 1747 | sizeof(struct iwl3945_txpowertable_cmd), |
1748 | &txpower); | ||
1742 | 1749 | ||
1743 | } | 1750 | } |
1744 | 1751 | ||
@@ -1758,8 +1765,8 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) | |||
1758 | * properly fill out the scan powers, and actual h/w gain settings, | 1765 | * properly fill out the scan powers, and actual h/w gain settings, |
1759 | * and send changes to NIC | 1766 | * and send changes to NIC |
1760 | */ | 1767 | */ |
1761 | static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv, | 1768 | static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv, |
1762 | struct iwl3945_channel_info *ch_info) | 1769 | struct iwl_channel_info *ch_info) |
1763 | { | 1770 | { |
1764 | struct iwl3945_channel_power_info *power_info; | 1771 | struct iwl3945_channel_power_info *power_info; |
1765 | int power_changed = 0; | 1772 | int power_changed = 0; |
@@ -1768,7 +1775,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv, | |||
1768 | int power; | 1775 | int power; |
1769 | 1776 | ||
1770 | /* Get this chnlgrp's rate-to-max/clip-powers table */ | 1777 | /* Get this chnlgrp's rate-to-max/clip-powers table */ |
1771 | clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers; | 1778 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; |
1772 | 1779 | ||
1773 | /* Get this channel's rate-to-current-power settings table */ | 1780 | /* Get this channel's rate-to-current-power settings table */ |
1774 | power_info = ch_info->power_info; | 1781 | power_info = ch_info->power_info; |
@@ -1821,7 +1828,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv, | |||
1821 | * based strictly on regulatory (eeprom and spectrum mgt) limitations | 1828 | * based strictly on regulatory (eeprom and spectrum mgt) limitations |
1822 | * (no consideration for h/w clipping limitations). | 1829 | * (no consideration for h/w clipping limitations). |
1823 | */ | 1830 | */ |
1824 | static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info) | 1831 | static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) |
1825 | { | 1832 | { |
1826 | s8 max_power; | 1833 | s8 max_power; |
1827 | 1834 | ||
@@ -1849,9 +1856,10 @@ static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_i | |||
1849 | * | 1856 | * |
1850 | * If RxOn is "associated", this sends the new Txpower to NIC! | 1857 | * If RxOn is "associated", this sends the new Txpower to NIC! |
1851 | */ | 1858 | */ |
1852 | static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv) | 1859 | static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) |
1853 | { | 1860 | { |
1854 | struct iwl3945_channel_info *ch_info = NULL; | 1861 | struct iwl_channel_info *ch_info = NULL; |
1862 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
1855 | int delta_index; | 1863 | int delta_index; |
1856 | const s8 *clip_pwrs; /* array of h/w max power levels for each rate */ | 1864 | const s8 *clip_pwrs; /* array of h/w max power levels for each rate */ |
1857 | u8 a_band; | 1865 | u8 a_band; |
@@ -1867,7 +1875,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv) | |||
1867 | a_band = is_channel_a_band(ch_info); | 1875 | a_band = is_channel_a_band(ch_info); |
1868 | 1876 | ||
1869 | /* Get this chnlgrp's factory calibration temperature */ | 1877 | /* Get this chnlgrp's factory calibration temperature */ |
1870 | ref_temp = (s16)priv->eeprom.groups[ch_info->group_index]. | 1878 | ref_temp = (s16)eeprom->groups[ch_info->group_index]. |
1871 | temperature; | 1879 | temperature; |
1872 | 1880 | ||
1873 | /* get power index adjustment based on current and factory | 1881 | /* get power index adjustment based on current and factory |
@@ -1893,7 +1901,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv) | |||
1893 | } | 1901 | } |
1894 | 1902 | ||
1895 | /* Get this chnlgrp's rate-to-max/clip-powers table */ | 1903 | /* Get this chnlgrp's rate-to-max/clip-powers table */ |
1896 | clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers; | 1904 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; |
1897 | 1905 | ||
1898 | /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ | 1906 | /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ |
1899 | for (scan_tbl_index = 0; | 1907 | for (scan_tbl_index = 0; |
@@ -1907,24 +1915,24 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv) | |||
1907 | } | 1915 | } |
1908 | 1916 | ||
1909 | /* send Txpower command for current channel to ucode */ | 1917 | /* send Txpower command for current channel to ucode */ |
1910 | return iwl3945_hw_reg_send_txpower(priv); | 1918 | return priv->cfg->ops->lib->send_tx_power(priv); |
1911 | } | 1919 | } |
1912 | 1920 | ||
1913 | int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power) | 1921 | int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) |
1914 | { | 1922 | { |
1915 | struct iwl3945_channel_info *ch_info; | 1923 | struct iwl_channel_info *ch_info; |
1916 | s8 max_power; | 1924 | s8 max_power; |
1917 | u8 a_band; | 1925 | u8 a_band; |
1918 | u8 i; | 1926 | u8 i; |
1919 | 1927 | ||
1920 | if (priv->user_txpower_limit == power) { | 1928 | if (priv->tx_power_user_lmt == power) { |
1921 | IWL_DEBUG_POWER("Requested Tx power same as current " | 1929 | IWL_DEBUG_POWER("Requested Tx power same as current " |
1922 | "limit: %ddBm.\n", power); | 1930 | "limit: %ddBm.\n", power); |
1923 | return 0; | 1931 | return 0; |
1924 | } | 1932 | } |
1925 | 1933 | ||
1926 | IWL_DEBUG_POWER("Setting upper limit clamp to %ddBm.\n", power); | 1934 | IWL_DEBUG_POWER("Setting upper limit clamp to %ddBm.\n", power); |
1927 | priv->user_txpower_limit = power; | 1935 | priv->tx_power_user_lmt = power; |
1928 | 1936 | ||
1929 | /* set up new Tx powers for each and every channel, 2.4 and 5.x */ | 1937 | /* set up new Tx powers for each and every channel, 2.4 and 5.x */ |
1930 | 1938 | ||
@@ -1953,7 +1961,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power) | |||
1953 | } | 1961 | } |
1954 | 1962 | ||
1955 | /* will add 3945 channel switch cmd handling later */ | 1963 | /* will add 3945 channel switch cmd handling later */ |
1956 | int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel) | 1964 | int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel) |
1957 | { | 1965 | { |
1958 | return 0; | 1966 | return 0; |
1959 | } | 1967 | } |
@@ -1968,7 +1976,7 @@ int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel) | |||
1968 | * -- send new set of gain settings to NIC | 1976 | * -- send new set of gain settings to NIC |
1969 | * NOTE: This should continue working, even when we're not associated, | 1977 | * NOTE: This should continue working, even when we're not associated, |
1970 | * so we can keep our internal table of scan powers current. */ | 1978 | * so we can keep our internal table of scan powers current. */ |
1971 | void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv) | 1979 | void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) |
1972 | { | 1980 | { |
1973 | /* This will kick in the "brute force" | 1981 | /* This will kick in the "brute force" |
1974 | * iwl3945_hw_reg_comp_txpower_temp() below */ | 1982 | * iwl3945_hw_reg_comp_txpower_temp() below */ |
@@ -1987,7 +1995,7 @@ void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv) | |||
1987 | 1995 | ||
1988 | static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) | 1996 | static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) |
1989 | { | 1997 | { |
1990 | struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, | 1998 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
1991 | thermal_periodic.work); | 1999 | thermal_periodic.work); |
1992 | 2000 | ||
1993 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2001 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
@@ -2009,10 +2017,11 @@ static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) | |||
2009 | * on A-band, EEPROM's "group frequency" entries represent the top | 2017 | * on A-band, EEPROM's "group frequency" entries represent the top |
2010 | * channel in each group 1-4. Group 5 All B/G channels are in group 0. | 2018 | * channel in each group 1-4. Group 5 All B/G channels are in group 0. |
2011 | */ | 2019 | */ |
2012 | static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv, | 2020 | static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv, |
2013 | const struct iwl3945_channel_info *ch_info) | 2021 | const struct iwl_channel_info *ch_info) |
2014 | { | 2022 | { |
2015 | struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0]; | 2023 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; |
2024 | struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0]; | ||
2016 | u8 group; | 2025 | u8 group; |
2017 | u16 group_index = 0; /* based on factory calib frequencies */ | 2026 | u16 group_index = 0; /* based on factory calib frequencies */ |
2018 | u8 grp_channel; | 2027 | u8 grp_channel; |
@@ -2043,11 +2052,12 @@ static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv, | |||
2043 | * Interpolate to get nominal (i.e. at factory calibration temperature) index | 2052 | * Interpolate to get nominal (i.e. at factory calibration temperature) index |
2044 | * into radio/DSP gain settings table for requested power. | 2053 | * into radio/DSP gain settings table for requested power. |
2045 | */ | 2054 | */ |
2046 | static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv, | 2055 | static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv, |
2047 | s8 requested_power, | 2056 | s8 requested_power, |
2048 | s32 setting_index, s32 *new_index) | 2057 | s32 setting_index, s32 *new_index) |
2049 | { | 2058 | { |
2050 | const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL; | 2059 | const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL; |
2060 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
2051 | s32 index0, index1; | 2061 | s32 index0, index1; |
2052 | s32 power = 2 * requested_power; | 2062 | s32 power = 2 * requested_power; |
2053 | s32 i; | 2063 | s32 i; |
@@ -2056,7 +2066,7 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv, | |||
2056 | s32 res; | 2066 | s32 res; |
2057 | s32 denominator; | 2067 | s32 denominator; |
2058 | 2068 | ||
2059 | chnl_grp = &priv->eeprom.groups[setting_index]; | 2069 | chnl_grp = &eeprom->groups[setting_index]; |
2060 | samples = chnl_grp->samples; | 2070 | samples = chnl_grp->samples; |
2061 | for (i = 0; i < 5; i++) { | 2071 | for (i = 0; i < 5; i++) { |
2062 | if (power == samples[i].power) { | 2072 | if (power == samples[i].power) { |
@@ -2091,10 +2101,11 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv, | |||
2091 | return 0; | 2101 | return 0; |
2092 | } | 2102 | } |
2093 | 2103 | ||
2094 | static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv) | 2104 | static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) |
2095 | { | 2105 | { |
2096 | u32 i; | 2106 | u32 i; |
2097 | s32 rate_index; | 2107 | s32 rate_index; |
2108 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
2098 | const struct iwl3945_eeprom_txpower_group *group; | 2109 | const struct iwl3945_eeprom_txpower_group *group; |
2099 | 2110 | ||
2100 | IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n"); | 2111 | IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n"); |
@@ -2102,11 +2113,11 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv) | |||
2102 | for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) { | 2113 | for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) { |
2103 | s8 *clip_pwrs; /* table of power levels for each rate */ | 2114 | s8 *clip_pwrs; /* table of power levels for each rate */ |
2104 | s8 satur_pwr; /* saturation power for each chnl group */ | 2115 | s8 satur_pwr; /* saturation power for each chnl group */ |
2105 | group = &priv->eeprom.groups[i]; | 2116 | group = &eeprom->groups[i]; |
2106 | 2117 | ||
2107 | /* sanity check on factory saturation power value */ | 2118 | /* sanity check on factory saturation power value */ |
2108 | if (group->saturation_power < 40) { | 2119 | if (group->saturation_power < 40) { |
2109 | IWL_WARNING("Error: saturation power is %d, " | 2120 | IWL_WARN(priv, "Error: saturation power is %d, " |
2110 | "less than minimum expected 40\n", | 2121 | "less than minimum expected 40\n", |
2111 | group->saturation_power); | 2122 | group->saturation_power); |
2112 | return; | 2123 | return; |
@@ -2121,7 +2132,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv) | |||
2121 | * power peaks, without too much distortion (clipping). | 2132 | * power peaks, without too much distortion (clipping). |
2122 | */ | 2133 | */ |
2123 | /* we'll fill in this array with h/w max power levels */ | 2134 | /* we'll fill in this array with h/w max power levels */ |
2124 | clip_pwrs = (s8 *) priv->clip_groups[i].clip_powers; | 2135 | clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers; |
2125 | 2136 | ||
2126 | /* divide factory saturation power by 2 to find -3dB level */ | 2137 | /* divide factory saturation power by 2 to find -3dB level */ |
2127 | satur_pwr = (s8) (group->saturation_power >> 1); | 2138 | satur_pwr = (s8) (group->saturation_power >> 1); |
@@ -2171,10 +2182,11 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv) | |||
2171 | * | 2182 | * |
2172 | * This does *not* write values to NIC, just sets up our internal table. | 2183 | * This does *not* write values to NIC, just sets up our internal table. |
2173 | */ | 2184 | */ |
2174 | int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv) | 2185 | int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) |
2175 | { | 2186 | { |
2176 | struct iwl3945_channel_info *ch_info = NULL; | 2187 | struct iwl_channel_info *ch_info = NULL; |
2177 | struct iwl3945_channel_power_info *pwr_info; | 2188 | struct iwl3945_channel_power_info *pwr_info; |
2189 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
2178 | int delta_index; | 2190 | int delta_index; |
2179 | u8 rate_index; | 2191 | u8 rate_index; |
2180 | u8 scan_tbl_index; | 2192 | u8 scan_tbl_index; |
@@ -2204,12 +2216,12 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv) | |||
2204 | iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); | 2216 | iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); |
2205 | 2217 | ||
2206 | /* Get this chnlgrp's rate->max/clip-powers table */ | 2218 | /* Get this chnlgrp's rate->max/clip-powers table */ |
2207 | clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers; | 2219 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; |
2208 | 2220 | ||
2209 | /* calculate power index *adjustment* value according to | 2221 | /* calculate power index *adjustment* value according to |
2210 | * diff between current temperature and factory temperature */ | 2222 | * diff between current temperature and factory temperature */ |
2211 | delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, | 2223 | delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, |
2212 | priv->eeprom.groups[ch_info->group_index]. | 2224 | eeprom->groups[ch_info->group_index]. |
2213 | temperature); | 2225 | temperature); |
2214 | 2226 | ||
2215 | IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n", | 2227 | IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n", |
@@ -2235,7 +2247,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv) | |||
2235 | ch_info->group_index, | 2247 | ch_info->group_index, |
2236 | &power_idx); | 2248 | &power_idx); |
2237 | if (rc) { | 2249 | if (rc) { |
2238 | IWL_ERROR("Invalid power index\n"); | 2250 | IWL_ERR(priv, "Invalid power index\n"); |
2239 | return rc; | 2251 | return rc; |
2240 | } | 2252 | } |
2241 | pwr_info->base_power_index = (u8) power_idx; | 2253 | pwr_info->base_power_index = (u8) power_idx; |
@@ -2295,75 +2307,88 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv) | |||
2295 | return 0; | 2307 | return 0; |
2296 | } | 2308 | } |
2297 | 2309 | ||
2298 | int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv) | 2310 | int iwl3945_hw_rxq_stop(struct iwl_priv *priv) |
2299 | { | 2311 | { |
2300 | int rc; | 2312 | int rc; |
2301 | unsigned long flags; | 2313 | unsigned long flags; |
2302 | 2314 | ||
2303 | spin_lock_irqsave(&priv->lock, flags); | 2315 | spin_lock_irqsave(&priv->lock, flags); |
2304 | rc = iwl3945_grab_nic_access(priv); | 2316 | rc = iwl_grab_nic_access(priv); |
2305 | if (rc) { | 2317 | if (rc) { |
2306 | spin_unlock_irqrestore(&priv->lock, flags); | 2318 | spin_unlock_irqrestore(&priv->lock, flags); |
2307 | return rc; | 2319 | return rc; |
2308 | } | 2320 | } |
2309 | 2321 | ||
2310 | iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0); | 2322 | iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0); |
2311 | rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, | 2323 | rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS, |
2312 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | 2324 | FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); |
2313 | if (rc < 0) | 2325 | if (rc < 0) |
2314 | IWL_ERROR("Can't stop Rx DMA.\n"); | 2326 | IWL_ERR(priv, "Can't stop Rx DMA.\n"); |
2315 | 2327 | ||
2316 | iwl3945_release_nic_access(priv); | 2328 | iwl_release_nic_access(priv); |
2317 | spin_unlock_irqrestore(&priv->lock, flags); | 2329 | spin_unlock_irqrestore(&priv->lock, flags); |
2318 | 2330 | ||
2319 | return 0; | 2331 | return 0; |
2320 | } | 2332 | } |
2321 | 2333 | ||
2322 | int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) | 2334 | int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) |
2323 | { | 2335 | { |
2324 | int rc; | 2336 | int rc; |
2325 | unsigned long flags; | 2337 | unsigned long flags; |
2326 | int txq_id = txq->q.id; | 2338 | int txq_id = txq->q.id; |
2327 | 2339 | ||
2328 | struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt; | 2340 | struct iwl3945_shared *shared_data = priv->shared_virt; |
2329 | 2341 | ||
2330 | shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); | 2342 | shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); |
2331 | 2343 | ||
2332 | spin_lock_irqsave(&priv->lock, flags); | 2344 | spin_lock_irqsave(&priv->lock, flags); |
2333 | rc = iwl3945_grab_nic_access(priv); | 2345 | rc = iwl_grab_nic_access(priv); |
2334 | if (rc) { | 2346 | if (rc) { |
2335 | spin_unlock_irqrestore(&priv->lock, flags); | 2347 | spin_unlock_irqrestore(&priv->lock, flags); |
2336 | return rc; | 2348 | return rc; |
2337 | } | 2349 | } |
2338 | iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0); | 2350 | iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0); |
2339 | iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0); | 2351 | iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0); |
2340 | 2352 | ||
2341 | iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id), | 2353 | iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), |
2342 | ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT | | 2354 | FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT | |
2343 | ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF | | 2355 | FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF | |
2344 | ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | | 2356 | FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | |
2345 | ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | | 2357 | FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | |
2346 | ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); | 2358 | FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); |
2347 | iwl3945_release_nic_access(priv); | 2359 | iwl_release_nic_access(priv); |
2348 | 2360 | ||
2349 | /* fake read to flush all prev. writes */ | 2361 | /* fake read to flush all prev. writes */ |
2350 | iwl3945_read32(priv, FH_TSSR_CBB_BASE); | 2362 | iwl_read32(priv, FH39_TSSR_CBB_BASE); |
2351 | spin_unlock_irqrestore(&priv->lock, flags); | 2363 | spin_unlock_irqrestore(&priv->lock, flags); |
2352 | 2364 | ||
2353 | return 0; | 2365 | return 0; |
2354 | } | 2366 | } |
2355 | 2367 | ||
2356 | int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv) | 2368 | /* |
2369 | * HCMD utils | ||
2370 | */ | ||
2371 | static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len) | ||
2357 | { | 2372 | { |
2358 | struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt; | 2373 | switch (cmd_id) { |
2374 | case REPLY_RXON: | ||
2375 | return (u16) sizeof(struct iwl3945_rxon_cmd); | ||
2376 | default: | ||
2377 | return len; | ||
2378 | } | ||
2379 | } | ||
2359 | 2380 | ||
2360 | return le32_to_cpu(shared_data->rx_read_ptr[0]); | 2381 | static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) |
2382 | { | ||
2383 | u16 size = (u16)sizeof(struct iwl3945_addsta_cmd); | ||
2384 | memcpy(data, cmd, size); | ||
2385 | return size; | ||
2361 | } | 2386 | } |
2362 | 2387 | ||
2363 | /** | 2388 | /** |
2364 | * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table | 2389 | * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table |
2365 | */ | 2390 | */ |
2366 | int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | 2391 | int iwl3945_init_hw_rate_table(struct iwl_priv *priv) |
2367 | { | 2392 | { |
2368 | int rc, i, index, prev_index; | 2393 | int rc, i, index, prev_index; |
2369 | struct iwl3945_rate_scaling_cmd rate_cmd = { | 2394 | struct iwl3945_rate_scaling_cmd rate_cmd = { |
@@ -2428,47 +2453,48 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2428 | 2453 | ||
2429 | /* Update the rate scaling for control frame Tx */ | 2454 | /* Update the rate scaling for control frame Tx */ |
2430 | rate_cmd.table_id = 0; | 2455 | rate_cmd.table_id = 0; |
2431 | rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), | 2456 | rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), |
2432 | &rate_cmd); | 2457 | &rate_cmd); |
2433 | if (rc) | 2458 | if (rc) |
2434 | return rc; | 2459 | return rc; |
2435 | 2460 | ||
2436 | /* Update the rate scaling for data frame Tx */ | 2461 | /* Update the rate scaling for data frame Tx */ |
2437 | rate_cmd.table_id = 1; | 2462 | rate_cmd.table_id = 1; |
2438 | return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), | 2463 | return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), |
2439 | &rate_cmd); | 2464 | &rate_cmd); |
2440 | } | 2465 | } |
2441 | 2466 | ||
2442 | /* Called when initializing driver */ | 2467 | /* Called when initializing driver */ |
2443 | int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv) | 2468 | int iwl3945_hw_set_hw_params(struct iwl_priv *priv) |
2444 | { | 2469 | { |
2445 | memset((void *)&priv->hw_setting, 0, | 2470 | memset((void *)&priv->hw_params, 0, |
2446 | sizeof(struct iwl3945_driver_hw_info)); | 2471 | sizeof(struct iwl_hw_params)); |
2447 | 2472 | ||
2448 | priv->hw_setting.shared_virt = | 2473 | priv->shared_virt = |
2449 | pci_alloc_consistent(priv->pci_dev, | 2474 | pci_alloc_consistent(priv->pci_dev, |
2450 | sizeof(struct iwl3945_shared), | 2475 | sizeof(struct iwl3945_shared), |
2451 | &priv->hw_setting.shared_phys); | 2476 | &priv->shared_phys); |
2452 | 2477 | ||
2453 | if (!priv->hw_setting.shared_virt) { | 2478 | if (!priv->shared_virt) { |
2454 | IWL_ERROR("failed to allocate pci memory\n"); | 2479 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
2455 | mutex_unlock(&priv->mutex); | 2480 | mutex_unlock(&priv->mutex); |
2456 | return -ENOMEM; | 2481 | return -ENOMEM; |
2457 | } | 2482 | } |
2458 | 2483 | ||
2459 | priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE; | 2484 | priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); |
2460 | priv->hw_setting.max_pkt_size = 2342; | 2485 | priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K; |
2461 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd); | 2486 | priv->hw_params.max_pkt_size = 2342; |
2462 | priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; | 2487 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
2463 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; | 2488 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
2464 | priv->hw_setting.max_stations = IWL3945_STATION_COUNT; | 2489 | priv->hw_params.max_stations = IWL3945_STATION_COUNT; |
2465 | priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID; | 2490 | priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID; |
2491 | |||
2492 | priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; | ||
2466 | 2493 | ||
2467 | priv->hw_setting.tx_ant_num = 2; | ||
2468 | return 0; | 2494 | return 0; |
2469 | } | 2495 | } |
2470 | 2496 | ||
2471 | unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, | 2497 | unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, |
2472 | struct iwl3945_frame *frame, u8 rate) | 2498 | struct iwl3945_frame *frame, u8 rate) |
2473 | { | 2499 | { |
2474 | struct iwl3945_tx_beacon_cmd *tx_beacon_cmd; | 2500 | struct iwl3945_tx_beacon_cmd *tx_beacon_cmd; |
@@ -2477,7 +2503,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, | |||
2477 | tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; | 2503 | tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; |
2478 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); | 2504 | memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); |
2479 | 2505 | ||
2480 | tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id; | 2506 | tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; |
2481 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 2507 | tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
2482 | 2508 | ||
2483 | frame_size = iwl3945_fill_beacon_frame(priv, | 2509 | frame_size = iwl3945_fill_beacon_frame(priv, |
@@ -2501,37 +2527,261 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, | |||
2501 | return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size; | 2527 | return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size; |
2502 | } | 2528 | } |
2503 | 2529 | ||
2504 | void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) | 2530 | void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv) |
2505 | { | 2531 | { |
2506 | priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; | 2532 | priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; |
2507 | priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; | 2533 | priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; |
2508 | } | 2534 | } |
2509 | 2535 | ||
2510 | void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv) | 2536 | void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) |
2511 | { | 2537 | { |
2512 | INIT_DELAYED_WORK(&priv->thermal_periodic, | 2538 | INIT_DELAYED_WORK(&priv->thermal_periodic, |
2513 | iwl3945_bg_reg_txpower_periodic); | 2539 | iwl3945_bg_reg_txpower_periodic); |
2514 | } | 2540 | } |
2515 | 2541 | ||
2516 | void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv) | 2542 | void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) |
2517 | { | 2543 | { |
2518 | cancel_delayed_work(&priv->thermal_periodic); | 2544 | cancel_delayed_work(&priv->thermal_periodic); |
2519 | } | 2545 | } |
2520 | 2546 | ||
2521 | static struct iwl_3945_cfg iwl3945_bg_cfg = { | 2547 | /* check contents of special bootstrap uCode SRAM */ |
2548 | static int iwl3945_verify_bsm(struct iwl_priv *priv) | ||
2549 | { | ||
2550 | __le32 *image = priv->ucode_boot.v_addr; | ||
2551 | u32 len = priv->ucode_boot.len; | ||
2552 | u32 reg; | ||
2553 | u32 val; | ||
2554 | |||
2555 | IWL_DEBUG_INFO("Begin verify bsm\n"); | ||
2556 | |||
2557 | /* verify BSM SRAM contents */ | ||
2558 | val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG); | ||
2559 | for (reg = BSM_SRAM_LOWER_BOUND; | ||
2560 | reg < BSM_SRAM_LOWER_BOUND + len; | ||
2561 | reg += sizeof(u32), image++) { | ||
2562 | val = iwl_read_prph(priv, reg); | ||
2563 | if (val != le32_to_cpu(*image)) { | ||
2564 | IWL_ERR(priv, "BSM uCode verification failed at " | ||
2565 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | ||
2566 | BSM_SRAM_LOWER_BOUND, | ||
2567 | reg - BSM_SRAM_LOWER_BOUND, len, | ||
2568 | val, le32_to_cpu(*image)); | ||
2569 | return -EIO; | ||
2570 | } | ||
2571 | } | ||
2572 | |||
2573 | IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); | ||
2574 | |||
2575 | return 0; | ||
2576 | } | ||
2577 | |||
2578 | |||
2579 | /****************************************************************************** | ||
2580 | * | ||
2581 | * EEPROM related functions | ||
2582 | * | ||
2583 | ******************************************************************************/ | ||
2584 | |||
2585 | /* | ||
2586 | * Clear the OWNER_MSK, to establish driver (instead of uCode running on | ||
2587 | * embedded controller) as EEPROM reader; each read is a series of pulses | ||
2588 | * to/from the EEPROM chip, not a single event, so even reads could conflict | ||
2589 | * if they weren't arbitrated by some ownership mechanism. Here, the driver | ||
2590 | * simply claims ownership, which should be safe when this function is called | ||
2591 | * (i.e. before loading uCode!). | ||
2592 | */ | ||
2593 | static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv) | ||
2594 | { | ||
2595 | _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); | ||
2596 | return 0; | ||
2597 | } | ||
2598 | |||
2599 | |||
2600 | static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv) | ||
2601 | { | ||
2602 | return; | ||
2603 | } | ||
2604 | |||
2605 | /** | ||
2606 | * iwl3945_load_bsm - Load bootstrap instructions | ||
2607 | * | ||
2608 | * BSM operation: | ||
2609 | * | ||
2610 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program | ||
2611 | * in special SRAM that does not power down during RFKILL. When powering back | ||
2612 | * up after power-saving sleeps (or during initial uCode load), the BSM loads | ||
2613 | * the bootstrap program into the on-board processor, and starts it. | ||
2614 | * | ||
2615 | * The bootstrap program loads (via DMA) instructions and data for a new | ||
2616 | * program from host DRAM locations indicated by the host driver in the | ||
2617 | * BSM_DRAM_* registers. Once the new program is loaded, it starts | ||
2618 | * automatically. | ||
2619 | * | ||
2620 | * When initializing the NIC, the host driver points the BSM to the | ||
2621 | * "initialize" uCode image. This uCode sets up some internal data, then | ||
2622 | * notifies host via "initialize alive" that it is complete. | ||
2623 | * | ||
2624 | * The host then replaces the BSM_DRAM_* pointer values to point to the | ||
2625 | * normal runtime uCode instructions and a backup uCode data cache buffer | ||
2626 | * (filled initially with starting data values for the on-board processor), | ||
2627 | * then triggers the "initialize" uCode to load and launch the runtime uCode, | ||
2628 | * which begins normal operation. | ||
2629 | * | ||
2630 | * When doing a power-save shutdown, runtime uCode saves data SRAM into | ||
2631 | * the backup data cache in DRAM before SRAM is powered down. | ||
2632 | * | ||
2633 | * When powering back up, the BSM loads the bootstrap program. This reloads | ||
2634 | * the runtime uCode instructions and the backup data cache into SRAM, | ||
2635 | * and re-launches the runtime uCode from where it left off. | ||
2636 | */ | ||
2637 | static int iwl3945_load_bsm(struct iwl_priv *priv) | ||
2638 | { | ||
2639 | __le32 *image = priv->ucode_boot.v_addr; | ||
2640 | u32 len = priv->ucode_boot.len; | ||
2641 | dma_addr_t pinst; | ||
2642 | dma_addr_t pdata; | ||
2643 | u32 inst_len; | ||
2644 | u32 data_len; | ||
2645 | int rc; | ||
2646 | int i; | ||
2647 | u32 done; | ||
2648 | u32 reg_offset; | ||
2649 | |||
2650 | IWL_DEBUG_INFO("Begin load bsm\n"); | ||
2651 | |||
2652 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | ||
2653 | if (len > IWL39_MAX_BSM_SIZE) | ||
2654 | return -EINVAL; | ||
2655 | |||
2656 | /* Tell bootstrap uCode where to find the "Initialize" uCode | ||
2657 | * in host DRAM ... host DRAM physical address bits 31:0 for 3945. | ||
2658 | * NOTE: iwl3945_initialize_alive_start() will replace these values, | ||
2659 | * after the "initialize" uCode has run, to point to | ||
2660 | * runtime/protocol instructions and backup data cache. */ | ||
2661 | pinst = priv->ucode_init.p_addr; | ||
2662 | pdata = priv->ucode_init_data.p_addr; | ||
2663 | inst_len = priv->ucode_init.len; | ||
2664 | data_len = priv->ucode_init_data.len; | ||
2665 | |||
2666 | rc = iwl_grab_nic_access(priv); | ||
2667 | if (rc) | ||
2668 | return rc; | ||
2669 | |||
2670 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
2671 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
2672 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); | ||
2673 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); | ||
2674 | |||
2675 | /* Fill BSM memory with bootstrap instructions */ | ||
2676 | for (reg_offset = BSM_SRAM_LOWER_BOUND; | ||
2677 | reg_offset < BSM_SRAM_LOWER_BOUND + len; | ||
2678 | reg_offset += sizeof(u32), image++) | ||
2679 | _iwl_write_prph(priv, reg_offset, | ||
2680 | le32_to_cpu(*image)); | ||
2681 | |||
2682 | rc = iwl3945_verify_bsm(priv); | ||
2683 | if (rc) { | ||
2684 | iwl_release_nic_access(priv); | ||
2685 | return rc; | ||
2686 | } | ||
2687 | |||
2688 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | ||
2689 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | ||
2690 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, | ||
2691 | IWL39_RTC_INST_LOWER_BOUND); | ||
2692 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | ||
2693 | |||
2694 | /* Load bootstrap code into instruction SRAM now, | ||
2695 | * to prepare to load "initialize" uCode */ | ||
2696 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
2697 | BSM_WR_CTRL_REG_BIT_START); | ||
2698 | |||
2699 | /* Wait for load of bootstrap uCode to finish */ | ||
2700 | for (i = 0; i < 100; i++) { | ||
2701 | done = iwl_read_prph(priv, BSM_WR_CTRL_REG); | ||
2702 | if (!(done & BSM_WR_CTRL_REG_BIT_START)) | ||
2703 | break; | ||
2704 | udelay(10); | ||
2705 | } | ||
2706 | if (i < 100) | ||
2707 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | ||
2708 | else { | ||
2709 | IWL_ERR(priv, "BSM write did not complete!\n"); | ||
2710 | return -EIO; | ||
2711 | } | ||
2712 | |||
2713 | /* Enable future boot loads whenever power management unit triggers it | ||
2714 | * (e.g. when powering back up after power-save shutdown) */ | ||
2715 | iwl_write_prph(priv, BSM_WR_CTRL_REG, | ||
2716 | BSM_WR_CTRL_REG_BIT_START_EN); | ||
2717 | |||
2718 | iwl_release_nic_access(priv); | ||
2719 | |||
2720 | return 0; | ||
2721 | } | ||
2722 | |||
2723 | static struct iwl_lib_ops iwl3945_lib = { | ||
2724 | .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, | ||
2725 | .txq_free_tfd = iwl3945_hw_txq_free_tfd, | ||
2726 | .txq_init = iwl3945_hw_tx_queue_init, | ||
2727 | .load_ucode = iwl3945_load_bsm, | ||
2728 | .apm_ops = { | ||
2729 | .init = iwl3945_apm_init, | ||
2730 | .reset = iwl3945_apm_reset, | ||
2731 | .stop = iwl3945_apm_stop, | ||
2732 | .config = iwl3945_nic_config, | ||
2733 | .set_pwr_src = iwl3945_set_pwr_src, | ||
2734 | }, | ||
2735 | .eeprom_ops = { | ||
2736 | .regulatory_bands = { | ||
2737 | EEPROM_REGULATORY_BAND_1_CHANNELS, | ||
2738 | EEPROM_REGULATORY_BAND_2_CHANNELS, | ||
2739 | EEPROM_REGULATORY_BAND_3_CHANNELS, | ||
2740 | EEPROM_REGULATORY_BAND_4_CHANNELS, | ||
2741 | EEPROM_REGULATORY_BAND_5_CHANNELS, | ||
2742 | IWL3945_EEPROM_IMG_SIZE, | ||
2743 | IWL3945_EEPROM_IMG_SIZE, | ||
2744 | }, | ||
2745 | .verify_signature = iwlcore_eeprom_verify_signature, | ||
2746 | .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, | ||
2747 | .release_semaphore = iwl3945_eeprom_release_semaphore, | ||
2748 | .query_addr = iwlcore_eeprom_query_addr, | ||
2749 | }, | ||
2750 | .send_tx_power = iwl3945_send_tx_power, | ||
2751 | }; | ||
2752 | |||
2753 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { | ||
2754 | .get_hcmd_size = iwl3945_get_hcmd_size, | ||
2755 | .build_addsta_hcmd = iwl3945_build_addsta_hcmd, | ||
2756 | }; | ||
2757 | |||
2758 | static struct iwl_ops iwl3945_ops = { | ||
2759 | .lib = &iwl3945_lib, | ||
2760 | .utils = &iwl3945_hcmd_utils, | ||
2761 | }; | ||
2762 | |||
2763 | static struct iwl_cfg iwl3945_bg_cfg = { | ||
2522 | .name = "3945BG", | 2764 | .name = "3945BG", |
2523 | .fw_name_pre = IWL3945_FW_PRE, | 2765 | .fw_name_pre = IWL3945_FW_PRE, |
2524 | .ucode_api_max = IWL3945_UCODE_API_MAX, | 2766 | .ucode_api_max = IWL3945_UCODE_API_MAX, |
2525 | .ucode_api_min = IWL3945_UCODE_API_MIN, | 2767 | .ucode_api_min = IWL3945_UCODE_API_MIN, |
2526 | .sku = IWL_SKU_G, | 2768 | .sku = IWL_SKU_G, |
2769 | .eeprom_size = IWL3945_EEPROM_IMG_SIZE, | ||
2770 | .eeprom_ver = EEPROM_3945_EEPROM_VERSION, | ||
2771 | .ops = &iwl3945_ops, | ||
2772 | .mod_params = &iwl3945_mod_params | ||
2527 | }; | 2773 | }; |
2528 | 2774 | ||
2529 | static struct iwl_3945_cfg iwl3945_abg_cfg = { | 2775 | static struct iwl_cfg iwl3945_abg_cfg = { |
2530 | .name = "3945ABG", | 2776 | .name = "3945ABG", |
2531 | .fw_name_pre = IWL3945_FW_PRE, | 2777 | .fw_name_pre = IWL3945_FW_PRE, |
2532 | .ucode_api_max = IWL3945_UCODE_API_MAX, | 2778 | .ucode_api_max = IWL3945_UCODE_API_MAX, |
2533 | .ucode_api_min = IWL3945_UCODE_API_MIN, | 2779 | .ucode_api_min = IWL3945_UCODE_API_MIN, |
2534 | .sku = IWL_SKU_A|IWL_SKU_G, | 2780 | .sku = IWL_SKU_A|IWL_SKU_G, |
2781 | .eeprom_size = IWL3945_EEPROM_IMG_SIZE, | ||
2782 | .eeprom_ver = EEPROM_3945_EEPROM_VERSION, | ||
2783 | .ops = &iwl3945_ops, | ||
2784 | .mod_params = &iwl3945_mod_params | ||
2535 | }; | 2785 | }; |
2536 | 2786 | ||
2537 | struct pci_device_id iwl3945_hw_card_ids[] = { | 2787 | struct pci_device_id iwl3945_hw_card_ids[] = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 2c0ddc5110c6..fef54e9cf8a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -43,11 +43,13 @@ | |||
43 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | 43 | /* Hardware specific file defines the PCI IDs table for that hardware module */ |
44 | extern struct pci_device_id iwl3945_hw_card_ids[]; | 44 | extern struct pci_device_id iwl3945_hw_card_ids[]; |
45 | 45 | ||
46 | #define DRV_NAME "iwl3945" | ||
47 | #include "iwl-csr.h" | 46 | #include "iwl-csr.h" |
48 | #include "iwl-prph.h" | 47 | #include "iwl-prph.h" |
48 | #include "iwl-fh.h" | ||
49 | #include "iwl-3945-hw.h" | 49 | #include "iwl-3945-hw.h" |
50 | #include "iwl-3945-debug.h" | 50 | #include "iwl-debug.h" |
51 | #include "iwl-power.h" | ||
52 | #include "iwl-dev.h" | ||
51 | #include "iwl-3945-led.h" | 53 | #include "iwl-3945-led.h" |
52 | 54 | ||
53 | /* Highest firmware API version supported */ | 55 | /* Highest firmware API version supported */ |
@@ -74,8 +76,7 @@ extern struct pci_device_id iwl3945_hw_card_ids[]; | |||
74 | #define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) | 76 | #define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) |
75 | 77 | ||
76 | /* Module parameters accessible from iwl-*.c */ | 78 | /* Module parameters accessible from iwl-*.c */ |
77 | extern int iwl3945_param_hwcrypto; | 79 | extern struct iwl_mod_params iwl3945_mod_params; |
78 | extern int iwl3945_param_queues_num; | ||
79 | 80 | ||
80 | struct iwl3945_sta_priv { | 81 | struct iwl3945_sta_priv { |
81 | struct iwl3945_rs_sta *rs_sta; | 82 | struct iwl3945_rs_sta *rs_sta; |
@@ -95,7 +96,6 @@ enum iwl3945_antenna { | |||
95 | * else RTS for data/management frames where MPDU is larger | 96 | * else RTS for data/management frames where MPDU is larger |
96 | * than RTS value. | 97 | * than RTS value. |
97 | */ | 98 | */ |
98 | #define IWL_RX_BUF_SIZE 3000U | ||
99 | #define DEFAULT_RTS_THRESHOLD 2347U | 99 | #define DEFAULT_RTS_THRESHOLD 2347U |
100 | #define MIN_RTS_THRESHOLD 0U | 100 | #define MIN_RTS_THRESHOLD 0U |
101 | #define MAX_RTS_THRESHOLD 2347U | 101 | #define MAX_RTS_THRESHOLD 2347U |
@@ -105,136 +105,7 @@ enum iwl3945_antenna { | |||
105 | #define DEFAULT_SHORT_RETRY_LIMIT 7U | 105 | #define DEFAULT_SHORT_RETRY_LIMIT 7U |
106 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 106 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
107 | 107 | ||
108 | struct iwl3945_rx_mem_buffer { | 108 | #include "iwl-agn-rs.h" |
109 | dma_addr_t dma_addr; | ||
110 | struct sk_buff *skb; | ||
111 | struct list_head list; | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * Generic queue structure | ||
116 | * | ||
117 | * Contains common data for Rx and Tx queues | ||
118 | */ | ||
119 | struct iwl3945_queue { | ||
120 | int n_bd; /* number of BDs in this queue */ | ||
121 | int write_ptr; /* 1-st empty entry (index) host_w*/ | ||
122 | int read_ptr; /* last used entry (index) host_r*/ | ||
123 | dma_addr_t dma_addr; /* physical addr for BD's */ | ||
124 | int n_window; /* safe queue window */ | ||
125 | u32 id; | ||
126 | int low_mark; /* low watermark, resume queue if free | ||
127 | * space more than this */ | ||
128 | int high_mark; /* high watermark, stop queue if free | ||
129 | * space less than this */ | ||
130 | } __attribute__ ((packed)); | ||
131 | |||
132 | int iwl3945_queue_space(const struct iwl3945_queue *q); | ||
133 | int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i); | ||
134 | |||
135 | #define MAX_NUM_OF_TBS (20) | ||
136 | |||
137 | /* One for each TFD */ | ||
138 | struct iwl3945_tx_info { | ||
139 | struct sk_buff *skb[MAX_NUM_OF_TBS]; | ||
140 | }; | ||
141 | |||
142 | /** | ||
143 | * struct iwl3945_tx_queue - Tx Queue for DMA | ||
144 | * @q: generic Rx/Tx queue descriptor | ||
145 | * @bd: base of circular buffer of TFDs | ||
146 | * @cmd: array of command/Tx buffers | ||
147 | * @dma_addr_cmd: physical address of cmd/tx buffer array | ||
148 | * @txb: array of per-TFD driver data | ||
149 | * @need_update: indicates need to update read/write index | ||
150 | * | ||
151 | * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame | ||
152 | * descriptors) and required locking structures. | ||
153 | */ | ||
154 | struct iwl3945_tx_queue { | ||
155 | struct iwl3945_queue q; | ||
156 | struct iwl3945_tfd_frame *bd; | ||
157 | struct iwl3945_cmd *cmd; | ||
158 | dma_addr_t dma_addr_cmd; | ||
159 | struct iwl3945_tx_info *txb; | ||
160 | int need_update; | ||
161 | int active; | ||
162 | }; | ||
163 | |||
164 | #define IWL_NUM_SCAN_RATES (2) | ||
165 | |||
166 | struct iwl3945_channel_tgd_info { | ||
167 | u8 type; | ||
168 | s8 max_power; | ||
169 | }; | ||
170 | |||
171 | struct iwl3945_channel_tgh_info { | ||
172 | s64 last_radar_time; | ||
173 | }; | ||
174 | |||
175 | /* current Tx power values to use, one for each rate for each channel. | ||
176 | * requested power is limited by: | ||
177 | * -- regulatory EEPROM limits for this channel | ||
178 | * -- hardware capabilities (clip-powers) | ||
179 | * -- spectrum management | ||
180 | * -- user preference (e.g. iwconfig) | ||
181 | * when requested power is set, base power index must also be set. */ | ||
182 | struct iwl3945_channel_power_info { | ||
183 | struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ | ||
184 | s8 power_table_index; /* actual (compenst'd) index into gain table */ | ||
185 | s8 base_power_index; /* gain index for power at factory temp. */ | ||
186 | s8 requested_power; /* power (dBm) requested for this chnl/rate */ | ||
187 | }; | ||
188 | |||
189 | /* current scan Tx power values to use, one for each scan rate for each | ||
190 | * channel. */ | ||
191 | struct iwl3945_scan_power_info { | ||
192 | struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ | ||
193 | s8 power_table_index; /* actual (compenst'd) index into gain table */ | ||
194 | s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ | ||
195 | }; | ||
196 | |||
197 | /* | ||
198 | * One for each channel, holds all channel setup data | ||
199 | * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant | ||
200 | * with one another! | ||
201 | */ | ||
202 | #define IWL4965_MAX_RATE (33) | ||
203 | |||
204 | struct iwl3945_channel_info { | ||
205 | struct iwl3945_channel_tgd_info tgd; | ||
206 | struct iwl3945_channel_tgh_info tgh; | ||
207 | struct iwl3945_eeprom_channel eeprom; /* EEPROM regulatory limit */ | ||
208 | struct iwl3945_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for | ||
209 | * FAT channel */ | ||
210 | |||
211 | u8 channel; /* channel number */ | ||
212 | u8 flags; /* flags copied from EEPROM */ | ||
213 | s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ | ||
214 | s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ | ||
215 | s8 min_power; /* always 0 */ | ||
216 | s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ | ||
217 | |||
218 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ | ||
219 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | ||
220 | enum ieee80211_band band; | ||
221 | |||
222 | /* Radio/DSP gain settings for each "normal" data Tx rate. | ||
223 | * These include, in addition to RF and DSP gain, a few fields for | ||
224 | * remembering/modifying gain settings (indexes). */ | ||
225 | struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE]; | ||
226 | |||
227 | /* Radio/DSP gain settings for each scan rate, for directed scans. */ | ||
228 | struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; | ||
229 | }; | ||
230 | |||
231 | struct iwl3945_clip_group { | ||
232 | /* maximum power level to prevent clipping for each rate, derived by | ||
233 | * us from this band's saturation power in EEPROM */ | ||
234 | const s8 clip_powers[IWL_MAX_RATES]; | ||
235 | }; | ||
236 | |||
237 | #include "iwl-3945-rs.h" | ||
238 | 109 | ||
239 | #define IWL_TX_FIFO_AC0 0 | 110 | #define IWL_TX_FIFO_AC0 0 |
240 | #define IWL_TX_FIFO_AC1 1 | 111 | #define IWL_TX_FIFO_AC1 1 |
@@ -247,33 +118,6 @@ struct iwl3945_clip_group { | |||
247 | /* Minimum number of queues. MAX_NUM is defined in hw specific files */ | 118 | /* Minimum number of queues. MAX_NUM is defined in hw specific files */ |
248 | #define IWL_MIN_NUM_QUEUES 4 | 119 | #define IWL_MIN_NUM_QUEUES 4 |
249 | 120 | ||
250 | /* Power management (not Tx power) structures */ | ||
251 | |||
252 | struct iwl3945_power_vec_entry { | ||
253 | struct iwl3945_powertable_cmd cmd; | ||
254 | u8 no_dtim; | ||
255 | }; | ||
256 | #define IWL_POWER_RANGE_0 (0) | ||
257 | #define IWL_POWER_RANGE_1 (1) | ||
258 | |||
259 | #define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */ | ||
260 | #define IWL_POWER_INDEX_3 0x03 | ||
261 | #define IWL_POWER_INDEX_5 0x05 | ||
262 | #define IWL_POWER_AC 0x06 | ||
263 | #define IWL_POWER_BATTERY 0x07 | ||
264 | #define IWL_POWER_LIMIT 0x07 | ||
265 | #define IWL_POWER_MASK 0x0F | ||
266 | #define IWL_POWER_ENABLED 0x10 | ||
267 | #define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK) | ||
268 | |||
269 | struct iwl3945_power_mgr { | ||
270 | spinlock_t lock; | ||
271 | struct iwl3945_power_vec_entry pwr_range_0[IWL_POWER_AC]; | ||
272 | struct iwl3945_power_vec_entry pwr_range_1[IWL_POWER_AC]; | ||
273 | u8 active_index; | ||
274 | u32 dtim_val; | ||
275 | }; | ||
276 | |||
277 | #define IEEE80211_DATA_LEN 2304 | 121 | #define IEEE80211_DATA_LEN 2304 |
278 | #define IEEE80211_4ADDR_LEN 30 | 122 | #define IEEE80211_4ADDR_LEN 30 |
279 | #define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) | 123 | #define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) |
@@ -289,81 +133,10 @@ struct iwl3945_frame { | |||
289 | struct list_head list; | 133 | struct list_head list; |
290 | }; | 134 | }; |
291 | 135 | ||
292 | #define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf) | ||
293 | #define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8) | ||
294 | #define SEQ_TO_INDEX(x) ((u8)(x & 0xff)) | ||
295 | #define INDEX_TO_SEQ(x) ((u8)(x & 0xff)) | ||
296 | #define SEQ_HUGE_FRAME (0x4000) | ||
297 | #define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000) | ||
298 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) | 136 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) |
299 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) | 137 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) |
300 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) | 138 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) |
301 | 139 | ||
302 | enum { | ||
303 | /* CMD_SIZE_NORMAL = 0, */ | ||
304 | CMD_SIZE_HUGE = (1 << 0), | ||
305 | /* CMD_SYNC = 0, */ | ||
306 | CMD_ASYNC = (1 << 1), | ||
307 | /* CMD_NO_SKB = 0, */ | ||
308 | CMD_WANT_SKB = (1 << 2), | ||
309 | }; | ||
310 | |||
311 | struct iwl3945_cmd; | ||
312 | struct iwl3945_priv; | ||
313 | |||
314 | struct iwl3945_cmd_meta { | ||
315 | struct iwl3945_cmd_meta *source; | ||
316 | union { | ||
317 | struct sk_buff *skb; | ||
318 | int (*callback)(struct iwl3945_priv *priv, | ||
319 | struct iwl3945_cmd *cmd, struct sk_buff *skb); | ||
320 | } __attribute__ ((packed)) u; | ||
321 | |||
322 | /* The CMD_SIZE_HUGE flag bit indicates that the command | ||
323 | * structure is stored at the end of the shared queue memory. */ | ||
324 | u32 flags; | ||
325 | |||
326 | } __attribute__ ((packed)); | ||
327 | |||
328 | /** | ||
329 | * struct iwl3945_cmd | ||
330 | * | ||
331 | * For allocation of the command and tx queues, this establishes the overall | ||
332 | * size of the largest command we send to uCode, except for a scan command | ||
333 | * (which is relatively huge; space is allocated separately). | ||
334 | */ | ||
335 | struct iwl3945_cmd { | ||
336 | struct iwl3945_cmd_meta meta; | ||
337 | struct iwl3945_cmd_header hdr; | ||
338 | union { | ||
339 | struct iwl3945_addsta_cmd addsta; | ||
340 | struct iwl3945_led_cmd led; | ||
341 | u32 flags; | ||
342 | u8 val8; | ||
343 | u16 val16; | ||
344 | u32 val32; | ||
345 | struct iwl3945_bt_cmd bt; | ||
346 | struct iwl3945_rxon_time_cmd rxon_time; | ||
347 | struct iwl3945_powertable_cmd powertable; | ||
348 | struct iwl3945_qosparam_cmd qosparam; | ||
349 | struct iwl3945_tx_cmd tx; | ||
350 | struct iwl3945_tx_beacon_cmd tx_beacon; | ||
351 | struct iwl3945_rxon_assoc_cmd rxon_assoc; | ||
352 | u8 *indirect; | ||
353 | u8 payload[360]; | ||
354 | } __attribute__ ((packed)) cmd; | ||
355 | } __attribute__ ((packed)); | ||
356 | |||
357 | struct iwl3945_host_cmd { | ||
358 | u8 id; | ||
359 | u16 len; | ||
360 | struct iwl3945_cmd_meta meta; | ||
361 | const void *data; | ||
362 | }; | ||
363 | |||
364 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \ | ||
365 | sizeof(struct iwl3945_cmd_meta)) | ||
366 | |||
367 | /* | 140 | /* |
368 | * RX related structures and functions | 141 | * RX related structures and functions |
369 | */ | 142 | */ |
@@ -374,33 +147,6 @@ struct iwl3945_host_cmd { | |||
374 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 | 147 | #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 |
375 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 | 148 | #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 |
376 | 149 | ||
377 | /** | ||
378 | * struct iwl3945_rx_queue - Rx queue | ||
379 | * @processed: Internal index to last handled Rx packet | ||
380 | * @read: Shared index to newest available Rx buffer | ||
381 | * @write: Shared index to oldest written Rx packet | ||
382 | * @free_count: Number of pre-allocated buffers in rx_free | ||
383 | * @rx_free: list of free SKBs for use | ||
384 | * @rx_used: List of Rx buffers with no SKB | ||
385 | * @need_update: flag to indicate we need to update read/write index | ||
386 | * | ||
387 | * NOTE: rx_free and rx_used are used as a FIFO for iwl3945_rx_mem_buffers | ||
388 | */ | ||
389 | struct iwl3945_rx_queue { | ||
390 | __le32 *bd; | ||
391 | dma_addr_t dma_addr; | ||
392 | struct iwl3945_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; | ||
393 | struct iwl3945_rx_mem_buffer *queue[RX_QUEUE_SIZE]; | ||
394 | u32 processed; | ||
395 | u32 read; | ||
396 | u32 write; | ||
397 | u32 free_count; | ||
398 | struct list_head rx_free; | ||
399 | struct list_head rx_used; | ||
400 | int need_update; | ||
401 | spinlock_t lock; | ||
402 | }; | ||
403 | |||
404 | #define IWL_SUPPORTED_RATES_IE_LEN 8 | 150 | #define IWL_SUPPORTED_RATES_IE_LEN 8 |
405 | 151 | ||
406 | #define SCAN_INTERVAL 100 | 152 | #define SCAN_INTERVAL 100 |
@@ -430,87 +176,9 @@ struct iwl3945_rx_queue { | |||
430 | #define IWL_INVALID_RATE 0xFF | 176 | #define IWL_INVALID_RATE 0xFF |
431 | #define IWL_INVALID_VALUE -1 | 177 | #define IWL_INVALID_VALUE -1 |
432 | 178 | ||
433 | struct iwl3945_tid_data { | ||
434 | u16 seq_number; | ||
435 | }; | ||
436 | |||
437 | struct iwl3945_hw_key { | ||
438 | enum ieee80211_key_alg alg; | ||
439 | int keylen; | ||
440 | u8 key[32]; | ||
441 | }; | ||
442 | |||
443 | union iwl3945_ht_rate_supp { | ||
444 | u16 rates; | ||
445 | struct { | ||
446 | u8 siso_rate; | ||
447 | u8 mimo_rate; | ||
448 | }; | ||
449 | }; | ||
450 | |||
451 | union iwl3945_qos_capabity { | ||
452 | struct { | ||
453 | u8 edca_count:4; /* bit 0-3 */ | ||
454 | u8 q_ack:1; /* bit 4 */ | ||
455 | u8 queue_request:1; /* bit 5 */ | ||
456 | u8 txop_request:1; /* bit 6 */ | ||
457 | u8 reserved:1; /* bit 7 */ | ||
458 | } q_AP; | ||
459 | struct { | ||
460 | u8 acvo_APSD:1; /* bit 0 */ | ||
461 | u8 acvi_APSD:1; /* bit 1 */ | ||
462 | u8 ac_bk_APSD:1; /* bit 2 */ | ||
463 | u8 ac_be_APSD:1; /* bit 3 */ | ||
464 | u8 q_ack:1; /* bit 4 */ | ||
465 | u8 max_len:2; /* bit 5-6 */ | ||
466 | u8 more_data_ack:1; /* bit 7 */ | ||
467 | } q_STA; | ||
468 | u8 val; | ||
469 | }; | ||
470 | |||
471 | /* QoS structures */ | ||
472 | struct iwl3945_qos_info { | ||
473 | int qos_active; | ||
474 | union iwl3945_qos_capabity qos_cap; | ||
475 | struct iwl3945_qosparam_cmd def_qos_parm; | ||
476 | }; | ||
477 | |||
478 | #define STA_PS_STATUS_WAKE 0 | 179 | #define STA_PS_STATUS_WAKE 0 |
479 | #define STA_PS_STATUS_SLEEP 1 | 180 | #define STA_PS_STATUS_SLEEP 1 |
480 | 181 | ||
481 | struct iwl3945_station_entry { | ||
482 | struct iwl3945_addsta_cmd sta; | ||
483 | struct iwl3945_tid_data tid[MAX_TID_COUNT]; | ||
484 | union { | ||
485 | struct { | ||
486 | u8 rate; | ||
487 | u8 flags; | ||
488 | } s; | ||
489 | u16 rate_n_flags; | ||
490 | } current_rate; | ||
491 | u8 used; | ||
492 | u8 ps_status; | ||
493 | struct iwl3945_hw_key keyinfo; | ||
494 | }; | ||
495 | |||
496 | /* one for each uCode image (inst/data, boot/init/runtime) */ | ||
497 | struct fw_desc { | ||
498 | void *v_addr; /* access by driver */ | ||
499 | dma_addr_t p_addr; /* access by card's busmaster DMA */ | ||
500 | u32 len; /* bytes */ | ||
501 | }; | ||
502 | |||
503 | /* uCode file layout */ | ||
504 | struct iwl3945_ucode { | ||
505 | __le32 ver; /* major/minor/API/serial */ | ||
506 | __le32 inst_size; /* bytes of runtime instructions */ | ||
507 | __le32 data_size; /* bytes of runtime data */ | ||
508 | __le32 init_size; /* bytes of initialization instructions */ | ||
509 | __le32 init_data_size; /* bytes of initialization data */ | ||
510 | __le32 boot_size; /* bytes of bootstrap instructions */ | ||
511 | u8 data[0]; /* data in same order as "size" elements */ | ||
512 | }; | ||
513 | |||
514 | struct iwl3945_ibss_seq { | 182 | struct iwl3945_ibss_seq { |
515 | u8 mac[ETH_ALEN]; | 183 | u8 mac[ETH_ALEN]; |
516 | u16 seq_num; | 184 | u16 seq_num; |
@@ -519,34 +187,6 @@ struct iwl3945_ibss_seq { | |||
519 | struct list_head list; | 187 | struct list_head list; |
520 | }; | 188 | }; |
521 | 189 | ||
522 | /** | ||
523 | * struct iwl3945_driver_hw_info | ||
524 | * @max_txq_num: Max # Tx queues supported | ||
525 | * @tx_cmd_len: Size of Tx command (but not including frame itself) | ||
526 | * @tx_ant_num: Number of TX antennas | ||
527 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | ||
528 | * @rx_buf_size: | ||
529 | * @max_pkt_size: | ||
530 | * @max_rxq_log: Log-base-2 of max_rxq_size | ||
531 | * @max_stations: | ||
532 | * @bcast_sta_id: | ||
533 | * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status | ||
534 | * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status | ||
535 | */ | ||
536 | struct iwl3945_driver_hw_info { | ||
537 | u16 max_txq_num; | ||
538 | u16 tx_cmd_len; | ||
539 | u16 tx_ant_num; | ||
540 | u16 max_rxq_size; | ||
541 | u32 rx_buf_size; | ||
542 | u32 max_pkt_size; | ||
543 | u16 max_rxq_log; | ||
544 | u8 max_stations; | ||
545 | u8 bcast_sta_id; | ||
546 | void *shared_virt; | ||
547 | dma_addr_t shared_phys; | ||
548 | }; | ||
549 | |||
550 | #define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\ | 190 | #define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\ |
551 | x->u.rx_frame.stats.payload + \ | 191 | x->u.rx_frame.stats.payload + \ |
552 | x->u.rx_frame.stats.phy_count)) | 192 | x->u.rx_frame.stats.phy_count)) |
@@ -564,40 +204,33 @@ struct iwl3945_driver_hw_info { | |||
564 | * | 204 | * |
565 | *****************************************************************************/ | 205 | *****************************************************************************/ |
566 | struct iwl3945_addsta_cmd; | 206 | struct iwl3945_addsta_cmd; |
567 | extern int iwl3945_send_add_station(struct iwl3945_priv *priv, | 207 | extern int iwl3945_send_add_station(struct iwl_priv *priv, |
568 | struct iwl3945_addsta_cmd *sta, u8 flags); | 208 | struct iwl3945_addsta_cmd *sta, u8 flags); |
569 | extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid, | 209 | extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid, |
570 | int is_ap, u8 flags); | 210 | int is_ap, u8 flags); |
571 | extern int iwl3945_power_init_handle(struct iwl3945_priv *priv); | 211 | extern int iwl3945_power_init_handle(struct iwl_priv *priv); |
572 | extern int iwl3945_eeprom_init(struct iwl3945_priv *priv); | 212 | extern int iwl3945_eeprom_init(struct iwl_priv *priv); |
573 | extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv); | ||
574 | extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, | ||
575 | struct iwl3945_rx_queue *rxq); | ||
576 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); | 213 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); |
577 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); | 214 | extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); |
578 | extern int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | 215 | extern int iwl3945_tx_queue_init(struct iwl_priv *priv, |
579 | struct iwl3945_tx_queue *txq, int count, u32 id); | 216 | struct iwl_tx_queue *txq, int count, u32 id); |
580 | extern void iwl3945_rx_replenish(void *data); | 217 | extern void iwl3945_rx_replenish(void *data); |
581 | extern void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq); | 218 | extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
582 | extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, | 219 | extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, |
583 | const void *data); | 220 | const void *data); |
584 | extern int __must_check iwl3945_send_cmd(struct iwl3945_priv *priv, | 221 | extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv, |
585 | struct iwl3945_host_cmd *cmd); | 222 | struct iwl_host_cmd *cmd); |
586 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv, | 223 | extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, |
587 | struct ieee80211_hdr *hdr,int left); | 224 | struct ieee80211_hdr *hdr,int left); |
588 | extern int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, | 225 | extern void iwl3945_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, |
589 | struct iwl3945_rx_queue *q); | ||
590 | extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv); | ||
591 | extern void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb, | ||
592 | u32 decrypt_res, | 226 | u32 decrypt_res, |
593 | struct ieee80211_rx_status *stats); | 227 | struct ieee80211_rx_status *stats); |
594 | extern const u8 iwl3945_broadcast_addr[ETH_ALEN]; | ||
595 | 228 | ||
596 | /* | 229 | /* |
597 | * Currently used by iwl-3945-rs... look at restructuring so that it doesn't | 230 | * Currently used by iwl-3945-rs... look at restructuring so that it doesn't |
598 | * call this... todo... fix that. | 231 | * call this... todo... fix that. |
599 | */ | 232 | */ |
600 | extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id, | 233 | extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id, |
601 | u16 tx_rate, u8 flags); | 234 | u16 tx_rate, u8 flags); |
602 | 235 | ||
603 | /****************************************************************************** | 236 | /****************************************************************************** |
@@ -616,36 +249,37 @@ extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id, | |||
616 | * iwl3945_mac_ <-- mac80211 callback | 249 | * iwl3945_mac_ <-- mac80211 callback |
617 | * | 250 | * |
618 | ****************************************************************************/ | 251 | ****************************************************************************/ |
619 | extern void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv); | 252 | extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv); |
620 | extern void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv); | 253 | extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv); |
621 | extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv); | 254 | extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv); |
622 | extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv); | 255 | extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv); |
623 | extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv); | 256 | extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv); |
624 | extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv); | 257 | extern int iwl3945_hw_nic_init(struct iwl_priv *priv); |
625 | extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv); | 258 | extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv); |
626 | extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv); | 259 | extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv); |
627 | extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv); | 260 | extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv); |
628 | extern int iwl3945_hw_nic_reset(struct iwl3945_priv *priv); | 261 | extern int iwl3945_hw_nic_reset(struct iwl_priv *priv); |
629 | extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *tfd, | 262 | extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, |
630 | dma_addr_t addr, u16 len); | 263 | struct iwl_tx_queue *txq, |
631 | extern int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq); | 264 | dma_addr_t addr, u16 len, |
632 | extern int iwl3945_hw_get_temperature(struct iwl3945_priv *priv); | 265 | u8 reset, u8 pad); |
633 | extern int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, | 266 | extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, |
634 | struct iwl3945_tx_queue *txq); | 267 | struct iwl_tx_queue *txq); |
635 | extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, | 268 | extern int iwl3945_hw_get_temperature(struct iwl_priv *priv); |
269 | extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, | ||
270 | struct iwl_tx_queue *txq); | ||
271 | extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, | ||
636 | struct iwl3945_frame *frame, u8 rate); | 272 | struct iwl3945_frame *frame, u8 rate); |
637 | extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv); | 273 | void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, |
638 | extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | ||
639 | struct iwl3945_cmd *cmd, | ||
640 | struct ieee80211_tx_info *info, | 274 | struct ieee80211_tx_info *info, |
641 | struct ieee80211_hdr *hdr, | 275 | struct ieee80211_hdr *hdr, |
642 | int sta_id, int tx_id); | 276 | int sta_id, int tx_id); |
643 | extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv); | 277 | extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); |
644 | extern int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power); | 278 | extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); |
645 | extern void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, | 279 | extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
646 | struct iwl3945_rx_mem_buffer *rxb); | 280 | struct iwl_rx_mem_buffer *rxb); |
647 | extern void iwl3945_disable_events(struct iwl3945_priv *priv); | 281 | extern void iwl3945_disable_events(struct iwl_priv *priv); |
648 | extern int iwl4965_get_temperature(const struct iwl3945_priv *priv); | 282 | extern int iwl4965_get_temperature(const struct iwl_priv *priv); |
649 | 283 | ||
650 | /** | 284 | /** |
651 | * iwl3945_hw_find_station - Find station id for a given BSSID | 285 | * iwl3945_hw_find_station - Find station id for a given BSSID |
@@ -655,302 +289,31 @@ extern int iwl4965_get_temperature(const struct iwl3945_priv *priv); | |||
655 | * not yet been merged into a single common layer for managing the | 289 | * not yet been merged into a single common layer for managing the |
656 | * station tables. | 290 | * station tables. |
657 | */ | 291 | */ |
658 | extern u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *bssid); | 292 | extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); |
659 | 293 | ||
660 | extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel); | 294 | extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel); |
661 | 295 | ||
662 | /* | 296 | /* |
663 | * Forward declare iwl-3945.c functions for iwl-base.c | 297 | * Forward declare iwl-3945.c functions for iwl-base.c |
664 | */ | 298 | */ |
665 | extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv); | 299 | extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv); |
666 | extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv); | 300 | extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); |
667 | extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv); | 301 | extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv); |
668 | extern int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv); | 302 | extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv); |
669 | extern u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, | 303 | extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, |
670 | u16 tx_rate, u8 flags); | 304 | u16 tx_rate, u8 flags); |
671 | 305 | ||
672 | 306 | static inline int iwl3945_is_associated(struct iwl_priv *priv) | |
673 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | ||
674 | |||
675 | enum { | ||
676 | MEASUREMENT_READY = (1 << 0), | ||
677 | MEASUREMENT_ACTIVE = (1 << 1), | ||
678 | }; | ||
679 | |||
680 | #endif | ||
681 | |||
682 | #ifdef CONFIG_IWL3945_RFKILL | ||
683 | struct iwl3945_priv; | ||
684 | |||
685 | void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv); | ||
686 | void iwl3945_rfkill_unregister(struct iwl3945_priv *priv); | ||
687 | int iwl3945_rfkill_init(struct iwl3945_priv *priv); | ||
688 | #else | ||
689 | static inline void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) {} | ||
690 | static inline void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) {} | ||
691 | static inline int iwl3945_rfkill_init(struct iwl3945_priv *priv) { return 0; } | ||
692 | #endif | ||
693 | |||
694 | #define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES | ||
695 | |||
696 | struct iwl3945_priv { | ||
697 | |||
698 | /* ieee device used by generic ieee processing code */ | ||
699 | struct ieee80211_hw *hw; | ||
700 | struct ieee80211_channel *ieee_channels; | ||
701 | struct ieee80211_rate *ieee_rates; | ||
702 | struct iwl_3945_cfg *cfg; /* device configuration */ | ||
703 | |||
704 | /* temporary frame storage list */ | ||
705 | struct list_head free_frames; | ||
706 | int frames_count; | ||
707 | |||
708 | enum ieee80211_band band; | ||
709 | int alloc_rxb_skb; | ||
710 | |||
711 | void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv, | ||
712 | struct iwl3945_rx_mem_buffer *rxb); | ||
713 | |||
714 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | ||
715 | |||
716 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | ||
717 | /* spectrum measurement report caching */ | ||
718 | struct iwl3945_spectrum_notification measure_report; | ||
719 | u8 measurement_status; | ||
720 | #endif | ||
721 | /* ucode beacon time */ | ||
722 | u32 ucode_beacon_time; | ||
723 | |||
724 | /* we allocate array of iwl3945_channel_info for NIC's valid channels. | ||
725 | * Access via channel # using indirect index array */ | ||
726 | struct iwl3945_channel_info *channel_info; /* channel info array */ | ||
727 | u8 channel_count; /* # of channels */ | ||
728 | |||
729 | /* each calibration channel group in the EEPROM has a derived | ||
730 | * clip setting for each rate. */ | ||
731 | const struct iwl3945_clip_group clip_groups[5]; | ||
732 | |||
733 | /* thermal calibration */ | ||
734 | s32 temperature; /* degrees Kelvin */ | ||
735 | s32 last_temperature; | ||
736 | |||
737 | /* Scan related variables */ | ||
738 | unsigned long last_scan_jiffies; | ||
739 | unsigned long next_scan_jiffies; | ||
740 | unsigned long scan_start; | ||
741 | unsigned long scan_pass_start; | ||
742 | unsigned long scan_start_tsf; | ||
743 | int scan_bands; | ||
744 | int one_direct_scan; | ||
745 | u8 direct_ssid_len; | ||
746 | u8 direct_ssid[IW_ESSID_MAX_SIZE]; | ||
747 | struct iwl3945_scan_cmd *scan; | ||
748 | |||
749 | /* spinlock */ | ||
750 | spinlock_t lock; /* protect general shared data */ | ||
751 | spinlock_t hcmd_lock; /* protect hcmd */ | ||
752 | struct mutex mutex; | ||
753 | |||
754 | /* basic pci-network driver stuff */ | ||
755 | struct pci_dev *pci_dev; | ||
756 | |||
757 | /* pci hardware address support */ | ||
758 | void __iomem *hw_base; | ||
759 | |||
760 | /* uCode images, save to reload in case of failure */ | ||
761 | u32 ucode_ver; /* ucode version, copy of | ||
762 | iwl3945_ucode.ver */ | ||
763 | struct fw_desc ucode_code; /* runtime inst */ | ||
764 | struct fw_desc ucode_data; /* runtime data original */ | ||
765 | struct fw_desc ucode_data_backup; /* runtime data save/restore */ | ||
766 | struct fw_desc ucode_init; /* initialization inst */ | ||
767 | struct fw_desc ucode_init_data; /* initialization data */ | ||
768 | struct fw_desc ucode_boot; /* bootstrap inst */ | ||
769 | |||
770 | |||
771 | struct iwl3945_rxon_time_cmd rxon_timing; | ||
772 | |||
773 | /* We declare this const so it can only be | ||
774 | * changed via explicit cast within the | ||
775 | * routines that actually update the physical | ||
776 | * hardware */ | ||
777 | const struct iwl3945_rxon_cmd active_rxon; | ||
778 | struct iwl3945_rxon_cmd staging_rxon; | ||
779 | |||
780 | int error_recovering; | ||
781 | struct iwl3945_rxon_cmd recovery_rxon; | ||
782 | |||
783 | /* 1st responses from initialize and runtime uCode images. | ||
784 | * 4965's initialize alive response contains some calibration data. */ | ||
785 | struct iwl3945_init_alive_resp card_alive_init; | ||
786 | struct iwl3945_alive_resp card_alive; | ||
787 | |||
788 | #ifdef CONFIG_IWL3945_RFKILL | ||
789 | struct rfkill *rfkill; | ||
790 | #endif | ||
791 | |||
792 | #ifdef CONFIG_IWL3945_LEDS | ||
793 | struct iwl3945_led led[IWL_LED_TRG_MAX]; | ||
794 | unsigned long last_blink_time; | ||
795 | u8 last_blink_rate; | ||
796 | u8 allow_blinking; | ||
797 | unsigned int rxtxpackets; | ||
798 | u64 led_tpt; | ||
799 | #endif | ||
800 | |||
801 | |||
802 | u16 active_rate; | ||
803 | u16 active_rate_basic; | ||
804 | |||
805 | u32 sta_supp_rates; | ||
806 | |||
807 | u8 call_post_assoc_from_beacon; | ||
808 | /* Rate scaling data */ | ||
809 | s8 data_retry_limit; | ||
810 | u8 retry_rate; | ||
811 | |||
812 | wait_queue_head_t wait_command_queue; | ||
813 | |||
814 | int activity_timer_active; | ||
815 | |||
816 | /* Rx and Tx DMA processing queues */ | ||
817 | struct iwl3945_rx_queue rxq; | ||
818 | struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES]; | ||
819 | |||
820 | unsigned long status; | ||
821 | |||
822 | int last_rx_rssi; /* From Rx packet statisitics */ | ||
823 | int last_rx_noise; /* From beacon statistics */ | ||
824 | |||
825 | struct iwl3945_power_mgr power_data; | ||
826 | |||
827 | struct iwl3945_notif_statistics statistics; | ||
828 | unsigned long last_statistics_time; | ||
829 | |||
830 | /* context information */ | ||
831 | u16 rates_mask; | ||
832 | |||
833 | u32 power_mode; | ||
834 | u32 antenna; | ||
835 | u8 bssid[ETH_ALEN]; | ||
836 | u16 rts_threshold; | ||
837 | u8 mac_addr[ETH_ALEN]; | ||
838 | |||
839 | /*station table variables */ | ||
840 | spinlock_t sta_lock; | ||
841 | int num_stations; | ||
842 | struct iwl3945_station_entry stations[IWL_STATION_COUNT]; | ||
843 | |||
844 | /* Indication if ieee80211_ops->open has been called */ | ||
845 | u8 is_open; | ||
846 | |||
847 | u8 mac80211_registered; | ||
848 | |||
849 | /* Rx'd packet timing information */ | ||
850 | u32 last_beacon_time; | ||
851 | u64 last_tsf; | ||
852 | |||
853 | /* eeprom */ | ||
854 | struct iwl3945_eeprom eeprom; | ||
855 | |||
856 | enum nl80211_iftype iw_mode; | ||
857 | |||
858 | struct sk_buff *ibss_beacon; | ||
859 | |||
860 | /* Last Rx'd beacon timestamp */ | ||
861 | u32 timestamp0; | ||
862 | u32 timestamp1; | ||
863 | u16 beacon_int; | ||
864 | struct iwl3945_driver_hw_info hw_setting; | ||
865 | struct ieee80211_vif *vif; | ||
866 | |||
867 | /* Current association information needed to configure the | ||
868 | * hardware */ | ||
869 | u16 assoc_id; | ||
870 | u16 assoc_capability; | ||
871 | u8 ps_mode; | ||
872 | |||
873 | struct iwl3945_qos_info qos_data; | ||
874 | |||
875 | struct workqueue_struct *workqueue; | ||
876 | |||
877 | struct work_struct up; | ||
878 | struct work_struct restart; | ||
879 | struct work_struct calibrated_work; | ||
880 | struct work_struct scan_completed; | ||
881 | struct work_struct rx_replenish; | ||
882 | struct work_struct rf_kill; | ||
883 | struct work_struct abort_scan; | ||
884 | struct work_struct update_link_led; | ||
885 | struct work_struct auth_work; | ||
886 | struct work_struct report_work; | ||
887 | struct work_struct request_scan; | ||
888 | struct work_struct beacon_update; | ||
889 | |||
890 | struct tasklet_struct irq_tasklet; | ||
891 | |||
892 | struct delayed_work init_alive_start; | ||
893 | struct delayed_work alive_start; | ||
894 | struct delayed_work activity_timer; | ||
895 | struct delayed_work thermal_periodic; | ||
896 | struct delayed_work gather_stats; | ||
897 | struct delayed_work scan_check; | ||
898 | |||
899 | #define IWL_DEFAULT_TX_POWER 0x0F | ||
900 | s8 user_txpower_limit; | ||
901 | s8 max_channel_txpower_limit; | ||
902 | |||
903 | |||
904 | #ifdef CONFIG_IWL3945_DEBUG | ||
905 | /* debugging info */ | ||
906 | u32 framecnt_to_us; | ||
907 | atomic_t restrict_refcnt; | ||
908 | #endif | ||
909 | }; /*iwl3945_priv */ | ||
910 | |||
911 | static inline int iwl3945_is_associated(struct iwl3945_priv *priv) | ||
912 | { | ||
913 | return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; | ||
914 | } | ||
915 | |||
916 | static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info) | ||
917 | { | ||
918 | if (ch_info == NULL) | ||
919 | return 0; | ||
920 | return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; | ||
921 | } | ||
922 | |||
923 | static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info) | ||
924 | { | ||
925 | return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; | ||
926 | } | ||
927 | |||
928 | static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info) | ||
929 | { | ||
930 | return ch_info->band == IEEE80211_BAND_5GHZ; | ||
931 | } | ||
932 | |||
933 | static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info) | ||
934 | { | ||
935 | return ch_info->band == IEEE80211_BAND_2GHZ; | ||
936 | } | ||
937 | |||
938 | static inline int is_channel_passive(const struct iwl3945_channel_info *ch) | ||
939 | { | ||
940 | return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; | ||
941 | } | ||
942 | |||
943 | static inline int is_channel_ibss(const struct iwl3945_channel_info *ch) | ||
944 | { | 307 | { |
945 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; | 308 | return (priv->active39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; |
946 | } | 309 | } |
947 | 310 | ||
948 | extern const struct iwl3945_channel_info *iwl3945_get_channel_info( | 311 | extern const struct iwl_channel_info *iwl3945_get_channel_info( |
949 | const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel); | 312 | const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); |
950 | 313 | ||
951 | extern int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate); | 314 | extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); |
952 | 315 | ||
953 | /* Requires full declaration of iwl3945_priv before including */ | 316 | /* Requires full declaration of iwl_priv before including */ |
954 | #include "iwl-3945-io.h" | 317 | #include "iwl-io.h" |
955 | 318 | ||
956 | #endif | 319 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index 6649f7b55650..af4c1bb0de14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -89,7 +89,7 @@ | |||
89 | #define LONG_SLOT_TIME 20 | 89 | #define LONG_SLOT_TIME 20 |
90 | 90 | ||
91 | /* RSSI to dBm */ | 91 | /* RSSI to dBm */ |
92 | #define IWL_RSSI_OFFSET 44 | 92 | #define IWL49_RSSI_OFFSET 44 |
93 | 93 | ||
94 | 94 | ||
95 | 95 | ||
@@ -110,43 +110,29 @@ | |||
110 | 110 | ||
111 | #define IWL_DEFAULT_TX_RETRY 15 | 111 | #define IWL_DEFAULT_TX_RETRY 15 |
112 | 112 | ||
113 | #define RX_QUEUE_SIZE 256 | ||
114 | #define RX_QUEUE_MASK 255 | ||
115 | #define RX_QUEUE_SIZE_LOG 8 | ||
116 | |||
117 | #define TFD_TX_CMD_SLOTS 256 | ||
118 | #define TFD_CMD_SLOTS 32 | ||
119 | |||
120 | /* | ||
121 | * RX related structures and functions | ||
122 | */ | ||
123 | #define RX_FREE_BUFFERS 64 | ||
124 | #define RX_LOW_WATERMARK 8 | ||
125 | |||
126 | /* Size of one Rx buffer in host DRAM */ | ||
127 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) | ||
128 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) | ||
129 | 113 | ||
130 | /* Sizes and addresses for instruction and data memory (SRAM) in | 114 | /* Sizes and addresses for instruction and data memory (SRAM) in |
131 | * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ | 115 | * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ |
132 | #define RTC_INST_LOWER_BOUND (0x000000) | 116 | #define IWL49_RTC_INST_LOWER_BOUND (0x000000) |
133 | #define IWL49_RTC_INST_UPPER_BOUND (0x018000) | 117 | #define IWL49_RTC_INST_UPPER_BOUND (0x018000) |
134 | 118 | ||
135 | #define RTC_DATA_LOWER_BOUND (0x800000) | 119 | #define IWL49_RTC_DATA_LOWER_BOUND (0x800000) |
136 | #define IWL49_RTC_DATA_UPPER_BOUND (0x80A000) | 120 | #define IWL49_RTC_DATA_UPPER_BOUND (0x80A000) |
137 | 121 | ||
138 | #define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND) | 122 | #define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \ |
139 | #define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND) | 123 | IWL49_RTC_INST_LOWER_BOUND) |
124 | #define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \ | ||
125 | IWL49_RTC_DATA_LOWER_BOUND) | ||
140 | 126 | ||
141 | #define IWL_MAX_INST_SIZE IWL49_RTC_INST_SIZE | 127 | #define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE |
142 | #define IWL_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE | 128 | #define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE |
143 | 129 | ||
144 | /* Size of uCode instruction memory in bootstrap state machine */ | 130 | /* Size of uCode instruction memory in bootstrap state machine */ |
145 | #define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE | 131 | #define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE |
146 | 132 | ||
147 | static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) | 133 | static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) |
148 | { | 134 | { |
149 | return (addr >= RTC_DATA_LOWER_BOUND) && | 135 | return (addr >= IWL49_RTC_DATA_LOWER_BOUND) && |
150 | (addr < IWL49_RTC_DATA_UPPER_BOUND); | 136 | (addr < IWL49_RTC_DATA_UPPER_BOUND); |
151 | } | 137 | } |
152 | 138 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 5a72bc0377de..d7d956db19d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -85,7 +85,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv) | |||
85 | reg += sizeof(u32), image++) { | 85 | reg += sizeof(u32), image++) { |
86 | val = iwl_read_prph(priv, reg); | 86 | val = iwl_read_prph(priv, reg); |
87 | if (val != le32_to_cpu(*image)) { | 87 | if (val != le32_to_cpu(*image)) { |
88 | IWL_ERROR("BSM uCode verification failed at " | 88 | IWL_ERR(priv, "BSM uCode verification failed at " |
89 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | 89 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", |
90 | BSM_SRAM_LOWER_BOUND, | 90 | BSM_SRAM_LOWER_BOUND, |
91 | reg - BSM_SRAM_LOWER_BOUND, len, | 91 | reg - BSM_SRAM_LOWER_BOUND, len, |
@@ -149,7 +149,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) | |||
149 | priv->ucode_type = UCODE_RT; | 149 | priv->ucode_type = UCODE_RT; |
150 | 150 | ||
151 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | 151 | /* make sure bootstrap program is no larger than BSM's SRAM size */ |
152 | if (len > IWL_MAX_BSM_SIZE) | 152 | if (len > IWL49_MAX_BSM_SIZE) |
153 | return -EINVAL; | 153 | return -EINVAL; |
154 | 154 | ||
155 | /* Tell bootstrap uCode where to find the "Initialize" uCode | 155 | /* Tell bootstrap uCode where to find the "Initialize" uCode |
@@ -186,7 +186,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) | |||
186 | 186 | ||
187 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | 187 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ |
188 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | 188 | iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); |
189 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND); | 189 | iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND); |
190 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | 190 | iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); |
191 | 191 | ||
192 | /* Load bootstrap code into instruction SRAM now, | 192 | /* Load bootstrap code into instruction SRAM now, |
@@ -203,7 +203,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) | |||
203 | if (i < 100) | 203 | if (i < 100) |
204 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | 204 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); |
205 | else { | 205 | else { |
206 | IWL_ERROR("BSM write did not complete!\n"); | 206 | IWL_ERR(priv, "BSM write did not complete!\n"); |
207 | return -EIO; | 207 | return -EIO; |
208 | } | 208 | } |
209 | 209 | ||
@@ -523,7 +523,8 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv) | |||
523 | cmd.diff_gain_c = 0; | 523 | cmd.diff_gain_c = 0; |
524 | if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, | 524 | if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, |
525 | sizeof(cmd), &cmd)) | 525 | sizeof(cmd), &cmd)) |
526 | IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n"); | 526 | IWL_ERR(priv, |
527 | "Could not send REPLY_PHY_CALIBRATION_CMD\n"); | ||
527 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; | 528 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; |
528 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); | 529 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); |
529 | } | 530 | } |
@@ -804,8 +805,9 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
804 | 805 | ||
805 | if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) || | 806 | if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) || |
806 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { | 807 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { |
807 | IWL_ERROR("invalid queues_num, should be between %d and %d\n", | 808 | IWL_ERR(priv, |
808 | IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES); | 809 | "invalid queues_num, should be between %d and %d\n", |
810 | IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES); | ||
809 | return -EINVAL; | 811 | return -EINVAL; |
810 | } | 812 | } |
811 | 813 | ||
@@ -813,6 +815,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
813 | priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; | 815 | priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; |
814 | priv->hw_params.scd_bc_tbls_size = | 816 | priv->hw_params.scd_bc_tbls_size = |
815 | IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); | 817 | IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); |
818 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | ||
816 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; | 819 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; |
817 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; | 820 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; |
818 | priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; | 821 | priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; |
@@ -820,6 +823,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
820 | priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; | 823 | priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; |
821 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ); | 824 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ); |
822 | 825 | ||
826 | priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; | ||
827 | |||
823 | priv->hw_params.tx_chains_num = 2; | 828 | priv->hw_params.tx_chains_num = 2; |
824 | priv->hw_params.rx_chains_num = 2; | 829 | priv->hw_params.rx_chains_num = 2; |
825 | priv->hw_params.valid_tx_ant = ANT_A | ANT_B; | 830 | priv->hw_params.valid_tx_ant = ANT_A | ANT_B; |
@@ -902,7 +907,6 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel) | |||
902 | channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) | 907 | channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) |
903 | return CALIB_CH_GROUP_4; | 908 | return CALIB_CH_GROUP_4; |
904 | 909 | ||
905 | IWL_ERROR("Can't find txatten group for channel %d.\n", channel); | ||
906 | return -1; | 910 | return -1; |
907 | } | 911 | } |
908 | 912 | ||
@@ -956,7 +960,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, | |||
956 | 960 | ||
957 | s = iwl4965_get_sub_band(priv, channel); | 961 | s = iwl4965_get_sub_band(priv, channel); |
958 | if (s >= EEPROM_TX_POWER_BANDS) { | 962 | if (s >= EEPROM_TX_POWER_BANDS) { |
959 | IWL_ERROR("Tx Power can not find channel %d\n", channel); | 963 | IWL_ERR(priv, "Tx Power can not find channel %d\n", channel); |
960 | return -1; | 964 | return -1; |
961 | } | 965 | } |
962 | 966 | ||
@@ -1303,7 +1307,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
1303 | s32 factory_actual_pwr[2]; | 1307 | s32 factory_actual_pwr[2]; |
1304 | s32 power_index; | 1308 | s32 power_index; |
1305 | 1309 | ||
1306 | /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units | 1310 | /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units |
1307 | * are used for indexing into txpower table) */ | 1311 | * are used for indexing into txpower table) */ |
1308 | user_target_power = 2 * priv->tx_power_user_lmt; | 1312 | user_target_power = 2 * priv->tx_power_user_lmt; |
1309 | 1313 | ||
@@ -1319,8 +1323,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
1319 | /* get txatten group, used to select 1) thermal txpower adjustment | 1323 | /* get txatten group, used to select 1) thermal txpower adjustment |
1320 | * and 2) mimo txpower balance between Tx chains. */ | 1324 | * and 2) mimo txpower balance between Tx chains. */ |
1321 | txatten_grp = iwl4965_get_tx_atten_grp(channel); | 1325 | txatten_grp = iwl4965_get_tx_atten_grp(channel); |
1322 | if (txatten_grp < 0) | 1326 | if (txatten_grp < 0) { |
1327 | IWL_ERR(priv, "Can't find txatten group for channel %d.\n", | ||
1328 | channel); | ||
1323 | return -EINVAL; | 1329 | return -EINVAL; |
1330 | } | ||
1324 | 1331 | ||
1325 | IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n", | 1332 | IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n", |
1326 | channel, txatten_grp); | 1333 | channel, txatten_grp); |
@@ -1483,12 +1490,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
1483 | 1490 | ||
1484 | /* stay within the table! */ | 1491 | /* stay within the table! */ |
1485 | if (power_index > 107) { | 1492 | if (power_index > 107) { |
1486 | IWL_WARNING("txpower index %d > 107\n", | 1493 | IWL_WARN(priv, "txpower index %d > 107\n", |
1487 | power_index); | 1494 | power_index); |
1488 | power_index = 107; | 1495 | power_index = 107; |
1489 | } | 1496 | } |
1490 | if (power_index < 0) { | 1497 | if (power_index < 0) { |
1491 | IWL_WARNING("txpower index %d < 0\n", | 1498 | IWL_WARN(priv, "txpower index %d < 0\n", |
1492 | power_index); | 1499 | power_index); |
1493 | power_index = 0; | 1500 | power_index = 0; |
1494 | } | 1501 | } |
@@ -1531,7 +1538,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) | |||
1531 | /* If this gets hit a lot, switch it to a BUG() and catch | 1538 | /* If this gets hit a lot, switch it to a BUG() and catch |
1532 | * the stack trace to find out who is calling this during | 1539 | * the stack trace to find out who is calling this during |
1533 | * a scan. */ | 1540 | * a scan. */ |
1534 | IWL_WARNING("TX Power requested while scanning!\n"); | 1541 | IWL_WARN(priv, "TX Power requested while scanning!\n"); |
1535 | return -EAGAIN; | 1542 | return -EAGAIN; |
1536 | } | 1543 | } |
1537 | 1544 | ||
@@ -1725,7 +1732,7 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv) | |||
1725 | IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); | 1732 | IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); |
1726 | 1733 | ||
1727 | if (R3 == R1) { | 1734 | if (R3 == R1) { |
1728 | IWL_ERROR("Calibration conflict R1 == R3\n"); | 1735 | IWL_ERR(priv, "Calibration conflict R1 == R3\n"); |
1729 | return -1; | 1736 | return -1; |
1730 | } | 1737 | } |
1731 | 1738 | ||
@@ -1837,7 +1844,8 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
1837 | 1844 | ||
1838 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || | 1845 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || |
1839 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { | 1846 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { |
1840 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", | 1847 | IWL_WARN(priv, |
1848 | "queue number out of range: %d, must be %d to %d\n", | ||
1841 | txq_id, IWL49_FIRST_AMPDU_QUEUE, | 1849 | txq_id, IWL49_FIRST_AMPDU_QUEUE, |
1842 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); | 1850 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); |
1843 | return -EINVAL; | 1851 | return -EINVAL; |
@@ -1908,7 +1916,8 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
1908 | 1916 | ||
1909 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || | 1917 | if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || |
1910 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { | 1918 | (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) { |
1911 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", | 1919 | IWL_WARN(priv, |
1920 | "queue number out of range: %d, must be %d to %d\n", | ||
1912 | txq_id, IWL49_FIRST_AMPDU_QUEUE, | 1921 | txq_id, IWL49_FIRST_AMPDU_QUEUE, |
1913 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); | 1922 | IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1); |
1914 | return -EINVAL; | 1923 | return -EINVAL; |
@@ -2067,10 +2076,10 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
2067 | 2076 | ||
2068 | sc = le16_to_cpu(hdr->seq_ctrl); | 2077 | sc = le16_to_cpu(hdr->seq_ctrl); |
2069 | if (idx != (SEQ_TO_SN(sc) & 0xff)) { | 2078 | if (idx != (SEQ_TO_SN(sc) & 0xff)) { |
2070 | IWL_ERROR("BUG_ON idx doesn't match seq control" | 2079 | IWL_ERR(priv, |
2071 | " idx=%d, seq_idx=%d, seq=%d\n", | 2080 | "BUG_ON idx doesn't match seq control" |
2072 | idx, SEQ_TO_SN(sc), | 2081 | " idx=%d, seq_idx=%d, seq=%d\n", |
2073 | hdr->seq_ctrl); | 2082 | idx, SEQ_TO_SN(sc), hdr->seq_ctrl); |
2074 | return -1; | 2083 | return -1; |
2075 | } | 2084 | } |
2076 | 2085 | ||
@@ -2129,7 +2138,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2129 | u8 *qc = NULL; | 2138 | u8 *qc = NULL; |
2130 | 2139 | ||
2131 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { | 2140 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
2132 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 2141 | IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " |
2133 | "is out of range [0-%d] %d %d\n", txq_id, | 2142 | "is out of range [0-%d] %d %d\n", txq_id, |
2134 | index, txq->q.n_bd, txq->q.write_ptr, | 2143 | index, txq->q.n_bd, txq->q.write_ptr, |
2135 | txq->q.read_ptr); | 2144 | txq->q.read_ptr); |
@@ -2147,7 +2156,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2147 | 2156 | ||
2148 | sta_id = iwl_get_ra_sta_id(priv, hdr); | 2157 | sta_id = iwl_get_ra_sta_id(priv, hdr); |
2149 | if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { | 2158 | if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { |
2150 | IWL_ERROR("Station not known\n"); | 2159 | IWL_ERR(priv, "Station not known\n"); |
2151 | return; | 2160 | return; |
2152 | } | 2161 | } |
2153 | 2162 | ||
@@ -2210,7 +2219,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2210 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 2219 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
2211 | 2220 | ||
2212 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 2221 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
2213 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | 2222 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
2214 | } | 2223 | } |
2215 | 2224 | ||
2216 | static int iwl4965_calc_rssi(struct iwl_priv *priv, | 2225 | static int iwl4965_calc_rssi(struct iwl_priv *priv, |
@@ -2244,7 +2253,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv, | |||
2244 | 2253 | ||
2245 | /* dBm = max_rssi dB - agc dB - constant. | 2254 | /* dBm = max_rssi dB - agc dB - constant. |
2246 | * Higher AGC (higher radio gain) means lower signal. */ | 2255 | * Higher AGC (higher radio gain) means lower signal. */ |
2247 | return max_rssi - agc - IWL_RSSI_OFFSET; | 2256 | return max_rssi - agc - IWL49_RSSI_OFFSET; |
2248 | } | 2257 | } |
2249 | 2258 | ||
2250 | 2259 | ||
@@ -2287,6 +2296,9 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
2287 | .txq_set_sched = iwl4965_txq_set_sched, | 2296 | .txq_set_sched = iwl4965_txq_set_sched, |
2288 | .txq_agg_enable = iwl4965_txq_agg_enable, | 2297 | .txq_agg_enable = iwl4965_txq_agg_enable, |
2289 | .txq_agg_disable = iwl4965_txq_agg_disable, | 2298 | .txq_agg_disable = iwl4965_txq_agg_disable, |
2299 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
2300 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
2301 | .txq_init = iwl_hw_tx_queue_init, | ||
2290 | .rx_handler_setup = iwl4965_rx_handler_setup, | 2302 | .rx_handler_setup = iwl4965_rx_handler_setup, |
2291 | .setup_deferred_work = iwl4965_setup_deferred_work, | 2303 | .setup_deferred_work = iwl4965_setup_deferred_work, |
2292 | .cancel_deferred_work = iwl4965_cancel_deferred_work, | 2304 | .cancel_deferred_work = iwl4965_cancel_deferred_work, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 82c3859ce0f8..15cac70e36e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -68,10 +68,16 @@ | |||
68 | #ifndef __iwl_5000_hw_h__ | 68 | #ifndef __iwl_5000_hw_h__ |
69 | #define __iwl_5000_hw_h__ | 69 | #define __iwl_5000_hw_h__ |
70 | 70 | ||
71 | #define IWL50_RTC_INST_LOWER_BOUND (0x000000) | ||
71 | #define IWL50_RTC_INST_UPPER_BOUND (0x020000) | 72 | #define IWL50_RTC_INST_UPPER_BOUND (0x020000) |
73 | |||
74 | #define IWL50_RTC_DATA_LOWER_BOUND (0x800000) | ||
72 | #define IWL50_RTC_DATA_UPPER_BOUND (0x80C000) | 75 | #define IWL50_RTC_DATA_UPPER_BOUND (0x80C000) |
73 | #define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND) | 76 | |
74 | #define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND) | 77 | #define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - \ |
78 | IWL50_RTC_INST_LOWER_BOUND) | ||
79 | #define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - \ | ||
80 | IWL50_RTC_DATA_LOWER_BOUND) | ||
75 | 81 | ||
76 | /* EEPROM */ | 82 | /* EEPROM */ |
77 | #define IWL_5000_EEPROM_IMG_SIZE 2048 | 83 | #define IWL_5000_EEPROM_IMG_SIZE 2048 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 66d053d28a74..89d92a8ca157 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007-2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -289,7 +289,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address) | |||
289 | offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS); | 289 | offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS); |
290 | break; | 290 | break; |
291 | default: | 291 | default: |
292 | IWL_ERROR("illegal indirect type: 0x%X\n", | 292 | IWL_ERR(priv, "illegal indirect type: 0x%X\n", |
293 | address & INDIRECT_TYPE_MSK); | 293 | address & INDIRECT_TYPE_MSK); |
294 | break; | 294 | break; |
295 | } | 295 | } |
@@ -384,7 +384,8 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv) | |||
384 | ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, | 384 | ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, |
385 | sizeof(cmd), &cmd); | 385 | sizeof(cmd), &cmd); |
386 | if (ret) | 386 | if (ret) |
387 | IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n"); | 387 | IWL_ERR(priv, |
388 | "Could not send REPLY_PHY_CALIBRATION_CMD\n"); | ||
388 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; | 389 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; |
389 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); | 390 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); |
390 | } | 391 | } |
@@ -507,7 +508,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv, | |||
507 | index = IWL_CALIB_BASE_BAND; | 508 | index = IWL_CALIB_BASE_BAND; |
508 | break; | 509 | break; |
509 | default: | 510 | default: |
510 | IWL_ERROR("Unknown calibration notification %d\n", | 511 | IWL_ERR(priv, "Unknown calibration notification %d\n", |
511 | hdr->op_code); | 512 | hdr->op_code); |
512 | return; | 513 | return; |
513 | } | 514 | } |
@@ -580,7 +581,8 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv, | |||
580 | { | 581 | { |
581 | int ret = 0; | 582 | int ret = 0; |
582 | 583 | ||
583 | ret = iwl5000_load_section(priv, inst_image, RTC_INST_LOWER_BOUND); | 584 | ret = iwl5000_load_section(priv, inst_image, |
585 | IWL50_RTC_INST_LOWER_BOUND); | ||
584 | if (ret) | 586 | if (ret) |
585 | return ret; | 587 | return ret; |
586 | 588 | ||
@@ -588,19 +590,19 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv, | |||
588 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 590 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
589 | priv->ucode_write_complete, 5 * HZ); | 591 | priv->ucode_write_complete, 5 * HZ); |
590 | if (ret == -ERESTARTSYS) { | 592 | if (ret == -ERESTARTSYS) { |
591 | IWL_ERROR("Could not load the INST uCode section due " | 593 | IWL_ERR(priv, "Could not load the INST uCode section due " |
592 | "to interrupt\n"); | 594 | "to interrupt\n"); |
593 | return ret; | 595 | return ret; |
594 | } | 596 | } |
595 | if (!ret) { | 597 | if (!ret) { |
596 | IWL_ERROR("Could not load the INST uCode section\n"); | 598 | IWL_ERR(priv, "Could not load the INST uCode section\n"); |
597 | return -ETIMEDOUT; | 599 | return -ETIMEDOUT; |
598 | } | 600 | } |
599 | 601 | ||
600 | priv->ucode_write_complete = 0; | 602 | priv->ucode_write_complete = 0; |
601 | 603 | ||
602 | ret = iwl5000_load_section( | 604 | ret = iwl5000_load_section( |
603 | priv, data_image, RTC_DATA_LOWER_BOUND); | 605 | priv, data_image, IWL50_RTC_DATA_LOWER_BOUND); |
604 | if (ret) | 606 | if (ret) |
605 | return ret; | 607 | return ret; |
606 | 608 | ||
@@ -609,11 +611,11 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv, | |||
609 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | 611 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, |
610 | priv->ucode_write_complete, 5 * HZ); | 612 | priv->ucode_write_complete, 5 * HZ); |
611 | if (ret == -ERESTARTSYS) { | 613 | if (ret == -ERESTARTSYS) { |
612 | IWL_ERROR("Could not load the INST uCode section due " | 614 | IWL_ERR(priv, "Could not load the INST uCode section due " |
613 | "to interrupt\n"); | 615 | "to interrupt\n"); |
614 | return ret; | 616 | return ret; |
615 | } else if (!ret) { | 617 | } else if (!ret) { |
616 | IWL_ERROR("Could not load the DATA uCode section\n"); | 618 | IWL_ERR(priv, "Could not load the DATA uCode section\n"); |
617 | return -ETIMEDOUT; | 619 | return -ETIMEDOUT; |
618 | } else | 620 | } else |
619 | ret = 0; | 621 | ret = 0; |
@@ -675,7 +677,8 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv) | |||
675 | iwl_clear_stations_table(priv); | 677 | iwl_clear_stations_table(priv); |
676 | ret = priv->cfg->ops->lib->alive_notify(priv); | 678 | ret = priv->cfg->ops->lib->alive_notify(priv); |
677 | if (ret) { | 679 | if (ret) { |
678 | IWL_WARNING("Could not complete ALIVE transition: %d\n", ret); | 680 | IWL_WARN(priv, |
681 | "Could not complete ALIVE transition: %d\n", ret); | ||
679 | goto restart; | 682 | goto restart; |
680 | } | 683 | } |
681 | 684 | ||
@@ -824,8 +827,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
824 | { | 827 | { |
825 | if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || | 828 | if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || |
826 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { | 829 | (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { |
827 | IWL_ERROR("invalid queues_num, should be between %d and %d\n", | 830 | IWL_ERR(priv, |
828 | IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES); | 831 | "invalid queues_num, should be between %d and %d\n", |
832 | IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES); | ||
829 | return -EINVAL; | 833 | return -EINVAL; |
830 | } | 834 | } |
831 | 835 | ||
@@ -833,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
833 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | 837 | priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; |
834 | priv->hw_params.scd_bc_tbls_size = | 838 | priv->hw_params.scd_bc_tbls_size = |
835 | IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); | 839 | IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); |
840 | priv->hw_params.tfd_size = sizeof(struct iwl_tfd); | ||
836 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | 841 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; |
837 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; | 842 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; |
838 | priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; | 843 | priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; |
@@ -840,6 +845,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
840 | priv->hw_params.max_bsm_size = 0; | 845 | priv->hw_params.max_bsm_size = 0; |
841 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | | 846 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | |
842 | BIT(IEEE80211_BAND_5GHZ); | 847 | BIT(IEEE80211_BAND_5GHZ); |
848 | priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; | ||
849 | |||
843 | priv->hw_params.sens = &iwl5000_sensitivity; | 850 | priv->hw_params.sens = &iwl5000_sensitivity; |
844 | 851 | ||
845 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { | 852 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { |
@@ -1011,7 +1018,8 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
1011 | 1018 | ||
1012 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || | 1019 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || |
1013 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { | 1020 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { |
1014 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", | 1021 | IWL_WARN(priv, |
1022 | "queue number out of range: %d, must be %d to %d\n", | ||
1015 | txq_id, IWL50_FIRST_AMPDU_QUEUE, | 1023 | txq_id, IWL50_FIRST_AMPDU_QUEUE, |
1016 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); | 1024 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); |
1017 | return -EINVAL; | 1025 | return -EINVAL; |
@@ -1076,7 +1084,8 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
1076 | 1084 | ||
1077 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || | 1085 | if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || |
1078 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { | 1086 | (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) { |
1079 | IWL_WARNING("queue number out of range: %d, must be %d to %d\n", | 1087 | IWL_WARN(priv, |
1088 | "queue number out of range: %d, must be %d to %d\n", | ||
1080 | txq_id, IWL50_FIRST_AMPDU_QUEUE, | 1089 | txq_id, IWL50_FIRST_AMPDU_QUEUE, |
1081 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); | 1090 | IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1); |
1082 | return -EINVAL; | 1091 | return -EINVAL; |
@@ -1197,8 +1206,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1197 | 1206 | ||
1198 | sc = le16_to_cpu(hdr->seq_ctrl); | 1207 | sc = le16_to_cpu(hdr->seq_ctrl); |
1199 | if (idx != (SEQ_TO_SN(sc) & 0xff)) { | 1208 | if (idx != (SEQ_TO_SN(sc) & 0xff)) { |
1200 | IWL_ERROR("BUG_ON idx doesn't match seq control" | 1209 | IWL_ERR(priv, |
1201 | " idx=%d, seq_idx=%d, seq=%d\n", | 1210 | "BUG_ON idx doesn't match seq control" |
1211 | " idx=%d, seq_idx=%d, seq=%d\n", | ||
1202 | idx, SEQ_TO_SN(sc), | 1212 | idx, SEQ_TO_SN(sc), |
1203 | hdr->seq_ctrl); | 1213 | hdr->seq_ctrl); |
1204 | return -1; | 1214 | return -1; |
@@ -1254,7 +1264,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1254 | int freed; | 1264 | int freed; |
1255 | 1265 | ||
1256 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { | 1266 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
1257 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 1267 | IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " |
1258 | "is out of range [0-%d] %d %d\n", txq_id, | 1268 | "is out of range [0-%d] %d %d\n", txq_id, |
1259 | index, txq->q.n_bd, txq->q.write_ptr, | 1269 | index, txq->q.n_bd, txq->q.write_ptr, |
1260 | txq->q.read_ptr); | 1270 | txq->q.read_ptr); |
@@ -1328,7 +1338,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1328 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 1338 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
1329 | 1339 | ||
1330 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 1340 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
1331 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | 1341 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
1332 | } | 1342 | } |
1333 | 1343 | ||
1334 | /* Currently 5000 is the superset of everything */ | 1344 | /* Currently 5000 is the superset of everything */ |
@@ -1356,7 +1366,7 @@ static void iwl5000_rx_handler_setup(struct iwl_priv *priv) | |||
1356 | 1366 | ||
1357 | static int iwl5000_hw_valid_rtc_data_addr(u32 addr) | 1367 | static int iwl5000_hw_valid_rtc_data_addr(u32 addr) |
1358 | { | 1368 | { |
1359 | return (addr >= RTC_DATA_LOWER_BOUND) && | 1369 | return (addr >= IWL50_RTC_DATA_LOWER_BOUND) && |
1360 | (addr < IWL50_RTC_DATA_UPPER_BOUND); | 1370 | (addr < IWL50_RTC_DATA_UPPER_BOUND); |
1361 | } | 1371 | } |
1362 | 1372 | ||
@@ -1460,7 +1470,7 @@ static int iwl5000_calc_rssi(struct iwl_priv *priv, | |||
1460 | 1470 | ||
1461 | /* dBm = max_rssi dB - agc dB - constant. | 1471 | /* dBm = max_rssi dB - agc dB - constant. |
1462 | * Higher AGC (higher radio gain) means lower signal. */ | 1472 | * Higher AGC (higher radio gain) means lower signal. */ |
1463 | return max_rssi - agc - IWL_RSSI_OFFSET; | 1473 | return max_rssi - agc - IWL49_RSSI_OFFSET; |
1464 | } | 1474 | } |
1465 | 1475 | ||
1466 | static struct iwl_hcmd_ops iwl5000_hcmd = { | 1476 | static struct iwl_hcmd_ops iwl5000_hcmd = { |
@@ -1483,6 +1493,9 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
1483 | .txq_set_sched = iwl5000_txq_set_sched, | 1493 | .txq_set_sched = iwl5000_txq_set_sched, |
1484 | .txq_agg_enable = iwl5000_txq_agg_enable, | 1494 | .txq_agg_enable = iwl5000_txq_agg_enable, |
1485 | .txq_agg_disable = iwl5000_txq_agg_disable, | 1495 | .txq_agg_disable = iwl5000_txq_agg_disable, |
1496 | .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, | ||
1497 | .txq_free_tfd = iwl_hw_txq_free_tfd, | ||
1498 | .txq_init = iwl_hw_tx_queue_init, | ||
1486 | .rx_handler_setup = iwl5000_rx_handler_setup, | 1499 | .rx_handler_setup = iwl5000_rx_handler_setup, |
1487 | .setup_deferred_work = iwl5000_setup_deferred_work, | 1500 | .setup_deferred_work = iwl5000_setup_deferred_work, |
1488 | .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, | 1501 | .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, |
@@ -1517,13 +1530,13 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
1517 | }, | 1530 | }, |
1518 | }; | 1531 | }; |
1519 | 1532 | ||
1520 | static struct iwl_ops iwl5000_ops = { | 1533 | struct iwl_ops iwl5000_ops = { |
1521 | .lib = &iwl5000_lib, | 1534 | .lib = &iwl5000_lib, |
1522 | .hcmd = &iwl5000_hcmd, | 1535 | .hcmd = &iwl5000_hcmd, |
1523 | .utils = &iwl5000_hcmd_utils, | 1536 | .utils = &iwl5000_hcmd_utils, |
1524 | }; | 1537 | }; |
1525 | 1538 | ||
1526 | static struct iwl_mod_params iwl50_mod_params = { | 1539 | struct iwl_mod_params iwl50_mod_params = { |
1527 | .num_of_queues = IWL50_NUM_QUEUES, | 1540 | .num_of_queues = IWL50_NUM_QUEUES, |
1528 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, | 1541 | .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES, |
1529 | .amsdu_size_8K = 1, | 1542 | .amsdu_size_8K = 1, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-core.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h index 6f463555402c..90185777d98b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -58,47 +58,24 @@ | |||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | * | ||
61 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | /* | ||
64 | * Please use this file (iwl-6000-hw.h) only for hardware-related definitions. | ||
65 | * Use iwl-5000-commands.h for uCode API definitions. | ||
66 | */ | ||
62 | 67 | ||
63 | #ifndef __iwl_3945_dev_h__ | 68 | #ifndef __iwl_6000_hw_h__ |
64 | #define __iwl_3945_dev_h__ | 69 | #define __iwl_6000_hw_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 | 70 | ||
71 | #define IWL_SKU_G 0x1 | 71 | #define IWL60_RTC_INST_LOWER_BOUND (0x000000) |
72 | #define IWL_SKU_A 0x2 | 72 | #define IWL60_RTC_INST_UPPER_BOUND (0x040000) |
73 | #define IWL60_RTC_DATA_LOWER_BOUND (0x800000) | ||
74 | #define IWL60_RTC_DATA_UPPER_BOUND (0x814000) | ||
75 | #define IWL60_RTC_INST_SIZE \ | ||
76 | (IWL60_RTC_INST_UPPER_BOUND - IWL60_RTC_INST_LOWER_BOUND) | ||
77 | #define IWL60_RTC_DATA_SIZE \ | ||
78 | (IWL60_RTC_DATA_UPPER_BOUND - IWL60_RTC_DATA_LOWER_BOUND) | ||
73 | 79 | ||
74 | /** | 80 | #endif /* __iwl_6000_hw_h__ */ |
75 | * struct iwl_3945_cfg | ||
76 | * @fw_name_pre: Firmware filename prefix. The api version and extension | ||
77 | * (.ucode) will be added to filename before loading from disk. The | ||
78 | * filename is constructed as fw_name_pre<api>.ucode. | ||
79 | * @ucode_api_max: Highest version of uCode API supported by driver. | ||
80 | * @ucode_api_min: Lowest version of uCode API supported by driver. | ||
81 | * | ||
82 | * We enable the driver to be backward compatible wrt API version. The | ||
83 | * driver specifies which APIs it supports (with @ucode_api_max being the | ||
84 | * highest and @ucode_api_min the lowest). Firmware will only be loaded if | ||
85 | * it has a supported API version. The firmware's API version will be | ||
86 | * stored in @iwl_priv, enabling the driver to make runtime changes based | ||
87 | * on firmware version used. | ||
88 | * | ||
89 | * For example, | ||
90 | * if (IWL_UCODE_API(priv->ucode_ver) >= 2) { | ||
91 | * Driver interacts with Firmware API version >= 2. | ||
92 | * } else { | ||
93 | * Driver interacts with Firmware API version 1. | ||
94 | * } | ||
95 | */ | ||
96 | struct iwl_3945_cfg { | ||
97 | const char *name; | ||
98 | const char *fw_name_pre; | ||
99 | const unsigned int ucode_api_max; | ||
100 | const unsigned int ucode_api_min; | ||
101 | unsigned int sku; | ||
102 | }; | ||
103 | 81 | ||
104 | #endif /* __iwl_dev_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c new file mode 100644 index 000000000000..4515a6053dd0 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
23 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
24 | * | ||
25 | *****************************************************************************/ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/pci.h> | ||
31 | #include <linux/dma-mapping.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/skbuff.h> | ||
34 | #include <linux/netdevice.h> | ||
35 | #include <linux/wireless.h> | ||
36 | #include <net/mac80211.h> | ||
37 | #include <linux/etherdevice.h> | ||
38 | #include <asm/unaligned.h> | ||
39 | |||
40 | #include "iwl-eeprom.h" | ||
41 | #include "iwl-dev.h" | ||
42 | #include "iwl-core.h" | ||
43 | #include "iwl-io.h" | ||
44 | #include "iwl-sta.h" | ||
45 | #include "iwl-helpers.h" | ||
46 | #include "iwl-5000-hw.h" | ||
47 | |||
48 | /* Highest firmware API version supported */ | ||
49 | #define IWL6000_UCODE_API_MAX 1 | ||
50 | #define IWL6050_UCODE_API_MAX 1 | ||
51 | |||
52 | /* Lowest firmware API version supported */ | ||
53 | #define IWL6000_UCODE_API_MIN 1 | ||
54 | #define IWL6050_UCODE_API_MIN 1 | ||
55 | |||
56 | #define IWL6000_FW_PRE "iwlwifi-6000-" | ||
57 | #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" | ||
58 | #define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api) | ||
59 | |||
60 | #define IWL6050_FW_PRE "iwlwifi-6050-" | ||
61 | #define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" | ||
62 | #define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) | ||
63 | |||
64 | struct iwl_cfg iwl6000_2ag_cfg = { | ||
65 | .name = "6000 Series 2x2 AG", | ||
66 | .fw_name_pre = IWL6000_FW_PRE, | ||
67 | .ucode_api_max = IWL6000_UCODE_API_MAX, | ||
68 | .ucode_api_min = IWL6000_UCODE_API_MIN, | ||
69 | .sku = IWL_SKU_A|IWL_SKU_G, | ||
70 | .ops = &iwl5000_ops, | ||
71 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
72 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | ||
73 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
74 | .mod_params = &iwl50_mod_params, | ||
75 | }; | ||
76 | |||
77 | struct iwl_cfg iwl6000_2agn_cfg = { | ||
78 | .name = "6000 Series 2x2 AGN", | ||
79 | .fw_name_pre = IWL6000_FW_PRE, | ||
80 | .ucode_api_max = IWL6000_UCODE_API_MAX, | ||
81 | .ucode_api_min = IWL6000_UCODE_API_MIN, | ||
82 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
83 | .ops = &iwl5000_ops, | ||
84 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
85 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | ||
86 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
87 | .mod_params = &iwl50_mod_params, | ||
88 | }; | ||
89 | |||
90 | struct iwl_cfg iwl6050_2agn_cfg = { | ||
91 | .name = "6050 Series 2x2 AGN", | ||
92 | .fw_name_pre = IWL6050_FW_PRE, | ||
93 | .ucode_api_max = IWL6050_UCODE_API_MAX, | ||
94 | .ucode_api_min = IWL6050_UCODE_API_MIN, | ||
95 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
96 | .ops = &iwl5000_ops, | ||
97 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
98 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | ||
99 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
100 | .mod_params = &iwl50_mod_params, | ||
101 | }; | ||
102 | |||
103 | struct iwl_cfg iwl6000_3agn_cfg = { | ||
104 | .name = "6000 Series 3x3 AGN", | ||
105 | .fw_name_pre = IWL6000_FW_PRE, | ||
106 | .ucode_api_max = IWL6000_UCODE_API_MAX, | ||
107 | .ucode_api_min = IWL6000_UCODE_API_MIN, | ||
108 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
109 | .ops = &iwl5000_ops, | ||
110 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
111 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | ||
112 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
113 | .mod_params = &iwl50_mod_params, | ||
114 | }; | ||
115 | |||
116 | struct iwl_cfg iwl6050_3agn_cfg = { | ||
117 | .name = "6050 Series 3x3 AGN", | ||
118 | .fw_name_pre = IWL6050_FW_PRE, | ||
119 | .ucode_api_max = IWL6050_UCODE_API_MAX, | ||
120 | .ucode_api_min = IWL6050_UCODE_API_MIN, | ||
121 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
122 | .ops = &iwl5000_ops, | ||
123 | .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, | ||
124 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, | ||
125 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, | ||
126 | .mod_params = &iwl50_mod_params, | ||
127 | }; | ||
128 | |||
129 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | ||
130 | MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c index b8137eeae1db..1217a1da88f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -40,67 +40,68 @@ | |||
40 | * be #ifdef'd out once the driver is stable and folks aren't actively | 40 | * be #ifdef'd out once the driver is stable and folks aren't actively |
41 | * making changes | 41 | * making changes |
42 | */ | 42 | */ |
43 | int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon) | 43 | int iwl_agn_check_rxon_cmd(struct iwl_priv *priv) |
44 | { | 44 | { |
45 | int error = 0; | 45 | int error = 0; |
46 | int counter = 1; | 46 | int counter = 1; |
47 | struct iwl_rxon_cmd *rxon = &priv->staging_rxon; | ||
47 | 48 | ||
48 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { | 49 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { |
49 | error |= le32_to_cpu(rxon->flags & | 50 | error |= le32_to_cpu(rxon->flags & |
50 | (RXON_FLG_TGJ_NARROW_BAND_MSK | | 51 | (RXON_FLG_TGJ_NARROW_BAND_MSK | |
51 | RXON_FLG_RADAR_DETECT_MSK)); | 52 | RXON_FLG_RADAR_DETECT_MSK)); |
52 | if (error) | 53 | if (error) |
53 | IWL_WARNING("check 24G fields %d | %d\n", | 54 | IWL_WARN(priv, "check 24G fields %d | %d\n", |
54 | counter++, error); | 55 | counter++, error); |
55 | } else { | 56 | } else { |
56 | error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? | 57 | error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? |
57 | 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); | 58 | 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); |
58 | if (error) | 59 | if (error) |
59 | IWL_WARNING("check 52 fields %d | %d\n", | 60 | IWL_WARN(priv, "check 52 fields %d | %d\n", |
60 | counter++, error); | 61 | counter++, error); |
61 | error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); | 62 | error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); |
62 | if (error) | 63 | if (error) |
63 | IWL_WARNING("check 52 CCK %d | %d\n", | 64 | IWL_WARN(priv, "check 52 CCK %d | %d\n", |
64 | counter++, error); | 65 | counter++, error); |
65 | } | 66 | } |
66 | error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; | 67 | error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; |
67 | if (error) | 68 | if (error) |
68 | IWL_WARNING("check mac addr %d | %d\n", counter++, error); | 69 | IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error); |
69 | 70 | ||
70 | /* make sure basic rates 6Mbps and 1Mbps are supported */ | 71 | /* make sure basic rates 6Mbps and 1Mbps are supported */ |
71 | error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && | 72 | error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && |
72 | ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); | 73 | ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); |
73 | if (error) | 74 | if (error) |
74 | IWL_WARNING("check basic rate %d | %d\n", counter++, error); | 75 | IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error); |
75 | 76 | ||
76 | error |= (le16_to_cpu(rxon->assoc_id) > 2007); | 77 | error |= (le16_to_cpu(rxon->assoc_id) > 2007); |
77 | if (error) | 78 | if (error) |
78 | IWL_WARNING("check assoc id %d | %d\n", counter++, error); | 79 | IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error); |
79 | 80 | ||
80 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) | 81 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) |
81 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); | 82 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); |
82 | if (error) | 83 | if (error) |
83 | IWL_WARNING("check CCK and short slot %d | %d\n", | 84 | IWL_WARN(priv, "check CCK and short slot %d | %d\n", |
84 | counter++, error); | 85 | counter++, error); |
85 | 86 | ||
86 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) | 87 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) |
87 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); | 88 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); |
88 | if (error) | 89 | if (error) |
89 | IWL_WARNING("check CCK & auto detect %d | %d\n", | 90 | IWL_WARN(priv, "check CCK & auto detect %d | %d\n", |
90 | counter++, error); | 91 | counter++, error); |
91 | 92 | ||
92 | error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | | 93 | error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | |
93 | RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); | 94 | RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); |
94 | if (error) | 95 | if (error) |
95 | IWL_WARNING("check TGG and auto detect %d | %d\n", | 96 | IWL_WARN(priv, "check TGG and auto detect %d | %d\n", |
96 | counter++, error); | 97 | counter++, error); |
97 | 98 | ||
98 | if (error) | 99 | if (error) |
99 | IWL_WARNING("Tuning to channel %d\n", | 100 | IWL_WARN(priv, "Tuning to channel %d\n", |
100 | le16_to_cpu(rxon->channel)); | 101 | le16_to_cpu(rxon->channel)); |
101 | 102 | ||
102 | if (error) { | 103 | if (error) { |
103 | IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n"); | 104 | IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n"); |
104 | return -1; | 105 | return -1; |
105 | } | 106 | } |
106 | return 0; | 107 | return 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 27f50471aed8..13039a024473 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -49,6 +49,8 @@ | |||
49 | #define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ | 49 | #define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ |
50 | #define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ | 50 | #define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ |
51 | 51 | ||
52 | /* max allowed rate miss before sync LQ cmd */ | ||
53 | #define IWL_MISSED_RATE_MAX 15 | ||
52 | /* max time to accum history 2 seconds */ | 54 | /* max time to accum history 2 seconds */ |
53 | #define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) | 55 | #define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) |
54 | 56 | ||
@@ -148,6 +150,8 @@ struct iwl_lq_sta { | |||
148 | u16 active_mimo2_rate; | 150 | u16 active_mimo2_rate; |
149 | u16 active_mimo3_rate; | 151 | u16 active_mimo3_rate; |
150 | u16 active_rate_basic; | 152 | u16 active_rate_basic; |
153 | s8 max_rate_idx; /* Max rate set by user */ | ||
154 | u8 missed_rate_counter; | ||
151 | 155 | ||
152 | struct iwl_link_quality_cmd lq; | 156 | struct iwl_link_quality_cmd lq; |
153 | struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 157 | struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
@@ -463,8 +467,9 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | |||
463 | * Fill uCode API rate_n_flags field, based on "search" or "active" table. | 467 | * Fill uCode API rate_n_flags field, based on "search" or "active" table. |
464 | */ | 468 | */ |
465 | /* FIXME:RS:remove this function and put the flags statically in the table */ | 469 | /* FIXME:RS:remove this function and put the flags statically in the table */ |
466 | static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl, | 470 | static u32 rate_n_flags_from_tbl(struct iwl_priv *priv, |
467 | int index, u8 use_green) | 471 | struct iwl_scale_tbl_info *tbl, |
472 | int index, u8 use_green) | ||
468 | { | 473 | { |
469 | u32 rate_n_flags = 0; | 474 | u32 rate_n_flags = 0; |
470 | 475 | ||
@@ -475,7 +480,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl, | |||
475 | 480 | ||
476 | } else if (is_Ht(tbl->lq_type)) { | 481 | } else if (is_Ht(tbl->lq_type)) { |
477 | if (index > IWL_LAST_OFDM_RATE) { | 482 | if (index > IWL_LAST_OFDM_RATE) { |
478 | IWL_ERROR("invalid HT rate index %d\n", index); | 483 | IWL_ERR(priv, "Invalid HT rate index %d\n", index); |
479 | index = IWL_LAST_OFDM_RATE; | 484 | index = IWL_LAST_OFDM_RATE; |
480 | } | 485 | } |
481 | rate_n_flags = RATE_MCS_HT_MSK; | 486 | rate_n_flags = RATE_MCS_HT_MSK; |
@@ -487,7 +492,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl, | |||
487 | else | 492 | else |
488 | rate_n_flags |= iwl_rates[index].plcp_mimo3; | 493 | rate_n_flags |= iwl_rates[index].plcp_mimo3; |
489 | } else { | 494 | } else { |
490 | IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type); | 495 | IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type); |
491 | } | 496 | } |
492 | 497 | ||
493 | rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & | 498 | rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & |
@@ -507,7 +512,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl, | |||
507 | rate_n_flags |= RATE_MCS_GF_MSK; | 512 | rate_n_flags |= RATE_MCS_GF_MSK; |
508 | if (is_siso(tbl->lq_type) && tbl->is_SGI) { | 513 | if (is_siso(tbl->lq_type) && tbl->is_SGI) { |
509 | rate_n_flags &= ~RATE_MCS_SGI_MSK; | 514 | rate_n_flags &= ~RATE_MCS_SGI_MSK; |
510 | IWL_ERROR("GF was set with SGI:SISO\n"); | 515 | IWL_ERR(priv, "GF was set with SGI:SISO\n"); |
511 | } | 516 | } |
512 | } | 517 | } |
513 | } | 518 | } |
@@ -758,7 +763,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | |||
758 | low = scale_index; | 763 | low = scale_index; |
759 | 764 | ||
760 | out: | 765 | out: |
761 | return rate_n_flags_from_tbl(tbl, low, is_green); | 766 | return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green); |
762 | } | 767 | } |
763 | 768 | ||
764 | /* | 769 | /* |
@@ -839,10 +844,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
839 | /* the last LQ command could failed so the LQ in ucode not | 844 | /* the last LQ command could failed so the LQ in ucode not |
840 | * the same in driver sync up | 845 | * the same in driver sync up |
841 | */ | 846 | */ |
842 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 847 | lq_sta->missed_rate_counter++; |
848 | if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { | ||
849 | lq_sta->missed_rate_counter = 0; | ||
850 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | ||
851 | } | ||
843 | goto out; | 852 | goto out; |
844 | } | 853 | } |
845 | 854 | ||
855 | lq_sta->missed_rate_counter = 0; | ||
846 | /* Update frame history window with "failure" for each Tx retry. */ | 856 | /* Update frame history window with "failure" for each Tx retry. */ |
847 | while (retries) { | 857 | while (retries) { |
848 | /* Look up the rate and other info used for each tx attempt. | 858 | /* Look up the rate and other info used for each tx attempt. |
@@ -1129,7 +1139,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, | |||
1129 | s32 rate; | 1139 | s32 rate; |
1130 | s8 is_green = lq_sta->is_green; | 1140 | s8 is_green = lq_sta->is_green; |
1131 | 1141 | ||
1132 | if (!conf->ht.enabled || !sta->ht_cap.ht_supported) | 1142 | if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) |
1133 | return -1; | 1143 | return -1; |
1134 | 1144 | ||
1135 | if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) | 1145 | if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) |
@@ -1176,7 +1186,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, | |||
1176 | rate, rate_mask); | 1186 | rate, rate_mask); |
1177 | return -1; | 1187 | return -1; |
1178 | } | 1188 | } |
1179 | tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green); | 1189 | tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green); |
1180 | 1190 | ||
1181 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", | 1191 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", |
1182 | tbl->current_rate, is_green); | 1192 | tbl->current_rate, is_green); |
@@ -1196,7 +1206,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1196 | u8 is_green = lq_sta->is_green; | 1206 | u8 is_green = lq_sta->is_green; |
1197 | s32 rate; | 1207 | s32 rate; |
1198 | 1208 | ||
1199 | if (!conf->ht.enabled || !sta->ht_cap.ht_supported) | 1209 | if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) |
1200 | return -1; | 1210 | return -1; |
1201 | 1211 | ||
1202 | IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); | 1212 | IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); |
@@ -1236,7 +1246,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1236 | rate, rate_mask); | 1246 | rate, rate_mask); |
1237 | return -1; | 1247 | return -1; |
1238 | } | 1248 | } |
1239 | tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green); | 1249 | tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green); |
1240 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", | 1250 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", |
1241 | tbl->current_rate, is_green); | 1251 | tbl->current_rate, is_green); |
1242 | return 0; | 1252 | return 0; |
@@ -1430,7 +1440,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1430 | if (!tbl->is_SGI) | 1440 | if (!tbl->is_SGI) |
1431 | break; | 1441 | break; |
1432 | else | 1442 | else |
1433 | IWL_ERROR("SGI was set in GF+SISO\n"); | 1443 | IWL_ERR(priv, |
1444 | "SGI was set in GF+SISO\n"); | ||
1434 | } | 1445 | } |
1435 | search_tbl->is_SGI = !tbl->is_SGI; | 1446 | search_tbl->is_SGI = !tbl->is_SGI; |
1436 | rs_set_expected_tpt_table(lq_sta, search_tbl); | 1447 | rs_set_expected_tpt_table(lq_sta, search_tbl); |
@@ -1439,8 +1450,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1439 | if (tpt >= search_tbl->expected_tpt[index]) | 1450 | if (tpt >= search_tbl->expected_tpt[index]) |
1440 | break; | 1451 | break; |
1441 | } | 1452 | } |
1442 | search_tbl->current_rate = rate_n_flags_from_tbl( | 1453 | search_tbl->current_rate = |
1443 | search_tbl, index, is_green); | 1454 | rate_n_flags_from_tbl(priv, search_tbl, |
1455 | index, is_green); | ||
1444 | goto out; | 1456 | goto out; |
1445 | } | 1457 | } |
1446 | tbl->action++; | 1458 | tbl->action++; |
@@ -1551,8 +1563,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, | |||
1551 | if (tpt >= search_tbl->expected_tpt[index]) | 1563 | if (tpt >= search_tbl->expected_tpt[index]) |
1552 | break; | 1564 | break; |
1553 | } | 1565 | } |
1554 | search_tbl->current_rate = rate_n_flags_from_tbl( | 1566 | search_tbl->current_rate = |
1555 | search_tbl, index, is_green); | 1567 | rate_n_flags_from_tbl(priv, search_tbl, |
1568 | index, is_green); | ||
1556 | goto out; | 1569 | goto out; |
1557 | 1570 | ||
1558 | } | 1571 | } |
@@ -1745,16 +1758,25 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1745 | rate_scale_index_msk = rate_mask; | 1758 | rate_scale_index_msk = rate_mask; |
1746 | 1759 | ||
1747 | if (!((1 << index) & rate_scale_index_msk)) { | 1760 | if (!((1 << index) & rate_scale_index_msk)) { |
1748 | IWL_ERROR("Current Rate is not valid\n"); | 1761 | IWL_ERR(priv, "Current Rate is not valid\n"); |
1749 | return; | 1762 | return; |
1750 | } | 1763 | } |
1751 | 1764 | ||
1752 | /* Get expected throughput table and history window for current rate */ | 1765 | /* Get expected throughput table and history window for current rate */ |
1753 | if (!tbl->expected_tpt) { | 1766 | if (!tbl->expected_tpt) { |
1754 | IWL_ERROR("tbl->expected_tpt is NULL\n"); | 1767 | IWL_ERR(priv, "tbl->expected_tpt is NULL\n"); |
1755 | return; | 1768 | return; |
1756 | } | 1769 | } |
1757 | 1770 | ||
1771 | /* force user max rate if set by user */ | ||
1772 | if ((lq_sta->max_rate_idx != -1) && | ||
1773 | (lq_sta->max_rate_idx < index)) { | ||
1774 | index = lq_sta->max_rate_idx; | ||
1775 | update_lq = 1; | ||
1776 | window = &(tbl->win[index]); | ||
1777 | goto lq_update; | ||
1778 | } | ||
1779 | |||
1758 | window = &(tbl->win[index]); | 1780 | window = &(tbl->win[index]); |
1759 | 1781 | ||
1760 | /* | 1782 | /* |
@@ -1846,6 +1868,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1846 | low = high_low & 0xff; | 1868 | low = high_low & 0xff; |
1847 | high = (high_low >> 8) & 0xff; | 1869 | high = (high_low >> 8) & 0xff; |
1848 | 1870 | ||
1871 | /* If user set max rate, dont allow higher than user constrain */ | ||
1872 | if ((lq_sta->max_rate_idx != -1) && | ||
1873 | (lq_sta->max_rate_idx < high)) | ||
1874 | high = IWL_RATE_INVALID; | ||
1875 | |||
1849 | sr = window->success_ratio; | 1876 | sr = window->success_ratio; |
1850 | 1877 | ||
1851 | /* Collect measured throughputs for current and adjacent rates */ | 1878 | /* Collect measured throughputs for current and adjacent rates */ |
@@ -1944,7 +1971,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1944 | lq_update: | 1971 | lq_update: |
1945 | /* Replace uCode's rate table for the destination station. */ | 1972 | /* Replace uCode's rate table for the destination station. */ |
1946 | if (update_lq) { | 1973 | if (update_lq) { |
1947 | rate = rate_n_flags_from_tbl(tbl, index, is_green); | 1974 | rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); |
1948 | rs_fill_link_cmd(priv, lq_sta, rate); | 1975 | rs_fill_link_cmd(priv, lq_sta, rate); |
1949 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 1976 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
1950 | } | 1977 | } |
@@ -1993,7 +2020,7 @@ lq_update: | |||
1993 | * stay with best antenna legacy modulation for a while | 2020 | * stay with best antenna legacy modulation for a while |
1994 | * before next round of mode comparisons. */ | 2021 | * before next round of mode comparisons. */ |
1995 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); | 2022 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); |
1996 | if (is_legacy(tbl1->lq_type) && !conf->ht.enabled && | 2023 | if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && |
1997 | lq_sta->action_counter >= 1) { | 2024 | lq_sta->action_counter >= 1) { |
1998 | lq_sta->action_counter = 0; | 2025 | lq_sta->action_counter = 0; |
1999 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); | 2026 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); |
@@ -2028,7 +2055,7 @@ lq_update: | |||
2028 | } | 2055 | } |
2029 | 2056 | ||
2030 | out: | 2057 | out: |
2031 | tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green); | 2058 | tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); |
2032 | i = index; | 2059 | i = index; |
2033 | lq_sta->last_txrate_idx = i; | 2060 | lq_sta->last_txrate_idx = i; |
2034 | 2061 | ||
@@ -2081,7 +2108,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2081 | if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) | 2108 | if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) |
2082 | rs_toggle_antenna(valid_tx_ant, &rate, tbl); | 2109 | rs_toggle_antenna(valid_tx_ant, &rate, tbl); |
2083 | 2110 | ||
2084 | rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green); | 2111 | rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green); |
2085 | tbl->current_rate = rate; | 2112 | tbl->current_rate = rate; |
2086 | rs_set_expected_tpt_table(lq_sta, tbl); | 2113 | rs_set_expected_tpt_table(lq_sta, tbl); |
2087 | rs_fill_link_cmd(NULL, lq_sta, rate); | 2114 | rs_fill_link_cmd(NULL, lq_sta, rate); |
@@ -2106,6 +2133,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, | |||
2106 | 2133 | ||
2107 | IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); | 2134 | IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); |
2108 | 2135 | ||
2136 | /* Get max rate if user set max rate */ | ||
2137 | if (lq_sta) { | ||
2138 | lq_sta->max_rate_idx = txrc->max_rate_idx; | ||
2139 | if ((sband->band == IEEE80211_BAND_5GHZ) && | ||
2140 | (lq_sta->max_rate_idx != -1)) | ||
2141 | lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE; | ||
2142 | if ((lq_sta->max_rate_idx < 0) || | ||
2143 | (lq_sta->max_rate_idx >= IWL_RATE_COUNT)) | ||
2144 | lq_sta->max_rate_idx = -1; | ||
2145 | } | ||
2146 | |||
2109 | if (sta) | 2147 | if (sta) |
2110 | mask_bit = sta->supp_rates[sband->band]; | 2148 | mask_bit = sta->supp_rates[sband->band]; |
2111 | 2149 | ||
@@ -2182,6 +2220,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
2182 | struct ieee80211_conf *conf = &priv->hw->conf; | 2220 | struct ieee80211_conf *conf = &priv->hw->conf; |
2183 | struct iwl_lq_sta *lq_sta = priv_sta; | 2221 | struct iwl_lq_sta *lq_sta = priv_sta; |
2184 | u16 mask_bit = 0; | 2222 | u16 mask_bit = 0; |
2223 | int count; | ||
2224 | int start_rate = 0; | ||
2185 | 2225 | ||
2186 | lq_sta->flush_timer = 0; | 2226 | lq_sta->flush_timer = 0; |
2187 | lq_sta->supp_rates = sta->supp_rates[sband->band]; | 2227 | lq_sta->supp_rates = sta->supp_rates[sband->band]; |
@@ -2216,6 +2256,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
2216 | } | 2256 | } |
2217 | 2257 | ||
2218 | lq_sta->is_dup = 0; | 2258 | lq_sta->is_dup = 0; |
2259 | lq_sta->max_rate_idx = -1; | ||
2260 | lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; | ||
2219 | lq_sta->is_green = rs_use_green(priv, conf); | 2261 | lq_sta->is_green = rs_use_green(priv, conf); |
2220 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); | 2262 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); |
2221 | lq_sta->active_rate_basic = priv->active_rate_basic; | 2263 | lq_sta->active_rate_basic = priv->active_rate_basic; |
@@ -2254,16 +2296,20 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
2254 | lq_sta->drv = priv; | 2296 | lq_sta->drv = priv; |
2255 | 2297 | ||
2256 | /* Find highest tx rate supported by hardware and destination station */ | 2298 | /* Find highest tx rate supported by hardware and destination station */ |
2257 | mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate; | 2299 | mask_bit = sta->supp_rates[sband->band]; |
2258 | lq_sta->last_txrate_idx = 3; | 2300 | count = sband->n_bitrates; |
2259 | for (i = 0; i < sband->n_bitrates; i++) | 2301 | if (sband->band == IEEE80211_BAND_5GHZ) { |
2302 | count += IWL_FIRST_OFDM_RATE; | ||
2303 | start_rate = IWL_FIRST_OFDM_RATE; | ||
2304 | mask_bit <<= IWL_FIRST_OFDM_RATE; | ||
2305 | } | ||
2306 | |||
2307 | mask_bit = mask_bit & lq_sta->active_legacy_rate; | ||
2308 | lq_sta->last_txrate_idx = 4; | ||
2309 | for (i = start_rate; i < count; i++) | ||
2260 | if (mask_bit & BIT(i)) | 2310 | if (mask_bit & BIT(i)) |
2261 | lq_sta->last_txrate_idx = i; | 2311 | lq_sta->last_txrate_idx = i; |
2262 | 2312 | ||
2263 | /* For MODE_IEEE80211A, skip over cck rates in global rate table */ | ||
2264 | if (sband->band == IEEE80211_BAND_5GHZ) | ||
2265 | lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | ||
2266 | |||
2267 | rs_initialize_lq(priv, conf, sta, lq_sta); | 2313 | rs_initialize_lq(priv, conf, sta, lq_sta); |
2268 | } | 2314 | } |
2269 | 2315 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 78ee83adf742..345806dd8870 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -27,8 +27,6 @@ | |||
27 | #ifndef __iwl_agn_rs_h__ | 27 | #ifndef __iwl_agn_rs_h__ |
28 | #define __iwl_agn_rs_h__ | 28 | #define __iwl_agn_rs_h__ |
29 | 29 | ||
30 | #include "iwl-dev.h" | ||
31 | |||
32 | struct iwl_rate_info { | 30 | struct iwl_rate_info { |
33 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ | 31 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ |
34 | u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ | 32 | u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ |
@@ -43,6 +41,19 @@ struct iwl_rate_info { | |||
43 | u8 next_rs_tgg; /* next rate used in TGG rs algo */ | 41 | u8 next_rs_tgg; /* next rate used in TGG rs algo */ |
44 | }; | 42 | }; |
45 | 43 | ||
44 | struct iwl3945_rate_info { | ||
45 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ | ||
46 | u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ | ||
47 | u8 prev_ieee; /* previous rate in IEEE speeds */ | ||
48 | u8 next_ieee; /* next rate in IEEE speeds */ | ||
49 | u8 prev_rs; /* previous rate used in rs algo */ | ||
50 | u8 next_rs; /* next rate used in rs algo */ | ||
51 | u8 prev_rs_tgg; /* previous rate used in TGG rs algo */ | ||
52 | u8 next_rs_tgg; /* next rate used in TGG rs algo */ | ||
53 | u8 table_rs_index; /* index in rate scale table cmd */ | ||
54 | u8 prev_table_rs; /* prev in rate table cmd */ | ||
55 | }; | ||
56 | |||
46 | /* | 57 | /* |
47 | * These serve as indexes into | 58 | * These serve as indexes into |
48 | * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; | 59 | * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; |
@@ -62,12 +73,30 @@ enum { | |||
62 | IWL_RATE_54M_INDEX, | 73 | IWL_RATE_54M_INDEX, |
63 | IWL_RATE_60M_INDEX, | 74 | IWL_RATE_60M_INDEX, |
64 | IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/ | 75 | IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/ |
76 | IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1, | ||
65 | IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, | 77 | IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, |
66 | IWL_RATE_INVALID = IWL_RATE_COUNT, | 78 | IWL_RATE_INVALID = IWL_RATE_COUNT, |
67 | }; | 79 | }; |
68 | 80 | ||
69 | enum { | 81 | enum { |
82 | IWL_RATE_6M_INDEX_TABLE = 0, | ||
83 | IWL_RATE_9M_INDEX_TABLE, | ||
84 | IWL_RATE_12M_INDEX_TABLE, | ||
85 | IWL_RATE_18M_INDEX_TABLE, | ||
86 | IWL_RATE_24M_INDEX_TABLE, | ||
87 | IWL_RATE_36M_INDEX_TABLE, | ||
88 | IWL_RATE_48M_INDEX_TABLE, | ||
89 | IWL_RATE_54M_INDEX_TABLE, | ||
90 | IWL_RATE_1M_INDEX_TABLE, | ||
91 | IWL_RATE_2M_INDEX_TABLE, | ||
92 | IWL_RATE_5M_INDEX_TABLE, | ||
93 | IWL_RATE_11M_INDEX_TABLE, | ||
94 | IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1, | ||
95 | }; | ||
96 | |||
97 | enum { | ||
70 | IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, | 98 | IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, |
99 | IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX, | ||
71 | IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, | 100 | IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, |
72 | IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, | 101 | IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX, |
73 | IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, | 102 | IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, |
@@ -248,6 +277,7 @@ enum { | |||
248 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) | 277 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) |
249 | 278 | ||
250 | extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; | 279 | extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; |
280 | extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; | ||
251 | 281 | ||
252 | enum iwl_table_type { | 282 | enum iwl_table_type { |
253 | LQ_NONE, | 283 | LQ_NONE, |
@@ -303,6 +333,23 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index) | |||
303 | return rate; | 333 | return rate; |
304 | } | 334 | } |
305 | 335 | ||
336 | static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) | ||
337 | { | ||
338 | u8 rate = iwl3945_rates[rate_index].prev_ieee; | ||
339 | |||
340 | if (rate == IWL_RATE_INVALID) | ||
341 | rate = rate_index; | ||
342 | return rate; | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info | ||
347 | * | ||
348 | * The specific throughput table used is based on the type of network | ||
349 | * the associated with, including A, B, G, and G w/ TGG protection | ||
350 | */ | ||
351 | extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); | ||
352 | |||
306 | /** | 353 | /** |
307 | * iwl_rate_control_register - Register the rate control algorithm callbacks | 354 | * iwl_rate_control_register - Register the rate control algorithm callbacks |
308 | * | 355 | * |
@@ -314,6 +361,7 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index) | |||
314 | * | 361 | * |
315 | */ | 362 | */ |
316 | extern int iwlagn_rate_control_register(void); | 363 | extern int iwlagn_rate_control_register(void); |
364 | extern int iwl3945_rate_control_register(void); | ||
317 | 365 | ||
318 | /** | 366 | /** |
319 | * iwl_rate_control_unregister - Unregister the rate control callbacks | 367 | * iwl_rate_control_unregister - Unregister the rate control callbacks |
@@ -322,5 +370,6 @@ extern int iwlagn_rate_control_register(void); | |||
322 | * the driver is unloaded. | 370 | * the driver is unloaded. |
323 | */ | 371 | */ |
324 | extern void iwlagn_rate_control_unregister(void); | 372 | extern void iwlagn_rate_control_unregister(void); |
373 | extern void iwl3945_rate_control_unregister(void); | ||
325 | 374 | ||
326 | #endif /* __iwl_agn__rs__ */ | 375 | #endif /* __iwl_agn__rs__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b35c8813bef4..6b7120a41ab2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -44,6 +44,8 @@ | |||
44 | 44 | ||
45 | #include <asm/div64.h> | 45 | #include <asm/div64.h> |
46 | 46 | ||
47 | #define DRV_NAME "iwlagn" | ||
48 | |||
47 | #include "iwl-eeprom.h" | 49 | #include "iwl-eeprom.h" |
48 | #include "iwl-dev.h" | 50 | #include "iwl-dev.h" |
49 | #include "iwl-core.h" | 51 | #include "iwl-core.h" |
@@ -61,9 +63,7 @@ | |||
61 | 63 | ||
62 | /* | 64 | /* |
63 | * module name, copyright, version, etc. | 65 | * module name, copyright, version, etc. |
64 | * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk | ||
65 | */ | 66 | */ |
66 | |||
67 | #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux" | 67 | #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux" |
68 | 68 | ||
69 | #ifdef CONFIG_IWLWIFI_DEBUG | 69 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -179,9 +179,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
179 | * 5000, but will not damage 4965 */ | 179 | * 5000, but will not damage 4965 */ |
180 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; | 180 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; |
181 | 181 | ||
182 | ret = iwl_agn_check_rxon_cmd(&priv->staging_rxon); | 182 | ret = iwl_agn_check_rxon_cmd(priv); |
183 | if (ret) { | 183 | if (ret) { |
184 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); | 184 | IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); |
185 | return -EINVAL; | 185 | return -EINVAL; |
186 | } | 186 | } |
187 | 187 | ||
@@ -191,7 +191,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
191 | if (!iwl_full_rxon_required(priv)) { | 191 | if (!iwl_full_rxon_required(priv)) { |
192 | ret = iwl_send_rxon_assoc(priv); | 192 | ret = iwl_send_rxon_assoc(priv); |
193 | if (ret) { | 193 | if (ret) { |
194 | IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); | 194 | IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); |
195 | return ret; | 195 | return ret; |
196 | } | 196 | } |
197 | 197 | ||
@@ -218,7 +218,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
218 | * active_rxon back to what it was previously */ | 218 | * active_rxon back to what it was previously */ |
219 | if (ret) { | 219 | if (ret) { |
220 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; | 220 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; |
221 | IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret); | 221 | IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); |
222 | return ret; | 222 | return ret; |
223 | } | 223 | } |
224 | } | 224 | } |
@@ -242,7 +242,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
242 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, | 242 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, |
243 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); | 243 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); |
244 | if (ret) { | 244 | if (ret) { |
245 | IWL_ERROR("Error setting new RXON (%d)\n", ret); | 245 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); |
246 | return ret; | 246 | return ret; |
247 | } | 247 | } |
248 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 248 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
@@ -256,7 +256,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
256 | /* Add the broadcast address so we can send broadcast frames */ | 256 | /* Add the broadcast address so we can send broadcast frames */ |
257 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == | 257 | if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == |
258 | IWL_INVALID_STATION) { | 258 | IWL_INVALID_STATION) { |
259 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); | 259 | IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); |
260 | return -EIO; | 260 | return -EIO; |
261 | } | 261 | } |
262 | 262 | ||
@@ -267,13 +267,15 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
267 | ret = iwl_rxon_add_station(priv, | 267 | ret = iwl_rxon_add_station(priv, |
268 | priv->active_rxon.bssid_addr, 1); | 268 | priv->active_rxon.bssid_addr, 1); |
269 | if (ret == IWL_INVALID_STATION) { | 269 | if (ret == IWL_INVALID_STATION) { |
270 | IWL_ERROR("Error adding AP address for TX.\n"); | 270 | IWL_ERR(priv, |
271 | "Error adding AP address for TX.\n"); | ||
271 | return -EIO; | 272 | return -EIO; |
272 | } | 273 | } |
273 | priv->assoc_station_added = 1; | 274 | priv->assoc_station_added = 1; |
274 | if (priv->default_wep_key && | 275 | if (priv->default_wep_key && |
275 | iwl_send_static_wepkey_cmd(priv, 0)) | 276 | iwl_send_static_wepkey_cmd(priv, 0)) |
276 | IWL_ERROR("Could not send WEP static key.\n"); | 277 | IWL_ERR(priv, |
278 | "Could not send WEP static key.\n"); | ||
277 | } | 279 | } |
278 | 280 | ||
279 | /* Apply the new configuration | 281 | /* Apply the new configuration |
@@ -282,7 +284,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
282 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, | 284 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, |
283 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); | 285 | sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); |
284 | if (ret) { | 286 | if (ret) { |
285 | IWL_ERROR("Error setting new RXON (%d)\n", ret); | 287 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); |
286 | return ret; | 288 | return ret; |
287 | } | 289 | } |
288 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 290 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
@@ -294,7 +296,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv) | |||
294 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 296 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
295 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | 297 | ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); |
296 | if (ret) { | 298 | if (ret) { |
297 | IWL_ERROR("Error sending TX power (%d)\n", ret); | 299 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); |
298 | return ret; | 300 | return ret; |
299 | } | 301 | } |
300 | 302 | ||
@@ -308,20 +310,6 @@ void iwl_update_chain_flags(struct iwl_priv *priv) | |||
308 | iwl_commit_rxon(priv); | 310 | iwl_commit_rxon(priv); |
309 | } | 311 | } |
310 | 312 | ||
311 | static int iwl_send_bt_config(struct iwl_priv *priv) | ||
312 | { | ||
313 | struct iwl_bt_cmd bt_cmd = { | ||
314 | .flags = 3, | ||
315 | .lead_time = 0xAA, | ||
316 | .max_kill = 1, | ||
317 | .kill_ack_mask = 0, | ||
318 | .kill_cts_mask = 0, | ||
319 | }; | ||
320 | |||
321 | return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, | ||
322 | sizeof(struct iwl_bt_cmd), &bt_cmd); | ||
323 | } | ||
324 | |||
325 | static void iwl_clear_free_frames(struct iwl_priv *priv) | 313 | static void iwl_clear_free_frames(struct iwl_priv *priv) |
326 | { | 314 | { |
327 | struct list_head *element; | 315 | struct list_head *element; |
@@ -337,7 +325,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv) | |||
337 | } | 325 | } |
338 | 326 | ||
339 | if (priv->frames_count) { | 327 | if (priv->frames_count) { |
340 | IWL_WARNING("%d frames still in use. Did we lose one?\n", | 328 | IWL_WARN(priv, "%d frames still in use. Did we lose one?\n", |
341 | priv->frames_count); | 329 | priv->frames_count); |
342 | priv->frames_count = 0; | 330 | priv->frames_count = 0; |
343 | } | 331 | } |
@@ -350,7 +338,7 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv) | |||
350 | if (list_empty(&priv->free_frames)) { | 338 | if (list_empty(&priv->free_frames)) { |
351 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); | 339 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); |
352 | if (!frame) { | 340 | if (!frame) { |
353 | IWL_ERROR("Could not allocate frame!\n"); | 341 | IWL_ERR(priv, "Could not allocate frame!\n"); |
354 | return NULL; | 342 | return NULL; |
355 | } | 343 | } |
356 | 344 | ||
@@ -452,7 +440,7 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) | |||
452 | frame = iwl_get_free_frame(priv); | 440 | frame = iwl_get_free_frame(priv); |
453 | 441 | ||
454 | if (!frame) { | 442 | if (!frame) { |
455 | IWL_ERROR("Could not obtain free frame buffer for beacon " | 443 | IWL_ERR(priv, "Could not obtain free frame buffer for beacon " |
456 | "command.\n"); | 444 | "command.\n"); |
457 | return -ENOMEM; | 445 | return -ENOMEM; |
458 | } | 446 | } |
@@ -469,6 +457,159 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) | |||
469 | return rc; | 457 | return rc; |
470 | } | 458 | } |
471 | 459 | ||
460 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | ||
461 | { | ||
462 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
463 | |||
464 | dma_addr_t addr = get_unaligned_le32(&tb->lo); | ||
465 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
466 | addr |= | ||
467 | ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; | ||
468 | |||
469 | return addr; | ||
470 | } | ||
471 | |||
472 | static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) | ||
473 | { | ||
474 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
475 | |||
476 | return le16_to_cpu(tb->hi_n_len) >> 4; | ||
477 | } | ||
478 | |||
479 | static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, | ||
480 | dma_addr_t addr, u16 len) | ||
481 | { | ||
482 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
483 | u16 hi_n_len = len << 4; | ||
484 | |||
485 | put_unaligned_le32(addr, &tb->lo); | ||
486 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
487 | hi_n_len |= ((addr >> 16) >> 16) & 0xF; | ||
488 | |||
489 | tb->hi_n_len = cpu_to_le16(hi_n_len); | ||
490 | |||
491 | tfd->num_tbs = idx + 1; | ||
492 | } | ||
493 | |||
494 | static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | ||
495 | { | ||
496 | return tfd->num_tbs & 0x1f; | ||
497 | } | ||
498 | |||
499 | /** | ||
500 | * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
501 | * @priv - driver private data | ||
502 | * @txq - tx queue | ||
503 | * | ||
504 | * Does NOT advance any TFD circular buffer read/write indexes | ||
505 | * Does NOT free the TFD itself (which is within circular buffer) | ||
506 | */ | ||
507 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | ||
508 | { | ||
509 | struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds; | ||
510 | struct iwl_tfd *tfd; | ||
511 | struct pci_dev *dev = priv->pci_dev; | ||
512 | int index = txq->q.read_ptr; | ||
513 | int i; | ||
514 | int num_tbs; | ||
515 | |||
516 | tfd = &tfd_tmp[index]; | ||
517 | |||
518 | /* Sanity check on number of chunks */ | ||
519 | num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
520 | |||
521 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
522 | IWL_ERR(priv, "Too many chunks: %i\n", num_tbs); | ||
523 | /* @todo issue fatal error, it is quite serious situation */ | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | /* Unmap tx_cmd */ | ||
528 | if (num_tbs) | ||
529 | pci_unmap_single(dev, | ||
530 | pci_unmap_addr(&txq->cmd[index]->meta, mapping), | ||
531 | pci_unmap_len(&txq->cmd[index]->meta, len), | ||
532 | PCI_DMA_TODEVICE); | ||
533 | |||
534 | /* Unmap chunks, if any. */ | ||
535 | for (i = 1; i < num_tbs; i++) { | ||
536 | pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), | ||
537 | iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); | ||
538 | |||
539 | if (txq->txb) { | ||
540 | dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]); | ||
541 | txq->txb[txq->q.read_ptr].skb[i - 1] = NULL; | ||
542 | } | ||
543 | } | ||
544 | } | ||
545 | |||
546 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | ||
547 | struct iwl_tx_queue *txq, | ||
548 | dma_addr_t addr, u16 len, | ||
549 | u8 reset, u8 pad) | ||
550 | { | ||
551 | struct iwl_queue *q; | ||
552 | struct iwl_tfd *tfd, *tfd_tmp; | ||
553 | u32 num_tbs; | ||
554 | |||
555 | q = &txq->q; | ||
556 | tfd_tmp = (struct iwl_tfd *)txq->tfds; | ||
557 | tfd = &tfd_tmp[q->write_ptr]; | ||
558 | |||
559 | if (reset) | ||
560 | memset(tfd, 0, sizeof(*tfd)); | ||
561 | |||
562 | num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
563 | |||
564 | /* Each TFD can point to a maximum 20 Tx buffers */ | ||
565 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
566 | IWL_ERR(priv, "Error can not send more than %d chunks\n", | ||
567 | IWL_NUM_OF_TBS); | ||
568 | return -EINVAL; | ||
569 | } | ||
570 | |||
571 | BUG_ON(addr & ~DMA_BIT_MASK(36)); | ||
572 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) | ||
573 | IWL_ERR(priv, "Unaligned address = %llx\n", | ||
574 | (unsigned long long)addr); | ||
575 | |||
576 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
583 | * given Tx queue, and enable the DMA channel used for that queue. | ||
584 | * | ||
585 | * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
586 | * channels supported in hardware. | ||
587 | */ | ||
588 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | ||
589 | struct iwl_tx_queue *txq) | ||
590 | { | ||
591 | int ret; | ||
592 | unsigned long flags; | ||
593 | int txq_id = txq->q.id; | ||
594 | |||
595 | spin_lock_irqsave(&priv->lock, flags); | ||
596 | ret = iwl_grab_nic_access(priv); | ||
597 | if (ret) { | ||
598 | spin_unlock_irqrestore(&priv->lock, flags); | ||
599 | return ret; | ||
600 | } | ||
601 | |||
602 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
603 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
604 | txq->q.dma_addr >> 8); | ||
605 | |||
606 | iwl_release_nic_access(priv); | ||
607 | spin_unlock_irqrestore(&priv->lock, flags); | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | |||
472 | /****************************************************************************** | 613 | /****************************************************************************** |
473 | * | 614 | * |
474 | * Misc. internal state and helper functions | 615 | * Misc. internal state and helper functions |
@@ -520,9 +661,9 @@ static void iwl_ht_conf(struct iwl_priv *priv, | |||
520 | */ | 661 | */ |
521 | 662 | ||
522 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | 663 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; |
523 | if (priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40MINUS) | 664 | if (conf_is_ht40_minus(&priv->hw->conf)) |
524 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | 665 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; |
525 | else if(priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40PLUS) | 666 | else if (conf_is_ht40_plus(&priv->hw->conf)) |
526 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | 667 | iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; |
527 | 668 | ||
528 | /* If no above or below channel supplied disable FAT channel */ | 669 | /* If no above or below channel supplied disable FAT channel */ |
@@ -686,7 +827,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) | |||
686 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; | 827 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; |
687 | break; | 828 | break; |
688 | default: | 829 | default: |
689 | IWL_ERROR("Unsupported interface type %d\n", mode); | 830 | IWL_ERR(priv, "Unsupported interface type %d\n", mode); |
690 | break; | 831 | break; |
691 | } | 832 | } |
692 | 833 | ||
@@ -745,7 +886,7 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode) | |||
745 | 886 | ||
746 | cancel_delayed_work(&priv->scan_check); | 887 | cancel_delayed_work(&priv->scan_check); |
747 | if (iwl_scan_cancel_timeout(priv, 100)) { | 888 | if (iwl_scan_cancel_timeout(priv, 100)) { |
748 | IWL_WARNING("Aborted scan still in progress after 100ms\n"); | 889 | IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); |
749 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 890 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
750 | return -EAGAIN; | 891 | return -EAGAIN; |
751 | } | 892 | } |
@@ -763,7 +904,7 @@ static void iwl_set_rate(struct iwl_priv *priv) | |||
763 | 904 | ||
764 | hw = iwl_get_hw_mode(priv, priv->band); | 905 | hw = iwl_get_hw_mode(priv, priv->band); |
765 | if (!hw) { | 906 | if (!hw) { |
766 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 907 | IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n"); |
767 | return; | 908 | return; |
768 | } | 909 | } |
769 | 910 | ||
@@ -841,7 +982,7 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, | |||
841 | queue_delayed_work(priv->workqueue, pwork, | 982 | queue_delayed_work(priv->workqueue, pwork, |
842 | msecs_to_jiffies(5)); | 983 | msecs_to_jiffies(5)); |
843 | else | 984 | else |
844 | IWL_WARNING("uCode did not respond OK.\n"); | 985 | IWL_WARN(priv, "uCode did not respond OK.\n"); |
845 | } | 986 | } |
846 | 987 | ||
847 | static void iwl_rx_reply_error(struct iwl_priv *priv, | 988 | static void iwl_rx_reply_error(struct iwl_priv *priv, |
@@ -849,7 +990,7 @@ static void iwl_rx_reply_error(struct iwl_priv *priv, | |||
849 | { | 990 | { |
850 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 991 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
851 | 992 | ||
852 | IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " | 993 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " |
853 | "seq 0x%04X ser 0x%08X\n", | 994 | "seq 0x%04X ser 0x%08X\n", |
854 | le32_to_cpu(pkt->u.err_resp.error_type), | 995 | le32_to_cpu(pkt->u.err_resp.error_type), |
855 | get_cmd_string(pkt->u.err_resp.cmd_id), | 996 | get_cmd_string(pkt->u.err_resp.cmd_id), |
@@ -902,7 +1043,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) | |||
902 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); | 1043 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); |
903 | 1044 | ||
904 | if (!beacon) { | 1045 | if (!beacon) { |
905 | IWL_ERROR("update beacon failed\n"); | 1046 | IWL_ERR(priv, "update beacon failed\n"); |
906 | return; | 1047 | return; |
907 | } | 1048 | } |
908 | 1049 | ||
@@ -1193,7 +1334,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
1193 | if (rxb && rxb->skb) | 1334 | if (rxb && rxb->skb) |
1194 | iwl_tx_cmd_complete(priv, rxb); | 1335 | iwl_tx_cmd_complete(priv, rxb); |
1195 | else | 1336 | else |
1196 | IWL_WARNING("Claim null rxb?\n"); | 1337 | IWL_WARN(priv, "Claim null rxb?\n"); |
1197 | } | 1338 | } |
1198 | 1339 | ||
1199 | /* For now we just don't re-use anything. We can tweak this | 1340 | /* For now we just don't re-use anything. We can tweak this |
@@ -1357,7 +1498,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1357 | 1498 | ||
1358 | /* Now service all interrupt bits discovered above. */ | 1499 | /* Now service all interrupt bits discovered above. */ |
1359 | if (inta & CSR_INT_BIT_HW_ERR) { | 1500 | if (inta & CSR_INT_BIT_HW_ERR) { |
1360 | IWL_ERROR("Microcode HW error detected. Restarting.\n"); | 1501 | IWL_ERR(priv, "Microcode HW error detected. Restarting.\n"); |
1361 | 1502 | ||
1362 | /* Tell the device to stop sending interrupts */ | 1503 | /* Tell the device to stop sending interrupts */ |
1363 | iwl_disable_interrupts(priv); | 1504 | iwl_disable_interrupts(priv); |
@@ -1397,13 +1538,16 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1397 | hw_rf_kill ? "disable radio" : "enable radio"); | 1538 | hw_rf_kill ? "disable radio" : "enable radio"); |
1398 | 1539 | ||
1399 | /* driver only loads ucode once setting the interface up. | 1540 | /* driver only loads ucode once setting the interface up. |
1400 | * the driver as well won't allow loading if RFKILL is set | 1541 | * the driver allows loading the ucode even if the radio |
1401 | * therefore no need to restart the driver from this handler | 1542 | * is killed. Hence update the killswitch state here. The |
1543 | * rfkill handler will care about restarting if needed. | ||
1402 | */ | 1544 | */ |
1403 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 1545 | if (!test_bit(STATUS_ALIVE, &priv->status)) { |
1404 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1546 | if (hw_rf_kill) |
1405 | if (priv->is_open && !iwl_is_rfkill(priv)) | 1547 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1406 | queue_work(priv->workqueue, &priv->up); | 1548 | else |
1549 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
1550 | queue_work(priv->workqueue, &priv->rf_kill); | ||
1407 | } | 1551 | } |
1408 | 1552 | ||
1409 | handled |= CSR_INT_BIT_RF_KILL; | 1553 | handled |= CSR_INT_BIT_RF_KILL; |
@@ -1411,14 +1555,14 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1411 | 1555 | ||
1412 | /* Chip got too hot and stopped itself */ | 1556 | /* Chip got too hot and stopped itself */ |
1413 | if (inta & CSR_INT_BIT_CT_KILL) { | 1557 | if (inta & CSR_INT_BIT_CT_KILL) { |
1414 | IWL_ERROR("Microcode CT kill error detected.\n"); | 1558 | IWL_ERR(priv, "Microcode CT kill error detected.\n"); |
1415 | handled |= CSR_INT_BIT_CT_KILL; | 1559 | handled |= CSR_INT_BIT_CT_KILL; |
1416 | } | 1560 | } |
1417 | 1561 | ||
1418 | /* Error detected by uCode */ | 1562 | /* Error detected by uCode */ |
1419 | if (inta & CSR_INT_BIT_SW_ERR) { | 1563 | if (inta & CSR_INT_BIT_SW_ERR) { |
1420 | IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n", | 1564 | IWL_ERR(priv, "Microcode SW error detected. " |
1421 | inta); | 1565 | " Restarting 0x%X.\n", inta); |
1422 | iwl_irq_handle_error(priv); | 1566 | iwl_irq_handle_error(priv); |
1423 | handled |= CSR_INT_BIT_SW_ERR; | 1567 | handled |= CSR_INT_BIT_SW_ERR; |
1424 | } | 1568 | } |
@@ -1454,12 +1598,12 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1454 | } | 1598 | } |
1455 | 1599 | ||
1456 | if (inta & ~handled) | 1600 | if (inta & ~handled) |
1457 | IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); | 1601 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); |
1458 | 1602 | ||
1459 | if (inta & ~CSR_INI_SET_MASK) { | 1603 | if (inta & ~CSR_INI_SET_MASK) { |
1460 | IWL_WARNING("Disabled INTA bits 0x%08x were pending\n", | 1604 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", |
1461 | inta & ~CSR_INI_SET_MASK); | 1605 | inta & ~CSR_INI_SET_MASK); |
1462 | IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh); | 1606 | IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); |
1463 | } | 1607 | } |
1464 | 1608 | ||
1465 | /* Re-enable all interrupts */ | 1609 | /* Re-enable all interrupts */ |
@@ -1511,7 +1655,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1511 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | 1655 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { |
1512 | /* Hardware disappeared. It might have already raised | 1656 | /* Hardware disappeared. It might have already raised |
1513 | * an interrupt */ | 1657 | * an interrupt */ |
1514 | IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta); | 1658 | IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); |
1515 | goto unplugged; | 1659 | goto unplugged; |
1516 | } | 1660 | } |
1517 | 1661 | ||
@@ -1584,7 +1728,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1584 | sprintf(buf, "%s%d%s", name_pre, index, ".ucode"); | 1728 | sprintf(buf, "%s%d%s", name_pre, index, ".ucode"); |
1585 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); | 1729 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); |
1586 | if (ret < 0) { | 1730 | if (ret < 0) { |
1587 | IWL_ERROR("%s firmware file req failed: Reason %d\n", | 1731 | IWL_ERR(priv, "%s firmware file req failed: %d\n", |
1588 | buf, ret); | 1732 | buf, ret); |
1589 | if (ret == -ENOENT) | 1733 | if (ret == -ENOENT) |
1590 | continue; | 1734 | continue; |
@@ -1592,8 +1736,11 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1592 | goto error; | 1736 | goto error; |
1593 | } else { | 1737 | } else { |
1594 | if (index < api_max) | 1738 | if (index < api_max) |
1595 | IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n", | 1739 | IWL_ERR(priv, "Loaded firmware %s, " |
1740 | "which is deprecated. " | ||
1741 | "Please use API v%u instead.\n", | ||
1596 | buf, api_max); | 1742 | buf, api_max); |
1743 | |||
1597 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", | 1744 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", |
1598 | buf, ucode_raw->size); | 1745 | buf, ucode_raw->size); |
1599 | break; | 1746 | break; |
@@ -1605,7 +1752,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1605 | 1752 | ||
1606 | /* Make sure that we got at least our header! */ | 1753 | /* Make sure that we got at least our header! */ |
1607 | if (ucode_raw->size < sizeof(*ucode)) { | 1754 | if (ucode_raw->size < sizeof(*ucode)) { |
1608 | IWL_ERROR("File size way too small!\n"); | 1755 | IWL_ERR(priv, "File size way too small!\n"); |
1609 | ret = -EINVAL; | 1756 | ret = -EINVAL; |
1610 | goto err_release; | 1757 | goto err_release; |
1611 | } | 1758 | } |
@@ -1626,7 +1773,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1626 | * on the API version read from firware header from here on forward */ | 1773 | * on the API version read from firware header from here on forward */ |
1627 | 1774 | ||
1628 | if (api_ver < api_min || api_ver > api_max) { | 1775 | if (api_ver < api_min || api_ver > api_max) { |
1629 | IWL_ERROR("Driver unable to support your firmware API. " | 1776 | IWL_ERR(priv, "Driver unable to support your firmware API. " |
1630 | "Driver supports v%u, firmware is v%u.\n", | 1777 | "Driver supports v%u, firmware is v%u.\n", |
1631 | api_max, api_ver); | 1778 | api_max, api_ver); |
1632 | priv->ucode_ver = 0; | 1779 | priv->ucode_ver = 0; |
@@ -1634,16 +1781,16 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1634 | goto err_release; | 1781 | goto err_release; |
1635 | } | 1782 | } |
1636 | if (api_ver != api_max) | 1783 | if (api_ver != api_max) |
1637 | IWL_ERROR("Firmware has old API version. Expected v%u, " | 1784 | IWL_ERR(priv, "Firmware has old API version. Expected v%u, " |
1638 | "got v%u. New firmware can be obtained " | 1785 | "got v%u. New firmware can be obtained " |
1639 | "from http://www.intellinuxwireless.org.\n", | 1786 | "from http://www.intellinuxwireless.org.\n", |
1640 | api_max, api_ver); | 1787 | api_max, api_ver); |
1641 | 1788 | ||
1642 | printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n", | 1789 | IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", |
1643 | IWL_UCODE_MAJOR(priv->ucode_ver), | 1790 | IWL_UCODE_MAJOR(priv->ucode_ver), |
1644 | IWL_UCODE_MINOR(priv->ucode_ver), | 1791 | IWL_UCODE_MINOR(priv->ucode_ver), |
1645 | IWL_UCODE_API(priv->ucode_ver), | 1792 | IWL_UCODE_API(priv->ucode_ver), |
1646 | IWL_UCODE_SERIAL(priv->ucode_ver)); | 1793 | IWL_UCODE_SERIAL(priv->ucode_ver)); |
1647 | 1794 | ||
1648 | IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", | 1795 | IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", |
1649 | priv->ucode_ver); | 1796 | priv->ucode_ver); |
@@ -1791,7 +1938,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) | |||
1791 | return 0; | 1938 | return 0; |
1792 | 1939 | ||
1793 | err_pci_alloc: | 1940 | err_pci_alloc: |
1794 | IWL_ERROR("failed to allocate pci memory\n"); | 1941 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
1795 | ret = -ENOMEM; | 1942 | ret = -ENOMEM; |
1796 | iwl_dealloc_ucode_pci(priv); | 1943 | iwl_dealloc_ucode_pci(priv); |
1797 | 1944 | ||
@@ -1837,8 +1984,8 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1837 | iwl_clear_stations_table(priv); | 1984 | iwl_clear_stations_table(priv); |
1838 | ret = priv->cfg->ops->lib->alive_notify(priv); | 1985 | ret = priv->cfg->ops->lib->alive_notify(priv); |
1839 | if (ret) { | 1986 | if (ret) { |
1840 | IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n", | 1987 | IWL_WARN(priv, |
1841 | ret); | 1988 | "Could not complete ALIVE transition [ntf]: %d\n", ret); |
1842 | goto restart; | 1989 | goto restart; |
1843 | } | 1990 | } |
1844 | 1991 | ||
@@ -2024,12 +2171,12 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2024 | int ret; | 2171 | int ret; |
2025 | 2172 | ||
2026 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 2173 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
2027 | IWL_WARNING("Exit pending; will not bring the NIC up\n"); | 2174 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); |
2028 | return -EIO; | 2175 | return -EIO; |
2029 | } | 2176 | } |
2030 | 2177 | ||
2031 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { | 2178 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { |
2032 | IWL_ERROR("ucode not available for device bringup\n"); | 2179 | IWL_ERR(priv, "ucode not available for device bringup\n"); |
2033 | return -EIO; | 2180 | return -EIO; |
2034 | } | 2181 | } |
2035 | 2182 | ||
@@ -2041,7 +2188,7 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2041 | 2188 | ||
2042 | if (iwl_is_rfkill(priv)) { | 2189 | if (iwl_is_rfkill(priv)) { |
2043 | iwl_enable_interrupts(priv); | 2190 | iwl_enable_interrupts(priv); |
2044 | IWL_WARNING("Radio disabled by %s RF Kill switch\n", | 2191 | IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n", |
2045 | test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); | 2192 | test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); |
2046 | return 0; | 2193 | return 0; |
2047 | } | 2194 | } |
@@ -2050,7 +2197,7 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2050 | 2197 | ||
2051 | ret = iwl_hw_nic_init(priv); | 2198 | ret = iwl_hw_nic_init(priv); |
2052 | if (ret) { | 2199 | if (ret) { |
2053 | IWL_ERROR("Unable to init nic\n"); | 2200 | IWL_ERR(priv, "Unable to init nic\n"); |
2054 | return ret; | 2201 | return ret; |
2055 | } | 2202 | } |
2056 | 2203 | ||
@@ -2083,7 +2230,8 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2083 | ret = priv->cfg->ops->lib->load_ucode(priv); | 2230 | ret = priv->cfg->ops->lib->load_ucode(priv); |
2084 | 2231 | ||
2085 | if (ret) { | 2232 | if (ret) { |
2086 | IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret); | 2233 | IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n", |
2234 | ret); | ||
2087 | continue; | 2235 | continue; |
2088 | } | 2236 | } |
2089 | 2237 | ||
@@ -2104,7 +2252,7 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2104 | 2252 | ||
2105 | /* tried to restart and config the device for as long as our | 2253 | /* tried to restart and config the device for as long as our |
2106 | * patience could withstand */ | 2254 | * patience could withstand */ |
2107 | IWL_ERROR("Unable to initialize device after %d attempts.\n", i); | 2255 | IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); |
2108 | return -EIO; | 2256 | return -EIO; |
2109 | } | 2257 | } |
2110 | 2258 | ||
@@ -2141,40 +2289,6 @@ static void iwl_bg_alive_start(struct work_struct *data) | |||
2141 | mutex_unlock(&priv->mutex); | 2289 | mutex_unlock(&priv->mutex); |
2142 | } | 2290 | } |
2143 | 2291 | ||
2144 | static void iwl_bg_rf_kill(struct work_struct *work) | ||
2145 | { | ||
2146 | struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); | ||
2147 | |||
2148 | wake_up_interruptible(&priv->wait_command_queue); | ||
2149 | |||
2150 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2151 | return; | ||
2152 | |||
2153 | mutex_lock(&priv->mutex); | ||
2154 | |||
2155 | if (!iwl_is_rfkill(priv)) { | ||
2156 | IWL_DEBUG(IWL_DL_RF_KILL, | ||
2157 | "HW and/or SW RF Kill no longer active, restarting " | ||
2158 | "device\n"); | ||
2159 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2160 | queue_work(priv->workqueue, &priv->restart); | ||
2161 | } else { | ||
2162 | /* make sure mac80211 stop sending Tx frame */ | ||
2163 | if (priv->mac80211_registered) | ||
2164 | ieee80211_stop_queues(priv->hw); | ||
2165 | |||
2166 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | ||
2167 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " | ||
2168 | "disabled by SW switch\n"); | ||
2169 | else | ||
2170 | IWL_WARNING("Radio Frequency Kill Switch is On:\n" | ||
2171 | "Kill switch must be turned off for " | ||
2172 | "wireless networking to work.\n"); | ||
2173 | } | ||
2174 | mutex_unlock(&priv->mutex); | ||
2175 | iwl_rfkill_set_hw_state(priv); | ||
2176 | } | ||
2177 | |||
2178 | static void iwl_bg_run_time_calib_work(struct work_struct *work) | 2292 | static void iwl_bg_run_time_calib_work(struct work_struct *work) |
2179 | { | 2293 | { |
2180 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 2294 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
@@ -2244,7 +2358,7 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
2244 | unsigned long flags; | 2358 | unsigned long flags; |
2245 | 2359 | ||
2246 | if (priv->iw_mode == NL80211_IFTYPE_AP) { | 2360 | if (priv->iw_mode == NL80211_IFTYPE_AP) { |
2247 | IWL_ERROR("%s Should not be called in AP mode\n", __func__); | 2361 | IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); |
2248 | return; | 2362 | return; |
2249 | } | 2363 | } |
2250 | 2364 | ||
@@ -2271,7 +2385,7 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
2271 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, | 2385 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, |
2272 | sizeof(priv->rxon_timing), &priv->rxon_timing); | 2386 | sizeof(priv->rxon_timing), &priv->rxon_timing); |
2273 | if (ret) | 2387 | if (ret) |
2274 | IWL_WARNING("REPLY_RXON_TIMING failed - " | 2388 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
2275 | "Attempting to continue.\n"); | 2389 | "Attempting to continue.\n"); |
2276 | 2390 | ||
2277 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2391 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
@@ -2317,7 +2431,7 @@ static void iwl_post_associate(struct iwl_priv *priv) | |||
2317 | break; | 2431 | break; |
2318 | 2432 | ||
2319 | default: | 2433 | default: |
2320 | IWL_ERROR("%s Should not be called in %d mode\n", | 2434 | IWL_ERR(priv, "%s Should not be called in %d mode\n", |
2321 | __func__, priv->iw_mode); | 2435 | __func__, priv->iw_mode); |
2322 | break; | 2436 | break; |
2323 | } | 2437 | } |
@@ -2353,31 +2467,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2353 | { | 2467 | { |
2354 | struct iwl_priv *priv = hw->priv; | 2468 | struct iwl_priv *priv = hw->priv; |
2355 | int ret; | 2469 | int ret; |
2356 | u16 pci_cmd; | ||
2357 | 2470 | ||
2358 | IWL_DEBUG_MAC80211("enter\n"); | 2471 | IWL_DEBUG_MAC80211("enter\n"); |
2359 | 2472 | ||
2360 | if (pci_enable_device(priv->pci_dev)) { | ||
2361 | IWL_ERROR("Fail to pci_enable_device\n"); | ||
2362 | return -ENODEV; | ||
2363 | } | ||
2364 | pci_restore_state(priv->pci_dev); | ||
2365 | pci_enable_msi(priv->pci_dev); | ||
2366 | |||
2367 | /* enable interrupts if needed: hw bug w/a */ | ||
2368 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | ||
2369 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
2370 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
2371 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | ||
2372 | } | ||
2373 | |||
2374 | ret = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED, | ||
2375 | DRV_NAME, priv); | ||
2376 | if (ret) { | ||
2377 | IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq); | ||
2378 | goto out_disable_msi; | ||
2379 | } | ||
2380 | |||
2381 | /* we should be verifying the device is ready to be opened */ | 2473 | /* we should be verifying the device is ready to be opened */ |
2382 | mutex_lock(&priv->mutex); | 2474 | mutex_lock(&priv->mutex); |
2383 | 2475 | ||
@@ -2388,9 +2480,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2388 | if (!priv->ucode_code.len) { | 2480 | if (!priv->ucode_code.len) { |
2389 | ret = iwl_read_ucode(priv); | 2481 | ret = iwl_read_ucode(priv); |
2390 | if (ret) { | 2482 | if (ret) { |
2391 | IWL_ERROR("Could not read microcode: %d\n", ret); | 2483 | IWL_ERR(priv, "Could not read microcode: %d\n", ret); |
2392 | mutex_unlock(&priv->mutex); | 2484 | mutex_unlock(&priv->mutex); |
2393 | goto out_release_irq; | 2485 | return ret; |
2394 | } | 2486 | } |
2395 | } | 2487 | } |
2396 | 2488 | ||
@@ -2401,7 +2493,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2401 | iwl_rfkill_set_hw_state(priv); | 2493 | iwl_rfkill_set_hw_state(priv); |
2402 | 2494 | ||
2403 | if (ret) | 2495 | if (ret) |
2404 | goto out_release_irq; | 2496 | return ret; |
2405 | 2497 | ||
2406 | if (iwl_is_rfkill(priv)) | 2498 | if (iwl_is_rfkill(priv)) |
2407 | goto out; | 2499 | goto out; |
@@ -2418,10 +2510,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2418 | UCODE_READY_TIMEOUT); | 2510 | UCODE_READY_TIMEOUT); |
2419 | if (!ret) { | 2511 | if (!ret) { |
2420 | if (!test_bit(STATUS_READY, &priv->status)) { | 2512 | if (!test_bit(STATUS_READY, &priv->status)) { |
2421 | IWL_ERROR("START_ALIVE timeout after %dms.\n", | 2513 | IWL_ERR(priv, "START_ALIVE timeout after %dms.\n", |
2422 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | 2514 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); |
2423 | ret = -ETIMEDOUT; | 2515 | return -ETIMEDOUT; |
2424 | goto out_release_irq; | ||
2425 | } | 2516 | } |
2426 | } | 2517 | } |
2427 | 2518 | ||
@@ -2429,15 +2520,6 @@ out: | |||
2429 | priv->is_open = 1; | 2520 | priv->is_open = 1; |
2430 | IWL_DEBUG_MAC80211("leave\n"); | 2521 | IWL_DEBUG_MAC80211("leave\n"); |
2431 | return 0; | 2522 | return 0; |
2432 | |||
2433 | out_release_irq: | ||
2434 | free_irq(priv->pci_dev->irq, priv); | ||
2435 | out_disable_msi: | ||
2436 | pci_disable_msi(priv->pci_dev); | ||
2437 | pci_disable_device(priv->pci_dev); | ||
2438 | priv->is_open = 0; | ||
2439 | IWL_DEBUG_MAC80211("leave - failed\n"); | ||
2440 | return ret; | ||
2441 | } | 2523 | } |
2442 | 2524 | ||
2443 | static void iwl_mac_stop(struct ieee80211_hw *hw) | 2525 | static void iwl_mac_stop(struct ieee80211_hw *hw) |
@@ -2465,10 +2547,10 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) | |||
2465 | iwl_down(priv); | 2547 | iwl_down(priv); |
2466 | 2548 | ||
2467 | flush_workqueue(priv->workqueue); | 2549 | flush_workqueue(priv->workqueue); |
2468 | free_irq(priv->pci_dev->irq, priv); | 2550 | |
2469 | pci_disable_msi(priv->pci_dev); | 2551 | /* enable interrupts again in order to receive rfkill changes */ |
2470 | pci_save_state(priv->pci_dev); | 2552 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
2471 | pci_disable_device(priv->pci_dev); | 2553 | iwl_enable_interrupts(priv); |
2472 | 2554 | ||
2473 | IWL_DEBUG_MAC80211("leave\n"); | 2555 | IWL_DEBUG_MAC80211("leave\n"); |
2474 | } | 2556 | } |
@@ -2544,7 +2626,7 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2544 | mutex_lock(&priv->mutex); | 2626 | mutex_lock(&priv->mutex); |
2545 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); | 2627 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
2546 | 2628 | ||
2547 | priv->current_ht_config.is_ht = conf->ht.enabled; | 2629 | priv->current_ht_config.is_ht = conf_is_ht(conf); |
2548 | 2630 | ||
2549 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { | 2631 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { |
2550 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); | 2632 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); |
@@ -2577,7 +2659,7 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2577 | 2659 | ||
2578 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | 2660 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && |
2579 | !is_channel_ibss(ch_info)) { | 2661 | !is_channel_ibss(ch_info)) { |
2580 | IWL_ERROR("channel %d in band %d not IBSS channel\n", | 2662 | IWL_ERR(priv, "channel %d in band %d not IBSS channel\n", |
2581 | conf->channel->hw_value, conf->channel->band); | 2663 | conf->channel->hw_value, conf->channel->band); |
2582 | ret = -EINVAL; | 2664 | ret = -EINVAL; |
2583 | goto out; | 2665 | goto out; |
@@ -2639,6 +2721,9 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2639 | 2721 | ||
2640 | iwl_set_rate(priv); | 2722 | iwl_set_rate(priv); |
2641 | 2723 | ||
2724 | /* call to ensure that 4965 rx_chain is set properly in monitor mode */ | ||
2725 | iwl_set_rxon_chain(priv); | ||
2726 | |||
2642 | if (memcmp(&priv->active_rxon, | 2727 | if (memcmp(&priv->active_rxon, |
2643 | &priv->staging_rxon, sizeof(priv->staging_rxon))) | 2728 | &priv->staging_rxon, sizeof(priv->staging_rxon))) |
2644 | iwl_commit_rxon(priv); | 2729 | iwl_commit_rxon(priv); |
@@ -2672,7 +2757,7 @@ static void iwl_config_ap(struct iwl_priv *priv) | |||
2672 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, | 2757 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, |
2673 | sizeof(priv->rxon_timing), &priv->rxon_timing); | 2758 | sizeof(priv->rxon_timing), &priv->rxon_timing); |
2674 | if (ret) | 2759 | if (ret) |
2675 | IWL_WARNING("REPLY_RXON_TIMING failed - " | 2760 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
2676 | "Attempting to continue.\n"); | 2761 | "Attempting to continue.\n"); |
2677 | 2762 | ||
2678 | iwl_set_rxon_chain(priv); | 2763 | iwl_set_rxon_chain(priv); |
@@ -2778,7 +2863,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, | |||
2778 | /* If there is currently a HW scan going on in the background | 2863 | /* If there is currently a HW scan going on in the background |
2779 | * then we need to cancel it else the RXON below will fail. */ | 2864 | * then we need to cancel it else the RXON below will fail. */ |
2780 | if (iwl_scan_cancel_timeout(priv, 100)) { | 2865 | if (iwl_scan_cancel_timeout(priv, 100)) { |
2781 | IWL_WARNING("Aborted scan still in progress " | 2866 | IWL_WARN(priv, "Aborted scan still in progress " |
2782 | "after 100ms\n"); | 2867 | "after 100ms\n"); |
2783 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 2868 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
2784 | mutex_unlock(&priv->mutex); | 2869 | mutex_unlock(&priv->mutex); |
@@ -3019,13 +3104,15 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
3019 | } | 3104 | } |
3020 | 3105 | ||
3021 | static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 3106 | static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
3022 | const u8 *local_addr, const u8 *addr, | 3107 | struct ieee80211_vif *vif, |
3108 | struct ieee80211_sta *sta, | ||
3023 | struct ieee80211_key_conf *key) | 3109 | struct ieee80211_key_conf *key) |
3024 | { | 3110 | { |
3025 | struct iwl_priv *priv = hw->priv; | 3111 | struct iwl_priv *priv = hw->priv; |
3026 | int ret = 0; | 3112 | const u8 *addr; |
3027 | u8 sta_id = IWL_INVALID_STATION; | 3113 | int ret; |
3028 | u8 is_default_wep_key = 0; | 3114 | u8 sta_id; |
3115 | bool is_default_wep_key = false; | ||
3029 | 3116 | ||
3030 | IWL_DEBUG_MAC80211("enter\n"); | 3117 | IWL_DEBUG_MAC80211("enter\n"); |
3031 | 3118 | ||
@@ -3033,11 +3120,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3033 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); | 3120 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); |
3034 | return -EOPNOTSUPP; | 3121 | return -EOPNOTSUPP; |
3035 | } | 3122 | } |
3036 | 3123 | addr = sta ? sta->addr : iwl_bcast_addr; | |
3037 | if (is_zero_ether_addr(addr)) | ||
3038 | /* only support pairwise keys */ | ||
3039 | return -EOPNOTSUPP; | ||
3040 | |||
3041 | sta_id = iwl_find_station(priv, addr); | 3124 | sta_id = iwl_find_station(priv, addr); |
3042 | if (sta_id == IWL_INVALID_STATION) { | 3125 | if (sta_id == IWL_INVALID_STATION) { |
3043 | IWL_DEBUG_MAC80211("leave - %pM not in station map.\n", | 3126 | IWL_DEBUG_MAC80211("leave - %pM not in station map.\n", |
@@ -3359,8 +3442,7 @@ static ssize_t store_debug_level(struct device *d, | |||
3359 | 3442 | ||
3360 | ret = strict_strtoul(buf, 0, &val); | 3443 | ret = strict_strtoul(buf, 0, &val); |
3361 | if (ret) | 3444 | if (ret) |
3362 | printk(KERN_INFO DRV_NAME | 3445 | IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); |
3363 | ": %s is not in hex or decimal form.\n", buf); | ||
3364 | else | 3446 | else |
3365 | priv->debug_level = val; | 3447 | priv->debug_level = val; |
3366 | 3448 | ||
@@ -3439,8 +3521,7 @@ static ssize_t store_tx_power(struct device *d, | |||
3439 | 3521 | ||
3440 | ret = strict_strtoul(buf, 10, &val); | 3522 | ret = strict_strtoul(buf, 10, &val); |
3441 | if (ret) | 3523 | if (ret) |
3442 | printk(KERN_INFO DRV_NAME | 3524 | IWL_INFO(priv, "%s is not in decimal form.\n", buf); |
3443 | ": %s is not in decimal form.\n", buf); | ||
3444 | else | 3525 | else |
3445 | iwl_set_tx_power(priv, val, false); | 3526 | iwl_set_tx_power(priv, val, false); |
3446 | 3527 | ||
@@ -3473,7 +3554,7 @@ static ssize_t store_flags(struct device *d, | |||
3473 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { | 3554 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { |
3474 | /* Cancel any currently running scans... */ | 3555 | /* Cancel any currently running scans... */ |
3475 | if (iwl_scan_cancel_timeout(priv, 100)) | 3556 | if (iwl_scan_cancel_timeout(priv, 100)) |
3476 | IWL_WARNING("Could not cancel scan.\n"); | 3557 | IWL_WARN(priv, "Could not cancel scan.\n"); |
3477 | else { | 3558 | else { |
3478 | IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags); | 3559 | IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags); |
3479 | priv->staging_rxon.flags = cpu_to_le32(flags); | 3560 | priv->staging_rxon.flags = cpu_to_le32(flags); |
@@ -3512,7 +3593,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
3512 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { | 3593 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { |
3513 | /* Cancel any currently running scans... */ | 3594 | /* Cancel any currently running scans... */ |
3514 | if (iwl_scan_cancel_timeout(priv, 100)) | 3595 | if (iwl_scan_cancel_timeout(priv, 100)) |
3515 | IWL_WARNING("Could not cancel scan.\n"); | 3596 | IWL_WARN(priv, "Could not cancel scan.\n"); |
3516 | else { | 3597 | else { |
3517 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " | 3598 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " |
3518 | "0x%04X\n", filter_flags); | 3599 | "0x%04X\n", filter_flags); |
@@ -3529,31 +3610,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
3529 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 3610 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
3530 | store_filter_flags); | 3611 | store_filter_flags); |
3531 | 3612 | ||
3532 | static ssize_t store_retry_rate(struct device *d, | ||
3533 | struct device_attribute *attr, | ||
3534 | const char *buf, size_t count) | ||
3535 | { | ||
3536 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3537 | long val; | ||
3538 | int ret = strict_strtol(buf, 10, &val); | ||
3539 | if (!ret) | ||
3540 | return ret; | ||
3541 | |||
3542 | priv->retry_rate = (val > 0) ? val : 1; | ||
3543 | |||
3544 | return count; | ||
3545 | } | ||
3546 | |||
3547 | static ssize_t show_retry_rate(struct device *d, | ||
3548 | struct device_attribute *attr, char *buf) | ||
3549 | { | ||
3550 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3551 | return sprintf(buf, "%d", priv->retry_rate); | ||
3552 | } | ||
3553 | |||
3554 | static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate, | ||
3555 | store_retry_rate); | ||
3556 | |||
3557 | static ssize_t store_power_level(struct device *d, | 3613 | static ssize_t store_power_level(struct device *d, |
3558 | struct device_attribute *attr, | 3614 | struct device_attribute *attr, |
3559 | const char *buf, size_t count) | 3615 | const char *buf, size_t count) |
@@ -3656,16 +3712,6 @@ static ssize_t show_statistics(struct device *d, | |||
3656 | 3712 | ||
3657 | static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); | 3713 | static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); |
3658 | 3714 | ||
3659 | static ssize_t show_status(struct device *d, | ||
3660 | struct device_attribute *attr, char *buf) | ||
3661 | { | ||
3662 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | ||
3663 | if (!iwl_is_alive(priv)) | ||
3664 | return -EAGAIN; | ||
3665 | return sprintf(buf, "0x%08x\n", (int)priv->status); | ||
3666 | } | ||
3667 | |||
3668 | static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | ||
3669 | 3715 | ||
3670 | /***************************************************************************** | 3716 | /***************************************************************************** |
3671 | * | 3717 | * |
@@ -3719,9 +3765,7 @@ static struct attribute *iwl_sysfs_entries[] = { | |||
3719 | &dev_attr_flags.attr, | 3765 | &dev_attr_flags.attr, |
3720 | &dev_attr_filter_flags.attr, | 3766 | &dev_attr_filter_flags.attr, |
3721 | &dev_attr_power_level.attr, | 3767 | &dev_attr_power_level.attr, |
3722 | &dev_attr_retry_rate.attr, | ||
3723 | &dev_attr_statistics.attr, | 3768 | &dev_attr_statistics.attr, |
3724 | &dev_attr_status.attr, | ||
3725 | &dev_attr_temperature.attr, | 3769 | &dev_attr_temperature.attr, |
3726 | &dev_attr_tx_power.attr, | 3770 | &dev_attr_tx_power.attr, |
3727 | #ifdef CONFIG_IWLWIFI_DEBUG | 3771 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -3764,6 +3808,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3764 | struct ieee80211_hw *hw; | 3808 | struct ieee80211_hw *hw; |
3765 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); | 3809 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); |
3766 | unsigned long flags; | 3810 | unsigned long flags; |
3811 | u16 pci_cmd; | ||
3767 | 3812 | ||
3768 | /************************ | 3813 | /************************ |
3769 | * 1. Allocating HW data | 3814 | * 1. Allocating HW data |
@@ -3816,8 +3861,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3816 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | 3861 | err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); |
3817 | /* both attempts failed: */ | 3862 | /* both attempts failed: */ |
3818 | if (err) { | 3863 | if (err) { |
3819 | printk(KERN_WARNING "%s: No suitable DMA available.\n", | 3864 | IWL_WARN(priv, "No suitable DMA available.\n"); |
3820 | DRV_NAME); | ||
3821 | goto out_pci_disable_device; | 3865 | goto out_pci_disable_device; |
3822 | } | 3866 | } |
3823 | } | 3867 | } |
@@ -3843,8 +3887,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3843 | IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base); | 3887 | IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base); |
3844 | 3888 | ||
3845 | iwl_hw_detect(priv); | 3889 | iwl_hw_detect(priv); |
3846 | printk(KERN_INFO DRV_NAME | 3890 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", |
3847 | ": Detected Intel Wireless WiFi Link %s REV=0x%X\n", | ||
3848 | priv->cfg->name, priv->hw_rev); | 3891 | priv->cfg->name, priv->hw_rev); |
3849 | 3892 | ||
3850 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | 3893 | /* We disable the RETRY_TIMEOUT register (0x41) to keep |
@@ -3863,7 +3906,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3863 | /* Read the EEPROM */ | 3906 | /* Read the EEPROM */ |
3864 | err = iwl_eeprom_init(priv); | 3907 | err = iwl_eeprom_init(priv); |
3865 | if (err) { | 3908 | if (err) { |
3866 | IWL_ERROR("Unable to init EEPROM\n"); | 3909 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
3867 | goto out_iounmap; | 3910 | goto out_iounmap; |
3868 | } | 3911 | } |
3869 | err = iwl_eeprom_check_version(priv); | 3912 | err = iwl_eeprom_check_version(priv); |
@@ -3879,7 +3922,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3879 | * 5. Setup HW constants | 3922 | * 5. Setup HW constants |
3880 | ************************/ | 3923 | ************************/ |
3881 | if (iwl_set_hw_params(priv)) { | 3924 | if (iwl_set_hw_params(priv)) { |
3882 | IWL_ERROR("failed to set hw parameters\n"); | 3925 | IWL_ERR(priv, "failed to set hw parameters\n"); |
3883 | goto out_free_eeprom; | 3926 | goto out_free_eeprom; |
3884 | } | 3927 | } |
3885 | 3928 | ||
@@ -3909,43 +3952,65 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3909 | iwl_disable_interrupts(priv); | 3952 | iwl_disable_interrupts(priv); |
3910 | spin_unlock_irqrestore(&priv->lock, flags); | 3953 | spin_unlock_irqrestore(&priv->lock, flags); |
3911 | 3954 | ||
3955 | pci_enable_msi(priv->pci_dev); | ||
3956 | |||
3957 | err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED, | ||
3958 | DRV_NAME, priv); | ||
3959 | if (err) { | ||
3960 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | ||
3961 | goto out_disable_msi; | ||
3962 | } | ||
3912 | err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group); | 3963 | err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group); |
3913 | if (err) { | 3964 | if (err) { |
3914 | IWL_ERROR("failed to create sysfs device attributes\n"); | 3965 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); |
3915 | goto out_uninit_drv; | 3966 | goto out_uninit_drv; |
3916 | } | 3967 | } |
3917 | 3968 | ||
3918 | |||
3919 | iwl_setup_deferred_work(priv); | 3969 | iwl_setup_deferred_work(priv); |
3920 | iwl_setup_rx_handlers(priv); | 3970 | iwl_setup_rx_handlers(priv); |
3921 | 3971 | ||
3922 | /******************** | ||
3923 | * 9. Conclude | ||
3924 | ********************/ | ||
3925 | pci_save_state(pdev); | ||
3926 | pci_disable_device(pdev); | ||
3927 | |||
3928 | /********************************** | 3972 | /********************************** |
3929 | * 10. Setup and register mac80211 | 3973 | * 9. Setup and register mac80211 |
3930 | **********************************/ | 3974 | **********************************/ |
3931 | 3975 | ||
3976 | /* enable interrupts if needed: hw bug w/a */ | ||
3977 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | ||
3978 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
3979 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
3980 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | ||
3981 | } | ||
3982 | |||
3983 | iwl_enable_interrupts(priv); | ||
3984 | |||
3932 | err = iwl_setup_mac(priv); | 3985 | err = iwl_setup_mac(priv); |
3933 | if (err) | 3986 | if (err) |
3934 | goto out_remove_sysfs; | 3987 | goto out_remove_sysfs; |
3935 | 3988 | ||
3936 | err = iwl_dbgfs_register(priv, DRV_NAME); | 3989 | err = iwl_dbgfs_register(priv, DRV_NAME); |
3937 | if (err) | 3990 | if (err) |
3938 | IWL_ERROR("failed to create debugfs files\n"); | 3991 | IWL_ERR(priv, "failed to create debugfs files\n"); |
3992 | |||
3993 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
3994 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||
3995 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
3996 | else | ||
3997 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
3939 | 3998 | ||
3940 | err = iwl_rfkill_init(priv); | 3999 | err = iwl_rfkill_init(priv); |
3941 | if (err) | 4000 | if (err) |
3942 | IWL_ERROR("Unable to initialize RFKILL system. " | 4001 | IWL_ERR(priv, "Unable to initialize RFKILL system. " |
3943 | "Ignoring error: %d\n", err); | 4002 | "Ignoring error: %d\n", err); |
4003 | else | ||
4004 | iwl_rfkill_set_hw_state(priv); | ||
4005 | |||
3944 | iwl_power_initialize(priv); | 4006 | iwl_power_initialize(priv); |
3945 | return 0; | 4007 | return 0; |
3946 | 4008 | ||
3947 | out_remove_sysfs: | 4009 | out_remove_sysfs: |
3948 | sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); | 4010 | sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); |
4011 | out_disable_msi: | ||
4012 | pci_disable_msi(priv->pci_dev); | ||
4013 | pci_disable_device(priv->pci_dev); | ||
3949 | out_uninit_drv: | 4014 | out_uninit_drv: |
3950 | iwl_uninit_drv(priv); | 4015 | iwl_uninit_drv(priv); |
3951 | out_free_eeprom: | 4016 | out_free_eeprom: |
@@ -4017,6 +4082,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
4017 | destroy_workqueue(priv->workqueue); | 4082 | destroy_workqueue(priv->workqueue); |
4018 | priv->workqueue = NULL; | 4083 | priv->workqueue = NULL; |
4019 | 4084 | ||
4085 | free_irq(priv->pci_dev->irq, priv); | ||
4086 | pci_disable_msi(priv->pci_dev); | ||
4020 | pci_iounmap(pdev, priv->hw_base); | 4087 | pci_iounmap(pdev, priv->hw_base); |
4021 | pci_release_regions(pdev); | 4088 | pci_release_regions(pdev); |
4022 | pci_disable_device(pdev); | 4089 | pci_disable_device(pdev); |
@@ -4042,6 +4109,8 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4042 | priv->is_open = 1; | 4109 | priv->is_open = 1; |
4043 | } | 4110 | } |
4044 | 4111 | ||
4112 | pci_save_state(pdev); | ||
4113 | pci_disable_device(pdev); | ||
4045 | pci_set_power_state(pdev, PCI_D3hot); | 4114 | pci_set_power_state(pdev, PCI_D3hot); |
4046 | 4115 | ||
4047 | return 0; | 4116 | return 0; |
@@ -4052,6 +4121,9 @@ static int iwl_pci_resume(struct pci_dev *pdev) | |||
4052 | struct iwl_priv *priv = pci_get_drvdata(pdev); | 4121 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
4053 | 4122 | ||
4054 | pci_set_power_state(pdev, PCI_D0); | 4123 | pci_set_power_state(pdev, PCI_D0); |
4124 | pci_enable_device(pdev); | ||
4125 | pci_restore_state(pdev); | ||
4126 | iwl_enable_interrupts(priv); | ||
4055 | 4127 | ||
4056 | if (priv->is_open) | 4128 | if (priv->is_open) |
4057 | iwl_mac_start(priv->hw); | 4129 | iwl_mac_start(priv->hw); |
@@ -4092,6 +4164,21 @@ static struct pci_device_id iwl_hw_card_ids[] = { | |||
4092 | /* 5150 Wifi/WiMax */ | 4164 | /* 5150 Wifi/WiMax */ |
4093 | {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)}, | 4165 | {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)}, |
4094 | {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, | 4166 | {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, |
4167 | /* 6000/6050 Series */ | ||
4168 | {IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)}, | ||
4169 | {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)}, | ||
4170 | {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)}, | ||
4171 | {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)}, | ||
4172 | {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)}, | ||
4173 | {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)}, | ||
4174 | {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)}, | ||
4175 | {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)}, | ||
4176 | {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)}, | ||
4177 | {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)}, | ||
4178 | {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)}, | ||
4179 | /* 100 Series WiFi */ | ||
4180 | {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl100_bgn_cfg)}, | ||
4181 | {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl100_bgn_cfg)}, | ||
4095 | #endif /* CONFIG_IWL5000 */ | 4182 | #endif /* CONFIG_IWL5000 */ |
4096 | 4183 | ||
4097 | {0} | 4184 | {0} |
@@ -4118,13 +4205,14 @@ static int __init iwl_init(void) | |||
4118 | 4205 | ||
4119 | ret = iwlagn_rate_control_register(); | 4206 | ret = iwlagn_rate_control_register(); |
4120 | if (ret) { | 4207 | if (ret) { |
4121 | IWL_ERROR("Unable to register rate control algorithm: %d\n", ret); | 4208 | printk(KERN_ERR DRV_NAME |
4209 | "Unable to register rate control algorithm: %d\n", ret); | ||
4122 | return ret; | 4210 | return ret; |
4123 | } | 4211 | } |
4124 | 4212 | ||
4125 | ret = pci_register_driver(&iwl_driver); | 4213 | ret = pci_register_driver(&iwl_driver); |
4126 | if (ret) { | 4214 | if (ret) { |
4127 | IWL_ERROR("Unable to initialize PCI module\n"); | 4215 | printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); |
4128 | goto error_register; | 4216 | goto error_register; |
4129 | } | 4217 | } |
4130 | 4218 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index f836ecc55758..8e5e6663be35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -102,7 +102,7 @@ int iwl_send_calib_results(struct iwl_priv *priv) | |||
102 | 102 | ||
103 | return 0; | 103 | return 0; |
104 | err: | 104 | err: |
105 | IWL_ERROR("Error %d iteration %d\n", ret, i); | 105 | IWL_ERR(priv, "Error %d iteration %d\n", ret, i); |
106 | return ret; | 106 | return ret; |
107 | } | 107 | } |
108 | EXPORT_SYMBOL(iwl_send_calib_results); | 108 | EXPORT_SYMBOL(iwl_send_calib_results); |
@@ -483,7 +483,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) | |||
483 | 483 | ||
484 | ret = iwl_send_cmd(priv, &cmd_out); | 484 | ret = iwl_send_cmd(priv, &cmd_out); |
485 | if (ret) | 485 | if (ret) |
486 | IWL_ERROR("SENSITIVITY_CMD failed\n"); | 486 | IWL_ERR(priv, "SENSITIVITY_CMD failed\n"); |
487 | 487 | ||
488 | return ret; | 488 | return ret; |
489 | } | 489 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h index 1abe84bb74ad..b6cef989a796 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-calib.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index ba997204c8d4..e49415c7fb2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -69,12 +69,20 @@ | |||
69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
70 | #define __iwl_commands_h__ | 70 | #define __iwl_commands_h__ |
71 | 71 | ||
72 | struct iwl_priv; | ||
73 | |||
72 | /* uCode version contains 4 values: Major/Minor/API/Serial */ | 74 | /* uCode version contains 4 values: Major/Minor/API/Serial */ |
73 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) | 75 | #define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) |
74 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) | 76 | #define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) |
75 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) | 77 | #define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) |
76 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) | 78 | #define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) |
77 | 79 | ||
80 | |||
81 | /* Tx rates */ | ||
82 | #define IWL_CCK_RATES 4 | ||
83 | #define IWL_OFDM_RATES 8 | ||
84 | #define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES) | ||
85 | |||
78 | enum { | 86 | enum { |
79 | REPLY_ALIVE = 0x1, | 87 | REPLY_ALIVE = 0x1, |
80 | REPLY_ERROR = 0x2, | 88 | REPLY_ERROR = 0x2, |
@@ -219,6 +227,37 @@ struct iwl_cmd_header { | |||
219 | u8 data[0]; | 227 | u8 data[0]; |
220 | } __attribute__ ((packed)); | 228 | } __attribute__ ((packed)); |
221 | 229 | ||
230 | |||
231 | /** | ||
232 | * struct iwl3945_tx_power | ||
233 | * | ||
234 | * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH | ||
235 | * | ||
236 | * Each entry contains two values: | ||
237 | * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained | ||
238 | * linear value that multiplies the output of the digital signal processor, | ||
239 | * before being sent to the analog radio. | ||
240 | * 2) Radio gain. This sets the analog gain of the radio Tx path. | ||
241 | * It is a coarser setting, and behaves in a logarithmic (dB) fashion. | ||
242 | * | ||
243 | * Driver obtains values from struct iwl3945_tx_power power_gain_table[][]. | ||
244 | */ | ||
245 | struct iwl3945_tx_power { | ||
246 | u8 tx_gain; /* gain for analog radio */ | ||
247 | u8 dsp_atten; /* gain for DSP */ | ||
248 | } __attribute__ ((packed)); | ||
249 | |||
250 | /** | ||
251 | * struct iwl3945_power_per_rate | ||
252 | * | ||
253 | * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH | ||
254 | */ | ||
255 | struct iwl3945_power_per_rate { | ||
256 | u8 rate; /* plcp */ | ||
257 | struct iwl3945_tx_power tpc; | ||
258 | u8 reserved; | ||
259 | } __attribute__ ((packed)); | ||
260 | |||
222 | /** | 261 | /** |
223 | * iwlagn rate_n_flags bit fields | 262 | * iwlagn rate_n_flags bit fields |
224 | * | 263 | * |
@@ -300,11 +339,12 @@ struct iwl_cmd_header { | |||
300 | * 5350 has 3 transmitters | 339 | * 5350 has 3 transmitters |
301 | * bit14:16 | 340 | * bit14:16 |
302 | */ | 341 | */ |
303 | #define RATE_MCS_ANT_POS 14 | 342 | #define RATE_MCS_ANT_POS 14 |
304 | #define RATE_MCS_ANT_A_MSK 0x04000 | 343 | #define RATE_MCS_ANT_A_MSK 0x04000 |
305 | #define RATE_MCS_ANT_B_MSK 0x08000 | 344 | #define RATE_MCS_ANT_B_MSK 0x08000 |
306 | #define RATE_MCS_ANT_C_MSK 0x10000 | 345 | #define RATE_MCS_ANT_C_MSK 0x10000 |
307 | #define RATE_MCS_ANT_ABC_MSK 0x1C000 | 346 | #define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK) |
347 | #define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK) | ||
308 | #define RATE_ANT_NUM 3 | 348 | #define RATE_ANT_NUM 3 |
309 | 349 | ||
310 | #define POWER_TABLE_NUM_ENTRIES 33 | 350 | #define POWER_TABLE_NUM_ENTRIES 33 |
@@ -492,8 +532,6 @@ struct iwl_alive_resp { | |||
492 | __le32 is_valid; | 532 | __le32 is_valid; |
493 | } __attribute__ ((packed)); | 533 | } __attribute__ ((packed)); |
494 | 534 | ||
495 | |||
496 | |||
497 | /* | 535 | /* |
498 | * REPLY_ERROR = 0x2 (response only, not a command) | 536 | * REPLY_ERROR = 0x2 (response only, not a command) |
499 | */ | 537 | */ |
@@ -525,6 +563,7 @@ enum { | |||
525 | 563 | ||
526 | 564 | ||
527 | #define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0) | 565 | #define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0) |
566 | #define RXON_RX_CHAIN_DRIVER_FORCE_POS (0) | ||
528 | #define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1) | 567 | #define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1) |
529 | #define RXON_RX_CHAIN_VALID_POS (1) | 568 | #define RXON_RX_CHAIN_VALID_POS (1) |
530 | #define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4) | 569 | #define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4) |
@@ -611,6 +650,26 @@ enum { | |||
611 | * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), | 650 | * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), |
612 | * regardless of whether RXON_FILTER_ASSOC_MSK is set. | 651 | * regardless of whether RXON_FILTER_ASSOC_MSK is set. |
613 | */ | 652 | */ |
653 | |||
654 | struct iwl3945_rxon_cmd { | ||
655 | u8 node_addr[6]; | ||
656 | __le16 reserved1; | ||
657 | u8 bssid_addr[6]; | ||
658 | __le16 reserved2; | ||
659 | u8 wlap_bssid_addr[6]; | ||
660 | __le16 reserved3; | ||
661 | u8 dev_type; | ||
662 | u8 air_propagation; | ||
663 | __le16 reserved4; | ||
664 | u8 ofdm_basic_rates; | ||
665 | u8 cck_basic_rates; | ||
666 | __le16 assoc_id; | ||
667 | __le32 flags; | ||
668 | __le32 filter_flags; | ||
669 | __le16 channel; | ||
670 | __le16 reserved5; | ||
671 | } __attribute__ ((packed)); | ||
672 | |||
614 | struct iwl4965_rxon_cmd { | 673 | struct iwl4965_rxon_cmd { |
615 | u8 node_addr[6]; | 674 | u8 node_addr[6]; |
616 | __le16 reserved1; | 675 | __le16 reserved1; |
@@ -656,33 +715,41 @@ struct iwl_rxon_cmd { | |||
656 | __le16 reserved6; | 715 | __le16 reserved6; |
657 | } __attribute__ ((packed)); | 716 | } __attribute__ ((packed)); |
658 | 717 | ||
659 | struct iwl5000_rxon_assoc_cmd { | 718 | /* |
719 | * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) | ||
720 | */ | ||
721 | struct iwl3945_rxon_assoc_cmd { | ||
722 | __le32 flags; | ||
723 | __le32 filter_flags; | ||
724 | u8 ofdm_basic_rates; | ||
725 | u8 cck_basic_rates; | ||
726 | __le16 reserved; | ||
727 | } __attribute__ ((packed)); | ||
728 | |||
729 | struct iwl4965_rxon_assoc_cmd { | ||
660 | __le32 flags; | 730 | __le32 flags; |
661 | __le32 filter_flags; | 731 | __le32 filter_flags; |
662 | u8 ofdm_basic_rates; | 732 | u8 ofdm_basic_rates; |
663 | u8 cck_basic_rates; | 733 | u8 cck_basic_rates; |
664 | __le16 reserved1; | ||
665 | u8 ofdm_ht_single_stream_basic_rates; | 734 | u8 ofdm_ht_single_stream_basic_rates; |
666 | u8 ofdm_ht_dual_stream_basic_rates; | 735 | u8 ofdm_ht_dual_stream_basic_rates; |
667 | u8 ofdm_ht_triple_stream_basic_rates; | ||
668 | u8 reserved2; | ||
669 | __le16 rx_chain_select_flags; | 736 | __le16 rx_chain_select_flags; |
670 | __le16 acquisition_data; | 737 | __le16 reserved; |
671 | __le32 reserved3; | ||
672 | } __attribute__ ((packed)); | 738 | } __attribute__ ((packed)); |
673 | 739 | ||
674 | /* | 740 | struct iwl5000_rxon_assoc_cmd { |
675 | * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) | ||
676 | */ | ||
677 | struct iwl4965_rxon_assoc_cmd { | ||
678 | __le32 flags; | 741 | __le32 flags; |
679 | __le32 filter_flags; | 742 | __le32 filter_flags; |
680 | u8 ofdm_basic_rates; | 743 | u8 ofdm_basic_rates; |
681 | u8 cck_basic_rates; | 744 | u8 cck_basic_rates; |
745 | __le16 reserved1; | ||
682 | u8 ofdm_ht_single_stream_basic_rates; | 746 | u8 ofdm_ht_single_stream_basic_rates; |
683 | u8 ofdm_ht_dual_stream_basic_rates; | 747 | u8 ofdm_ht_dual_stream_basic_rates; |
748 | u8 ofdm_ht_triple_stream_basic_rates; | ||
749 | u8 reserved2; | ||
684 | __le16 rx_chain_select_flags; | 750 | __le16 rx_chain_select_flags; |
685 | __le16 reserved; | 751 | __le16 acquisition_data; |
752 | __le32 reserved3; | ||
686 | } __attribute__ ((packed)); | 753 | } __attribute__ ((packed)); |
687 | 754 | ||
688 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 | 755 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 |
@@ -702,6 +769,16 @@ struct iwl_rxon_time_cmd { | |||
702 | /* | 769 | /* |
703 | * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) | 770 | * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) |
704 | */ | 771 | */ |
772 | struct iwl3945_channel_switch_cmd { | ||
773 | u8 band; | ||
774 | u8 expect_beacon; | ||
775 | __le16 channel; | ||
776 | __le32 rxon_flags; | ||
777 | __le32 rxon_filter_flags; | ||
778 | __le32 switch_time; | ||
779 | struct iwl3945_power_per_rate power[IWL_MAX_RATES]; | ||
780 | } __attribute__ ((packed)); | ||
781 | |||
705 | struct iwl_channel_switch_cmd { | 782 | struct iwl_channel_switch_cmd { |
706 | u8 band; | 783 | u8 band; |
707 | u8 expect_beacon; | 784 | u8 expect_beacon; |
@@ -783,6 +860,8 @@ struct iwl_qosparam_cmd { | |||
783 | #define IWL_AP_ID 0 | 860 | #define IWL_AP_ID 0 |
784 | #define IWL_MULTICAST_ID 1 | 861 | #define IWL_MULTICAST_ID 1 |
785 | #define IWL_STA_ID 2 | 862 | #define IWL_STA_ID 2 |
863 | #define IWL3945_BROADCAST_ID 24 | ||
864 | #define IWL3945_STATION_COUNT 25 | ||
786 | #define IWL4965_BROADCAST_ID 31 | 865 | #define IWL4965_BROADCAST_ID 31 |
787 | #define IWL4965_STATION_COUNT 32 | 866 | #define IWL4965_STATION_COUNT 32 |
788 | #define IWL5000_BROADCAST_ID 15 | 867 | #define IWL5000_BROADCAST_ID 15 |
@@ -791,6 +870,8 @@ struct iwl_qosparam_cmd { | |||
791 | #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ | 870 | #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ |
792 | #define IWL_INVALID_STATION 255 | 871 | #define IWL_INVALID_STATION 255 |
793 | 872 | ||
873 | #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2); | ||
874 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); | ||
794 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); | 875 | #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8); |
795 | #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) | 876 | #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) |
796 | #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) | 877 | #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) |
@@ -901,6 +982,35 @@ struct sta_id_modify { | |||
901 | * used as AP, or in an IBSS network, driver must set up station table | 982 | * used as AP, or in an IBSS network, driver must set up station table |
902 | * entries for all STAs in network, starting with index IWL_STA_ID. | 983 | * entries for all STAs in network, starting with index IWL_STA_ID. |
903 | */ | 984 | */ |
985 | |||
986 | struct iwl3945_addsta_cmd { | ||
987 | u8 mode; /* 1: modify existing, 0: add new station */ | ||
988 | u8 reserved[3]; | ||
989 | struct sta_id_modify sta; | ||
990 | struct iwl4965_keyinfo key; | ||
991 | __le32 station_flags; /* STA_FLG_* */ | ||
992 | __le32 station_flags_msk; /* STA_FLG_* */ | ||
993 | |||
994 | /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) | ||
995 | * corresponding to bit (e.g. bit 5 controls TID 5). | ||
996 | * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ | ||
997 | __le16 tid_disable_tx; | ||
998 | |||
999 | __le16 rate_n_flags; | ||
1000 | |||
1001 | /* TID for which to add block-ack support. | ||
1002 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | ||
1003 | u8 add_immediate_ba_tid; | ||
1004 | |||
1005 | /* TID for which to remove block-ack support. | ||
1006 | * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ | ||
1007 | u8 remove_immediate_ba_tid; | ||
1008 | |||
1009 | /* Starting Sequence Number for added block-ack support. | ||
1010 | * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ | ||
1011 | __le16 add_immediate_ba_ssn; | ||
1012 | } __attribute__ ((packed)); | ||
1013 | |||
904 | struct iwl4965_addsta_cmd { | 1014 | struct iwl4965_addsta_cmd { |
905 | u8 mode; /* 1: modify existing, 0: add new station */ | 1015 | u8 mode; /* 1: modify existing, 0: add new station */ |
906 | u8 reserved[3]; | 1016 | u8 reserved[3]; |
@@ -1054,6 +1164,48 @@ struct iwl_wep_cmd { | |||
1054 | #define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7) | 1164 | #define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7) |
1055 | #define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800) | 1165 | #define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800) |
1056 | 1166 | ||
1167 | |||
1168 | struct iwl3945_rx_frame_stats { | ||
1169 | u8 phy_count; | ||
1170 | u8 id; | ||
1171 | u8 rssi; | ||
1172 | u8 agc; | ||
1173 | __le16 sig_avg; | ||
1174 | __le16 noise_diff; | ||
1175 | u8 payload[0]; | ||
1176 | } __attribute__ ((packed)); | ||
1177 | |||
1178 | struct iwl3945_rx_frame_hdr { | ||
1179 | __le16 channel; | ||
1180 | __le16 phy_flags; | ||
1181 | u8 reserved1; | ||
1182 | u8 rate; | ||
1183 | __le16 len; | ||
1184 | u8 payload[0]; | ||
1185 | } __attribute__ ((packed)); | ||
1186 | |||
1187 | struct iwl3945_rx_frame_end { | ||
1188 | __le32 status; | ||
1189 | __le64 timestamp; | ||
1190 | __le32 beacon_timestamp; | ||
1191 | } __attribute__ ((packed)); | ||
1192 | |||
1193 | /* | ||
1194 | * REPLY_3945_RX = 0x1b (response only, not a command) | ||
1195 | * | ||
1196 | * NOTE: DO NOT dereference from casts to this structure | ||
1197 | * It is provided only for calculating minimum data set size. | ||
1198 | * The actual offsets of the hdr and end are dynamic based on | ||
1199 | * stats.phy_count | ||
1200 | */ | ||
1201 | struct iwl3945_rx_frame { | ||
1202 | struct iwl3945_rx_frame_stats stats; | ||
1203 | struct iwl3945_rx_frame_hdr hdr; | ||
1204 | struct iwl3945_rx_frame_end end; | ||
1205 | } __attribute__ ((packed)); | ||
1206 | |||
1207 | #define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame)) | ||
1208 | |||
1057 | /* Fixed (non-configurable) rx data from phy */ | 1209 | /* Fixed (non-configurable) rx data from phy */ |
1058 | 1210 | ||
1059 | #define IWL49_RX_RES_PHY_CNT 14 | 1211 | #define IWL49_RX_RES_PHY_CNT 14 |
@@ -1234,6 +1386,84 @@ struct iwl4965_rx_mpdu_res_start { | |||
1234 | #define TKIP_ICV_LEN 4 | 1386 | #define TKIP_ICV_LEN 4 |
1235 | 1387 | ||
1236 | /* | 1388 | /* |
1389 | * REPLY_TX = 0x1c (command) | ||
1390 | */ | ||
1391 | |||
1392 | struct iwl3945_tx_cmd { | ||
1393 | /* | ||
1394 | * MPDU byte count: | ||
1395 | * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, | ||
1396 | * + 8 byte IV for CCM or TKIP (not used for WEP) | ||
1397 | * + Data payload | ||
1398 | * + 8-byte MIC (not used for CCM/WEP) | ||
1399 | * NOTE: Does not include Tx command bytes, post-MAC pad bytes, | ||
1400 | * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i | ||
1401 | * Range: 14-2342 bytes. | ||
1402 | */ | ||
1403 | __le16 len; | ||
1404 | |||
1405 | /* | ||
1406 | * MPDU or MSDU byte count for next frame. | ||
1407 | * Used for fragmentation and bursting, but not 11n aggregation. | ||
1408 | * Same as "len", but for next frame. Set to 0 if not applicable. | ||
1409 | */ | ||
1410 | __le16 next_frame_len; | ||
1411 | |||
1412 | __le32 tx_flags; /* TX_CMD_FLG_* */ | ||
1413 | |||
1414 | u8 rate; | ||
1415 | |||
1416 | /* Index of recipient station in uCode's station table */ | ||
1417 | u8 sta_id; | ||
1418 | u8 tid_tspec; | ||
1419 | u8 sec_ctl; | ||
1420 | u8 key[16]; | ||
1421 | union { | ||
1422 | u8 byte[8]; | ||
1423 | __le16 word[4]; | ||
1424 | __le32 dw[2]; | ||
1425 | } tkip_mic; | ||
1426 | __le32 next_frame_info; | ||
1427 | union { | ||
1428 | __le32 life_time; | ||
1429 | __le32 attempt; | ||
1430 | } stop_time; | ||
1431 | u8 supp_rates[2]; | ||
1432 | u8 rts_retry_limit; /*byte 50 */ | ||
1433 | u8 data_retry_limit; /*byte 51 */ | ||
1434 | union { | ||
1435 | __le16 pm_frame_timeout; | ||
1436 | __le16 attempt_duration; | ||
1437 | } timeout; | ||
1438 | |||
1439 | /* | ||
1440 | * Duration of EDCA burst Tx Opportunity, in 32-usec units. | ||
1441 | * Set this if txop time is not specified by HCCA protocol (e.g. by AP). | ||
1442 | */ | ||
1443 | __le16 driver_txop; | ||
1444 | |||
1445 | /* | ||
1446 | * MAC header goes here, followed by 2 bytes padding if MAC header | ||
1447 | * length is 26 or 30 bytes, followed by payload data | ||
1448 | */ | ||
1449 | u8 payload[0]; | ||
1450 | struct ieee80211_hdr hdr[0]; | ||
1451 | } __attribute__ ((packed)); | ||
1452 | |||
1453 | /* | ||
1454 | * REPLY_TX = 0x1c (response) | ||
1455 | */ | ||
1456 | struct iwl3945_tx_resp { | ||
1457 | u8 failure_rts; | ||
1458 | u8 failure_frame; | ||
1459 | u8 bt_kill_count; | ||
1460 | u8 rate; | ||
1461 | __le32 wireless_media_time; | ||
1462 | __le32 status; /* TX status */ | ||
1463 | } __attribute__ ((packed)); | ||
1464 | |||
1465 | |||
1466 | /* | ||
1237 | * 4965 uCode updates these Tx attempt count values in host DRAM. | 1467 | * 4965 uCode updates these Tx attempt count values in host DRAM. |
1238 | * Used for managing Tx retries when expecting block-acks. | 1468 | * Used for managing Tx retries when expecting block-acks. |
1239 | * Driver should set these fields to 0. | 1469 | * Driver should set these fields to 0. |
@@ -1244,9 +1474,6 @@ struct iwl_dram_scratch { | |||
1244 | __le16 reserved; | 1474 | __le16 reserved; |
1245 | } __attribute__ ((packed)); | 1475 | } __attribute__ ((packed)); |
1246 | 1476 | ||
1247 | /* | ||
1248 | * REPLY_TX = 0x1c (command) | ||
1249 | */ | ||
1250 | struct iwl_tx_cmd { | 1477 | struct iwl_tx_cmd { |
1251 | /* | 1478 | /* |
1252 | * MPDU byte count: | 1479 | * MPDU byte count: |
@@ -1584,6 +1811,14 @@ struct iwl_compressed_ba_resp { | |||
1584 | * | 1811 | * |
1585 | * See details under "TXPOWER" in iwl-4965-hw.h. | 1812 | * See details under "TXPOWER" in iwl-4965-hw.h. |
1586 | */ | 1813 | */ |
1814 | |||
1815 | struct iwl3945_txpowertable_cmd { | ||
1816 | u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ | ||
1817 | u8 reserved; | ||
1818 | __le16 channel; | ||
1819 | struct iwl3945_power_per_rate power[IWL_MAX_RATES]; | ||
1820 | } __attribute__ ((packed)); | ||
1821 | |||
1587 | struct iwl4965_txpowertable_cmd { | 1822 | struct iwl4965_txpowertable_cmd { |
1588 | u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ | 1823 | u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ |
1589 | u8 reserved; | 1824 | u8 reserved; |
@@ -1591,6 +1826,35 @@ struct iwl4965_txpowertable_cmd { | |||
1591 | struct iwl4965_tx_power_db tx_power; | 1826 | struct iwl4965_tx_power_db tx_power; |
1592 | } __attribute__ ((packed)); | 1827 | } __attribute__ ((packed)); |
1593 | 1828 | ||
1829 | |||
1830 | /** | ||
1831 | * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response | ||
1832 | * | ||
1833 | * REPLY_RATE_SCALE = 0x47 (command, has simple generic response) | ||
1834 | * | ||
1835 | * NOTE: The table of rates passed to the uCode via the | ||
1836 | * RATE_SCALE command sets up the corresponding order of | ||
1837 | * rates used for all related commands, including rate | ||
1838 | * masks, etc. | ||
1839 | * | ||
1840 | * For example, if you set 9MB (PLCP 0x0f) as the first | ||
1841 | * rate in the rate table, the bit mask for that rate | ||
1842 | * when passed through ofdm_basic_rates on the REPLY_RXON | ||
1843 | * command would be bit 0 (1 << 0) | ||
1844 | */ | ||
1845 | struct iwl3945_rate_scaling_info { | ||
1846 | __le16 rate_n_flags; | ||
1847 | u8 try_cnt; | ||
1848 | u8 next_rate_index; | ||
1849 | } __attribute__ ((packed)); | ||
1850 | |||
1851 | struct iwl3945_rate_scaling_cmd { | ||
1852 | u8 table_id; | ||
1853 | u8 reserved[3]; | ||
1854 | struct iwl3945_rate_scaling_info table[IWL_MAX_RATES]; | ||
1855 | } __attribute__ ((packed)); | ||
1856 | |||
1857 | |||
1594 | /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ | 1858 | /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ |
1595 | #define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0) | 1859 | #define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0) |
1596 | 1860 | ||
@@ -2044,15 +2308,23 @@ struct iwl_spectrum_notification { | |||
2044 | */ | 2308 | */ |
2045 | #define IWL_POWER_VEC_SIZE 5 | 2309 | #define IWL_POWER_VEC_SIZE 5 |
2046 | 2310 | ||
2047 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(1 << 0) | 2311 | #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0)) |
2048 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(1 << 2) | 2312 | #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2)) |
2049 | #define IWL_POWER_PCI_PM_MSK cpu_to_le16(1 << 3) | 2313 | #define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3)) |
2050 | #define IWL_POWER_FAST_PD cpu_to_le16(1 << 4) | 2314 | #define IWL_POWER_FAST_PD cpu_to_le16(BIT(4)) |
2315 | |||
2316 | struct iwl3945_powertable_cmd { | ||
2317 | __le16 flags; | ||
2318 | u8 reserved[2]; | ||
2319 | __le32 rx_data_timeout; | ||
2320 | __le32 tx_data_timeout; | ||
2321 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; | ||
2322 | } __attribute__ ((packed)); | ||
2051 | 2323 | ||
2052 | struct iwl_powertable_cmd { | 2324 | struct iwl_powertable_cmd { |
2053 | __le16 flags; | 2325 | __le16 flags; |
2054 | u8 keep_alive_seconds; | 2326 | u8 keep_alive_seconds; /* 3945 reserved */ |
2055 | u8 debug_flags; | 2327 | u8 debug_flags; /* 3945 reserved */ |
2056 | __le32 rx_data_timeout; | 2328 | __le32 rx_data_timeout; |
2057 | __le32 tx_data_timeout; | 2329 | __le32 tx_data_timeout; |
2058 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; | 2330 | __le32 sleep_interval[IWL_POWER_VEC_SIZE]; |
@@ -2143,6 +2415,26 @@ struct iwl_ct_kill_config { | |||
2143 | * passive_dwell < max_out_time | 2415 | * passive_dwell < max_out_time |
2144 | * active_dwell < max_out_time | 2416 | * active_dwell < max_out_time |
2145 | */ | 2417 | */ |
2418 | |||
2419 | /* FIXME: rename to AP1, remove tpc */ | ||
2420 | struct iwl3945_scan_channel { | ||
2421 | /* | ||
2422 | * type is defined as: | ||
2423 | * 0:0 1 = active, 0 = passive | ||
2424 | * 1:4 SSID direct bit map; if a bit is set, then corresponding | ||
2425 | * SSID IE is transmitted in probe request. | ||
2426 | * 5:7 reserved | ||
2427 | */ | ||
2428 | u8 type; | ||
2429 | u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */ | ||
2430 | struct iwl3945_tx_power tpc; | ||
2431 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ | ||
2432 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ | ||
2433 | } __attribute__ ((packed)); | ||
2434 | |||
2435 | /* set number of direct probes u8 type */ | ||
2436 | #define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1)))) | ||
2437 | |||
2146 | struct iwl_scan_channel { | 2438 | struct iwl_scan_channel { |
2147 | /* | 2439 | /* |
2148 | * type is defined as: | 2440 | * type is defined as: |
@@ -2159,6 +2451,9 @@ struct iwl_scan_channel { | |||
2159 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ | 2451 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ |
2160 | } __attribute__ ((packed)); | 2452 | } __attribute__ ((packed)); |
2161 | 2453 | ||
2454 | /* set number of direct probes __le32 type */ | ||
2455 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) | ||
2456 | |||
2162 | /** | 2457 | /** |
2163 | * struct iwl_ssid_ie - directed scan network information element | 2458 | * struct iwl_ssid_ie - directed scan network information element |
2164 | * | 2459 | * |
@@ -2172,6 +2467,7 @@ struct iwl_ssid_ie { | |||
2172 | u8 ssid[32]; | 2467 | u8 ssid[32]; |
2173 | } __attribute__ ((packed)); | 2468 | } __attribute__ ((packed)); |
2174 | 2469 | ||
2470 | #define PROBE_OPTION_MAX_API1 0x4 | ||
2175 | #define PROBE_OPTION_MAX 0x14 | 2471 | #define PROBE_OPTION_MAX 0x14 |
2176 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) | 2472 | #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) |
2177 | #define IWL_GOOD_CRC_TH cpu_to_le16(1) | 2473 | #define IWL_GOOD_CRC_TH cpu_to_le16(1) |
@@ -2229,6 +2525,51 @@ struct iwl_ssid_ie { | |||
2229 | * To avoid uCode errors, see timing restrictions described under | 2525 | * To avoid uCode errors, see timing restrictions described under |
2230 | * struct iwl_scan_channel. | 2526 | * struct iwl_scan_channel. |
2231 | */ | 2527 | */ |
2528 | |||
2529 | struct iwl3945_scan_cmd { | ||
2530 | __le16 len; | ||
2531 | u8 reserved0; | ||
2532 | u8 channel_count; /* # channels in channel list */ | ||
2533 | __le16 quiet_time; /* dwell only this # millisecs on quiet channel | ||
2534 | * (only for active scan) */ | ||
2535 | __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ | ||
2536 | __le16 good_CRC_th; /* passive -> active promotion threshold */ | ||
2537 | __le16 reserved1; | ||
2538 | __le32 max_out_time; /* max usec to be away from associated (service) | ||
2539 | * channel */ | ||
2540 | __le32 suspend_time; /* pause scan this long (in "extended beacon | ||
2541 | * format") when returning to service channel: | ||
2542 | * 3945; 31:24 # beacons, 19:0 additional usec, | ||
2543 | * 4965; 31:22 # beacons, 21:0 additional usec. | ||
2544 | */ | ||
2545 | __le32 flags; /* RXON_FLG_* */ | ||
2546 | __le32 filter_flags; /* RXON_FILTER_* */ | ||
2547 | |||
2548 | /* For active scans (set to all-0s for passive scans). | ||
2549 | * Does not include payload. Must specify Tx rate; no rate scaling. */ | ||
2550 | struct iwl3945_tx_cmd tx_cmd; | ||
2551 | |||
2552 | /* For directed active scans (set to all-0s otherwise) */ | ||
2553 | struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1]; | ||
2554 | |||
2555 | /* | ||
2556 | * Probe request frame, followed by channel list. | ||
2557 | * | ||
2558 | * Size of probe request frame is specified by byte count in tx_cmd. | ||
2559 | * Channel list follows immediately after probe request frame. | ||
2560 | * Number of channels in list is specified by channel_count. | ||
2561 | * Each channel in list is of type: | ||
2562 | * | ||
2563 | * struct iwl3945_scan_channel channels[0]; | ||
2564 | * | ||
2565 | * NOTE: Only one band of channels can be scanned per pass. You | ||
2566 | * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait | ||
2567 | * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION) | ||
2568 | * before requesting another scan. | ||
2569 | */ | ||
2570 | u8 data[0]; | ||
2571 | } __attribute__ ((packed)); | ||
2572 | |||
2232 | struct iwl_scan_cmd { | 2573 | struct iwl_scan_cmd { |
2233 | __le16 len; | 2574 | __le16 len; |
2234 | u8 reserved0; | 2575 | u8 reserved0; |
@@ -2336,6 +2677,14 @@ struct iwl_scancomplete_notification { | |||
2336 | /* | 2677 | /* |
2337 | * BEACON_NOTIFICATION = 0x90 (notification only, not a command) | 2678 | * BEACON_NOTIFICATION = 0x90 (notification only, not a command) |
2338 | */ | 2679 | */ |
2680 | |||
2681 | struct iwl3945_beacon_notif { | ||
2682 | struct iwl3945_tx_resp beacon_notify_hdr; | ||
2683 | __le32 low_tsf; | ||
2684 | __le32 high_tsf; | ||
2685 | __le32 ibss_mgr_status; | ||
2686 | } __attribute__ ((packed)); | ||
2687 | |||
2339 | struct iwl4965_beacon_notif { | 2688 | struct iwl4965_beacon_notif { |
2340 | struct iwl4965_tx_resp beacon_notify_hdr; | 2689 | struct iwl4965_tx_resp beacon_notify_hdr; |
2341 | __le32 low_tsf; | 2690 | __le32 low_tsf; |
@@ -2346,6 +2695,15 @@ struct iwl4965_beacon_notif { | |||
2346 | /* | 2695 | /* |
2347 | * REPLY_TX_BEACON = 0x91 (command, has simple generic response) | 2696 | * REPLY_TX_BEACON = 0x91 (command, has simple generic response) |
2348 | */ | 2697 | */ |
2698 | |||
2699 | struct iwl3945_tx_beacon_cmd { | ||
2700 | struct iwl3945_tx_cmd tx; | ||
2701 | __le16 tim_idx; | ||
2702 | u8 tim_size; | ||
2703 | u8 reserved1; | ||
2704 | struct ieee80211_hdr frame[0]; /* beacon frame */ | ||
2705 | } __attribute__ ((packed)); | ||
2706 | |||
2349 | struct iwl_tx_beacon_cmd { | 2707 | struct iwl_tx_beacon_cmd { |
2350 | struct iwl_tx_cmd tx; | 2708 | struct iwl_tx_cmd tx; |
2351 | __le16 tim_idx; | 2709 | __le16 tim_idx; |
@@ -2382,6 +2740,76 @@ struct rate_histogram { | |||
2382 | 2740 | ||
2383 | /* statistics command response */ | 2741 | /* statistics command response */ |
2384 | 2742 | ||
2743 | struct iwl39_statistics_rx_phy { | ||
2744 | __le32 ina_cnt; | ||
2745 | __le32 fina_cnt; | ||
2746 | __le32 plcp_err; | ||
2747 | __le32 crc32_err; | ||
2748 | __le32 overrun_err; | ||
2749 | __le32 early_overrun_err; | ||
2750 | __le32 crc32_good; | ||
2751 | __le32 false_alarm_cnt; | ||
2752 | __le32 fina_sync_err_cnt; | ||
2753 | __le32 sfd_timeout; | ||
2754 | __le32 fina_timeout; | ||
2755 | __le32 unresponded_rts; | ||
2756 | __le32 rxe_frame_limit_overrun; | ||
2757 | __le32 sent_ack_cnt; | ||
2758 | __le32 sent_cts_cnt; | ||
2759 | } __attribute__ ((packed)); | ||
2760 | |||
2761 | struct iwl39_statistics_rx_non_phy { | ||
2762 | __le32 bogus_cts; /* CTS received when not expecting CTS */ | ||
2763 | __le32 bogus_ack; /* ACK received when not expecting ACK */ | ||
2764 | __le32 non_bssid_frames; /* number of frames with BSSID that | ||
2765 | * doesn't belong to the STA BSSID */ | ||
2766 | __le32 filtered_frames; /* count frames that were dumped in the | ||
2767 | * filtering process */ | ||
2768 | __le32 non_channel_beacons; /* beacons with our bss id but not on | ||
2769 | * our serving channel */ | ||
2770 | } __attribute__ ((packed)); | ||
2771 | |||
2772 | struct iwl39_statistics_rx { | ||
2773 | struct iwl39_statistics_rx_phy ofdm; | ||
2774 | struct iwl39_statistics_rx_phy cck; | ||
2775 | struct iwl39_statistics_rx_non_phy general; | ||
2776 | } __attribute__ ((packed)); | ||
2777 | |||
2778 | struct iwl39_statistics_tx { | ||
2779 | __le32 preamble_cnt; | ||
2780 | __le32 rx_detected_cnt; | ||
2781 | __le32 bt_prio_defer_cnt; | ||
2782 | __le32 bt_prio_kill_cnt; | ||
2783 | __le32 few_bytes_cnt; | ||
2784 | __le32 cts_timeout; | ||
2785 | __le32 ack_timeout; | ||
2786 | __le32 expected_ack_cnt; | ||
2787 | __le32 actual_ack_cnt; | ||
2788 | } __attribute__ ((packed)); | ||
2789 | |||
2790 | struct statistics_dbg { | ||
2791 | __le32 burst_check; | ||
2792 | __le32 burst_count; | ||
2793 | __le32 reserved[4]; | ||
2794 | } __attribute__ ((packed)); | ||
2795 | |||
2796 | struct iwl39_statistics_div { | ||
2797 | __le32 tx_on_a; | ||
2798 | __le32 tx_on_b; | ||
2799 | __le32 exec_time; | ||
2800 | __le32 probe_time; | ||
2801 | } __attribute__ ((packed)); | ||
2802 | |||
2803 | struct iwl39_statistics_general { | ||
2804 | __le32 temperature; | ||
2805 | struct statistics_dbg dbg; | ||
2806 | __le32 sleep_time; | ||
2807 | __le32 slots_out; | ||
2808 | __le32 slots_idle; | ||
2809 | __le32 ttl_timestamp; | ||
2810 | struct iwl39_statistics_div div; | ||
2811 | } __attribute__ ((packed)); | ||
2812 | |||
2385 | struct statistics_rx_phy { | 2813 | struct statistics_rx_phy { |
2386 | __le32 ina_cnt; | 2814 | __le32 ina_cnt; |
2387 | __le32 fina_cnt; | 2815 | __le32 fina_cnt; |
@@ -2493,11 +2921,6 @@ struct statistics_tx { | |||
2493 | struct statistics_tx_non_phy_agg agg; | 2921 | struct statistics_tx_non_phy_agg agg; |
2494 | } __attribute__ ((packed)); | 2922 | } __attribute__ ((packed)); |
2495 | 2923 | ||
2496 | struct statistics_dbg { | ||
2497 | __le32 burst_check; | ||
2498 | __le32 burst_count; | ||
2499 | __le32 reserved[4]; | ||
2500 | } __attribute__ ((packed)); | ||
2501 | 2924 | ||
2502 | struct statistics_div { | 2925 | struct statistics_div { |
2503 | __le32 tx_on_a; | 2926 | __le32 tx_on_a; |
@@ -2561,6 +2984,14 @@ struct iwl_statistics_cmd { | |||
2561 | */ | 2984 | */ |
2562 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) | 2985 | #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2) |
2563 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8) | 2986 | #define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8) |
2987 | |||
2988 | struct iwl3945_notif_statistics { | ||
2989 | __le32 flag; | ||
2990 | struct iwl39_statistics_rx rx; | ||
2991 | struct iwl39_statistics_tx tx; | ||
2992 | struct iwl39_statistics_general general; | ||
2993 | } __attribute__ ((packed)); | ||
2994 | |||
2564 | struct iwl_notif_statistics { | 2995 | struct iwl_notif_statistics { |
2565 | __le32 flag; | 2996 | __le32 flag; |
2566 | struct statistics_rx rx; | 2997 | struct statistics_rx rx; |
@@ -3012,6 +3443,10 @@ struct iwl_rx_packet { | |||
3012 | __le32 len; | 3443 | __le32 len; |
3013 | struct iwl_cmd_header hdr; | 3444 | struct iwl_cmd_header hdr; |
3014 | union { | 3445 | union { |
3446 | struct iwl3945_rx_frame rx_frame; | ||
3447 | struct iwl3945_tx_resp tx_resp; | ||
3448 | struct iwl3945_beacon_notif beacon_status; | ||
3449 | |||
3015 | struct iwl_alive_resp alive_frame; | 3450 | struct iwl_alive_resp alive_frame; |
3016 | struct iwl_spectrum_notification spectrum_notif; | 3451 | struct iwl_spectrum_notification spectrum_notif; |
3017 | struct iwl_csa_notification csa_notif; | 3452 | struct iwl_csa_notification csa_notif; |
@@ -3029,6 +3464,6 @@ struct iwl_rx_packet { | |||
3029 | } u; | 3464 | } u; |
3030 | } __attribute__ ((packed)); | 3465 | } __attribute__ ((packed)); |
3031 | 3466 | ||
3032 | int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon); | 3467 | int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); |
3033 | 3468 | ||
3034 | #endif /* __iwl_commands_h__ */ | 3469 | #endif /* __iwl_commands_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 73d7973707eb..21f386568c9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -170,7 +170,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, | |||
170 | struct ieee80211_hw *hw = | 170 | struct ieee80211_hw *hw = |
171 | ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops); | 171 | ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops); |
172 | if (hw == NULL) { | 172 | if (hw == NULL) { |
173 | IWL_ERROR("Can not allocate network device\n"); | 173 | printk(KERN_ERR "%s: Can not allocate network device\n", |
174 | cfg->name); | ||
174 | goto out; | 175 | goto out; |
175 | } | 176 | } |
176 | 177 | ||
@@ -210,7 +211,7 @@ int iwl_hw_nic_init(struct iwl_priv *priv) | |||
210 | if (!rxq->bd) { | 211 | if (!rxq->bd) { |
211 | ret = iwl_rx_queue_alloc(priv); | 212 | ret = iwl_rx_queue_alloc(priv); |
212 | if (ret) { | 213 | if (ret) { |
213 | IWL_ERROR("Unable to initialize Rx queue\n"); | 214 | IWL_ERR(priv, "Unable to initialize Rx queue\n"); |
214 | return -ENOMEM; | 215 | return -ENOMEM; |
215 | } | 216 | } |
216 | } else | 217 | } else |
@@ -405,7 +406,7 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv, | |||
405 | /** | 406 | /** |
406 | * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom | 407 | * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom |
407 | */ | 408 | */ |
408 | static int iwlcore_init_geos(struct iwl_priv *priv) | 409 | int iwlcore_init_geos(struct iwl_priv *priv) |
409 | { | 410 | { |
410 | struct iwl_channel_info *ch; | 411 | struct iwl_channel_info *ch; |
411 | struct ieee80211_supported_band *sband; | 412 | struct ieee80211_supported_band *sband; |
@@ -457,8 +458,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
457 | priv->ieee_channels = channels; | 458 | priv->ieee_channels = channels; |
458 | priv->ieee_rates = rates; | 459 | priv->ieee_rates = rates; |
459 | 460 | ||
460 | iwlcore_init_hw_rates(priv, rates); | ||
461 | |||
462 | for (i = 0; i < priv->channel_count; i++) { | 461 | for (i = 0; i < priv->channel_count; i++) { |
463 | ch = &priv->channel_info[i]; | 462 | ch = &priv->channel_info[i]; |
464 | 463 | ||
@@ -510,33 +509,33 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
510 | 509 | ||
511 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 510 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
512 | priv->cfg->sku & IWL_SKU_A) { | 511 | priv->cfg->sku & IWL_SKU_A) { |
513 | printk(KERN_INFO DRV_NAME | 512 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
514 | ": Incorrectly detected BG card as ABG. Please send " | 513 | "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n", |
515 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 514 | priv->pci_dev->device, |
516 | priv->pci_dev->device, priv->pci_dev->subsystem_device); | 515 | priv->pci_dev->subsystem_device); |
517 | priv->cfg->sku &= ~IWL_SKU_A; | 516 | priv->cfg->sku &= ~IWL_SKU_A; |
518 | } | 517 | } |
519 | 518 | ||
520 | printk(KERN_INFO DRV_NAME | 519 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
521 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 520 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
522 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | 521 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); |
523 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
524 | |||
525 | 522 | ||
526 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 523 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
527 | 524 | ||
528 | return 0; | 525 | return 0; |
529 | } | 526 | } |
527 | EXPORT_SYMBOL(iwlcore_init_geos); | ||
530 | 528 | ||
531 | /* | 529 | /* |
532 | * iwlcore_free_geos - undo allocations in iwlcore_init_geos | 530 | * iwlcore_free_geos - undo allocations in iwlcore_init_geos |
533 | */ | 531 | */ |
534 | static void iwlcore_free_geos(struct iwl_priv *priv) | 532 | void iwlcore_free_geos(struct iwl_priv *priv) |
535 | { | 533 | { |
536 | kfree(priv->ieee_channels); | 534 | kfree(priv->ieee_channels); |
537 | kfree(priv->ieee_rates); | 535 | kfree(priv->ieee_rates); |
538 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 536 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
539 | } | 537 | } |
538 | EXPORT_SYMBOL(iwlcore_free_geos); | ||
540 | 539 | ||
541 | static bool is_single_rx_stream(struct iwl_priv *priv) | 540 | static bool is_single_rx_stream(struct iwl_priv *priv) |
542 | { | 541 | { |
@@ -679,7 +678,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) | |||
679 | break; | 678 | break; |
680 | case WLAN_HT_CAP_SM_PS_INVALID: | 679 | case WLAN_HT_CAP_SM_PS_INVALID: |
681 | default: | 680 | default: |
682 | IWL_ERROR("invalid mimo ps mode %d\n", | 681 | IWL_ERR(priv, "invalid mimo ps mode %d\n", |
683 | priv->current_ht_config.sm_ps); | 682 | priv->current_ht_config.sm_ps); |
684 | WARN_ON(1); | 683 | WARN_ON(1); |
685 | idle_cnt = -1; | 684 | idle_cnt = -1; |
@@ -700,6 +699,18 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap) | |||
700 | } | 699 | } |
701 | 700 | ||
702 | /** | 701 | /** |
702 | * iwl_is_monitor_mode - Determine if interface in monitor mode | ||
703 | * | ||
704 | * priv->iw_mode is set in add_interface, but add_interface is | ||
705 | * never called for monitor mode. The only way mac80211 informs us about | ||
706 | * monitor mode is through configuring filters (call to configure_filter). | ||
707 | */ | ||
708 | static bool iwl_is_monitor_mode(struct iwl_priv *priv) | ||
709 | { | ||
710 | return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK); | ||
711 | } | ||
712 | |||
713 | /** | ||
703 | * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image | 714 | * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image |
704 | * | 715 | * |
705 | * Selects how many and which Rx receivers/antennas/chains to use. | 716 | * Selects how many and which Rx receivers/antennas/chains to use. |
@@ -742,6 +753,19 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) | |||
742 | rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; | 753 | rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; |
743 | rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; | 754 | rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; |
744 | 755 | ||
756 | /* copied from 'iwl_bg_request_scan()' */ | ||
757 | /* Force use of chains B and C (0x6) for Rx for 4965 | ||
758 | * Avoid A (0x1) because of its off-channel reception on A-band. | ||
759 | * MIMO is not used here, but value is required */ | ||
760 | if (iwl_is_monitor_mode(priv) && | ||
761 | !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) && | ||
762 | ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) { | ||
763 | rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS; | ||
764 | rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS; | ||
765 | rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; | ||
766 | rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS; | ||
767 | } | ||
768 | |||
745 | priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); | 769 | priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); |
746 | 770 | ||
747 | if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) | 771 | if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) |
@@ -806,12 +830,13 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
806 | /* Tell mac80211 our characteristics */ | 830 | /* Tell mac80211 our characteristics */ |
807 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 831 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
808 | IEEE80211_HW_NOISE_DBM | | 832 | IEEE80211_HW_NOISE_DBM | |
809 | IEEE80211_HW_AMPDU_AGGREGATION; | 833 | IEEE80211_HW_AMPDU_AGGREGATION | |
834 | IEEE80211_HW_SUPPORTS_PS; | ||
810 | hw->wiphy->interface_modes = | 835 | hw->wiphy->interface_modes = |
811 | BIT(NL80211_IFTYPE_STATION) | | 836 | BIT(NL80211_IFTYPE_STATION) | |
812 | BIT(NL80211_IFTYPE_ADHOC); | 837 | BIT(NL80211_IFTYPE_ADHOC); |
813 | 838 | ||
814 | hw->wiphy->fw_handles_regulatory = true; | 839 | hw->wiphy->custom_regulatory = true; |
815 | 840 | ||
816 | /* Default value; 4 EDCA QOS priorities */ | 841 | /* Default value; 4 EDCA QOS priorities */ |
817 | hw->queues = 4; | 842 | hw->queues = 4; |
@@ -831,7 +856,7 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
831 | 856 | ||
832 | ret = ieee80211_register_hw(priv->hw); | 857 | ret = ieee80211_register_hw(priv->hw); |
833 | if (ret) { | 858 | if (ret) { |
834 | IWL_ERROR("Failed to register hw (error %d)\n", ret); | 859 | IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); |
835 | return ret; | 860 | return ret; |
836 | } | 861 | } |
837 | priv->mac80211_registered = 1; | 862 | priv->mac80211_registered = 1; |
@@ -863,7 +888,6 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
863 | { | 888 | { |
864 | int ret; | 889 | int ret; |
865 | 890 | ||
866 | priv->retry_rate = 1; | ||
867 | priv->ibss_beacon = NULL; | 891 | priv->ibss_beacon = NULL; |
868 | 892 | ||
869 | spin_lock_init(&priv->lock); | 893 | spin_lock_init(&priv->lock); |
@@ -903,15 +927,16 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
903 | 927 | ||
904 | ret = iwl_init_channel_map(priv); | 928 | ret = iwl_init_channel_map(priv); |
905 | if (ret) { | 929 | if (ret) { |
906 | IWL_ERROR("initializing regulatory failed: %d\n", ret); | 930 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); |
907 | goto err; | 931 | goto err; |
908 | } | 932 | } |
909 | 933 | ||
910 | ret = iwlcore_init_geos(priv); | 934 | ret = iwlcore_init_geos(priv); |
911 | if (ret) { | 935 | if (ret) { |
912 | IWL_ERROR("initializing geos failed: %d\n", ret); | 936 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); |
913 | goto err_free_channel_map; | 937 | goto err_free_channel_map; |
914 | } | 938 | } |
939 | iwlcore_init_hw_rates(priv, priv->ieee_rates); | ||
915 | 940 | ||
916 | return 0; | 941 | return 0; |
917 | 942 | ||
@@ -926,13 +951,13 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
926 | { | 951 | { |
927 | int ret = 0; | 952 | int ret = 0; |
928 | if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) { | 953 | if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) { |
929 | IWL_WARNING("Requested user TXPOWER %d below limit.\n", | 954 | IWL_WARN(priv, "Requested user TXPOWER %d below limit.\n", |
930 | priv->tx_power_user_lmt); | 955 | priv->tx_power_user_lmt); |
931 | return -EINVAL; | 956 | return -EINVAL; |
932 | } | 957 | } |
933 | 958 | ||
934 | if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) { | 959 | if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) { |
935 | IWL_WARNING("Requested user TXPOWER %d above limit.\n", | 960 | IWL_WARN(priv, "Requested user TXPOWER %d above limit.\n", |
936 | priv->tx_power_user_lmt); | 961 | priv->tx_power_user_lmt); |
937 | return -EINVAL; | 962 | return -EINVAL; |
938 | } | 963 | } |
@@ -982,6 +1007,21 @@ void iwl_enable_interrupts(struct iwl_priv *priv) | |||
982 | } | 1007 | } |
983 | EXPORT_SYMBOL(iwl_enable_interrupts); | 1008 | EXPORT_SYMBOL(iwl_enable_interrupts); |
984 | 1009 | ||
1010 | int iwl_send_bt_config(struct iwl_priv *priv) | ||
1011 | { | ||
1012 | struct iwl_bt_cmd bt_cmd = { | ||
1013 | .flags = 3, | ||
1014 | .lead_time = 0xAA, | ||
1015 | .max_kill = 1, | ||
1016 | .kill_ack_mask = 0, | ||
1017 | .kill_cts_mask = 0, | ||
1018 | }; | ||
1019 | |||
1020 | return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, | ||
1021 | sizeof(struct iwl_bt_cmd), &bt_cmd); | ||
1022 | } | ||
1023 | EXPORT_SYMBOL(iwl_send_bt_config); | ||
1024 | |||
985 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) | 1025 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) |
986 | { | 1026 | { |
987 | u32 stat_flags = 0; | 1027 | u32 stat_flags = 0; |
@@ -1018,7 +1058,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 | |||
1018 | /* NOTE: Use the debugless read so we don't flood kernel log | 1058 | /* NOTE: Use the debugless read so we don't flood kernel log |
1019 | * if IWL_DL_IO is set */ | 1059 | * if IWL_DL_IO is set */ |
1020 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, | 1060 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
1021 | i + RTC_INST_LOWER_BOUND); | 1061 | i + IWL49_RTC_INST_LOWER_BOUND); |
1022 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1062 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1023 | if (val != le32_to_cpu(*image)) { | 1063 | if (val != le32_to_cpu(*image)) { |
1024 | ret = -EIO; | 1064 | ret = -EIO; |
@@ -1051,7 +1091,8 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image, | |||
1051 | if (ret) | 1091 | if (ret) |
1052 | return ret; | 1092 | return ret; |
1053 | 1093 | ||
1054 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); | 1094 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
1095 | IWL49_RTC_INST_LOWER_BOUND); | ||
1055 | 1096 | ||
1056 | errcnt = 0; | 1097 | errcnt = 0; |
1057 | for (; len > 0; len -= sizeof(u32), image++) { | 1098 | for (; len > 0; len -= sizeof(u32), image++) { |
@@ -1060,7 +1101,7 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image, | |||
1060 | * if IWL_DL_IO is set */ | 1101 | * if IWL_DL_IO is set */ |
1061 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 1102 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
1062 | if (val != le32_to_cpu(*image)) { | 1103 | if (val != le32_to_cpu(*image)) { |
1063 | IWL_ERROR("uCode INST section is invalid at " | 1104 | IWL_ERR(priv, "uCode INST section is invalid at " |
1064 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 1105 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
1065 | save_len - len, val, le32_to_cpu(*image)); | 1106 | save_len - len, val, le32_to_cpu(*image)); |
1066 | ret = -EIO; | 1107 | ret = -EIO; |
@@ -1116,7 +1157,7 @@ int iwl_verify_ucode(struct iwl_priv *priv) | |||
1116 | return 0; | 1157 | return 0; |
1117 | } | 1158 | } |
1118 | 1159 | ||
1119 | IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); | 1160 | IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); |
1120 | 1161 | ||
1121 | /* Since nothing seems to match, show first several data entries in | 1162 | /* Since nothing seems to match, show first several data entries in |
1122 | * instruction SRAM, so maybe visual inspection will give a clue. | 1163 | * instruction SRAM, so maybe visual inspection will give a clue. |
@@ -1188,21 +1229,22 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1188 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); | 1229 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); |
1189 | 1230 | ||
1190 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 1231 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
1191 | IWL_ERROR("Not valid error log pointer 0x%08X\n", base); | 1232 | IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); |
1192 | return; | 1233 | return; |
1193 | } | 1234 | } |
1194 | 1235 | ||
1195 | ret = iwl_grab_nic_access(priv); | 1236 | ret = iwl_grab_nic_access(priv); |
1196 | if (ret) { | 1237 | if (ret) { |
1197 | IWL_WARNING("Can not read from adapter at this time.\n"); | 1238 | IWL_WARN(priv, "Can not read from adapter at this time.\n"); |
1198 | return; | 1239 | return; |
1199 | } | 1240 | } |
1200 | 1241 | ||
1201 | count = iwl_read_targ_mem(priv, base); | 1242 | count = iwl_read_targ_mem(priv, base); |
1202 | 1243 | ||
1203 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { | 1244 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { |
1204 | IWL_ERROR("Start IWL Error Log Dump:\n"); | 1245 | IWL_ERR(priv, "Start IWL Error Log Dump:\n"); |
1205 | IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count); | 1246 | IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", |
1247 | priv->status, count); | ||
1206 | } | 1248 | } |
1207 | 1249 | ||
1208 | desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); | 1250 | desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); |
@@ -1215,12 +1257,12 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1215 | line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); | 1257 | line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); |
1216 | time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); | 1258 | time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); |
1217 | 1259 | ||
1218 | IWL_ERROR("Desc Time " | 1260 | IWL_ERR(priv, "Desc Time " |
1219 | "data1 data2 line\n"); | 1261 | "data1 data2 line\n"); |
1220 | IWL_ERROR("%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", | 1262 | IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n", |
1221 | desc_lookup(desc), desc, time, data1, data2, line); | 1263 | desc_lookup(desc), desc, time, data1, data2, line); |
1222 | IWL_ERROR("blink1 blink2 ilink1 ilink2\n"); | 1264 | IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n"); |
1223 | IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2, | 1265 | IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2, |
1224 | ilink1, ilink2); | 1266 | ilink1, ilink2); |
1225 | 1267 | ||
1226 | iwl_release_nic_access(priv); | 1268 | iwl_release_nic_access(priv); |
@@ -1266,11 +1308,11 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1266 | ptr += sizeof(u32); | 1308 | ptr += sizeof(u32); |
1267 | if (mode == 0) { | 1309 | if (mode == 0) { |
1268 | /* data, ev */ | 1310 | /* data, ev */ |
1269 | IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev); | 1311 | IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); |
1270 | } else { | 1312 | } else { |
1271 | data = iwl_read_targ_mem(priv, ptr); | 1313 | data = iwl_read_targ_mem(priv, ptr); |
1272 | ptr += sizeof(u32); | 1314 | ptr += sizeof(u32); |
1273 | IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n", | 1315 | IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", |
1274 | time, data, ev); | 1316 | time, data, ev); |
1275 | } | 1317 | } |
1276 | } | 1318 | } |
@@ -1292,13 +1334,13 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1292 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 1334 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
1293 | 1335 | ||
1294 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | 1336 | if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { |
1295 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); | 1337 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); |
1296 | return; | 1338 | return; |
1297 | } | 1339 | } |
1298 | 1340 | ||
1299 | ret = iwl_grab_nic_access(priv); | 1341 | ret = iwl_grab_nic_access(priv); |
1300 | if (ret) { | 1342 | if (ret) { |
1301 | IWL_WARNING("Can not read from adapter at this time.\n"); | 1343 | IWL_WARN(priv, "Can not read from adapter at this time.\n"); |
1302 | return; | 1344 | return; |
1303 | } | 1345 | } |
1304 | 1346 | ||
@@ -1312,12 +1354,12 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1312 | 1354 | ||
1313 | /* bail out if nothing in log */ | 1355 | /* bail out if nothing in log */ |
1314 | if (size == 0) { | 1356 | if (size == 0) { |
1315 | IWL_ERROR("Start IWL Event Log Dump: nothing in log\n"); | 1357 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); |
1316 | iwl_release_nic_access(priv); | 1358 | iwl_release_nic_access(priv); |
1317 | return; | 1359 | return; |
1318 | } | 1360 | } |
1319 | 1361 | ||
1320 | IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n", | 1362 | IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", |
1321 | size, num_wraps); | 1363 | size, num_wraps); |
1322 | 1364 | ||
1323 | /* if uCode has wrapped back to top of log, start at the oldest entry, | 1365 | /* if uCode has wrapped back to top of log, start at the oldest entry, |
@@ -1349,7 +1391,7 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
1349 | ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, | 1391 | ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, |
1350 | sizeof(cmd), &cmd); | 1392 | sizeof(cmd), &cmd); |
1351 | if (ret) | 1393 | if (ret) |
1352 | IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n"); | 1394 | IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); |
1353 | else | 1395 | else |
1354 | IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, " | 1396 | IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, " |
1355 | "critical temperature is %d\n", | 1397 | "critical temperature is %d\n", |
@@ -1368,7 +1410,7 @@ EXPORT_SYMBOL(iwl_rf_kill_ct_config); | |||
1368 | * When in the 'halt' state, the card is shut down and must be fully | 1410 | * When in the 'halt' state, the card is shut down and must be fully |
1369 | * restarted to come back on. | 1411 | * restarted to come back on. |
1370 | */ | 1412 | */ |
1371 | static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | 1413 | int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) |
1372 | { | 1414 | { |
1373 | struct iwl_host_cmd cmd = { | 1415 | struct iwl_host_cmd cmd = { |
1374 | .id = REPLY_CARD_STATE_CMD, | 1416 | .id = REPLY_CARD_STATE_CMD, |
@@ -1379,6 +1421,7 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | |||
1379 | 1421 | ||
1380 | return iwl_send_cmd(priv, &cmd); | 1422 | return iwl_send_cmd(priv, &cmd); |
1381 | } | 1423 | } |
1424 | EXPORT_SYMBOL(iwl_send_card_state); | ||
1382 | 1425 | ||
1383 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) | 1426 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) |
1384 | { | 1427 | { |
@@ -1463,3 +1506,39 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) | |||
1463 | return 1; | 1506 | return 1; |
1464 | } | 1507 | } |
1465 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); | 1508 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); |
1509 | |||
1510 | void iwl_bg_rf_kill(struct work_struct *work) | ||
1511 | { | ||
1512 | struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); | ||
1513 | |||
1514 | wake_up_interruptible(&priv->wait_command_queue); | ||
1515 | |||
1516 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
1517 | return; | ||
1518 | |||
1519 | mutex_lock(&priv->mutex); | ||
1520 | |||
1521 | if (!iwl_is_rfkill(priv)) { | ||
1522 | IWL_DEBUG(IWL_DL_RF_KILL, | ||
1523 | "HW and/or SW RF Kill no longer active, restarting " | ||
1524 | "device\n"); | ||
1525 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && | ||
1526 | test_bit(STATUS_ALIVE, &priv->status)) | ||
1527 | queue_work(priv->workqueue, &priv->restart); | ||
1528 | } else { | ||
1529 | /* make sure mac80211 stop sending Tx frame */ | ||
1530 | if (priv->mac80211_registered) | ||
1531 | ieee80211_stop_queues(priv->hw); | ||
1532 | |||
1533 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | ||
1534 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " | ||
1535 | "disabled by SW switch\n"); | ||
1536 | else | ||
1537 | IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n" | ||
1538 | "Kill switch must be turned off for " | ||
1539 | "wireless networking to work.\n"); | ||
1540 | } | ||
1541 | mutex_unlock(&priv->mutex); | ||
1542 | iwl_rfkill_set_hw_state(priv); | ||
1543 | } | ||
1544 | EXPORT_SYMBOL(iwl_bg_rf_kill); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7c3a20a986bb..3c6a4b0c2c3b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -71,7 +71,7 @@ struct iwl_cmd; | |||
71 | 71 | ||
72 | 72 | ||
73 | #define IWLWIFI_VERSION "1.3.27k" | 73 | #define IWLWIFI_VERSION "1.3.27k" |
74 | #define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation" | 74 | #define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" |
75 | #define DRV_AUTHOR "<ilw@linux.intel.com>" | 75 | #define DRV_AUTHOR "<ilw@linux.intel.com>" |
76 | 76 | ||
77 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | 77 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ |
@@ -110,6 +110,14 @@ struct iwl_lib_ops { | |||
110 | void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv, | 110 | void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv, |
111 | struct iwl_tx_queue *txq); | 111 | struct iwl_tx_queue *txq); |
112 | void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); | 112 | void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); |
113 | int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv, | ||
114 | struct iwl_tx_queue *txq, | ||
115 | dma_addr_t addr, | ||
116 | u16 len, u8 reset, u8 pad); | ||
117 | void (*txq_free_tfd)(struct iwl_priv *priv, | ||
118 | struct iwl_tx_queue *txq); | ||
119 | int (*txq_init)(struct iwl_priv *priv, | ||
120 | struct iwl_tx_queue *txq); | ||
113 | /* aggregations */ | 121 | /* aggregations */ |
114 | int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo, | 122 | int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo, |
115 | int sta_id, int tid, u16 ssn_idx); | 123 | int sta_id, int tid, u16 ssn_idx); |
@@ -252,9 +260,18 @@ void iwl_rx_statistics(struct iwl_priv *priv, | |||
252 | * TX | 260 | * TX |
253 | ******************************************************/ | 261 | ******************************************************/ |
254 | int iwl_txq_ctx_reset(struct iwl_priv *priv); | 262 | int iwl_txq_ctx_reset(struct iwl_priv *priv); |
263 | void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); | ||
264 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | ||
265 | struct iwl_tx_queue *txq, | ||
266 | dma_addr_t addr, u16 len, u8 reset, u8 pad); | ||
255 | int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); | 267 | int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); |
256 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv); | 268 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv); |
269 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | ||
270 | struct iwl_tx_queue *txq); | ||
257 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 271 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
272 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | ||
273 | int slots_num, u32 txq_id); | ||
274 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); | ||
258 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); | 275 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); |
259 | int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); | 276 | int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); |
260 | int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); | 277 | int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); |
@@ -267,7 +284,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); | |||
267 | * RF -Kill - here and not in iwl-rfkill.h to be available when | 284 | * RF -Kill - here and not in iwl-rfkill.h to be available when |
268 | * RF-kill subsystem is not compiled. | 285 | * RF-kill subsystem is not compiled. |
269 | ****************************************************/ | 286 | ****************************************************/ |
270 | void iwl_rf_kill(struct iwl_priv *priv); | 287 | void iwl_bg_rf_kill(struct work_struct *work); |
271 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); | 288 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); |
272 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); | 289 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); |
273 | 290 | ||
@@ -306,8 +323,29 @@ void iwl_init_scan_params(struct iwl_priv *priv); | |||
306 | int iwl_scan_cancel(struct iwl_priv *priv); | 323 | int iwl_scan_cancel(struct iwl_priv *priv); |
307 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | 324 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); |
308 | int iwl_scan_initiate(struct iwl_priv *priv); | 325 | int iwl_scan_initiate(struct iwl_priv *priv); |
326 | u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band, | ||
327 | struct ieee80211_mgmt *frame, int left); | ||
309 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | 328 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); |
329 | u16 iwl_get_active_dwell_time(struct iwl_priv *priv, | ||
330 | enum ieee80211_band band, | ||
331 | u8 n_probes); | ||
332 | u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | ||
333 | enum ieee80211_band band); | ||
334 | void iwl_bg_scan_check(struct work_struct *data); | ||
335 | void iwl_bg_abort_scan(struct work_struct *work); | ||
336 | void iwl_bg_scan_completed(struct work_struct *work); | ||
310 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); | 337 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); |
338 | int iwl_send_scan_abort(struct iwl_priv *priv); | ||
339 | |||
340 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
341 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
342 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
343 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
344 | * no other traffic). | ||
345 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
346 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */ | ||
347 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | ||
348 | |||
311 | 349 | ||
312 | /******************************************************************************* | 350 | /******************************************************************************* |
313 | * Calibrations - implemented in iwl-calib.c | 351 | * Calibrations - implemented in iwl-calib.c |
@@ -342,6 +380,9 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, | |||
342 | 380 | ||
343 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 381 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); |
344 | 382 | ||
383 | int iwl_send_card_state(struct iwl_priv *priv, u32 flags, | ||
384 | u8 meta_flag); | ||
385 | |||
345 | /***************************************************** | 386 | /***************************************************** |
346 | * PCI * | 387 | * PCI * |
347 | *****************************************************/ | 388 | *****************************************************/ |
@@ -354,6 +395,11 @@ void iwl_enable_interrupts(struct iwl_priv *priv); | |||
354 | void iwl_dump_nic_error_log(struct iwl_priv *priv); | 395 | void iwl_dump_nic_error_log(struct iwl_priv *priv); |
355 | void iwl_dump_nic_event_log(struct iwl_priv *priv); | 396 | void iwl_dump_nic_event_log(struct iwl_priv *priv); |
356 | 397 | ||
398 | /***************************************************** | ||
399 | * GEOS | ||
400 | ******************************************************/ | ||
401 | int iwlcore_init_geos(struct iwl_priv *priv); | ||
402 | void iwlcore_free_geos(struct iwl_priv *priv); | ||
357 | 403 | ||
358 | /*************** DRIVER STATUS FUNCTIONS *****/ | 404 | /*************** DRIVER STATUS FUNCTIONS *****/ |
359 | 405 | ||
@@ -422,6 +468,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) | |||
422 | } | 468 | } |
423 | 469 | ||
424 | extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); | 470 | extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); |
471 | extern int iwl_send_bt_config(struct iwl_priv *priv); | ||
425 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); | 472 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); |
426 | extern int iwl_verify_ucode(struct iwl_priv *priv); | 473 | extern int iwl_verify_ucode(struct iwl_priv *priv); |
427 | extern int iwl_send_lq_cmd(struct iwl_priv *priv, | 474 | extern int iwl_send_lq_cmd(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index f34ede44ed10..74d3d43fa67d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 56c13b458de7..7192d3249caf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project. | 5 | * Portions of this file are derived from the ipw3945 project. |
6 | * | 6 | * |
@@ -29,16 +29,27 @@ | |||
29 | #ifndef __iwl_debug_h__ | 29 | #ifndef __iwl_debug_h__ |
30 | #define __iwl_debug_h__ | 30 | #define __iwl_debug_h__ |
31 | 31 | ||
32 | struct iwl_priv; | ||
33 | |||
34 | #define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a) | ||
35 | #define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a) | ||
36 | #define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a) | ||
37 | #define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a) | ||
38 | |||
32 | #ifdef CONFIG_IWLWIFI_DEBUG | 39 | #ifdef CONFIG_IWLWIFI_DEBUG |
33 | #define IWL_DEBUG(level, fmt, args...) \ | 40 | #define IWL_DEBUG(level, fmt, args...) \ |
34 | do { if (priv->debug_level & (level)) \ | 41 | do { \ |
35 | dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ | 42 | if (priv->debug_level & (level)) \ |
36 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) | 43 | dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ |
44 | in_interrupt() ? 'I' : 'U', __func__ , ## args); \ | ||
45 | } while (0) | ||
37 | 46 | ||
38 | #define IWL_DEBUG_LIMIT(level, fmt, args...) \ | 47 | #define IWL_DEBUG_LIMIT(level, fmt, args...) \ |
39 | do { if ((priv->debug_level & (level)) && net_ratelimit()) \ | 48 | do { \ |
40 | dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ | 49 | if ((priv->debug_level & (level)) && net_ratelimit()) \ |
41 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) | 50 | dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ |
51 | in_interrupt() ? 'I' : 'U', __func__ , ## args); \ | ||
52 | } while (0) | ||
42 | 53 | ||
43 | #define iwl_print_hex_dump(priv, level, p, len) \ | 54 | #define iwl_print_hex_dump(priv, level, p, len) \ |
44 | do { \ | 55 | do { \ |
@@ -61,6 +72,7 @@ struct iwl_debugfs { | |||
61 | struct dentry *file_tx_statistics; | 72 | struct dentry *file_tx_statistics; |
62 | struct dentry *file_log_event; | 73 | struct dentry *file_log_event; |
63 | struct dentry *file_channels; | 74 | struct dentry *file_channels; |
75 | struct dentry *file_status; | ||
64 | } dbgfs_data_files; | 76 | } dbgfs_data_files; |
65 | struct dir_rf_files { | 77 | struct dir_rf_files { |
66 | struct dentry *file_disable_sensitivity; | 78 | struct dentry *file_disable_sensitivity; |
@@ -117,84 +129,82 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
117 | * when CONFIG_IWLWIFI_DEBUG=y. | 129 | * when CONFIG_IWLWIFI_DEBUG=y. |
118 | */ | 130 | */ |
119 | 131 | ||
132 | /* 0x0000000F - 0x00000001 */ | ||
120 | #define IWL_DL_INFO (1 << 0) | 133 | #define IWL_DL_INFO (1 << 0) |
121 | #define IWL_DL_MAC80211 (1 << 1) | 134 | #define IWL_DL_MAC80211 (1 << 1) |
122 | #define IWL_DL_HCMD (1 << 2) | 135 | #define IWL_DL_HCMD (1 << 2) |
123 | #define IWL_DL_STATE (1 << 3) | 136 | #define IWL_DL_STATE (1 << 3) |
137 | /* 0x000000F0 - 0x00000010 */ | ||
124 | #define IWL_DL_MACDUMP (1 << 4) | 138 | #define IWL_DL_MACDUMP (1 << 4) |
125 | #define IWL_DL_HCMD_DUMP (1 << 5) | 139 | #define IWL_DL_HCMD_DUMP (1 << 5) |
126 | #define IWL_DL_RADIO (1 << 7) | 140 | #define IWL_DL_RADIO (1 << 7) |
127 | #define IWL_DL_POWER (1 << 8) | 141 | /* 0x00000F00 - 0x00000100 */ |
128 | #define IWL_DL_TEMP (1 << 9) | 142 | #define IWL_DL_POWER (1 << 8) |
129 | 143 | #define IWL_DL_TEMP (1 << 9) | |
130 | #define IWL_DL_NOTIF (1 << 10) | 144 | #define IWL_DL_NOTIF (1 << 10) |
131 | #define IWL_DL_SCAN (1 << 11) | 145 | #define IWL_DL_SCAN (1 << 11) |
132 | #define IWL_DL_ASSOC (1 << 12) | 146 | /* 0x0000F000 - 0x00001000 */ |
133 | #define IWL_DL_DROP (1 << 13) | 147 | #define IWL_DL_ASSOC (1 << 12) |
134 | 148 | #define IWL_DL_DROP (1 << 13) | |
135 | #define IWL_DL_TXPOWER (1 << 14) | 149 | #define IWL_DL_TXPOWER (1 << 14) |
136 | 150 | #define IWL_DL_AP (1 << 15) | |
137 | #define IWL_DL_AP (1 << 15) | 151 | /* 0x000F0000 - 0x00010000 */ |
138 | 152 | #define IWL_DL_FW (1 << 16) | |
139 | #define IWL_DL_FW (1 << 16) | 153 | #define IWL_DL_RF_KILL (1 << 17) |
140 | #define IWL_DL_RF_KILL (1 << 17) | 154 | #define IWL_DL_FW_ERRORS (1 << 18) |
141 | #define IWL_DL_FW_ERRORS (1 << 18) | 155 | #define IWL_DL_LED (1 << 19) |
142 | 156 | /* 0x00F00000 - 0x00100000 */ | |
143 | #define IWL_DL_LED (1 << 19) | 157 | #define IWL_DL_RATE (1 << 20) |
144 | 158 | #define IWL_DL_CALIB (1 << 21) | |
145 | #define IWL_DL_RATE (1 << 20) | 159 | #define IWL_DL_WEP (1 << 22) |
146 | 160 | #define IWL_DL_TX (1 << 23) | |
147 | #define IWL_DL_CALIB (1 << 21) | 161 | /* 0x0F000000 - 0x01000000 */ |
148 | #define IWL_DL_WEP (1 << 22) | 162 | #define IWL_DL_RX (1 << 24) |
149 | #define IWL_DL_TX (1 << 23) | 163 | #define IWL_DL_ISR (1 << 25) |
150 | #define IWL_DL_RX (1 << 24) | 164 | #define IWL_DL_HT (1 << 26) |
151 | #define IWL_DL_ISR (1 << 25) | 165 | #define IWL_DL_IO (1 << 27) |
152 | #define IWL_DL_HT (1 << 26) | 166 | /* 0xF0000000 - 0x10000000 */ |
153 | #define IWL_DL_IO (1 << 27) | 167 | #define IWL_DL_11H (1 << 28) |
154 | #define IWL_DL_11H (1 << 28) | 168 | #define IWL_DL_STATS (1 << 29) |
155 | 169 | #define IWL_DL_TX_REPLY (1 << 30) | |
156 | #define IWL_DL_STATS (1 << 29) | 170 | #define IWL_DL_QOS (1 << 31) |
157 | #define IWL_DL_TX_REPLY (1 << 30) | 171 | |
158 | #define IWL_DL_QOS (1 << 31) | 172 | #define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a) |
159 | 173 | #define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a) | |
160 | #define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) | 174 | #define IWL_DEBUG_MACDUMP(f, a...) IWL_DEBUG(IWL_DL_MACDUMP, f, ## a) |
161 | #define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) | 175 | #define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a) |
162 | #define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a) | 176 | #define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a) |
163 | 177 | #define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a) | |
164 | #define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a) | 178 | #define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a) |
165 | #define IWL_DEBUG_MACDUMP(f, a...) IWL_DEBUG(IWL_DL_MACDUMP, f, ## a) | 179 | #define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a) |
166 | #define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a) | 180 | #define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a) |
167 | #define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a) | 181 | #define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a) |
168 | #define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a) | 182 | #define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HCMD, f, ## a) |
169 | #define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a) | 183 | #define IWL_DEBUG_HC_DUMP(f, a...) IWL_DEBUG(IWL_DL_HCMD_DUMP, f, ## a) |
170 | #define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a) | 184 | #define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a) |
171 | #define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a) | 185 | #define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a) |
172 | #define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a) | 186 | #define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a) |
173 | #define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HCMD, f, ## a) | 187 | #define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a) |
174 | #define IWL_DEBUG_HC_DUMP(f, a...) IWL_DEBUG(IWL_DL_HCMD_DUMP, f, ## a) | 188 | #define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a) |
175 | #define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a) | 189 | #define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a) |
176 | #define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a) | 190 | #define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a) |
177 | #define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a) | 191 | #define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a) |
178 | #define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a) | 192 | #define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a) |
179 | #define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a) | 193 | #define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a) |
180 | #define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a) | 194 | #define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a) |
181 | #define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a) | 195 | #define IWL_DEBUG_ASSOC(f, a...) \ |
182 | #define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a) | 196 | IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) |
183 | #define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a) | 197 | #define IWL_DEBUG_ASSOC_LIMIT(f, a...) \ |
184 | #define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a) | 198 | IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) |
185 | #define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a) | 199 | #define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a) |
186 | #define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) | 200 | #define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) |
187 | #define IWL_DEBUG_ASSOC_LIMIT(f, a...) \ | 201 | #define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a) |
188 | IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) | 202 | #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) |
189 | #define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a) | ||
190 | #define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) | ||
191 | #define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a) | ||
192 | #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) | ||
193 | #define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \ | 203 | #define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \ |
194 | IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a) | 204 | IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a) |
195 | #define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) | 205 | #define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) |
196 | #define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) | 206 | #define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) |
197 | #define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) | 207 | #define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) |
198 | #define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a) | 208 | #define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a) |
199 | 209 | ||
200 | #endif | 210 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index d5253a179dec..36cfeccfafbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -63,6 +63,14 @@ | |||
63 | goto err; \ | 63 | goto err; \ |
64 | } while (0) | 64 | } while (0) |
65 | 65 | ||
66 | #define DEBUGFS_ADD_X32(name, parent, ptr) do { \ | ||
67 | dbgfs->dbgfs_##parent##_files.file_##name = \ | ||
68 | debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr); \ | ||
69 | if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ | ||
70 | || !dbgfs->dbgfs_##parent##_files.file_##name) \ | ||
71 | goto err; \ | ||
72 | } while (0) | ||
73 | |||
66 | #define DEBUGFS_REMOVE(name) do { \ | 74 | #define DEBUGFS_REMOVE(name) do { \ |
67 | debugfs_remove(name); \ | 75 | debugfs_remove(name); \ |
68 | name = NULL; \ | 76 | name = NULL; \ |
@@ -164,9 +172,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
164 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | 172 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; |
165 | const size_t bufsz = sizeof(buf); | 173 | const size_t bufsz = sizeof(buf); |
166 | 174 | ||
167 | printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n", | ||
168 | priv->dbgfs->sram_offset, priv->dbgfs->sram_len); | ||
169 | |||
170 | iwl_grab_nic_access(priv); | 175 | iwl_grab_nic_access(priv); |
171 | for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { | 176 | for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { |
172 | val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ | 177 | val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ |
@@ -301,14 +306,14 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file, | |||
301 | buf_size = 4 * eeprom_len + 256; | 306 | buf_size = 4 * eeprom_len + 256; |
302 | 307 | ||
303 | if (eeprom_len % 16) { | 308 | if (eeprom_len % 16) { |
304 | IWL_ERROR("EEPROM size is not multiple of 16.\n"); | 309 | IWL_ERR(priv, "EEPROM size is not multiple of 16.\n"); |
305 | return -ENODATA; | 310 | return -ENODATA; |
306 | } | 311 | } |
307 | 312 | ||
308 | /* 4 characters for byte 0xYY */ | 313 | /* 4 characters for byte 0xYY */ |
309 | buf = kzalloc(buf_size, GFP_KERNEL); | 314 | buf = kzalloc(buf_size, GFP_KERNEL); |
310 | if (!buf) { | 315 | if (!buf) { |
311 | IWL_ERROR("Can not allocate Buffer\n"); | 316 | IWL_ERR(priv, "Can not allocate Buffer\n"); |
312 | return -ENOMEM; | 317 | return -ENOMEM; |
313 | } | 318 | } |
314 | 319 | ||
@@ -365,7 +370,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | |||
365 | 370 | ||
366 | buf = kzalloc(bufsz, GFP_KERNEL); | 371 | buf = kzalloc(bufsz, GFP_KERNEL); |
367 | if (!buf) { | 372 | if (!buf) { |
368 | IWL_ERROR("Can not allocate Buffer\n"); | 373 | IWL_ERR(priv, "Can not allocate Buffer\n"); |
369 | return -ENOMEM; | 374 | return -ENOMEM; |
370 | } | 375 | } |
371 | 376 | ||
@@ -420,7 +425,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | |||
420 | return ret; | 425 | return ret; |
421 | } | 426 | } |
422 | 427 | ||
423 | |||
424 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 428 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
425 | DEBUGFS_WRITE_FILE_OPS(log_event); | 429 | DEBUGFS_WRITE_FILE_OPS(log_event); |
426 | DEBUGFS_READ_FILE_OPS(eeprom); | 430 | DEBUGFS_READ_FILE_OPS(eeprom); |
@@ -462,6 +466,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
462 | DEBUGFS_ADD_FILE(rx_statistics, data); | 466 | DEBUGFS_ADD_FILE(rx_statistics, data); |
463 | DEBUGFS_ADD_FILE(tx_statistics, data); | 467 | DEBUGFS_ADD_FILE(tx_statistics, data); |
464 | DEBUGFS_ADD_FILE(channels, data); | 468 | DEBUGFS_ADD_FILE(channels, data); |
469 | DEBUGFS_ADD_X32(status, data, (u32 *)&priv->status); | ||
465 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); | 470 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); |
466 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, | 471 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, |
467 | &priv->disable_chain_noise_cal); | 472 | &priv->disable_chain_noise_cal); |
@@ -469,7 +474,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
469 | return 0; | 474 | return 0; |
470 | 475 | ||
471 | err: | 476 | err: |
472 | IWL_ERROR("Can't open the debugfs directory\n"); | 477 | IWL_ERR(priv, "Can't open the debugfs directory\n"); |
473 | iwl_dbgfs_unregister(priv); | 478 | iwl_dbgfs_unregister(priv); |
474 | return ret; | 479 | return ret; |
475 | } | 480 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0468fcc1ea98..437c05b9a335 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -36,13 +36,15 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <net/ieee80211_radiotap.h> | 37 | #include <net/ieee80211_radiotap.h> |
38 | 38 | ||
39 | #define DRV_NAME "iwlagn" | ||
40 | #include "iwl-rfkill.h" | ||
41 | #include "iwl-eeprom.h" | 39 | #include "iwl-eeprom.h" |
42 | #include "iwl-4965-hw.h" | ||
43 | #include "iwl-csr.h" | 40 | #include "iwl-csr.h" |
44 | #include "iwl-prph.h" | 41 | #include "iwl-prph.h" |
42 | #include "iwl-fh.h" | ||
45 | #include "iwl-debug.h" | 43 | #include "iwl-debug.h" |
44 | #include "iwl-rfkill.h" | ||
45 | #include "iwl-4965-hw.h" | ||
46 | #include "iwl-3945-hw.h" | ||
47 | #include "iwl-3945-led.h" | ||
46 | #include "iwl-led.h" | 48 | #include "iwl-led.h" |
47 | #include "iwl-power.h" | 49 | #include "iwl-power.h" |
48 | #include "iwl-agn-rs.h" | 50 | #include "iwl-agn-rs.h" |
@@ -55,6 +57,16 @@ extern struct iwl_cfg iwl5350_agn_cfg; | |||
55 | extern struct iwl_cfg iwl5100_bg_cfg; | 57 | extern struct iwl_cfg iwl5100_bg_cfg; |
56 | extern struct iwl_cfg iwl5100_abg_cfg; | 58 | extern struct iwl_cfg iwl5100_abg_cfg; |
57 | extern struct iwl_cfg iwl5150_agn_cfg; | 59 | extern struct iwl_cfg iwl5150_agn_cfg; |
60 | extern struct iwl_cfg iwl6000_2ag_cfg; | ||
61 | extern struct iwl_cfg iwl6000_2agn_cfg; | ||
62 | extern struct iwl_cfg iwl6000_3agn_cfg; | ||
63 | extern struct iwl_cfg iwl6050_2agn_cfg; | ||
64 | extern struct iwl_cfg iwl6050_3agn_cfg; | ||
65 | extern struct iwl_cfg iwl100_bgn_cfg; | ||
66 | |||
67 | /* shared structures from iwl-5000.c */ | ||
68 | extern struct iwl_mod_params iwl50_mod_params; | ||
69 | extern struct iwl_ops iwl5000_ops; | ||
58 | 70 | ||
59 | /* CT-KILL constants */ | 71 | /* CT-KILL constants */ |
60 | #define CT_KILL_THRESHOLD 110 /* in Celsius */ | 72 | #define CT_KILL_THRESHOLD 110 /* in Celsius */ |
@@ -132,9 +144,12 @@ struct iwl_tx_info { | |||
132 | * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame | 144 | * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame |
133 | * descriptors) and required locking structures. | 145 | * descriptors) and required locking structures. |
134 | */ | 146 | */ |
147 | #define TFD_TX_CMD_SLOTS 256 | ||
148 | #define TFD_CMD_SLOTS 32 | ||
149 | |||
135 | struct iwl_tx_queue { | 150 | struct iwl_tx_queue { |
136 | struct iwl_queue q; | 151 | struct iwl_queue q; |
137 | struct iwl_tfd *tfds; | 152 | void *tfds; |
138 | struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; | 153 | struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; |
139 | struct iwl_tx_info *txb; | 154 | struct iwl_tx_info *txb; |
140 | u8 need_update; | 155 | u8 need_update; |
@@ -154,6 +169,36 @@ struct iwl4965_channel_tgh_info { | |||
154 | s64 last_radar_time; | 169 | s64 last_radar_time; |
155 | }; | 170 | }; |
156 | 171 | ||
172 | #define IWL4965_MAX_RATE (33) | ||
173 | |||
174 | struct iwl3945_clip_group { | ||
175 | /* maximum power level to prevent clipping for each rate, derived by | ||
176 | * us from this band's saturation power in EEPROM */ | ||
177 | const s8 clip_powers[IWL_MAX_RATES]; | ||
178 | }; | ||
179 | |||
180 | /* current Tx power values to use, one for each rate for each channel. | ||
181 | * requested power is limited by: | ||
182 | * -- regulatory EEPROM limits for this channel | ||
183 | * -- hardware capabilities (clip-powers) | ||
184 | * -- spectrum management | ||
185 | * -- user preference (e.g. iwconfig) | ||
186 | * when requested power is set, base power index must also be set. */ | ||
187 | struct iwl3945_channel_power_info { | ||
188 | struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ | ||
189 | s8 power_table_index; /* actual (compenst'd) index into gain table */ | ||
190 | s8 base_power_index; /* gain index for power at factory temp. */ | ||
191 | s8 requested_power; /* power (dBm) requested for this chnl/rate */ | ||
192 | }; | ||
193 | |||
194 | /* current scan Tx power values to use, one for each scan rate for each | ||
195 | * channel. */ | ||
196 | struct iwl3945_scan_power_info { | ||
197 | struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ | ||
198 | s8 power_table_index; /* actual (compenst'd) index into gain table */ | ||
199 | s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ | ||
200 | }; | ||
201 | |||
157 | /* | 202 | /* |
158 | * One for each channel, holds all channel setup data | 203 | * One for each channel, holds all channel setup data |
159 | * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant | 204 | * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant |
@@ -184,8 +229,15 @@ struct iwl_channel_info { | |||
184 | s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */ | 229 | s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */ |
185 | u8 fat_flags; /* flags copied from EEPROM */ | 230 | u8 fat_flags; /* flags copied from EEPROM */ |
186 | u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */ | 231 | u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */ |
187 | }; | ||
188 | 232 | ||
233 | /* Radio/DSP gain settings for each "normal" data Tx rate. | ||
234 | * These include, in addition to RF and DSP gain, a few fields for | ||
235 | * remembering/modifying gain settings (indexes). */ | ||
236 | struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE]; | ||
237 | |||
238 | /* Radio/DSP gain settings for each scan rate, for directed scans. */ | ||
239 | struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; | ||
240 | }; | ||
189 | 241 | ||
190 | #define IWL_TX_FIFO_AC0 0 | 242 | #define IWL_TX_FIFO_AC0 0 |
191 | #define IWL_TX_FIFO_AC1 1 | 243 | #define IWL_TX_FIFO_AC1 1 |
@@ -370,7 +422,7 @@ struct iwl_hw_key { | |||
370 | u8 key[32]; | 422 | u8 key[32]; |
371 | }; | 423 | }; |
372 | 424 | ||
373 | union iwl4965_ht_rate_supp { | 425 | union iwl_ht_rate_supp { |
374 | u16 rates; | 426 | u16 rates; |
375 | struct { | 427 | struct { |
376 | u8 siso_rate; | 428 | u8 siso_rate; |
@@ -430,6 +482,24 @@ struct iwl_qos_info { | |||
430 | #define STA_PS_STATUS_WAKE 0 | 482 | #define STA_PS_STATUS_WAKE 0 |
431 | #define STA_PS_STATUS_SLEEP 1 | 483 | #define STA_PS_STATUS_SLEEP 1 |
432 | 484 | ||
485 | struct iwl3945_tid_data { | ||
486 | u16 seq_number; | ||
487 | }; | ||
488 | |||
489 | struct iwl3945_hw_key { | ||
490 | enum ieee80211_key_alg alg; | ||
491 | int keylen; | ||
492 | u8 key[32]; | ||
493 | }; | ||
494 | |||
495 | struct iwl3945_station_entry { | ||
496 | struct iwl3945_addsta_cmd sta; | ||
497 | struct iwl3945_tid_data tid[MAX_TID_COUNT]; | ||
498 | u8 used; | ||
499 | u8 ps_status; | ||
500 | struct iwl3945_hw_key keyinfo; | ||
501 | }; | ||
502 | |||
433 | struct iwl_station_entry { | 503 | struct iwl_station_entry { |
434 | struct iwl_addsta_cmd sta; | 504 | struct iwl_addsta_cmd sta; |
435 | struct iwl_tid_data tid[MAX_TID_COUNT]; | 505 | struct iwl_tid_data tid[MAX_TID_COUNT]; |
@@ -497,11 +567,13 @@ struct iwl_sensitivity_ranges { | |||
497 | * @max_txq_num: Max # Tx queues supported | 567 | * @max_txq_num: Max # Tx queues supported |
498 | * @dma_chnl_num: Number of Tx DMA/FIFO channels | 568 | * @dma_chnl_num: Number of Tx DMA/FIFO channels |
499 | * @scd_bc_tbls_size: size of scheduler byte count tables | 569 | * @scd_bc_tbls_size: size of scheduler byte count tables |
570 | * @tfd_size: TFD size | ||
500 | * @tx/rx_chains_num: Number of TX/RX chains | 571 | * @tx/rx_chains_num: Number of TX/RX chains |
501 | * @valid_tx/rx_ant: usable antennas | 572 | * @valid_tx/rx_ant: usable antennas |
502 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | 573 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) |
503 | * @max_rxq_log: Log-base-2 of max_rxq_size | 574 | * @max_rxq_log: Log-base-2 of max_rxq_size |
504 | * @rx_buf_size: Rx buffer size | 575 | * @rx_buf_size: Rx buffer size |
576 | * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR | ||
505 | * @max_stations: | 577 | * @max_stations: |
506 | * @bcast_sta_id: | 578 | * @bcast_sta_id: |
507 | * @fat_channel: is 40MHz width possible in band 2.4 | 579 | * @fat_channel: is 40MHz width possible in band 2.4 |
@@ -516,6 +588,7 @@ struct iwl_hw_params { | |||
516 | u8 max_txq_num; | 588 | u8 max_txq_num; |
517 | u8 dma_chnl_num; | 589 | u8 dma_chnl_num; |
518 | u16 scd_bc_tbls_size; | 590 | u16 scd_bc_tbls_size; |
591 | u32 tfd_size; | ||
519 | u8 tx_chains_num; | 592 | u8 tx_chains_num; |
520 | u8 rx_chains_num; | 593 | u8 rx_chains_num; |
521 | u8 valid_tx_ant; | 594 | u8 valid_tx_ant; |
@@ -523,6 +596,7 @@ struct iwl_hw_params { | |||
523 | u16 max_rxq_size; | 596 | u16 max_rxq_size; |
524 | u16 max_rxq_log; | 597 | u16 max_rxq_log; |
525 | u32 rx_buf_size; | 598 | u32 rx_buf_size; |
599 | u32 rx_wrt_ptr_reg; | ||
526 | u32 max_pkt_size; | 600 | u32 max_pkt_size; |
527 | u8 max_stations; | 601 | u8 max_stations; |
528 | u8 bcast_sta_id; | 602 | u8 bcast_sta_id; |
@@ -755,7 +829,7 @@ struct iwl_priv { | |||
755 | 829 | ||
756 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 830 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
757 | 831 | ||
758 | #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT | 832 | #if defined(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT) |
759 | /* spectrum measurement report caching */ | 833 | /* spectrum measurement report caching */ |
760 | struct iwl_spectrum_notification measure_report; | 834 | struct iwl_spectrum_notification measure_report; |
761 | u8 measurement_status; | 835 | u8 measurement_status; |
@@ -768,6 +842,10 @@ struct iwl_priv { | |||
768 | struct iwl_channel_info *channel_info; /* channel info array */ | 842 | struct iwl_channel_info *channel_info; /* channel info array */ |
769 | u8 channel_count; /* # of channels */ | 843 | u8 channel_count; /* # of channels */ |
770 | 844 | ||
845 | /* each calibration channel group in the EEPROM has a derived | ||
846 | * clip setting for each rate. 3945 only.*/ | ||
847 | const struct iwl3945_clip_group clip39_groups[5]; | ||
848 | |||
771 | /* thermal calibration */ | 849 | /* thermal calibration */ |
772 | s32 temperature; /* degrees Kelvin */ | 850 | s32 temperature; /* degrees Kelvin */ |
773 | s32 last_temperature; | 851 | s32 last_temperature; |
@@ -781,7 +859,7 @@ struct iwl_priv { | |||
781 | unsigned long scan_start; | 859 | unsigned long scan_start; |
782 | unsigned long scan_pass_start; | 860 | unsigned long scan_pass_start; |
783 | unsigned long scan_start_tsf; | 861 | unsigned long scan_start_tsf; |
784 | struct iwl_scan_cmd *scan; | 862 | void *scan; |
785 | int scan_bands; | 863 | int scan_bands; |
786 | int one_direct_scan; | 864 | int one_direct_scan; |
787 | u8 direct_ssid_len; | 865 | u8 direct_ssid_len; |
@@ -832,18 +910,25 @@ struct iwl_priv { | |||
832 | * 4965's initialize alive response contains some calibration data. */ | 910 | * 4965's initialize alive response contains some calibration data. */ |
833 | struct iwl_init_alive_resp card_alive_init; | 911 | struct iwl_init_alive_resp card_alive_init; |
834 | struct iwl_alive_resp card_alive; | 912 | struct iwl_alive_resp card_alive; |
835 | #ifdef CONFIG_IWLWIFI_RFKILL | 913 | #if defined(CONFIG_IWLWIFI_RFKILL) || defined(CONFIG_IWL3945_RFKILL) |
836 | struct rfkill *rfkill; | 914 | struct rfkill *rfkill; |
837 | #endif | 915 | #endif |
838 | 916 | ||
839 | #ifdef CONFIG_IWLWIFI_LEDS | 917 | #if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS) |
840 | struct iwl_led led[IWL_LED_TRG_MAX]; | ||
841 | unsigned long last_blink_time; | 918 | unsigned long last_blink_time; |
842 | u8 last_blink_rate; | 919 | u8 last_blink_rate; |
843 | u8 allow_blinking; | 920 | u8 allow_blinking; |
844 | u64 led_tpt; | 921 | u64 led_tpt; |
845 | #endif | 922 | #endif |
846 | 923 | ||
924 | #ifdef CONFIG_IWLWIFI_LEDS | ||
925 | struct iwl_led led[IWL_LED_TRG_MAX]; | ||
926 | #endif | ||
927 | |||
928 | #ifdef CONFIG_IWL3945_LEDS | ||
929 | struct iwl3945_led led39[IWL_LED_TRG_MAX]; | ||
930 | unsigned int rxtxpackets; | ||
931 | #endif | ||
847 | u16 active_rate; | 932 | u16 active_rate; |
848 | u16 active_rate_basic; | 933 | u16 active_rate_basic; |
849 | 934 | ||
@@ -893,7 +978,6 @@ struct iwl_priv { | |||
893 | u16 rates_mask; | 978 | u16 rates_mask; |
894 | 979 | ||
895 | u32 power_mode; | 980 | u32 power_mode; |
896 | u32 antenna; | ||
897 | u8 bssid[ETH_ALEN]; | 981 | u8 bssid[ETH_ALEN]; |
898 | u16 rts_threshold; | 982 | u16 rts_threshold; |
899 | u8 mac_addr[ETH_ALEN]; | 983 | u8 mac_addr[ETH_ALEN]; |
@@ -929,6 +1013,10 @@ struct iwl_priv { | |||
929 | u16 beacon_int; | 1013 | u16 beacon_int; |
930 | struct ieee80211_vif *vif; | 1014 | struct ieee80211_vif *vif; |
931 | 1015 | ||
1016 | /*Added for 3945 */ | ||
1017 | void *shared_virt; | ||
1018 | dma_addr_t shared_phys; | ||
1019 | /*End*/ | ||
932 | struct iwl_hw_params hw_params; | 1020 | struct iwl_hw_params hw_params; |
933 | 1021 | ||
934 | 1022 | ||
@@ -960,6 +1048,11 @@ struct iwl_priv { | |||
960 | struct delayed_work init_alive_start; | 1048 | struct delayed_work init_alive_start; |
961 | struct delayed_work alive_start; | 1049 | struct delayed_work alive_start; |
962 | struct delayed_work scan_check; | 1050 | struct delayed_work scan_check; |
1051 | |||
1052 | /*For 3945 only*/ | ||
1053 | struct delayed_work thermal_periodic; | ||
1054 | struct delayed_work rfkill_poll; | ||
1055 | |||
963 | /* TX Power */ | 1056 | /* TX Power */ |
964 | s8 tx_power_user_lmt; | 1057 | s8 tx_power_user_lmt; |
965 | s8 tx_power_channel_lmt; | 1058 | s8 tx_power_channel_lmt; |
@@ -982,6 +1075,22 @@ struct iwl_priv { | |||
982 | u32 disable_tx_power_cal; | 1075 | u32 disable_tx_power_cal; |
983 | struct work_struct run_time_calib_work; | 1076 | struct work_struct run_time_calib_work; |
984 | struct timer_list statistics_periodic; | 1077 | struct timer_list statistics_periodic; |
1078 | |||
1079 | /*For 3945*/ | ||
1080 | #define IWL_DEFAULT_TX_POWER 0x0F | ||
1081 | /* We declare this const so it can only be | ||
1082 | * changed via explicit cast within the | ||
1083 | * routines that actually update the physical | ||
1084 | * hardware */ | ||
1085 | const struct iwl3945_rxon_cmd active39_rxon; | ||
1086 | struct iwl3945_rxon_cmd staging39_rxon; | ||
1087 | struct iwl3945_rxon_cmd recovery39_rxon; | ||
1088 | |||
1089 | struct iwl3945_notif_statistics statistics_39; | ||
1090 | |||
1091 | struct iwl3945_station_entry stations_39[IWL_STATION_COUNT]; | ||
1092 | |||
1093 | u32 sta_supp_rates; | ||
985 | }; /*iwl_priv */ | 1094 | }; /*iwl_priv */ |
986 | 1095 | ||
987 | static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) | 1096 | static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index ce2f47306cea..eaa658f9e54c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -145,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) | |||
145 | { | 145 | { |
146 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP); | 146 | u32 gp = iwl_read32(priv, CSR_EEPROM_GP); |
147 | if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { | 147 | if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { |
148 | IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); | 148 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
149 | return -ENOENT; | 149 | return -ENOENT; |
150 | } | 150 | } |
151 | return 0; | 151 | return 0; |
@@ -223,7 +223,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
223 | 223 | ||
224 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); | 224 | ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); |
225 | if (ret < 0) { | 225 | if (ret < 0) { |
226 | IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); | 226 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
227 | ret = -ENOENT; | 227 | ret = -ENOENT; |
228 | goto err; | 228 | goto err; |
229 | } | 229 | } |
@@ -231,7 +231,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
231 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | 231 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ |
232 | ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); | 232 | ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); |
233 | if (ret < 0) { | 233 | if (ret < 0) { |
234 | IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); | 234 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); |
235 | ret = -ENOENT; | 235 | ret = -ENOENT; |
236 | goto err; | 236 | goto err; |
237 | } | 237 | } |
@@ -247,7 +247,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) | |||
247 | CSR_EEPROM_REG_READ_VALID_MSK, | 247 | CSR_EEPROM_REG_READ_VALID_MSK, |
248 | IWL_EEPROM_ACCESS_TIMEOUT); | 248 | IWL_EEPROM_ACCESS_TIMEOUT); |
249 | if (ret < 0) { | 249 | if (ret < 0) { |
250 | IWL_ERROR("Time out reading EEPROM[%d]\n", addr); | 250 | IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); |
251 | goto done; | 251 | goto done; |
252 | } | 252 | } |
253 | r = _iwl_read_direct32(priv, CSR_EEPROM_REG); | 253 | r = _iwl_read_direct32(priv, CSR_EEPROM_REG); |
@@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) | |||
285 | 285 | ||
286 | return 0; | 286 | return 0; |
287 | err: | 287 | err: |
288 | IWL_ERROR("Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", | 288 | IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", |
289 | eeprom_ver, priv->cfg->eeprom_ver, | 289 | eeprom_ver, priv->cfg->eeprom_ver, |
290 | calib_ver, priv->cfg->eeprom_calib_ver); | 290 | calib_ver, priv->cfg->eeprom_calib_ver); |
291 | return -EINVAL; | 291 | return -EINVAL; |
@@ -450,7 +450,7 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
450 | priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * | 450 | priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * |
451 | priv->channel_count, GFP_KERNEL); | 451 | priv->channel_count, GFP_KERNEL); |
452 | if (!priv->channel_info) { | 452 | if (!priv->channel_info) { |
453 | IWL_ERROR("Could not allocate channel_info\n"); | 453 | IWL_ERR(priv, "Could not allocate channel_info\n"); |
454 | priv->channel_count = 0; | 454 | priv->channel_count = 0; |
455 | return -ENOMEM; | 455 | return -ENOMEM; |
456 | } | 456 | } |
@@ -520,7 +520,7 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
520 | flags & EEPROM_CHANNEL_RADAR)) | 520 | flags & EEPROM_CHANNEL_RADAR)) |
521 | ? "" : "not "); | 521 | ? "" : "not "); |
522 | 522 | ||
523 | /* Set the user_txpower_limit to the highest power | 523 | /* Set the tx_power_user_lmt to the highest power |
524 | * supported by any channel */ | 524 | * supported by any channel */ |
525 | if (eeprom_ch_info[ch].max_power_avg > | 525 | if (eeprom_ch_info[ch].max_power_avg > |
526 | priv->tx_power_user_lmt) | 526 | priv->tx_power_user_lmt) |
@@ -531,6 +531,13 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
531 | } | 531 | } |
532 | } | 532 | } |
533 | 533 | ||
534 | /* Check if we do have FAT channels */ | ||
535 | if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] >= | ||
536 | priv->cfg->eeprom_size && | ||
537 | priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] >= | ||
538 | priv->cfg->eeprom_size) | ||
539 | return 0; | ||
540 | |||
534 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ | 541 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ |
535 | for (band = 6; band <= 7; band++) { | 542 | for (band = 6; band <= 7; band++) { |
536 | enum ieee80211_band ieeeband; | 543 | enum ieee80211_band ieeeband; |
@@ -582,6 +589,7 @@ void iwl_free_channel_map(struct iwl_priv *priv) | |||
582 | kfree(priv->channel_info); | 589 | kfree(priv->channel_info); |
583 | priv->channel_count = 0; | 590 | priv->channel_count = 0; |
584 | } | 591 | } |
592 | EXPORT_SYMBOL(iwl_free_channel_map); | ||
585 | 593 | ||
586 | /** | 594 | /** |
587 | * iwl_get_channel_info - Find driver's private channel info | 595 | * iwl_get_channel_info - Find driver's private channel info |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 603c84bed630..17fed49f9d96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -118,6 +118,9 @@ struct iwl_eeprom_channel { | |||
118 | s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ | 118 | s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ |
119 | } __attribute__ ((packed)); | 119 | } __attribute__ ((packed)); |
120 | 120 | ||
121 | /* 3945 Specific */ | ||
122 | #define EEPROM_3945_EEPROM_VERSION (0x2f) | ||
123 | |||
121 | /* 4965 has two radio transmitters (and 3 radio receivers) */ | 124 | /* 4965 has two radio transmitters (and 3 radio receivers) */ |
122 | #define EEPROM_TX_POWER_TX_CHAINS (2) | 125 | #define EEPROM_TX_POWER_TX_CHAINS (2) |
123 | 126 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index d7da19864550..65fa8a69fd5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
@@ -399,6 +399,21 @@ | |||
399 | */ | 399 | */ |
400 | #define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002) | 400 | #define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002) |
401 | 401 | ||
402 | #define RX_QUEUE_SIZE 256 | ||
403 | #define RX_QUEUE_MASK 255 | ||
404 | #define RX_QUEUE_SIZE_LOG 8 | ||
405 | |||
406 | /* | ||
407 | * RX related structures and functions | ||
408 | */ | ||
409 | #define RX_FREE_BUFFERS 64 | ||
410 | #define RX_LOW_WATERMARK 8 | ||
411 | |||
412 | /* Size of one Rx buffer in host DRAM */ | ||
413 | #define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */ | ||
414 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) | ||
415 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) | ||
416 | |||
402 | /** | 417 | /** |
403 | * struct iwl_rb_status - reseve buffer status | 418 | * struct iwl_rb_status - reseve buffer status |
404 | * host memory mapped FH registers | 419 | * host memory mapped FH registers |
@@ -414,6 +429,7 @@ struct iwl_rb_status { | |||
414 | __le16 closed_fr_num; | 429 | __le16 closed_fr_num; |
415 | __le16 finished_rb_num; | 430 | __le16 finished_rb_num; |
416 | __le16 finished_fr_nam; | 431 | __le16 finished_fr_nam; |
432 | __le32 __unused; /* 3945 only */ | ||
417 | } __attribute__ ((packed)); | 433 | } __attribute__ ((packed)); |
418 | 434 | ||
419 | 435 | ||
@@ -477,7 +493,6 @@ struct iwl_tfd { | |||
477 | __le32 __pad; | 493 | __le32 __pad; |
478 | } __attribute__ ((packed)); | 494 | } __attribute__ ((packed)); |
479 | 495 | ||
480 | |||
481 | /* Keep Warm Size */ | 496 | /* Keep Warm Size */ |
482 | #define IWL_KW_SIZE 0x1000 /* 4k */ | 497 | #define IWL_KW_SIZE 0x1000 /* 4k */ |
483 | 498 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 4b35b30e493e..65ae2af61c8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -109,14 +109,14 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv, | |||
109 | struct iwl_rx_packet *pkt = NULL; | 109 | struct iwl_rx_packet *pkt = NULL; |
110 | 110 | ||
111 | if (!skb) { | 111 | if (!skb) { |
112 | IWL_ERROR("Error: Response NULL in %s.\n", | 112 | IWL_ERR(priv, "Error: Response NULL in %s.\n", |
113 | get_cmd_string(cmd->hdr.cmd)); | 113 | get_cmd_string(cmd->hdr.cmd)); |
114 | return 1; | 114 | return 1; |
115 | } | 115 | } |
116 | 116 | ||
117 | pkt = (struct iwl_rx_packet *)skb->data; | 117 | pkt = (struct iwl_rx_packet *)skb->data; |
118 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { | 118 | if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { |
119 | IWL_ERROR("Bad return from %s (0x%08X)\n", | 119 | IWL_ERR(priv, "Bad return from %s (0x%08X)\n", |
120 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); | 120 | get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); |
121 | return 1; | 121 | return 1; |
122 | } | 122 | } |
@@ -156,7 +156,7 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
156 | 156 | ||
157 | ret = iwl_enqueue_hcmd(priv, cmd); | 157 | ret = iwl_enqueue_hcmd(priv, cmd); |
158 | if (ret < 0) { | 158 | if (ret < 0) { |
159 | IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n", | 159 | IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", |
160 | get_cmd_string(cmd->id), ret); | 160 | get_cmd_string(cmd->id), ret); |
161 | return ret; | 161 | return ret; |
162 | } | 162 | } |
@@ -174,8 +174,9 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
174 | BUG_ON(cmd->meta.u.callback != NULL); | 174 | BUG_ON(cmd->meta.u.callback != NULL); |
175 | 175 | ||
176 | if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { | 176 | if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { |
177 | IWL_ERROR("Error sending %s: Already sending a host command\n", | 177 | IWL_ERR(priv, |
178 | get_cmd_string(cmd->id)); | 178 | "Error sending %s: Already sending a host command\n", |
179 | get_cmd_string(cmd->id)); | ||
179 | ret = -EBUSY; | 180 | ret = -EBUSY; |
180 | goto out; | 181 | goto out; |
181 | } | 182 | } |
@@ -188,7 +189,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
188 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); | 189 | cmd_idx = iwl_enqueue_hcmd(priv, cmd); |
189 | if (cmd_idx < 0) { | 190 | if (cmd_idx < 0) { |
190 | ret = cmd_idx; | 191 | ret = cmd_idx; |
191 | IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n", | 192 | IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", |
192 | get_cmd_string(cmd->id), ret); | 193 | get_cmd_string(cmd->id), ret); |
193 | goto out; | 194 | goto out; |
194 | } | 195 | } |
@@ -198,9 +199,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
198 | HOST_COMPLETE_TIMEOUT); | 199 | HOST_COMPLETE_TIMEOUT); |
199 | if (!ret) { | 200 | if (!ret) { |
200 | if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) { | 201 | if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) { |
201 | IWL_ERROR("Error sending %s: time out after %dms.\n", | 202 | IWL_ERR(priv, |
202 | get_cmd_string(cmd->id), | 203 | "Error sending %s: time out after %dms.\n", |
203 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 204 | get_cmd_string(cmd->id), |
205 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | ||
204 | 206 | ||
205 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 207 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
206 | ret = -ETIMEDOUT; | 208 | ret = -ETIMEDOUT; |
@@ -221,7 +223,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
221 | goto fail; | 223 | goto fail; |
222 | } | 224 | } |
223 | if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) { | 225 | if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) { |
224 | IWL_ERROR("Error: Response NULL in '%s'\n", | 226 | IWL_ERR(priv, "Error: Response NULL in '%s'\n", |
225 | get_cmd_string(cmd->id)); | 227 | get_cmd_string(cmd->id)); |
226 | ret = -EIO; | 228 | ret = -EIO; |
227 | goto cancel; | 229 | goto cancel; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index ca4f638ab9d0..fb64d297dd4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 0a92e7431ada..7341a2da8431 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project. | 5 | * Portions of this file are derived from the ipw3945 project. |
6 | * | 6 | * |
@@ -165,9 +165,9 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv) | |||
165 | ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, | 165 | ret = _iwl_poll_bit(priv, CSR_GP_CNTRL, |
166 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, | 166 | CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, |
167 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | 167 | (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | |
168 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50); | 168 | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); |
169 | if (ret < 0) { | 169 | if (ret < 0) { |
170 | IWL_ERROR("MAC is in deep sleep!\n"); | 170 | IWL_ERR(priv, "MAC is in deep sleep!\n"); |
171 | return -EIO; | 171 | return -EIO; |
172 | } | 172 | } |
173 | 173 | ||
@@ -182,7 +182,7 @@ static inline int __iwl_grab_nic_access(const char *f, u32 l, | |||
182 | struct iwl_priv *priv) | 182 | struct iwl_priv *priv) |
183 | { | 183 | { |
184 | if (atomic_read(&priv->restrict_refcnt)) | 184 | if (atomic_read(&priv->restrict_refcnt)) |
185 | IWL_ERROR("Grabbing access while already held %s %d.\n", f, l); | 185 | IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l); |
186 | 186 | ||
187 | IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l); | 187 | IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l); |
188 | return _iwl_grab_nic_access(priv); | 188 | return _iwl_grab_nic_access(priv); |
@@ -207,7 +207,7 @@ static inline void __iwl_release_nic_access(const char *f, u32 l, | |||
207 | struct iwl_priv *priv) | 207 | struct iwl_priv *priv) |
208 | { | 208 | { |
209 | if (atomic_read(&priv->restrict_refcnt) <= 0) | 209 | if (atomic_read(&priv->restrict_refcnt) <= 0) |
210 | IWL_ERROR("Release unheld nic access at line %s %d.\n", f, l); | 210 | IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l); |
211 | 211 | ||
212 | IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l); | 212 | IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l); |
213 | _iwl_release_nic_access(priv); | 213 | _iwl_release_nic_access(priv); |
@@ -229,7 +229,7 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l, | |||
229 | { | 229 | { |
230 | u32 value = _iwl_read_direct32(priv, reg); | 230 | u32 value = _iwl_read_direct32(priv, reg); |
231 | if (!atomic_read(&priv->restrict_refcnt)) | 231 | if (!atomic_read(&priv->restrict_refcnt)) |
232 | IWL_ERROR("Nic access not held from %s %d\n", f, l); | 232 | IWL_ERR(priv, "Nic access not held from %s %d\n", f, l); |
233 | IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, | 233 | IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, |
234 | f, l); | 234 | f, l); |
235 | return value; | 235 | return value; |
@@ -250,7 +250,7 @@ static void __iwl_write_direct32(const char *f , u32 line, | |||
250 | struct iwl_priv *priv, u32 reg, u32 value) | 250 | struct iwl_priv *priv, u32 reg, u32 value) |
251 | { | 251 | { |
252 | if (!atomic_read(&priv->restrict_refcnt)) | 252 | if (!atomic_read(&priv->restrict_refcnt)) |
253 | IWL_ERROR("Nic access not held from %s line %d\n", f, line); | 253 | IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); |
254 | _iwl_write_direct32(priv, reg, value); | 254 | _iwl_write_direct32(priv, reg, value); |
255 | } | 255 | } |
256 | #define iwl_write_direct32(priv, reg, value) \ | 256 | #define iwl_write_direct32(priv, reg, value) \ |
@@ -308,7 +308,7 @@ static inline u32 __iwl_read_prph(const char *f, u32 line, | |||
308 | struct iwl_priv *priv, u32 reg) | 308 | struct iwl_priv *priv, u32 reg) |
309 | { | 309 | { |
310 | if (!atomic_read(&priv->restrict_refcnt)) | 310 | if (!atomic_read(&priv->restrict_refcnt)) |
311 | IWL_ERROR("Nic access not held from %s line %d\n", f, line); | 311 | IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); |
312 | return _iwl_read_prph(priv, reg); | 312 | return _iwl_read_prph(priv, reg); |
313 | } | 313 | } |
314 | 314 | ||
@@ -331,7 +331,7 @@ static inline void __iwl_write_prph(const char *f, u32 line, | |||
331 | struct iwl_priv *priv, u32 addr, u32 val) | 331 | struct iwl_priv *priv, u32 addr, u32 val) |
332 | { | 332 | { |
333 | if (!atomic_read(&priv->restrict_refcnt)) | 333 | if (!atomic_read(&priv->restrict_refcnt)) |
334 | IWL_ERROR("Nic access not held from %s line %d\n", f, line); | 334 | IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); |
335 | _iwl_write_prph(priv, addr, val); | 335 | _iwl_write_prph(priv, addr, val); |
336 | } | 336 | } |
337 | 337 | ||
@@ -349,7 +349,7 @@ static inline void __iwl_set_bits_prph(const char *f, u32 line, | |||
349 | u32 reg, u32 mask) | 349 | u32 reg, u32 mask) |
350 | { | 350 | { |
351 | if (!atomic_read(&priv->restrict_refcnt)) | 351 | if (!atomic_read(&priv->restrict_refcnt)) |
352 | IWL_ERROR("Nic access not held from %s line %d\n", f, line); | 352 | IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); |
353 | 353 | ||
354 | _iwl_set_bits_prph(priv, reg, mask); | 354 | _iwl_set_bits_prph(priv, reg, mask); |
355 | } | 355 | } |
@@ -367,7 +367,7 @@ static inline void __iwl_set_bits_mask_prph(const char *f, u32 line, | |||
367 | struct iwl_priv *priv, u32 reg, u32 bits, u32 mask) | 367 | struct iwl_priv *priv, u32 reg, u32 bits, u32 mask) |
368 | { | 368 | { |
369 | if (!atomic_read(&priv->restrict_refcnt)) | 369 | if (!atomic_read(&priv->restrict_refcnt)) |
370 | IWL_ERROR("Nic access not held from %s line %d\n", f, line); | 370 | IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line); |
371 | _iwl_set_bits_mask_prph(priv, reg, bits, mask); | 371 | _iwl_set_bits_mask_prph(priv, reg, bits, mask); |
372 | } | 372 | } |
373 | #define iwl_set_bits_mask_prph(priv, reg, bits, mask) \ | 373 | #define iwl_set_bits_mask_prph(priv, reg, bits, mask) \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 11eccd7d268c..501cffeff5f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -254,7 +254,7 @@ static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led, | |||
254 | 254 | ||
255 | ret = led_classdev_register(device, &led->led_dev); | 255 | ret = led_classdev_register(device, &led->led_dev); |
256 | if (ret) { | 256 | if (ret) { |
257 | IWL_ERROR("Error: failed to register led handler.\n"); | 257 | IWL_ERR(priv, "Error: failed to register led handler.\n"); |
258 | return ret; | 258 | return ret; |
259 | } | 259 | } |
260 | 260 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 021e00bcd1be..1d798d086695 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | 6 | * under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | struct iwl_priv; | 31 | struct iwl_priv; |
32 | 32 | ||
33 | #ifdef CONFIG_IWLWIFI_LEDS | 33 | #if defined(CONFIG_IWLWIFI_LEDS) || defined(CONFIG_IWL3945_LEDS) |
34 | #include <linux/leds.h> | 34 | #include <linux/leds.h> |
35 | 35 | ||
36 | #define IWL_LED_SOLID 11 | 36 | #define IWL_LED_SOLID 11 |
@@ -47,7 +47,9 @@ enum led_type { | |||
47 | IWL_LED_TRG_RADIO, | 47 | IWL_LED_TRG_RADIO, |
48 | IWL_LED_TRG_MAX, | 48 | IWL_LED_TRG_MAX, |
49 | }; | 49 | }; |
50 | #endif | ||
50 | 51 | ||
52 | #ifdef CONFIG_IWLWIFI_LEDS | ||
51 | 53 | ||
52 | struct iwl_led { | 54 | struct iwl_led { |
53 | struct iwl_priv *priv; | 55 | struct iwl_priv *priv; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 75ca6a542174..a4634595c59f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -60,14 +60,6 @@ | |||
60 | #define IWL_POWER_RANGE_1_MAX (10) | 60 | #define IWL_POWER_RANGE_1_MAX (10) |
61 | 61 | ||
62 | 62 | ||
63 | #define NOSLP __constant_cpu_to_le16(0), 0, 0 | ||
64 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 | ||
65 | #define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC) | ||
66 | #define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \ | ||
67 | __constant_cpu_to_le32(X1), \ | ||
68 | __constant_cpu_to_le32(X2), \ | ||
69 | __constant_cpu_to_le32(X3), \ | ||
70 | __constant_cpu_to_le32(X4)} | ||
71 | 63 | ||
72 | #define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5 | 64 | #define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5 |
73 | #define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM | 65 | #define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM |
@@ -149,7 +141,7 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv) | |||
149 | } | 141 | } |
150 | 142 | ||
151 | /* initialize to default */ | 143 | /* initialize to default */ |
152 | static int iwl_power_init_handle(struct iwl_priv *priv) | 144 | static void iwl_power_init_handle(struct iwl_priv *priv) |
153 | { | 145 | { |
154 | struct iwl_power_mgr *pow_data; | 146 | struct iwl_power_mgr *pow_data; |
155 | int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; | 147 | int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; |
@@ -159,7 +151,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv) | |||
159 | 151 | ||
160 | IWL_DEBUG_POWER("Initialize power \n"); | 152 | IWL_DEBUG_POWER("Initialize power \n"); |
161 | 153 | ||
162 | pow_data = &(priv->power_data); | 154 | pow_data = &priv->power_data; |
163 | 155 | ||
164 | memset(pow_data, 0, sizeof(*pow_data)); | 156 | memset(pow_data, 0, sizeof(*pow_data)); |
165 | 157 | ||
@@ -179,26 +171,25 @@ static int iwl_power_init_handle(struct iwl_priv *priv) | |||
179 | else | 171 | else |
180 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | 172 | cmd->flags |= IWL_POWER_PCI_PM_MSK; |
181 | } | 173 | } |
182 | return 0; | ||
183 | } | 174 | } |
184 | 175 | ||
185 | /* adjust power command according to DTIM period and power level*/ | 176 | /* adjust power command according to DTIM period and power level*/ |
186 | static int iwl_update_power_command(struct iwl_priv *priv, | 177 | static int iwl_update_power_cmd(struct iwl_priv *priv, |
187 | struct iwl_powertable_cmd *cmd, | 178 | struct iwl_powertable_cmd *cmd, u16 mode) |
188 | u16 mode) | ||
189 | { | 179 | { |
190 | int ret = 0, i; | ||
191 | u8 skip; | ||
192 | u32 max_sleep = 0; | ||
193 | struct iwl_power_vec_entry *range; | 180 | struct iwl_power_vec_entry *range; |
194 | u8 period = 0; | ||
195 | struct iwl_power_mgr *pow_data; | 181 | struct iwl_power_mgr *pow_data; |
182 | int i; | ||
183 | u32 max_sleep = 0; | ||
184 | u8 period; | ||
185 | bool skip; | ||
196 | 186 | ||
197 | if (mode > IWL_POWER_INDEX_5) { | 187 | if (mode > IWL_POWER_INDEX_5) { |
198 | IWL_DEBUG_POWER("Error invalid power mode \n"); | 188 | IWL_DEBUG_POWER("Error invalid power mode \n"); |
199 | return -1; | 189 | return -EINVAL; |
200 | } | 190 | } |
201 | pow_data = &(priv->power_data); | 191 | |
192 | pow_data = &priv->power_data; | ||
202 | 193 | ||
203 | if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX) | 194 | if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX) |
204 | range = &pow_data->pwr_range_0[0]; | 195 | range = &pow_data->pwr_range_0[0]; |
@@ -212,14 +203,12 @@ static int iwl_update_power_command(struct iwl_priv *priv, | |||
212 | 203 | ||
213 | if (period == 0) { | 204 | if (period == 0) { |
214 | period = 1; | 205 | period = 1; |
215 | skip = 0; | 206 | skip = false; |
216 | } else | ||
217 | skip = range[mode].no_dtim; | ||
218 | |||
219 | if (skip == 0) { | ||
220 | max_sleep = period; | ||
221 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
222 | } else { | 207 | } else { |
208 | skip = !!range[mode].no_dtim; | ||
209 | } | ||
210 | |||
211 | if (skip) { | ||
223 | __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]; | 212 | __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]; |
224 | max_sleep = le32_to_cpu(slp_itrvl); | 213 | max_sleep = le32_to_cpu(slp_itrvl); |
225 | if (max_sleep == 0xFF) | 214 | if (max_sleep == 0xFF) |
@@ -227,12 +216,14 @@ static int iwl_update_power_command(struct iwl_priv *priv, | |||
227 | else if (max_sleep > period) | 216 | else if (max_sleep > period) |
228 | max_sleep = (le32_to_cpu(slp_itrvl) / period) * period; | 217 | max_sleep = (le32_to_cpu(slp_itrvl) / period) * period; |
229 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; | 218 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; |
219 | } else { | ||
220 | max_sleep = period; | ||
221 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
230 | } | 222 | } |
231 | 223 | ||
232 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) { | 224 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) |
233 | if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) | 225 | if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) |
234 | cmd->sleep_interval[i] = cpu_to_le32(max_sleep); | 226 | cmd->sleep_interval[i] = cpu_to_le32(max_sleep); |
235 | } | ||
236 | 227 | ||
237 | IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags); | 228 | IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags); |
238 | IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); | 229 | IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); |
@@ -244,7 +235,7 @@ static int iwl_update_power_command(struct iwl_priv *priv, | |||
244 | le32_to_cpu(cmd->sleep_interval[3]), | 235 | le32_to_cpu(cmd->sleep_interval[3]), |
245 | le32_to_cpu(cmd->sleep_interval[4])); | 236 | le32_to_cpu(cmd->sleep_interval[4])); |
246 | 237 | ||
247 | return ret; | 238 | return 0; |
248 | } | 239 | } |
249 | 240 | ||
250 | 241 | ||
@@ -295,7 +286,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) | |||
295 | if (final_mode != IWL_POWER_MODE_CAM) | 286 | if (final_mode != IWL_POWER_MODE_CAM) |
296 | set_bit(STATUS_POWER_PMI, &priv->status); | 287 | set_bit(STATUS_POWER_PMI, &priv->status); |
297 | 288 | ||
298 | iwl_update_power_command(priv, &cmd, final_mode); | 289 | iwl_update_power_cmd(priv, &cmd, final_mode); |
299 | cmd.keep_alive_beacons = 0; | 290 | cmd.keep_alive_beacons = 0; |
300 | 291 | ||
301 | if (final_mode == IWL_POWER_INDEX_5) | 292 | if (final_mode == IWL_POWER_INDEX_5) |
@@ -392,13 +383,11 @@ EXPORT_SYMBOL(iwl_power_set_system_mode); | |||
392 | /* initialize to default */ | 383 | /* initialize to default */ |
393 | void iwl_power_initialize(struct iwl_priv *priv) | 384 | void iwl_power_initialize(struct iwl_priv *priv) |
394 | { | 385 | { |
395 | |||
396 | iwl_power_init_handle(priv); | 386 | iwl_power_init_handle(priv); |
397 | priv->power_data.user_power_setting = IWL_POWER_AUTO; | 387 | priv->power_data.user_power_setting = IWL_POWER_AUTO; |
398 | priv->power_data.power_disabled = 0; | ||
399 | priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO; | 388 | priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO; |
400 | priv->power_data.is_battery_active = 0; | ||
401 | priv->power_data.power_disabled = 0; | 389 | priv->power_data.power_disabled = 0; |
390 | priv->power_data.is_battery_active = 0; | ||
402 | priv->power_data.critical_power_setting = 0; | 391 | priv->power_data.critical_power_setting = 0; |
403 | } | 392 | } |
404 | EXPORT_SYMBOL(iwl_power_initialize); | 393 | EXPORT_SYMBOL(iwl_power_initialize); |
@@ -407,8 +396,8 @@ EXPORT_SYMBOL(iwl_power_initialize); | |||
407 | int iwl_power_temperature_change(struct iwl_priv *priv) | 396 | int iwl_power_temperature_change(struct iwl_priv *priv) |
408 | { | 397 | { |
409 | int ret = 0; | 398 | int ret = 0; |
410 | u16 new_critical = priv->power_data.critical_power_setting; | ||
411 | s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature); | 399 | s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature); |
400 | u16 new_critical = priv->power_data.critical_power_setting; | ||
412 | 401 | ||
413 | if (temperature > IWL_CT_KILL_TEMPERATURE) | 402 | if (temperature > IWL_CT_KILL_TEMPERATURE) |
414 | return 0; | 403 | return 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index fa098d8975ce..859b60b5335c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -42,7 +42,10 @@ enum { | |||
42 | IWL_POWER_INDEX_5, | 42 | IWL_POWER_INDEX_5, |
43 | IWL_POWER_AUTO, | 43 | IWL_POWER_AUTO, |
44 | IWL_POWER_MAX = IWL_POWER_AUTO, | 44 | IWL_POWER_MAX = IWL_POWER_AUTO, |
45 | IWL39_POWER_AC = IWL_POWER_AUTO, /* 0x06 */ | ||
45 | IWL_POWER_AC, | 46 | IWL_POWER_AC, |
47 | IWL39_POWER_BATTERY = IWL_POWER_AC, /* 0x07 */ | ||
48 | IWL39_POWER_LIMIT = IWL_POWER_AC, | ||
46 | IWL_POWER_BATTERY, | 49 | IWL_POWER_BATTERY, |
47 | }; | 50 | }; |
48 | 51 | ||
@@ -56,8 +59,21 @@ enum { | |||
56 | #define IWL_POWER_MASK 0x0F | 59 | #define IWL_POWER_MASK 0x0F |
57 | #define IWL_POWER_ENABLED 0x10 | 60 | #define IWL_POWER_ENABLED 0x10 |
58 | 61 | ||
62 | #define IWL_POWER_RANGE_0 (0) | ||
63 | #define IWL_POWER_RANGE_1 (1) | ||
64 | |||
65 | #define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK) | ||
66 | |||
59 | /* Power management (not Tx power) structures */ | 67 | /* Power management (not Tx power) structures */ |
60 | 68 | ||
69 | #define NOSLP __constant_cpu_to_le16(0), 0, 0 | ||
70 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0 | ||
71 | #define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC) | ||
72 | #define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \ | ||
73 | __constant_cpu_to_le32(X1), \ | ||
74 | __constant_cpu_to_le32(X2), \ | ||
75 | __constant_cpu_to_le32(X3), \ | ||
76 | __constant_cpu_to_le32(X4)} | ||
61 | struct iwl_power_vec_entry { | 77 | struct iwl_power_vec_entry { |
62 | struct iwl_powertable_cmd cmd; | 78 | struct iwl_powertable_cmd cmd; |
63 | u8 no_dtim; | 79 | u8 no_dtim; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index b7a5f23351c3..3b9cac3fd216 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * GPL LICENSE SUMMARY | 6 | * GPL LICENSE SUMMARY |
7 | * | 7 | * |
8 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 8 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 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 | 11 | * it under the terms of version 2 of the GNU General Public License as |
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * BSD LICENSE | 31 | * BSD LICENSE |
32 | * | 32 | * |
33 | * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved. | 33 | * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. |
34 | * All rights reserved. | 34 | * All rights reserved. |
35 | * | 35 | * |
36 | * Redistribution and use in source and binary forms, with or without | 36 | * Redistribution and use in source and binary forms, with or without |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 4b69da30665c..f67d7be10748 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -62,7 +62,8 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | |||
62 | iwl_radio_kill_sw_disable_radio(priv); | 62 | iwl_radio_kill_sw_disable_radio(priv); |
63 | break; | 63 | break; |
64 | default: | 64 | default: |
65 | IWL_WARNING("we received unexpected RFKILL state %d\n", state); | 65 | IWL_WARN(priv, "we received unexpected RFKILL state %d\n", |
66 | state); | ||
66 | break; | 67 | break; |
67 | } | 68 | } |
68 | out_unlock: | 69 | out_unlock: |
@@ -81,7 +82,7 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
81 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); | 82 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); |
82 | priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | 83 | priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); |
83 | if (!priv->rfkill) { | 84 | if (!priv->rfkill) { |
84 | IWL_ERROR("Unable to allocate RFKILL device.\n"); | 85 | IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); |
85 | ret = -ENOMEM; | 86 | ret = -ENOMEM; |
86 | goto error; | 87 | goto error; |
87 | } | 88 | } |
@@ -97,7 +98,7 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
97 | 98 | ||
98 | ret = rfkill_register(priv->rfkill); | 99 | ret = rfkill_register(priv->rfkill); |
99 | if (ret) { | 100 | if (ret) { |
100 | IWL_ERROR("Unable to register RFKILL: %d\n", ret); | 101 | IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); |
101 | goto free_rfkill; | 102 | goto free_rfkill; |
102 | } | 103 | } |
103 | 104 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h index 86dc055a2e94..633dafb4bf1b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index c5f1aa0feac8..33145207fc15 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -125,9 +125,10 @@ EXPORT_SYMBOL(iwl_rx_queue_space); | |||
125 | */ | 125 | */ |
126 | int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | 126 | int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) |
127 | { | 127 | { |
128 | u32 reg = 0; | ||
129 | int ret = 0; | ||
130 | unsigned long flags; | 128 | unsigned long flags; |
129 | u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg; | ||
130 | u32 reg; | ||
131 | int ret = 0; | ||
131 | 132 | ||
132 | spin_lock_irqsave(&q->lock, flags); | 133 | spin_lock_irqsave(&q->lock, flags); |
133 | 134 | ||
@@ -149,15 +150,14 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | |||
149 | goto exit_unlock; | 150 | goto exit_unlock; |
150 | 151 | ||
151 | /* Device expects a multiple of 8 */ | 152 | /* Device expects a multiple of 8 */ |
152 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | 153 | iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write & ~0x7); |
153 | q->write & ~0x7); | ||
154 | iwl_release_nic_access(priv); | 154 | iwl_release_nic_access(priv); |
155 | 155 | ||
156 | /* Else device is assumed to be awake */ | 156 | /* Else device is assumed to be awake */ |
157 | } else | 157 | } else { |
158 | /* Device expects a multiple of 8 */ | 158 | /* Device expects a multiple of 8 */ |
159 | iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); | 159 | iwl_write32(priv, rx_wrt_ptr_reg, q->write & ~0x7); |
160 | 160 | } | |
161 | 161 | ||
162 | q->need_update = 0; | 162 | q->need_update = 0; |
163 | 163 | ||
@@ -262,8 +262,7 @@ void iwl_rx_allocate(struct iwl_priv *priv) | |||
262 | rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256, | 262 | rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256, |
263 | GFP_KERNEL); | 263 | GFP_KERNEL); |
264 | if (!rxb->skb) { | 264 | if (!rxb->skb) { |
265 | printk(KERN_CRIT DRV_NAME | 265 | IWL_CRIT(priv, "Can not allocate SKB buffers\n"); |
266 | "Can not allocate SKB buffers\n"); | ||
267 | /* We don't reschedule replenish work here -- we will | 266 | /* We don't reschedule replenish work here -- we will |
268 | * call the restock method and if it still needs | 267 | * call the restock method and if it still needs |
269 | * more buffers it will schedule replenish */ | 268 | * more buffers it will schedule replenish */ |
@@ -895,7 +894,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
895 | rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1]; | 894 | rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1]; |
896 | 895 | ||
897 | if (!rx_start) { | 896 | if (!rx_start) { |
898 | IWL_ERROR("MPDU frame without a PHY data\n"); | 897 | IWL_ERR(priv, "MPDU frame without a PHY data\n"); |
899 | return; | 898 | return; |
900 | } | 899 | } |
901 | if (include_phy) { | 900 | if (include_phy) { |
@@ -1021,7 +1020,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
1021 | } | 1020 | } |
1022 | 1021 | ||
1023 | if (!rx_start) { | 1022 | if (!rx_start) { |
1024 | IWL_ERROR("MPDU frame without a PHY data\n"); | 1023 | IWL_ERR(priv, "MPDU frame without a PHY data\n"); |
1025 | return; | 1024 | return; |
1026 | } | 1025 | } |
1027 | 1026 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 3c803f6922ef..c282d1d294e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * GPL LICENSE SUMMARY | 3 | * GPL LICENSE SUMMARY |
4 | * | 4 | * |
5 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | 5 | * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of version 2 of the GNU General Public License as | 8 | * it under the terms of version 2 of the GNU General Public License as |
@@ -46,15 +46,6 @@ | |||
46 | #define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3) | 46 | #define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3) |
47 | #define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2) | 47 | #define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2) |
48 | 48 | ||
49 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
50 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
51 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
52 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
53 | * no other traffic). | ||
54 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
55 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | ||
56 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */ | ||
57 | |||
58 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. | 49 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. |
59 | * Must be set longer than active dwell time. | 50 | * Must be set longer than active dwell time. |
60 | * For the most reliable scan, set > AP beacon interval (typically 100msec). */ | 51 | * For the most reliable scan, set > AP beacon interval (typically 100msec). */ |
@@ -63,7 +54,6 @@ | |||
63 | #define IWL_PASSIVE_DWELL_BASE (100) | 54 | #define IWL_PASSIVE_DWELL_BASE (100) |
64 | #define IWL_CHANNEL_TUNE_TIME 5 | 55 | #define IWL_CHANNEL_TUNE_TIME 5 |
65 | 56 | ||
66 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) | ||
67 | 57 | ||
68 | 58 | ||
69 | /** | 59 | /** |
@@ -119,7 +109,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | |||
119 | } | 109 | } |
120 | EXPORT_SYMBOL(iwl_scan_cancel_timeout); | 110 | EXPORT_SYMBOL(iwl_scan_cancel_timeout); |
121 | 111 | ||
122 | static int iwl_send_scan_abort(struct iwl_priv *priv) | 112 | int iwl_send_scan_abort(struct iwl_priv *priv) |
123 | { | 113 | { |
124 | int ret = 0; | 114 | int ret = 0; |
125 | struct iwl_rx_packet *res; | 115 | struct iwl_rx_packet *res; |
@@ -160,7 +150,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
160 | 150 | ||
161 | return ret; | 151 | return ret; |
162 | } | 152 | } |
163 | 153 | EXPORT_SYMBOL(iwl_send_scan_abort); | |
164 | 154 | ||
165 | /* Service response to REPLY_SCAN_CMD (0x80) */ | 155 | /* Service response to REPLY_SCAN_CMD (0x80) */ |
166 | static void iwl_rx_reply_scan(struct iwl_priv *priv, | 156 | static void iwl_rx_reply_scan(struct iwl_priv *priv, |
@@ -296,9 +286,9 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) | |||
296 | } | 286 | } |
297 | EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); | 287 | EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); |
298 | 288 | ||
299 | static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, | 289 | inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, |
300 | enum ieee80211_band band, | 290 | enum ieee80211_band band, |
301 | u8 n_probes) | 291 | u8 n_probes) |
302 | { | 292 | { |
303 | if (band == IEEE80211_BAND_5GHZ) | 293 | if (band == IEEE80211_BAND_5GHZ) |
304 | return IWL_ACTIVE_DWELL_TIME_52 + | 294 | return IWL_ACTIVE_DWELL_TIME_52 + |
@@ -307,9 +297,10 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, | |||
307 | return IWL_ACTIVE_DWELL_TIME_24 + | 297 | return IWL_ACTIVE_DWELL_TIME_24 + |
308 | IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); | 298 | IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); |
309 | } | 299 | } |
300 | EXPORT_SYMBOL(iwl_get_active_dwell_time); | ||
310 | 301 | ||
311 | static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | 302 | u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, |
312 | enum ieee80211_band band) | 303 | enum ieee80211_band band) |
313 | { | 304 | { |
314 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? | 305 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
315 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 306 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
@@ -327,6 +318,7 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | |||
327 | 318 | ||
328 | return passive; | 319 | return passive; |
329 | } | 320 | } |
321 | EXPORT_SYMBOL(iwl_get_passive_dwell_time); | ||
330 | 322 | ||
331 | static int iwl_get_channels_for_scan(struct iwl_priv *priv, | 323 | static int iwl_get_channels_for_scan(struct iwl_priv *priv, |
332 | enum ieee80211_band band, | 324 | enum ieee80211_band band, |
@@ -450,7 +442,7 @@ EXPORT_SYMBOL(iwl_scan_initiate); | |||
450 | 442 | ||
451 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 443 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
452 | 444 | ||
453 | static void iwl_bg_scan_check(struct work_struct *data) | 445 | void iwl_bg_scan_check(struct work_struct *data) |
454 | { | 446 | { |
455 | struct iwl_priv *priv = | 447 | struct iwl_priv *priv = |
456 | container_of(data, struct iwl_priv, scan_check.work); | 448 | container_of(data, struct iwl_priv, scan_check.work); |
@@ -470,6 +462,8 @@ static void iwl_bg_scan_check(struct work_struct *data) | |||
470 | } | 462 | } |
471 | mutex_unlock(&priv->mutex); | 463 | mutex_unlock(&priv->mutex); |
472 | } | 464 | } |
465 | EXPORT_SYMBOL(iwl_bg_scan_check); | ||
466 | |||
473 | /** | 467 | /** |
474 | * iwl_supported_rate_to_ie - fill in the supported rate in IE field | 468 | * iwl_supported_rate_to_ie - fill in the supported rate in IE field |
475 | * | 469 | * |
@@ -527,10 +521,10 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, | |||
527 | * iwl_fill_probe_req - fill in all required fields and IE for probe request | 521 | * iwl_fill_probe_req - fill in all required fields and IE for probe request |
528 | */ | 522 | */ |
529 | 523 | ||
530 | static u16 iwl_fill_probe_req(struct iwl_priv *priv, | 524 | u16 iwl_fill_probe_req(struct iwl_priv *priv, |
531 | enum ieee80211_band band, | 525 | enum ieee80211_band band, |
532 | struct ieee80211_mgmt *frame, | 526 | struct ieee80211_mgmt *frame, |
533 | int left) | 527 | int left) |
534 | { | 528 | { |
535 | int len = 0; | 529 | int len = 0; |
536 | u8 *pos = NULL; | 530 | u8 *pos = NULL; |
@@ -624,6 +618,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
624 | 618 | ||
625 | return (u16)len; | 619 | return (u16)len; |
626 | } | 620 | } |
621 | EXPORT_SYMBOL(iwl_fill_probe_req); | ||
627 | 622 | ||
628 | static void iwl_bg_request_scan(struct work_struct *data) | 623 | static void iwl_bg_request_scan(struct work_struct *data) |
629 | { | 624 | { |
@@ -650,7 +645,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
650 | mutex_lock(&priv->mutex); | 645 | mutex_lock(&priv->mutex); |
651 | 646 | ||
652 | if (!iwl_is_ready(priv)) { | 647 | if (!iwl_is_ready(priv)) { |
653 | IWL_WARNING("request scan called when driver not ready.\n"); | 648 | IWL_WARN(priv, "request scan called when driver not ready.\n"); |
654 | goto done; | 649 | goto done; |
655 | } | 650 | } |
656 | 651 | ||
@@ -773,7 +768,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
773 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) | 768 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) |
774 | rx_chain = 0x6; | 769 | rx_chain = 0x6; |
775 | } else { | 770 | } else { |
776 | IWL_WARNING("Invalid scan band count\n"); | 771 | IWL_WARN(priv, "Invalid scan band count\n"); |
777 | goto done; | 772 | goto done; |
778 | } | 773 | } |
779 | 774 | ||
@@ -839,7 +834,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
839 | mutex_unlock(&priv->mutex); | 834 | mutex_unlock(&priv->mutex); |
840 | } | 835 | } |
841 | 836 | ||
842 | static void iwl_bg_abort_scan(struct work_struct *work) | 837 | void iwl_bg_abort_scan(struct work_struct *work) |
843 | { | 838 | { |
844 | struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); | 839 | struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); |
845 | 840 | ||
@@ -853,8 +848,9 @@ static void iwl_bg_abort_scan(struct work_struct *work) | |||
853 | 848 | ||
854 | mutex_unlock(&priv->mutex); | 849 | mutex_unlock(&priv->mutex); |
855 | } | 850 | } |
851 | EXPORT_SYMBOL(iwl_bg_abort_scan); | ||
856 | 852 | ||
857 | static void iwl_bg_scan_completed(struct work_struct *work) | 853 | void iwl_bg_scan_completed(struct work_struct *work) |
858 | { | 854 | { |
859 | struct iwl_priv *priv = | 855 | struct iwl_priv *priv = |
860 | container_of(work, struct iwl_priv, scan_completed); | 856 | container_of(work, struct iwl_priv, scan_completed); |
@@ -872,7 +868,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) | |||
872 | iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); | 868 | iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); |
873 | mutex_unlock(&priv->mutex); | 869 | mutex_unlock(&priv->mutex); |
874 | } | 870 | } |
875 | 871 | EXPORT_SYMBOL(iwl_bg_scan_completed); | |
876 | 872 | ||
877 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv) | 873 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv) |
878 | { | 874 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c index 836c3c80b69e..aba1ef22fc61 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -146,7 +146,7 @@ static int iwl_get_measurement(struct iwl_priv *priv, | |||
146 | 146 | ||
147 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; | 147 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
148 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 148 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
149 | IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); | 149 | IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); |
150 | rc = -EIO; | 150 | rc = -EIO; |
151 | } | 151 | } |
152 | 152 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h index b7d7943e476b..a77c1e619062 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ieee80211 subsystem header files. | 5 | * Portions of this file are derived from the ieee80211 subsystem header files. |
6 | * | 6 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 412f66bac1af..9bba98e5e056 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -86,8 +86,10 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) | |||
86 | 86 | ||
87 | spin_lock_irqsave(&priv->sta_lock, flags); | 87 | spin_lock_irqsave(&priv->sta_lock, flags); |
88 | 88 | ||
89 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) | 89 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && |
90 | IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id); | 90 | !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE)) |
91 | IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", | ||
92 | sta_id); | ||
91 | 93 | ||
92 | priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; | 94 | priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; |
93 | IWL_DEBUG_ASSOC("Added STA to Ucode: %pM\n", | 95 | IWL_DEBUG_ASSOC("Added STA to Ucode: %pM\n", |
@@ -105,13 +107,13 @@ static int iwl_add_sta_callback(struct iwl_priv *priv, | |||
105 | u8 sta_id = addsta->sta.sta_id; | 107 | u8 sta_id = addsta->sta.sta_id; |
106 | 108 | ||
107 | if (!skb) { | 109 | if (!skb) { |
108 | IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n"); | 110 | IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n"); |
109 | return 1; | 111 | return 1; |
110 | } | 112 | } |
111 | 113 | ||
112 | res = (struct iwl_rx_packet *)skb->data; | 114 | res = (struct iwl_rx_packet *)skb->data; |
113 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 115 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
114 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | 116 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", |
115 | res->hdr.flags); | 117 | res->hdr.flags); |
116 | return 1; | 118 | return 1; |
117 | } | 119 | } |
@@ -130,7 +132,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv, | |||
130 | return 1; | 132 | return 1; |
131 | } | 133 | } |
132 | 134 | ||
133 | static int iwl_send_add_sta(struct iwl_priv *priv, | 135 | int iwl_send_add_sta(struct iwl_priv *priv, |
134 | struct iwl_addsta_cmd *sta, u8 flags) | 136 | struct iwl_addsta_cmd *sta, u8 flags) |
135 | { | 137 | { |
136 | struct iwl_rx_packet *res = NULL; | 138 | struct iwl_rx_packet *res = NULL; |
@@ -155,7 +157,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv, | |||
155 | 157 | ||
156 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; | 158 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
157 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 159 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
158 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | 160 | IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", |
159 | res->hdr.flags); | 161 | res->hdr.flags); |
160 | ret = -EIO; | 162 | ret = -EIO; |
161 | } | 163 | } |
@@ -168,7 +170,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv, | |||
168 | break; | 170 | break; |
169 | default: | 171 | default: |
170 | ret = -EIO; | 172 | ret = -EIO; |
171 | IWL_WARNING("REPLY_ADD_STA failed\n"); | 173 | IWL_WARN(priv, "REPLY_ADD_STA failed\n"); |
172 | break; | 174 | break; |
173 | } | 175 | } |
174 | } | 176 | } |
@@ -178,6 +180,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv, | |||
178 | 180 | ||
179 | return ret; | 181 | return ret; |
180 | } | 182 | } |
183 | EXPORT_SYMBOL(iwl_send_add_sta); | ||
181 | 184 | ||
182 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | 185 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, |
183 | struct ieee80211_sta_ht_cap *sta_ht_inf) | 186 | struct ieee80211_sta_ht_cap *sta_ht_inf) |
@@ -204,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | |||
204 | case WLAN_HT_CAP_SM_PS_DISABLED: | 207 | case WLAN_HT_CAP_SM_PS_DISABLED: |
205 | break; | 208 | break; |
206 | default: | 209 | default: |
207 | IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode); | 210 | IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode); |
208 | break; | 211 | break; |
209 | } | 212 | } |
210 | 213 | ||
@@ -307,7 +310,7 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) | |||
307 | 310 | ||
308 | /* Ucode must be active and driver must be non active */ | 311 | /* Ucode must be active and driver must be non active */ |
309 | if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE) | 312 | if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE) |
310 | IWL_ERROR("removed non active STA %d\n", sta_id); | 313 | IWL_ERR(priv, "removed non active STA %d\n", sta_id); |
311 | 314 | ||
312 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; | 315 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; |
313 | 316 | ||
@@ -324,13 +327,13 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv, | |||
324 | const char *addr = rm_sta->addr; | 327 | const char *addr = rm_sta->addr; |
325 | 328 | ||
326 | if (!skb) { | 329 | if (!skb) { |
327 | IWL_ERROR("Error: Response NULL in REPLY_REMOVE_STA.\n"); | 330 | IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n"); |
328 | return 1; | 331 | return 1; |
329 | } | 332 | } |
330 | 333 | ||
331 | res = (struct iwl_rx_packet *)skb->data; | 334 | res = (struct iwl_rx_packet *)skb->data; |
332 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 335 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
333 | IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 336 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
334 | res->hdr.flags); | 337 | res->hdr.flags); |
335 | return 1; | 338 | return 1; |
336 | } | 339 | } |
@@ -340,7 +343,7 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv, | |||
340 | iwl_sta_ucode_deactivate(priv, addr); | 343 | iwl_sta_ucode_deactivate(priv, addr); |
341 | break; | 344 | break; |
342 | default: | 345 | default: |
343 | IWL_ERROR("REPLY_REMOVE_STA failed\n"); | 346 | IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); |
344 | break; | 347 | break; |
345 | } | 348 | } |
346 | 349 | ||
@@ -378,7 +381,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
378 | 381 | ||
379 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; | 382 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
380 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 383 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
381 | IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n", | 384 | IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", |
382 | res->hdr.flags); | 385 | res->hdr.flags); |
383 | ret = -EIO; | 386 | ret = -EIO; |
384 | } | 387 | } |
@@ -391,7 +394,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
391 | break; | 394 | break; |
392 | default: | 395 | default: |
393 | ret = -EIO; | 396 | ret = -EIO; |
394 | IWL_ERROR("REPLY_REMOVE_STA failed\n"); | 397 | IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); |
395 | break; | 398 | break; |
396 | } | 399 | } |
397 | } | 400 | } |
@@ -433,13 +436,13 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
433 | sta_id, addr); | 436 | sta_id, addr); |
434 | 437 | ||
435 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | 438 | if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { |
436 | IWL_ERROR("Removing %pM but non DRIVER active\n", | 439 | IWL_ERR(priv, "Removing %pM but non DRIVER active\n", |
437 | addr); | 440 | addr); |
438 | goto out; | 441 | goto out; |
439 | } | 442 | } |
440 | 443 | ||
441 | if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { | 444 | if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { |
442 | IWL_ERROR("Removing %pM but non UCODE active\n", | 445 | IWL_ERR(priv, "Removing %pM but non UCODE active\n", |
443 | addr); | 446 | addr); |
444 | goto out; | 447 | goto out; |
445 | } | 448 | } |
@@ -475,7 +478,7 @@ void iwl_clear_stations_table(struct iwl_priv *priv) | |||
475 | if (iwl_is_alive(priv) && | 478 | if (iwl_is_alive(priv) && |
476 | !test_bit(STATUS_EXIT_PENDING, &priv->status) && | 479 | !test_bit(STATUS_EXIT_PENDING, &priv->status) && |
477 | iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL)) | 480 | iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL)) |
478 | IWL_ERROR("Couldn't clear the station table\n"); | 481 | IWL_ERR(priv, "Couldn't clear the station table\n"); |
479 | 482 | ||
480 | priv->num_stations = 0; | 483 | priv->num_stations = 0; |
481 | memset(priv->stations, 0, sizeof(priv->stations)); | 484 | memset(priv->stations, 0, sizeof(priv->stations)); |
@@ -548,7 +551,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
548 | spin_lock_irqsave(&priv->sta_lock, flags); | 551 | spin_lock_irqsave(&priv->sta_lock, flags); |
549 | 552 | ||
550 | if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table)) | 553 | if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table)) |
551 | IWL_ERROR("index %d not used in uCode key table.\n", | 554 | IWL_ERR(priv, "index %d not used in uCode key table.\n", |
552 | keyconf->keyidx); | 555 | keyconf->keyidx); |
553 | 556 | ||
554 | priv->default_wep_key--; | 557 | priv->default_wep_key--; |
@@ -582,7 +585,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
582 | priv->default_wep_key++; | 585 | priv->default_wep_key++; |
583 | 586 | ||
584 | if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) | 587 | if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) |
585 | IWL_ERROR("index %d already used in uCode key table.\n", | 588 | IWL_ERR(priv, "index %d already used in uCode key table.\n", |
586 | keyconf->keyidx); | 589 | keyconf->keyidx); |
587 | 590 | ||
588 | priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; | 591 | priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; |
@@ -638,7 +641,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | |||
638 | * in uCode. */ | 641 | * in uCode. */ |
639 | 642 | ||
640 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, | 643 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, |
641 | "no space for new kew"); | 644 | "no space for a new key"); |
642 | 645 | ||
643 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 646 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
644 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 647 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
@@ -686,7 +689,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | |||
686 | * in uCode. */ | 689 | * in uCode. */ |
687 | 690 | ||
688 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, | 691 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, |
689 | "no space for new kew"); | 692 | "no space for a new key"); |
690 | 693 | ||
691 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 694 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
692 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 695 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
@@ -722,7 +725,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, | |||
722 | * in uCode. */ | 725 | * in uCode. */ |
723 | 726 | ||
724 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, | 727 | WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, |
725 | "no space for new kew"); | 728 | "no space for a new key"); |
726 | 729 | ||
727 | /* This copy is acutally not needed: we get the key with each TX */ | 730 | /* This copy is acutally not needed: we get the key with each TX */ |
728 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); | 731 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); |
@@ -812,7 +815,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
812 | } | 815 | } |
813 | 816 | ||
814 | if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { | 817 | if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { |
815 | IWL_WARNING("Removing wrong key %d 0x%x\n", | 818 | IWL_WARN(priv, "Removing wrong key %d 0x%x\n", |
816 | keyconf->keyidx, key_flags); | 819 | keyconf->keyidx, key_flags); |
817 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 820 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
818 | return 0; | 821 | return 0; |
@@ -820,7 +823,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
820 | 823 | ||
821 | if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, | 824 | if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, |
822 | &priv->ucode_key_table)) | 825 | &priv->ucode_key_table)) |
823 | IWL_ERROR("index %d not used in uCode key table.\n", | 826 | IWL_ERR(priv, "index %d not used in uCode key table.\n", |
824 | priv->stations[sta_id].sta.key.key_offset); | 827 | priv->stations[sta_id].sta.key.key_offset); |
825 | memset(&priv->stations[sta_id].keyinfo, 0, | 828 | memset(&priv->stations[sta_id].keyinfo, 0, |
826 | sizeof(struct iwl_hw_key)); | 829 | sizeof(struct iwl_hw_key)); |
@@ -857,7 +860,8 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
857 | ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id); | 860 | ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id); |
858 | break; | 861 | break; |
859 | default: | 862 | default: |
860 | IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg); | 863 | IWL_ERR(priv, |
864 | "Unknown alg: %s alg = %d\n", __func__, keyconf->alg); | ||
861 | ret = -EINVAL; | 865 | ret = -EINVAL; |
862 | } | 866 | } |
863 | 867 | ||
@@ -1069,7 +1073,8 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) | |||
1069 | return priv->hw_params.bcast_sta_id; | 1073 | return priv->hw_params.bcast_sta_id; |
1070 | 1074 | ||
1071 | default: | 1075 | default: |
1072 | IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode); | 1076 | IWL_WARN(priv, "Unknown mode of operation: %d\n", |
1077 | priv->iw_mode); | ||
1073 | return priv->hw_params.bcast_sta_id; | 1078 | return priv->hw_params.bcast_sta_id; |
1074 | } | 1079 | } |
1075 | } | 1080 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 9bb7cefc1f3c..97f6169007f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -56,6 +56,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | |||
56 | void iwl_clear_stations_table(struct iwl_priv *priv); | 56 | void iwl_clear_stations_table(struct iwl_priv *priv); |
57 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 57 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
58 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 58 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
59 | int iwl_send_add_sta(struct iwl_priv *priv, | ||
60 | struct iwl_addsta_cmd *sta, u8 flags); | ||
59 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, | 61 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, |
60 | int is_ap, u8 flags, | 62 | int is_ap, u8 flags, |
61 | struct ieee80211_sta_ht_cap *ht_info); | 63 | struct ieee80211_sta_ht_cap *ht_info); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index b0ee86c62685..7d2b6e11f73e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -76,116 +76,6 @@ static inline void iwl_free_dma_ptr(struct iwl_priv *priv, | |||
76 | memset(ptr, 0, sizeof(*ptr)); | 76 | memset(ptr, 0, sizeof(*ptr)); |
77 | } | 77 | } |
78 | 78 | ||
79 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | ||
80 | { | ||
81 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
82 | |||
83 | dma_addr_t addr = get_unaligned_le32(&tb->lo); | ||
84 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
85 | addr |= | ||
86 | ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16; | ||
87 | |||
88 | return addr; | ||
89 | } | ||
90 | |||
91 | static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) | ||
92 | { | ||
93 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
94 | |||
95 | return le16_to_cpu(tb->hi_n_len) >> 4; | ||
96 | } | ||
97 | |||
98 | static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, | ||
99 | dma_addr_t addr, u16 len) | ||
100 | { | ||
101 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | ||
102 | u16 hi_n_len = len << 4; | ||
103 | |||
104 | put_unaligned_le32(addr, &tb->lo); | ||
105 | if (sizeof(dma_addr_t) > sizeof(u32)) | ||
106 | hi_n_len |= ((addr >> 16) >> 16) & 0xF; | ||
107 | |||
108 | tb->hi_n_len = cpu_to_le16(hi_n_len); | ||
109 | |||
110 | tfd->num_tbs = idx + 1; | ||
111 | } | ||
112 | |||
113 | static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | ||
114 | { | ||
115 | return tfd->num_tbs & 0x1f; | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
120 | * @priv - driver private data | ||
121 | * @txq - tx queue | ||
122 | * | ||
123 | * Does NOT advance any TFD circular buffer read/write indexes | ||
124 | * Does NOT free the TFD itself (which is within circular buffer) | ||
125 | */ | ||
126 | static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | ||
127 | { | ||
128 | struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)&txq->tfds[0]; | ||
129 | struct iwl_tfd *tfd; | ||
130 | struct pci_dev *dev = priv->pci_dev; | ||
131 | int index = txq->q.read_ptr; | ||
132 | int i; | ||
133 | int num_tbs; | ||
134 | |||
135 | tfd = &tfd_tmp[index]; | ||
136 | |||
137 | /* Sanity check on number of chunks */ | ||
138 | num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
139 | |||
140 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
141 | IWL_ERROR("Too many chunks: %i\n", num_tbs); | ||
142 | /* @todo issue fatal error, it is quite serious situation */ | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | /* Unmap tx_cmd */ | ||
147 | if (num_tbs) | ||
148 | pci_unmap_single(dev, | ||
149 | pci_unmap_addr(&txq->cmd[index]->meta, mapping), | ||
150 | pci_unmap_len(&txq->cmd[index]->meta, len), | ||
151 | PCI_DMA_TODEVICE); | ||
152 | |||
153 | /* Unmap chunks, if any. */ | ||
154 | for (i = 1; i < num_tbs; i++) { | ||
155 | pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), | ||
156 | iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); | ||
157 | |||
158 | if (txq->txb) { | ||
159 | dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]); | ||
160 | txq->txb[txq->q.read_ptr].skb[i - 1] = NULL; | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, | ||
166 | struct iwl_tfd *tfd, | ||
167 | dma_addr_t addr, u16 len) | ||
168 | { | ||
169 | |||
170 | u32 num_tbs = iwl_tfd_get_num_tbs(tfd); | ||
171 | |||
172 | /* Each TFD can point to a maximum 20 Tx buffers */ | ||
173 | if (num_tbs >= IWL_NUM_OF_TBS) { | ||
174 | IWL_ERROR("Error can not send more than %d chunks\n", | ||
175 | IWL_NUM_OF_TBS); | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | BUG_ON(addr & ~DMA_BIT_MASK(36)); | ||
180 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) | ||
181 | IWL_ERROR("Unaligned address = %llx\n", | ||
182 | (unsigned long long)addr); | ||
183 | |||
184 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | /** | 79 | /** |
190 | * iwl_txq_update_write_ptr - Send new write index to hardware | 80 | * iwl_txq_update_write_ptr - Send new write index to hardware |
191 | */ | 81 | */ |
@@ -241,7 +131,7 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr); | |||
241 | * Free all buffers. | 131 | * Free all buffers. |
242 | * 0-fill, but do not free "txq" descriptor structure. | 132 | * 0-fill, but do not free "txq" descriptor structure. |
243 | */ | 133 | */ |
244 | static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | 134 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) |
245 | { | 135 | { |
246 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 136 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
247 | struct iwl_queue *q = &txq->q; | 137 | struct iwl_queue *q = &txq->q; |
@@ -254,7 +144,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | |||
254 | /* first, empty all BD's */ | 144 | /* first, empty all BD's */ |
255 | for (; q->write_ptr != q->read_ptr; | 145 | for (; q->write_ptr != q->read_ptr; |
256 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | 146 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) |
257 | iwl_hw_txq_free_tfd(priv, txq); | 147 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
258 | 148 | ||
259 | len = sizeof(struct iwl_cmd) * q->n_window; | 149 | len = sizeof(struct iwl_cmd) * q->n_window; |
260 | 150 | ||
@@ -264,7 +154,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | |||
264 | 154 | ||
265 | /* De-alloc circular buffer of TFDs */ | 155 | /* De-alloc circular buffer of TFDs */ |
266 | if (txq->q.n_bd) | 156 | if (txq->q.n_bd) |
267 | pci_free_consistent(dev, sizeof(struct iwl_tfd) * | 157 | pci_free_consistent(dev, priv->hw_params.tfd_size * |
268 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | 158 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); |
269 | 159 | ||
270 | /* De-alloc array of per-TFD driver data */ | 160 | /* De-alloc array of per-TFD driver data */ |
@@ -274,7 +164,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) | |||
274 | /* 0-fill queue descriptor structure */ | 164 | /* 0-fill queue descriptor structure */ |
275 | memset(txq, 0, sizeof(*txq)); | 165 | memset(txq, 0, sizeof(*txq)); |
276 | } | 166 | } |
277 | 167 | EXPORT_SYMBOL(iwl_tx_queue_free); | |
278 | 168 | ||
279 | /** | 169 | /** |
280 | * iwl_cmd_queue_free - Deallocate DMA queue. | 170 | * iwl_cmd_queue_free - Deallocate DMA queue. |
@@ -388,6 +278,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, | |||
388 | struct iwl_tx_queue *txq, u32 id) | 278 | struct iwl_tx_queue *txq, u32 id) |
389 | { | 279 | { |
390 | struct pci_dev *dev = priv->pci_dev; | 280 | struct pci_dev *dev = priv->pci_dev; |
281 | size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX; | ||
391 | 282 | ||
392 | /* Driver private data, only for Tx (not command) queues, | 283 | /* Driver private data, only for Tx (not command) queues, |
393 | * not shared with device. */ | 284 | * not shared with device. */ |
@@ -395,22 +286,20 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, | |||
395 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | 286 | txq->txb = kmalloc(sizeof(txq->txb[0]) * |
396 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | 287 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); |
397 | if (!txq->txb) { | 288 | if (!txq->txb) { |
398 | IWL_ERROR("kmalloc for auxiliary BD " | 289 | IWL_ERR(priv, "kmalloc for auxiliary BD " |
399 | "structures failed\n"); | 290 | "structures failed\n"); |
400 | goto error; | 291 | goto error; |
401 | } | 292 | } |
402 | } else | 293 | } else { |
403 | txq->txb = NULL; | 294 | txq->txb = NULL; |
295 | } | ||
404 | 296 | ||
405 | /* Circular buffer of transmit frame descriptors (TFDs), | 297 | /* Circular buffer of transmit frame descriptors (TFDs), |
406 | * shared with device */ | 298 | * shared with device */ |
407 | txq->tfds = pci_alloc_consistent(dev, | 299 | txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr); |
408 | sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX, | ||
409 | &txq->q.dma_addr); | ||
410 | 300 | ||
411 | if (!txq->tfds) { | 301 | if (!txq->tfds) { |
412 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | 302 | IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz); |
413 | sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX); | ||
414 | goto error; | 303 | goto error; |
415 | } | 304 | } |
416 | txq->q.id = id; | 305 | txq->q.id = id; |
@@ -424,42 +313,11 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, | |||
424 | return -ENOMEM; | 313 | return -ENOMEM; |
425 | } | 314 | } |
426 | 315 | ||
427 | /* | ||
428 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
429 | * given Tx queue, and enable the DMA channel used for that queue. | ||
430 | * | ||
431 | * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
432 | * channels supported in hardware. | ||
433 | */ | ||
434 | static int iwl_hw_tx_queue_init(struct iwl_priv *priv, | ||
435 | struct iwl_tx_queue *txq) | ||
436 | { | ||
437 | int ret; | ||
438 | unsigned long flags; | ||
439 | int txq_id = txq->q.id; | ||
440 | |||
441 | spin_lock_irqsave(&priv->lock, flags); | ||
442 | ret = iwl_grab_nic_access(priv); | ||
443 | if (ret) { | ||
444 | spin_unlock_irqrestore(&priv->lock, flags); | ||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
449 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
450 | txq->q.dma_addr >> 8); | ||
451 | |||
452 | iwl_release_nic_access(priv); | ||
453 | spin_unlock_irqrestore(&priv->lock, flags); | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | /** | 316 | /** |
459 | * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue | 317 | * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue |
460 | */ | 318 | */ |
461 | static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 319 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
462 | int slots_num, u32 txq_id) | 320 | int slots_num, u32 txq_id) |
463 | { | 321 | { |
464 | int i, len; | 322 | int i, len; |
465 | int ret; | 323 | int ret; |
@@ -501,7 +359,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | |||
501 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | 359 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); |
502 | 360 | ||
503 | /* Tell device where to find queue */ | 361 | /* Tell device where to find queue */ |
504 | iwl_hw_tx_queue_init(priv, txq); | 362 | priv->cfg->ops->lib->txq_init(priv, txq); |
505 | 363 | ||
506 | return 0; | 364 | return 0; |
507 | err: | 365 | err: |
@@ -516,6 +374,8 @@ err: | |||
516 | } | 374 | } |
517 | return -ENOMEM; | 375 | return -ENOMEM; |
518 | } | 376 | } |
377 | EXPORT_SYMBOL(iwl_tx_queue_init); | ||
378 | |||
519 | /** | 379 | /** |
520 | * iwl_hw_txq_ctx_free - Free TXQ Context | 380 | * iwl_hw_txq_ctx_free - Free TXQ Context |
521 | * | 381 | * |
@@ -557,13 +417,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) | |||
557 | ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls, | 417 | ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls, |
558 | priv->hw_params.scd_bc_tbls_size); | 418 | priv->hw_params.scd_bc_tbls_size); |
559 | if (ret) { | 419 | if (ret) { |
560 | IWL_ERROR("Scheduler BC Table allocation failed\n"); | 420 | IWL_ERR(priv, "Scheduler BC Table allocation failed\n"); |
561 | goto error_bc_tbls; | 421 | goto error_bc_tbls; |
562 | } | 422 | } |
563 | /* Alloc keep-warm buffer */ | 423 | /* Alloc keep-warm buffer */ |
564 | ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE); | 424 | ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE); |
565 | if (ret) { | 425 | if (ret) { |
566 | IWL_ERROR("Keep Warm allocation failed\n"); | 426 | IWL_ERR(priv, "Keep Warm allocation failed\n"); |
567 | goto error_kw; | 427 | goto error_kw; |
568 | } | 428 | } |
569 | spin_lock_irqsave(&priv->lock, flags); | 429 | spin_lock_irqsave(&priv->lock, flags); |
@@ -589,7 +449,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) | |||
589 | ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | 449 | ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, |
590 | txq_id); | 450 | txq_id); |
591 | if (ret) { | 451 | if (ret) { |
592 | IWL_ERROR("Tx %d queue init failed\n", txq_id); | 452 | IWL_ERR(priv, "Tx %d queue init failed\n", txq_id); |
593 | goto error; | 453 | goto error; |
594 | } | 454 | } |
595 | } | 455 | } |
@@ -802,7 +662,7 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
802 | break; | 662 | break; |
803 | 663 | ||
804 | default: | 664 | default: |
805 | printk(KERN_ERR "Unknown encode alg %d\n", keyconf->alg); | 665 | IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg); |
806 | break; | 666 | break; |
807 | } | 667 | } |
808 | } | 668 | } |
@@ -822,7 +682,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
822 | { | 682 | { |
823 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 683 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
824 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 684 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
825 | struct iwl_tfd *tfd; | ||
826 | struct iwl_tx_queue *txq; | 685 | struct iwl_tx_queue *txq; |
827 | struct iwl_queue *q; | 686 | struct iwl_queue *q; |
828 | struct iwl_cmd *out_cmd; | 687 | struct iwl_cmd *out_cmd; |
@@ -850,7 +709,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
850 | 709 | ||
851 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == | 710 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == |
852 | IWL_INVALID_RATE) { | 711 | IWL_INVALID_RATE) { |
853 | IWL_ERROR("ERROR: No TX rate available.\n"); | 712 | IWL_ERR(priv, "ERROR: No TX rate available.\n"); |
854 | goto drop_unlock; | 713 | goto drop_unlock; |
855 | } | 714 | } |
856 | 715 | ||
@@ -913,10 +772,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
913 | 772 | ||
914 | spin_lock_irqsave(&priv->lock, flags); | 773 | spin_lock_irqsave(&priv->lock, flags); |
915 | 774 | ||
916 | /* Set up first empty TFD within this queue's circular TFD buffer */ | ||
917 | tfd = &txq->tfds[q->write_ptr]; | ||
918 | memset(tfd, 0, sizeof(*tfd)); | ||
919 | |||
920 | /* Set up driver data for this TFD */ | 775 | /* Set up driver data for this TFD */ |
921 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); | 776 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); |
922 | txq->txb[q->write_ptr].skb[0] = skb; | 777 | txq->txb[q->write_ptr].skb[0] = skb; |
@@ -970,7 +825,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
970 | /* Add buffer containing Tx command and MAC(!) header to TFD's | 825 | /* Add buffer containing Tx command and MAC(!) header to TFD's |
971 | * first entry */ | 826 | * first entry */ |
972 | txcmd_phys += offsetof(struct iwl_cmd, hdr); | 827 | txcmd_phys += offsetof(struct iwl_cmd, hdr); |
973 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 828 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
829 | txcmd_phys, len, 1, 0); | ||
974 | 830 | ||
975 | if (info->control.hw_key) | 831 | if (info->control.hw_key) |
976 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); | 832 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); |
@@ -981,7 +837,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
981 | if (len) { | 837 | if (len) { |
982 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, | 838 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, |
983 | len, PCI_DMA_TODEVICE); | 839 | len, PCI_DMA_TODEVICE); |
984 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); | 840 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
841 | phys_addr, len, | ||
842 | 0, 0); | ||
985 | } | 843 | } |
986 | 844 | ||
987 | /* Tell NIC about any 2-byte padding after MAC header */ | 845 | /* Tell NIC about any 2-byte padding after MAC header */ |
@@ -1063,7 +921,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1063 | { | 921 | { |
1064 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | 922 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; |
1065 | struct iwl_queue *q = &txq->q; | 923 | struct iwl_queue *q = &txq->q; |
1066 | struct iwl_tfd *tfd; | ||
1067 | struct iwl_cmd *out_cmd; | 924 | struct iwl_cmd *out_cmd; |
1068 | dma_addr_t phys_addr; | 925 | dma_addr_t phys_addr; |
1069 | unsigned long flags; | 926 | unsigned long flags; |
@@ -1086,16 +943,12 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1086 | } | 943 | } |
1087 | 944 | ||
1088 | if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { | 945 | if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { |
1089 | IWL_ERROR("No space for Tx\n"); | 946 | IWL_ERR(priv, "No space for Tx\n"); |
1090 | return -ENOSPC; | 947 | return -ENOSPC; |
1091 | } | 948 | } |
1092 | 949 | ||
1093 | spin_lock_irqsave(&priv->hcmd_lock, flags); | 950 | spin_lock_irqsave(&priv->hcmd_lock, flags); |
1094 | 951 | ||
1095 | tfd = &txq->tfds[q->write_ptr]; | ||
1096 | memset(tfd, 0, sizeof(*tfd)); | ||
1097 | |||
1098 | |||
1099 | idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); | 952 | idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); |
1100 | out_cmd = txq->cmd[idx]; | 953 | out_cmd = txq->cmd[idx]; |
1101 | 954 | ||
@@ -1120,7 +973,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1120 | pci_unmap_len_set(&out_cmd->meta, len, len); | 973 | pci_unmap_len_set(&out_cmd->meta, len, len); |
1121 | phys_addr += offsetof(struct iwl_cmd, hdr); | 974 | phys_addr += offsetof(struct iwl_cmd, hdr); |
1122 | 975 | ||
1123 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); | 976 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
977 | phys_addr, fix_size, 1, | ||
978 | U32_PAD(cmd->len)); | ||
1124 | 979 | ||
1125 | #ifdef CONFIG_IWLWIFI_DEBUG | 980 | #ifdef CONFIG_IWLWIFI_DEBUG |
1126 | switch (out_cmd->hdr.cmd) { | 981 | switch (out_cmd->hdr.cmd) { |
@@ -1144,8 +999,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1144 | #endif | 999 | #endif |
1145 | txq->need_update = 1; | 1000 | txq->need_update = 1; |
1146 | 1001 | ||
1147 | /* Set up entry in queue's byte count circular buffer */ | 1002 | if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl) |
1148 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); | 1003 | /* Set up entry in queue's byte count circular buffer */ |
1004 | priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0); | ||
1149 | 1005 | ||
1150 | /* Increment and update queue's write index */ | 1006 | /* Increment and update queue's write index */ |
1151 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1007 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
@@ -1163,7 +1019,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1163 | int nfreed = 0; | 1019 | int nfreed = 0; |
1164 | 1020 | ||
1165 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { | 1021 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { |
1166 | IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " | 1022 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " |
1167 | "is out of range [0-%d] %d %d.\n", txq_id, | 1023 | "is out of range [0-%d] %d %d.\n", txq_id, |
1168 | index, q->n_bd, q->write_ptr, q->read_ptr); | 1024 | index, q->n_bd, q->write_ptr, q->read_ptr); |
1169 | return 0; | 1025 | return 0; |
@@ -1180,7 +1036,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1180 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) | 1036 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) |
1181 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); | 1037 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); |
1182 | 1038 | ||
1183 | iwl_hw_txq_free_tfd(priv, txq); | 1039 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
1184 | nfreed++; | 1040 | nfreed++; |
1185 | } | 1041 | } |
1186 | return nfreed; | 1042 | return nfreed; |
@@ -1203,7 +1059,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, | |||
1203 | int nfreed = 0; | 1059 | int nfreed = 0; |
1204 | 1060 | ||
1205 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { | 1061 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { |
1206 | IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " | 1062 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " |
1207 | "is out of range [0-%d] %d %d.\n", txq_id, | 1063 | "is out of range [0-%d] %d %d.\n", txq_id, |
1208 | idx, q->n_bd, q->write_ptr, q->read_ptr); | 1064 | idx, q->n_bd, q->write_ptr, q->read_ptr); |
1209 | return; | 1065 | return; |
@@ -1218,7 +1074,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, | |||
1218 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 1074 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
1219 | 1075 | ||
1220 | if (nfreed++ > 0) { | 1076 | if (nfreed++ > 0) { |
1221 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", idx, | 1077 | IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx, |
1222 | q->write_ptr, q->read_ptr); | 1078 | q->write_ptr, q->read_ptr); |
1223 | queue_work(priv->workqueue, &priv->restart); | 1079 | queue_work(priv->workqueue, &priv->restart); |
1224 | } | 1080 | } |
@@ -1306,7 +1162,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) | |||
1306 | else | 1162 | else |
1307 | return -EINVAL; | 1163 | return -EINVAL; |
1308 | 1164 | ||
1309 | IWL_WARNING("%s on ra = %pM tid = %d\n", | 1165 | IWL_WARN(priv, "%s on ra = %pM tid = %d\n", |
1310 | __func__, ra, tid); | 1166 | __func__, ra, tid); |
1311 | 1167 | ||
1312 | sta_id = iwl_find_station(priv, ra); | 1168 | sta_id = iwl_find_station(priv, ra); |
@@ -1314,7 +1170,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) | |||
1314 | return -ENXIO; | 1170 | return -ENXIO; |
1315 | 1171 | ||
1316 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { | 1172 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { |
1317 | IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n"); | 1173 | IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); |
1318 | return -ENXIO; | 1174 | return -ENXIO; |
1319 | } | 1175 | } |
1320 | 1176 | ||
@@ -1334,7 +1190,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) | |||
1334 | return ret; | 1190 | return ret; |
1335 | 1191 | ||
1336 | if (tid_data->tfds_in_queue == 0) { | 1192 | if (tid_data->tfds_in_queue == 0) { |
1337 | printk(KERN_ERR "HW queue is empty\n"); | 1193 | IWL_ERR(priv, "HW queue is empty\n"); |
1338 | tid_data->agg.state = IWL_AGG_ON; | 1194 | tid_data->agg.state = IWL_AGG_ON; |
1339 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid); | 1195 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid); |
1340 | } else { | 1196 | } else { |
@@ -1354,7 +1210,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1354 | unsigned long flags; | 1210 | unsigned long flags; |
1355 | 1211 | ||
1356 | if (!ra) { | 1212 | if (!ra) { |
1357 | IWL_ERROR("ra = NULL\n"); | 1213 | IWL_ERR(priv, "ra = NULL\n"); |
1358 | return -EINVAL; | 1214 | return -EINVAL; |
1359 | } | 1215 | } |
1360 | 1216 | ||
@@ -1369,7 +1225,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1369 | return -ENXIO; | 1225 | return -ENXIO; |
1370 | 1226 | ||
1371 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) | 1227 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) |
1372 | IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n"); | 1228 | IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n"); |
1373 | 1229 | ||
1374 | tid_data = &priv->stations[sta_id].tid[tid]; | 1230 | tid_data = &priv->stations[sta_id].tid[tid]; |
1375 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; | 1231 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; |
@@ -1455,7 +1311,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv, | |||
1455 | struct ieee80211_tx_info *info; | 1311 | struct ieee80211_tx_info *info; |
1456 | 1312 | ||
1457 | if (unlikely(!agg->wait_for_ba)) { | 1313 | if (unlikely(!agg->wait_for_ba)) { |
1458 | IWL_ERROR("Received BA when not expected\n"); | 1314 | IWL_ERR(priv, "Received BA when not expected\n"); |
1459 | return -EINVAL; | 1315 | return -EINVAL; |
1460 | } | 1316 | } |
1461 | 1317 | ||
@@ -1528,7 +1384,8 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1528 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | 1384 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); |
1529 | 1385 | ||
1530 | if (scd_flow >= priv->hw_params.max_txq_num) { | 1386 | if (scd_flow >= priv->hw_params.max_txq_num) { |
1531 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n"); | 1387 | IWL_ERR(priv, |
1388 | "BUG_ON scd_flow is bigger than number of queues\n"); | ||
1532 | return; | 1389 | return; |
1533 | } | 1390 | } |
1534 | 1391 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 95d01984c80e..25a350810a10 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -46,40 +46,25 @@ | |||
46 | 46 | ||
47 | #include <asm/div64.h> | 47 | #include <asm/div64.h> |
48 | 48 | ||
49 | #include "iwl-3945-core.h" | 49 | #define DRV_NAME "iwl3945" |
50 | |||
51 | #include "iwl-fh.h" | ||
52 | #include "iwl-3945-fh.h" | ||
53 | #include "iwl-commands.h" | ||
54 | #include "iwl-sta.h" | ||
50 | #include "iwl-3945.h" | 55 | #include "iwl-3945.h" |
51 | #include "iwl-helpers.h" | 56 | #include "iwl-helpers.h" |
52 | 57 | #include "iwl-core.h" | |
53 | #ifdef CONFIG_IWL3945_DEBUG | 58 | #include "iwl-dev.h" |
54 | u32 iwl3945_debug_level; | ||
55 | #endif | ||
56 | |||
57 | static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv, | ||
58 | struct iwl3945_tx_queue *txq); | ||
59 | |||
60 | /****************************************************************************** | ||
61 | * | ||
62 | * module boiler plate | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | |||
66 | /* module parameters */ | ||
67 | static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */ | ||
68 | static u32 iwl3945_param_debug; /* def: 0 = minimal debug log messages */ | ||
69 | static int iwl3945_param_disable; /* def: 0 = enable radio */ | ||
70 | static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */ | ||
71 | int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */ | ||
72 | int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */ | ||
73 | 59 | ||
74 | /* | 60 | /* |
75 | * module name, copyright, version, etc. | 61 | * module name, copyright, version, etc. |
76 | * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk | ||
77 | */ | 62 | */ |
78 | 63 | ||
79 | #define DRV_DESCRIPTION \ | 64 | #define DRV_DESCRIPTION \ |
80 | "Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux" | 65 | "Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux" |
81 | 66 | ||
82 | #ifdef CONFIG_IWL3945_DEBUG | 67 | #ifdef CONFIG_IWLWIFI_DEBUG |
83 | #define VD "d" | 68 | #define VD "d" |
84 | #else | 69 | #else |
85 | #define VD | 70 | #define VD |
@@ -91,10 +76,10 @@ int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */ | |||
91 | #define VS | 76 | #define VS |
92 | #endif | 77 | #endif |
93 | 78 | ||
94 | #define IWLWIFI_VERSION "1.2.26k" VD VS | 79 | #define IWL39_VERSION "1.2.26k" VD VS |
95 | #define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation" | 80 | #define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" |
96 | #define DRV_AUTHOR "<ilw@linux.intel.com>" | 81 | #define DRV_AUTHOR "<ilw@linux.intel.com>" |
97 | #define DRV_VERSION IWLWIFI_VERSION | 82 | #define DRV_VERSION IWL39_VERSION |
98 | 83 | ||
99 | 84 | ||
100 | MODULE_DESCRIPTION(DRV_DESCRIPTION); | 85 | MODULE_DESCRIPTION(DRV_DESCRIPTION); |
@@ -102,235 +87,13 @@ MODULE_VERSION(DRV_VERSION); | |||
102 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); | 87 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); |
103 | MODULE_LICENSE("GPL"); | 88 | MODULE_LICENSE("GPL"); |
104 | 89 | ||
105 | static const struct ieee80211_supported_band *iwl3945_get_band( | 90 | /* module parameters */ |
106 | struct iwl3945_priv *priv, enum ieee80211_band band) | 91 | struct iwl_mod_params iwl3945_mod_params = { |
107 | { | 92 | .num_of_queues = IWL39_MAX_NUM_QUEUES, |
108 | return priv->hw->wiphy->bands[band]; | 93 | .sw_crypto = 1, |
109 | } | 94 | .restart_fw = 1, |
110 | 95 | /* the rest are 0 by default */ | |
111 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** | 96 | }; |
112 | * DMA services | ||
113 | * | ||
114 | * Theory of operation | ||
115 | * | ||
116 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer | ||
117 | * of buffer descriptors, each of which points to one or more data buffers for | ||
118 | * the device to read from or fill. Driver and device exchange status of each | ||
119 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty | ||
120 | * entries in each circular buffer, to protect against confusing empty and full | ||
121 | * queue states. | ||
122 | * | ||
123 | * The device reads or writes the data in the queues via the device's several | ||
124 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. | ||
125 | * | ||
126 | * For Tx queue, there are low mark and high mark limits. If, after queuing | ||
127 | * the packet for Tx, free space become < low mark, Tx queue stopped. When | ||
128 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | ||
129 | * Tx queue resumed. | ||
130 | * | ||
131 | * The 3945 operates with six queues: One receive queue, one transmit queue | ||
132 | * (#4) for sending commands to the device firmware, and four transmit queues | ||
133 | * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused. | ||
134 | ***************************************************/ | ||
135 | |||
136 | int iwl3945_queue_space(const struct iwl3945_queue *q) | ||
137 | { | ||
138 | int s = q->read_ptr - q->write_ptr; | ||
139 | |||
140 | if (q->read_ptr > q->write_ptr) | ||
141 | s -= q->n_bd; | ||
142 | |||
143 | if (s <= 0) | ||
144 | s += q->n_window; | ||
145 | /* keep some reserve to not confuse empty and full situations */ | ||
146 | s -= 2; | ||
147 | if (s < 0) | ||
148 | s = 0; | ||
149 | return s; | ||
150 | } | ||
151 | |||
152 | int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i) | ||
153 | { | ||
154 | return q->write_ptr > q->read_ptr ? | ||
155 | (i >= q->read_ptr && i < q->write_ptr) : | ||
156 | !(i < q->read_ptr && i >= q->write_ptr); | ||
157 | } | ||
158 | |||
159 | |||
160 | static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge) | ||
161 | { | ||
162 | /* This is for scan command, the big buffer at end of command array */ | ||
163 | if (is_huge) | ||
164 | return q->n_window; /* must be power of 2 */ | ||
165 | |||
166 | /* Otherwise, use normal size buffers */ | ||
167 | return index & (q->n_window - 1); | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes | ||
172 | */ | ||
173 | static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q, | ||
174 | int count, int slots_num, u32 id) | ||
175 | { | ||
176 | q->n_bd = count; | ||
177 | q->n_window = slots_num; | ||
178 | q->id = id; | ||
179 | |||
180 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
181 | * and iwl_queue_dec_wrap are broken. */ | ||
182 | BUG_ON(!is_power_of_2(count)); | ||
183 | |||
184 | /* slots_num must be power-of-two size, otherwise | ||
185 | * get_cmd_index is broken. */ | ||
186 | BUG_ON(!is_power_of_2(slots_num)); | ||
187 | |||
188 | q->low_mark = q->n_window / 4; | ||
189 | if (q->low_mark < 4) | ||
190 | q->low_mark = 4; | ||
191 | |||
192 | q->high_mark = q->n_window / 8; | ||
193 | if (q->high_mark < 2) | ||
194 | q->high_mark = 2; | ||
195 | |||
196 | q->write_ptr = q->read_ptr = 0; | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /** | ||
202 | * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
203 | */ | ||
204 | static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, | ||
205 | struct iwl3945_tx_queue *txq, u32 id) | ||
206 | { | ||
207 | struct pci_dev *dev = priv->pci_dev; | ||
208 | |||
209 | /* Driver private data, only for Tx (not command) queues, | ||
210 | * not shared with device. */ | ||
211 | if (id != IWL_CMD_QUEUE_NUM) { | ||
212 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | ||
213 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | ||
214 | if (!txq->txb) { | ||
215 | IWL_ERROR("kmalloc for auxiliary BD " | ||
216 | "structures failed\n"); | ||
217 | goto error; | ||
218 | } | ||
219 | } else | ||
220 | txq->txb = NULL; | ||
221 | |||
222 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
223 | * shared with device */ | ||
224 | txq->bd = pci_alloc_consistent(dev, | ||
225 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | ||
226 | &txq->q.dma_addr); | ||
227 | |||
228 | if (!txq->bd) { | ||
229 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | ||
230 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); | ||
231 | goto error; | ||
232 | } | ||
233 | txq->q.id = id; | ||
234 | |||
235 | return 0; | ||
236 | |||
237 | error: | ||
238 | kfree(txq->txb); | ||
239 | txq->txb = NULL; | ||
240 | |||
241 | return -ENOMEM; | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
246 | */ | ||
247 | int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | ||
248 | struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id) | ||
249 | { | ||
250 | struct pci_dev *dev = priv->pci_dev; | ||
251 | int len; | ||
252 | int rc = 0; | ||
253 | |||
254 | /* | ||
255 | * Alloc buffer array for commands (Tx or other types of commands). | ||
256 | * For the command queue (#4), allocate command space + one big | ||
257 | * command for scan, since scan command is very huge; the system will | ||
258 | * not have two scans at the same time, so only one is needed. | ||
259 | * For data Tx queues (all other queues), no super-size command | ||
260 | * space is needed. | ||
261 | */ | ||
262 | len = sizeof(struct iwl3945_cmd) * slots_num; | ||
263 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
264 | len += IWL_MAX_SCAN_SIZE; | ||
265 | txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); | ||
266 | if (!txq->cmd) | ||
267 | return -ENOMEM; | ||
268 | |||
269 | /* Alloc driver data array and TFD circular buffer */ | ||
270 | rc = iwl3945_tx_queue_alloc(priv, txq, txq_id); | ||
271 | if (rc) { | ||
272 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
273 | |||
274 | return -ENOMEM; | ||
275 | } | ||
276 | txq->need_update = 0; | ||
277 | |||
278 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
279 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
280 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
281 | |||
282 | /* Initialize queue high/low-water, head/tail indexes */ | ||
283 | iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
284 | |||
285 | /* Tell device where to find queue, enable DMA channel. */ | ||
286 | iwl3945_hw_tx_queue_init(priv, txq); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /** | ||
292 | * iwl3945_tx_queue_free - Deallocate DMA queue. | ||
293 | * @txq: Transmit queue to deallocate. | ||
294 | * | ||
295 | * Empty queue by removing and destroying all BD's. | ||
296 | * Free all buffers. | ||
297 | * 0-fill, but do not free "txq" descriptor structure. | ||
298 | */ | ||
299 | void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) | ||
300 | { | ||
301 | struct iwl3945_queue *q = &txq->q; | ||
302 | struct pci_dev *dev = priv->pci_dev; | ||
303 | int len; | ||
304 | |||
305 | if (q->n_bd == 0) | ||
306 | return; | ||
307 | |||
308 | /* first, empty all BD's */ | ||
309 | for (; q->write_ptr != q->read_ptr; | ||
310 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | ||
311 | iwl3945_hw_txq_free_tfd(priv, txq); | ||
312 | |||
313 | len = sizeof(struct iwl3945_cmd) * q->n_window; | ||
314 | if (q->id == IWL_CMD_QUEUE_NUM) | ||
315 | len += IWL_MAX_SCAN_SIZE; | ||
316 | |||
317 | /* De-alloc array of command/tx buffers */ | ||
318 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
319 | |||
320 | /* De-alloc circular buffer of TFDs */ | ||
321 | if (txq->q.n_bd) | ||
322 | pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) * | ||
323 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | ||
324 | |||
325 | /* De-alloc array of per-TFD driver data */ | ||
326 | kfree(txq->txb); | ||
327 | txq->txb = NULL; | ||
328 | |||
329 | /* 0-fill queue descriptor structure */ | ||
330 | memset(txq, 0, sizeof(*txq)); | ||
331 | } | ||
332 | |||
333 | const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
334 | 97 | ||
335 | /*************** STATION TABLE MANAGEMENT **** | 98 | /*************** STATION TABLE MANAGEMENT **** |
336 | * mac80211 should be examined to determine if sta_info is duplicating | 99 | * mac80211 should be examined to determine if sta_info is duplicating |
@@ -344,7 +107,7 @@ const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF | |||
344 | * | 107 | * |
345 | * NOTE: This does not remove station from device's station table. | 108 | * NOTE: This does not remove station from device's station table. |
346 | */ | 109 | */ |
347 | static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap) | 110 | static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) |
348 | { | 111 | { |
349 | int index = IWL_INVALID_STATION; | 112 | int index = IWL_INVALID_STATION; |
350 | int i; | 113 | int i; |
@@ -355,11 +118,11 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int | |||
355 | if (is_ap) | 118 | if (is_ap) |
356 | index = IWL_AP_ID; | 119 | index = IWL_AP_ID; |
357 | else if (is_broadcast_ether_addr(addr)) | 120 | else if (is_broadcast_ether_addr(addr)) |
358 | index = priv->hw_setting.bcast_sta_id; | 121 | index = priv->hw_params.bcast_sta_id; |
359 | else | 122 | else |
360 | for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) | 123 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) |
361 | if (priv->stations[i].used && | 124 | if (priv->stations_39[i].used && |
362 | !compare_ether_addr(priv->stations[i].sta.sta.addr, | 125 | !compare_ether_addr(priv->stations_39[i].sta.sta.addr, |
363 | addr)) { | 126 | addr)) { |
364 | index = i; | 127 | index = i; |
365 | break; | 128 | break; |
@@ -368,8 +131,8 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int | |||
368 | if (unlikely(index == IWL_INVALID_STATION)) | 131 | if (unlikely(index == IWL_INVALID_STATION)) |
369 | goto out; | 132 | goto out; |
370 | 133 | ||
371 | if (priv->stations[index].used) { | 134 | if (priv->stations_39[index].used) { |
372 | priv->stations[index].used = 0; | 135 | priv->stations_39[index].used = 0; |
373 | priv->num_stations--; | 136 | priv->num_stations--; |
374 | } | 137 | } |
375 | 138 | ||
@@ -386,14 +149,14 @@ out: | |||
386 | * | 149 | * |
387 | * NOTE: This does not clear or otherwise alter the device's station table. | 150 | * NOTE: This does not clear or otherwise alter the device's station table. |
388 | */ | 151 | */ |
389 | static void iwl3945_clear_stations_table(struct iwl3945_priv *priv) | 152 | static void iwl3945_clear_stations_table(struct iwl_priv *priv) |
390 | { | 153 | { |
391 | unsigned long flags; | 154 | unsigned long flags; |
392 | 155 | ||
393 | spin_lock_irqsave(&priv->sta_lock, flags); | 156 | spin_lock_irqsave(&priv->sta_lock, flags); |
394 | 157 | ||
395 | priv->num_stations = 0; | 158 | priv->num_stations = 0; |
396 | memset(priv->stations, 0, sizeof(priv->stations)); | 159 | memset(priv->stations_39, 0, sizeof(priv->stations_39)); |
397 | 160 | ||
398 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 161 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
399 | } | 162 | } |
@@ -401,7 +164,7 @@ static void iwl3945_clear_stations_table(struct iwl3945_priv *priv) | |||
401 | /** | 164 | /** |
402 | * iwl3945_add_station - Add station to station tables in driver and device | 165 | * iwl3945_add_station - Add station to station tables in driver and device |
403 | */ | 166 | */ |
404 | u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags) | 167 | u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) |
405 | { | 168 | { |
406 | int i; | 169 | int i; |
407 | int index = IWL_INVALID_STATION; | 170 | int index = IWL_INVALID_STATION; |
@@ -413,16 +176,16 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
413 | if (is_ap) | 176 | if (is_ap) |
414 | index = IWL_AP_ID; | 177 | index = IWL_AP_ID; |
415 | else if (is_broadcast_ether_addr(addr)) | 178 | else if (is_broadcast_ether_addr(addr)) |
416 | index = priv->hw_setting.bcast_sta_id; | 179 | index = priv->hw_params.bcast_sta_id; |
417 | else | 180 | else |
418 | for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) { | 181 | for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { |
419 | if (!compare_ether_addr(priv->stations[i].sta.sta.addr, | 182 | if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr, |
420 | addr)) { | 183 | addr)) { |
421 | index = i; | 184 | index = i; |
422 | break; | 185 | break; |
423 | } | 186 | } |
424 | 187 | ||
425 | if (!priv->stations[i].used && | 188 | if (!priv->stations_39[i].used && |
426 | index == IWL_INVALID_STATION) | 189 | index == IWL_INVALID_STATION) |
427 | index = i; | 190 | index = i; |
428 | } | 191 | } |
@@ -434,14 +197,14 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
434 | return index; | 197 | return index; |
435 | } | 198 | } |
436 | 199 | ||
437 | if (priv->stations[index].used && | 200 | if (priv->stations_39[index].used && |
438 | !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) { | 201 | !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) { |
439 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 202 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
440 | return index; | 203 | return index; |
441 | } | 204 | } |
442 | 205 | ||
443 | IWL_DEBUG_ASSOC("Add STA ID %d: %pM\n", index, addr); | 206 | IWL_DEBUG_ASSOC("Add STA ID %d: %pM\n", index, addr); |
444 | station = &priv->stations[index]; | 207 | station = &priv->stations_39[index]; |
445 | station->used = 1; | 208 | station->used = 1; |
446 | priv->num_stations++; | 209 | priv->num_stations++; |
447 | 210 | ||
@@ -460,353 +223,16 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
460 | /* Turn on both antennas for the station... */ | 223 | /* Turn on both antennas for the station... */ |
461 | station->sta.rate_n_flags = | 224 | station->sta.rate_n_flags = |
462 | iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK); | 225 | iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK); |
463 | station->current_rate.rate_n_flags = | ||
464 | le16_to_cpu(station->sta.rate_n_flags); | ||
465 | 226 | ||
466 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 227 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
467 | 228 | ||
468 | /* Add station to device's station table */ | 229 | /* Add station to device's station table */ |
469 | iwl3945_send_add_station(priv, &station->sta, flags); | 230 | iwl_send_add_sta(priv, |
231 | (struct iwl_addsta_cmd *)&station->sta, flags); | ||
470 | return index; | 232 | return index; |
471 | 233 | ||
472 | } | 234 | } |
473 | 235 | ||
474 | /*************** DRIVER STATUS FUNCTIONS *****/ | ||
475 | |||
476 | static inline int iwl3945_is_ready(struct iwl3945_priv *priv) | ||
477 | { | ||
478 | /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are | ||
479 | * set but EXIT_PENDING is not */ | ||
480 | return test_bit(STATUS_READY, &priv->status) && | ||
481 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) && | ||
482 | !test_bit(STATUS_EXIT_PENDING, &priv->status); | ||
483 | } | ||
484 | |||
485 | static inline int iwl3945_is_alive(struct iwl3945_priv *priv) | ||
486 | { | ||
487 | return test_bit(STATUS_ALIVE, &priv->status); | ||
488 | } | ||
489 | |||
490 | static inline int iwl3945_is_init(struct iwl3945_priv *priv) | ||
491 | { | ||
492 | return test_bit(STATUS_INIT, &priv->status); | ||
493 | } | ||
494 | |||
495 | static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv) | ||
496 | { | ||
497 | return test_bit(STATUS_RF_KILL_SW, &priv->status); | ||
498 | } | ||
499 | |||
500 | static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv) | ||
501 | { | ||
502 | return test_bit(STATUS_RF_KILL_HW, &priv->status); | ||
503 | } | ||
504 | |||
505 | static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv) | ||
506 | { | ||
507 | return iwl3945_is_rfkill_hw(priv) || | ||
508 | iwl3945_is_rfkill_sw(priv); | ||
509 | } | ||
510 | |||
511 | static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv) | ||
512 | { | ||
513 | |||
514 | if (iwl3945_is_rfkill(priv)) | ||
515 | return 0; | ||
516 | |||
517 | return iwl3945_is_ready(priv); | ||
518 | } | ||
519 | |||
520 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ | ||
521 | |||
522 | #define IWL_CMD(x) case x: return #x | ||
523 | |||
524 | static const char *get_cmd_string(u8 cmd) | ||
525 | { | ||
526 | switch (cmd) { | ||
527 | IWL_CMD(REPLY_ALIVE); | ||
528 | IWL_CMD(REPLY_ERROR); | ||
529 | IWL_CMD(REPLY_RXON); | ||
530 | IWL_CMD(REPLY_RXON_ASSOC); | ||
531 | IWL_CMD(REPLY_QOS_PARAM); | ||
532 | IWL_CMD(REPLY_RXON_TIMING); | ||
533 | IWL_CMD(REPLY_ADD_STA); | ||
534 | IWL_CMD(REPLY_REMOVE_STA); | ||
535 | IWL_CMD(REPLY_REMOVE_ALL_STA); | ||
536 | IWL_CMD(REPLY_3945_RX); | ||
537 | IWL_CMD(REPLY_TX); | ||
538 | IWL_CMD(REPLY_RATE_SCALE); | ||
539 | IWL_CMD(REPLY_LEDS_CMD); | ||
540 | IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); | ||
541 | IWL_CMD(RADAR_NOTIFICATION); | ||
542 | IWL_CMD(REPLY_QUIET_CMD); | ||
543 | IWL_CMD(REPLY_CHANNEL_SWITCH); | ||
544 | IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); | ||
545 | IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD); | ||
546 | IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION); | ||
547 | IWL_CMD(POWER_TABLE_CMD); | ||
548 | IWL_CMD(PM_SLEEP_NOTIFICATION); | ||
549 | IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC); | ||
550 | IWL_CMD(REPLY_SCAN_CMD); | ||
551 | IWL_CMD(REPLY_SCAN_ABORT_CMD); | ||
552 | IWL_CMD(SCAN_START_NOTIFICATION); | ||
553 | IWL_CMD(SCAN_RESULTS_NOTIFICATION); | ||
554 | IWL_CMD(SCAN_COMPLETE_NOTIFICATION); | ||
555 | IWL_CMD(BEACON_NOTIFICATION); | ||
556 | IWL_CMD(REPLY_TX_BEACON); | ||
557 | IWL_CMD(WHO_IS_AWAKE_NOTIFICATION); | ||
558 | IWL_CMD(QUIET_NOTIFICATION); | ||
559 | IWL_CMD(REPLY_TX_PWR_TABLE_CMD); | ||
560 | IWL_CMD(MEASURE_ABORT_NOTIFICATION); | ||
561 | IWL_CMD(REPLY_BT_CONFIG); | ||
562 | IWL_CMD(REPLY_STATISTICS_CMD); | ||
563 | IWL_CMD(STATISTICS_NOTIFICATION); | ||
564 | IWL_CMD(REPLY_CARD_STATE_CMD); | ||
565 | IWL_CMD(CARD_STATE_NOTIFICATION); | ||
566 | IWL_CMD(MISSED_BEACONS_NOTIFICATION); | ||
567 | default: | ||
568 | return "UNKNOWN"; | ||
569 | |||
570 | } | ||
571 | } | ||
572 | |||
573 | #define HOST_COMPLETE_TIMEOUT (HZ / 2) | ||
574 | |||
575 | /** | ||
576 | * iwl3945_enqueue_hcmd - enqueue a uCode command | ||
577 | * @priv: device private data point | ||
578 | * @cmd: a point to the ucode command structure | ||
579 | * | ||
580 | * The function returns < 0 values to indicate the operation is | ||
581 | * failed. On success, it turns the index (> 0) of command in the | ||
582 | * command queue. | ||
583 | */ | ||
584 | static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) | ||
585 | { | ||
586 | struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | ||
587 | struct iwl3945_queue *q = &txq->q; | ||
588 | struct iwl3945_tfd_frame *tfd; | ||
589 | u32 *control_flags; | ||
590 | struct iwl3945_cmd *out_cmd; | ||
591 | u32 idx; | ||
592 | u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); | ||
593 | dma_addr_t phys_addr; | ||
594 | int pad; | ||
595 | u16 count; | ||
596 | int ret; | ||
597 | unsigned long flags; | ||
598 | |||
599 | /* If any of the command structures end up being larger than | ||
600 | * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then | ||
601 | * we will need to increase the size of the TFD entries */ | ||
602 | BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && | ||
603 | !(cmd->meta.flags & CMD_SIZE_HUGE)); | ||
604 | |||
605 | |||
606 | if (iwl3945_is_rfkill(priv)) { | ||
607 | IWL_DEBUG_INFO("Not sending command - RF KILL"); | ||
608 | return -EIO; | ||
609 | } | ||
610 | |||
611 | if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { | ||
612 | IWL_ERROR("No space for Tx\n"); | ||
613 | return -ENOSPC; | ||
614 | } | ||
615 | |||
616 | spin_lock_irqsave(&priv->hcmd_lock, flags); | ||
617 | |||
618 | tfd = &txq->bd[q->write_ptr]; | ||
619 | memset(tfd, 0, sizeof(*tfd)); | ||
620 | |||
621 | control_flags = (u32 *) tfd; | ||
622 | |||
623 | idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); | ||
624 | out_cmd = &txq->cmd[idx]; | ||
625 | |||
626 | out_cmd->hdr.cmd = cmd->id; | ||
627 | memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta)); | ||
628 | memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); | ||
629 | |||
630 | /* At this point, the out_cmd now has all of the incoming cmd | ||
631 | * information */ | ||
632 | |||
633 | out_cmd->hdr.flags = 0; | ||
634 | out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | | ||
635 | INDEX_TO_SEQ(q->write_ptr)); | ||
636 | if (out_cmd->meta.flags & CMD_SIZE_HUGE) | ||
637 | out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME); | ||
638 | |||
639 | phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx + | ||
640 | offsetof(struct iwl3945_cmd, hdr); | ||
641 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); | ||
642 | |||
643 | pad = U32_PAD(cmd->len); | ||
644 | count = TFD_CTL_COUNT_GET(*control_flags); | ||
645 | *control_flags = TFD_CTL_COUNT_SET(count) | TFD_CTL_PAD_SET(pad); | ||
646 | |||
647 | IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, " | ||
648 | "%d bytes at %d[%d]:%d\n", | ||
649 | get_cmd_string(out_cmd->hdr.cmd), | ||
650 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), | ||
651 | fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); | ||
652 | |||
653 | txq->need_update = 1; | ||
654 | |||
655 | /* Increment and update queue's write index */ | ||
656 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | ||
657 | ret = iwl3945_tx_queue_update_write_ptr(priv, txq); | ||
658 | |||
659 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||
660 | return ret ? ret : idx; | ||
661 | } | ||
662 | |||
663 | static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) | ||
664 | { | ||
665 | int ret; | ||
666 | |||
667 | BUG_ON(!(cmd->meta.flags & CMD_ASYNC)); | ||
668 | |||
669 | /* An asynchronous command can not expect an SKB to be set. */ | ||
670 | BUG_ON(cmd->meta.flags & CMD_WANT_SKB); | ||
671 | |||
672 | /* An asynchronous command MUST have a callback. */ | ||
673 | BUG_ON(!cmd->meta.u.callback); | ||
674 | |||
675 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
676 | return -EBUSY; | ||
677 | |||
678 | ret = iwl3945_enqueue_hcmd(priv, cmd); | ||
679 | if (ret < 0) { | ||
680 | IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n", | ||
681 | get_cmd_string(cmd->id), ret); | ||
682 | return ret; | ||
683 | } | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) | ||
688 | { | ||
689 | int cmd_idx; | ||
690 | int ret; | ||
691 | |||
692 | BUG_ON(cmd->meta.flags & CMD_ASYNC); | ||
693 | |||
694 | /* A synchronous command can not have a callback set. */ | ||
695 | BUG_ON(cmd->meta.u.callback != NULL); | ||
696 | |||
697 | if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { | ||
698 | IWL_ERROR("Error sending %s: Already sending a host command\n", | ||
699 | get_cmd_string(cmd->id)); | ||
700 | ret = -EBUSY; | ||
701 | goto out; | ||
702 | } | ||
703 | |||
704 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
705 | |||
706 | if (cmd->meta.flags & CMD_WANT_SKB) | ||
707 | cmd->meta.source = &cmd->meta; | ||
708 | |||
709 | cmd_idx = iwl3945_enqueue_hcmd(priv, cmd); | ||
710 | if (cmd_idx < 0) { | ||
711 | ret = cmd_idx; | ||
712 | IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n", | ||
713 | get_cmd_string(cmd->id), ret); | ||
714 | goto out; | ||
715 | } | ||
716 | |||
717 | ret = wait_event_interruptible_timeout(priv->wait_command_queue, | ||
718 | !test_bit(STATUS_HCMD_ACTIVE, &priv->status), | ||
719 | HOST_COMPLETE_TIMEOUT); | ||
720 | if (!ret) { | ||
721 | if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) { | ||
722 | IWL_ERROR("Error sending %s: time out after %dms.\n", | ||
723 | get_cmd_string(cmd->id), | ||
724 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | ||
725 | |||
726 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
727 | ret = -ETIMEDOUT; | ||
728 | goto cancel; | ||
729 | } | ||
730 | } | ||
731 | |||
732 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | ||
733 | IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n", | ||
734 | get_cmd_string(cmd->id)); | ||
735 | ret = -ECANCELED; | ||
736 | goto fail; | ||
737 | } | ||
738 | if (test_bit(STATUS_FW_ERROR, &priv->status)) { | ||
739 | IWL_DEBUG_INFO("Command %s failed: FW Error\n", | ||
740 | get_cmd_string(cmd->id)); | ||
741 | ret = -EIO; | ||
742 | goto fail; | ||
743 | } | ||
744 | if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) { | ||
745 | IWL_ERROR("Error: Response NULL in '%s'\n", | ||
746 | get_cmd_string(cmd->id)); | ||
747 | ret = -EIO; | ||
748 | goto cancel; | ||
749 | } | ||
750 | |||
751 | ret = 0; | ||
752 | goto out; | ||
753 | |||
754 | cancel: | ||
755 | if (cmd->meta.flags & CMD_WANT_SKB) { | ||
756 | struct iwl3945_cmd *qcmd; | ||
757 | |||
758 | /* Cancel the CMD_WANT_SKB flag for the cmd in the | ||
759 | * TX cmd queue. Otherwise in case the cmd comes | ||
760 | * in later, it will possibly set an invalid | ||
761 | * address (cmd->meta.source). */ | ||
762 | qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx]; | ||
763 | qcmd->meta.flags &= ~CMD_WANT_SKB; | ||
764 | } | ||
765 | fail: | ||
766 | if (cmd->meta.u.skb) { | ||
767 | dev_kfree_skb_any(cmd->meta.u.skb); | ||
768 | cmd->meta.u.skb = NULL; | ||
769 | } | ||
770 | out: | ||
771 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); | ||
772 | return ret; | ||
773 | } | ||
774 | |||
775 | int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) | ||
776 | { | ||
777 | if (cmd->meta.flags & CMD_ASYNC) | ||
778 | return iwl3945_send_cmd_async(priv, cmd); | ||
779 | |||
780 | return iwl3945_send_cmd_sync(priv, cmd); | ||
781 | } | ||
782 | |||
783 | int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data) | ||
784 | { | ||
785 | struct iwl3945_host_cmd cmd = { | ||
786 | .id = id, | ||
787 | .len = len, | ||
788 | .data = data, | ||
789 | }; | ||
790 | |||
791 | return iwl3945_send_cmd_sync(priv, &cmd); | ||
792 | } | ||
793 | |||
794 | static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val) | ||
795 | { | ||
796 | struct iwl3945_host_cmd cmd = { | ||
797 | .id = id, | ||
798 | .len = sizeof(val), | ||
799 | .data = &val, | ||
800 | }; | ||
801 | |||
802 | return iwl3945_send_cmd_sync(priv, &cmd); | ||
803 | } | ||
804 | |||
805 | int iwl3945_send_statistics_request(struct iwl3945_priv *priv) | ||
806 | { | ||
807 | return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0); | ||
808 | } | ||
809 | |||
810 | /** | 236 | /** |
811 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON | 237 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON |
812 | * @band: 2.4 or 5 GHz band | 238 | * @band: 2.4 or 5 GHz band |
@@ -817,25 +243,25 @@ int iwl3945_send_statistics_request(struct iwl3945_priv *priv) | |||
817 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 243 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
818 | * in the staging RXON flag structure based on the band | 244 | * in the staging RXON flag structure based on the band |
819 | */ | 245 | */ |
820 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, | 246 | static int iwl3945_set_rxon_channel(struct iwl_priv *priv, |
821 | enum ieee80211_band band, | 247 | enum ieee80211_band band, |
822 | u16 channel) | 248 | u16 channel) |
823 | { | 249 | { |
824 | if (!iwl3945_get_channel_info(priv, band, channel)) { | 250 | if (!iwl_get_channel_info(priv, band, channel)) { |
825 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 251 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
826 | channel, band); | 252 | channel, band); |
827 | return -EINVAL; | 253 | return -EINVAL; |
828 | } | 254 | } |
829 | 255 | ||
830 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 256 | if ((le16_to_cpu(priv->staging39_rxon.channel) == channel) && |
831 | (priv->band == band)) | 257 | (priv->band == band)) |
832 | return 0; | 258 | return 0; |
833 | 259 | ||
834 | priv->staging_rxon.channel = cpu_to_le16(channel); | 260 | priv->staging39_rxon.channel = cpu_to_le16(channel); |
835 | if (band == IEEE80211_BAND_5GHZ) | 261 | if (band == IEEE80211_BAND_5GHZ) |
836 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 262 | priv->staging39_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
837 | else | 263 | else |
838 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 264 | priv->staging39_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
839 | 265 | ||
840 | priv->band = band; | 266 | priv->band = band; |
841 | 267 | ||
@@ -851,73 +277,74 @@ static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, | |||
851 | * be #ifdef'd out once the driver is stable and folks aren't actively | 277 | * be #ifdef'd out once the driver is stable and folks aren't actively |
852 | * making changes | 278 | * making changes |
853 | */ | 279 | */ |
854 | static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon) | 280 | static int iwl3945_check_rxon_cmd(struct iwl_priv *priv) |
855 | { | 281 | { |
856 | int error = 0; | 282 | int error = 0; |
857 | int counter = 1; | 283 | int counter = 1; |
284 | struct iwl3945_rxon_cmd *rxon = &priv->staging39_rxon; | ||
858 | 285 | ||
859 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { | 286 | if (rxon->flags & RXON_FLG_BAND_24G_MSK) { |
860 | error |= le32_to_cpu(rxon->flags & | 287 | error |= le32_to_cpu(rxon->flags & |
861 | (RXON_FLG_TGJ_NARROW_BAND_MSK | | 288 | (RXON_FLG_TGJ_NARROW_BAND_MSK | |
862 | RXON_FLG_RADAR_DETECT_MSK)); | 289 | RXON_FLG_RADAR_DETECT_MSK)); |
863 | if (error) | 290 | if (error) |
864 | IWL_WARNING("check 24G fields %d | %d\n", | 291 | IWL_WARN(priv, "check 24G fields %d | %d\n", |
865 | counter++, error); | 292 | counter++, error); |
866 | } else { | 293 | } else { |
867 | error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? | 294 | error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? |
868 | 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); | 295 | 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); |
869 | if (error) | 296 | if (error) |
870 | IWL_WARNING("check 52 fields %d | %d\n", | 297 | IWL_WARN(priv, "check 52 fields %d | %d\n", |
871 | counter++, error); | 298 | counter++, error); |
872 | error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); | 299 | error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); |
873 | if (error) | 300 | if (error) |
874 | IWL_WARNING("check 52 CCK %d | %d\n", | 301 | IWL_WARN(priv, "check 52 CCK %d | %d\n", |
875 | counter++, error); | 302 | counter++, error); |
876 | } | 303 | } |
877 | error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; | 304 | error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; |
878 | if (error) | 305 | if (error) |
879 | IWL_WARNING("check mac addr %d | %d\n", counter++, error); | 306 | IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error); |
880 | 307 | ||
881 | /* make sure basic rates 6Mbps and 1Mbps are supported */ | 308 | /* make sure basic rates 6Mbps and 1Mbps are supported */ |
882 | error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && | 309 | error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && |
883 | ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); | 310 | ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); |
884 | if (error) | 311 | if (error) |
885 | IWL_WARNING("check basic rate %d | %d\n", counter++, error); | 312 | IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error); |
886 | 313 | ||
887 | error |= (le16_to_cpu(rxon->assoc_id) > 2007); | 314 | error |= (le16_to_cpu(rxon->assoc_id) > 2007); |
888 | if (error) | 315 | if (error) |
889 | IWL_WARNING("check assoc id %d | %d\n", counter++, error); | 316 | IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error); |
890 | 317 | ||
891 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) | 318 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) |
892 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); | 319 | == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); |
893 | if (error) | 320 | if (error) |
894 | IWL_WARNING("check CCK and short slot %d | %d\n", | 321 | IWL_WARN(priv, "check CCK and short slot %d | %d\n", |
895 | counter++, error); | 322 | counter++, error); |
896 | 323 | ||
897 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) | 324 | error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) |
898 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); | 325 | == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); |
899 | if (error) | 326 | if (error) |
900 | IWL_WARNING("check CCK & auto detect %d | %d\n", | 327 | IWL_WARN(priv, "check CCK & auto detect %d | %d\n", |
901 | counter++, error); | 328 | counter++, error); |
902 | 329 | ||
903 | error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | | 330 | error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | |
904 | RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); | 331 | RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); |
905 | if (error) | 332 | if (error) |
906 | IWL_WARNING("check TGG and auto detect %d | %d\n", | 333 | IWL_WARN(priv, "check TGG and auto detect %d | %d\n", |
907 | counter++, error); | 334 | counter++, error); |
908 | 335 | ||
909 | if ((rxon->flags & RXON_FLG_DIS_DIV_MSK)) | 336 | if ((rxon->flags & RXON_FLG_DIS_DIV_MSK)) |
910 | error |= ((rxon->flags & (RXON_FLG_ANT_B_MSK | | 337 | error |= ((rxon->flags & (RXON_FLG_ANT_B_MSK | |
911 | RXON_FLG_ANT_A_MSK)) == 0); | 338 | RXON_FLG_ANT_A_MSK)) == 0); |
912 | if (error) | 339 | if (error) |
913 | IWL_WARNING("check antenna %d %d\n", counter++, error); | 340 | IWL_WARN(priv, "check antenna %d %d\n", counter++, error); |
914 | 341 | ||
915 | if (error) | 342 | if (error) |
916 | IWL_WARNING("Tuning to channel %d\n", | 343 | IWL_WARN(priv, "Tuning to channel %d\n", |
917 | le16_to_cpu(rxon->channel)); | 344 | le16_to_cpu(rxon->channel)); |
918 | 345 | ||
919 | if (error) { | 346 | if (error) { |
920 | IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n"); | 347 | IWL_ERR(priv, "Not a valid rxon_assoc_cmd field values\n"); |
921 | return -1; | 348 | return -1; |
922 | } | 349 | } |
923 | return 0; | 350 | return 0; |
@@ -931,22 +358,22 @@ static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon) | |||
931 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that | 358 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that |
932 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. | 359 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. |
933 | */ | 360 | */ |
934 | static int iwl3945_full_rxon_required(struct iwl3945_priv *priv) | 361 | static int iwl3945_full_rxon_required(struct iwl_priv *priv) |
935 | { | 362 | { |
936 | 363 | ||
937 | /* These items are only settable from the full RXON command */ | 364 | /* These items are only settable from the full RXON command */ |
938 | if (!(iwl3945_is_associated(priv)) || | 365 | if (!(iwl3945_is_associated(priv)) || |
939 | compare_ether_addr(priv->staging_rxon.bssid_addr, | 366 | compare_ether_addr(priv->staging39_rxon.bssid_addr, |
940 | priv->active_rxon.bssid_addr) || | 367 | priv->active39_rxon.bssid_addr) || |
941 | compare_ether_addr(priv->staging_rxon.node_addr, | 368 | compare_ether_addr(priv->staging39_rxon.node_addr, |
942 | priv->active_rxon.node_addr) || | 369 | priv->active39_rxon.node_addr) || |
943 | compare_ether_addr(priv->staging_rxon.wlap_bssid_addr, | 370 | compare_ether_addr(priv->staging39_rxon.wlap_bssid_addr, |
944 | priv->active_rxon.wlap_bssid_addr) || | 371 | priv->active39_rxon.wlap_bssid_addr) || |
945 | (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) || | 372 | (priv->staging39_rxon.dev_type != priv->active39_rxon.dev_type) || |
946 | (priv->staging_rxon.channel != priv->active_rxon.channel) || | 373 | (priv->staging39_rxon.channel != priv->active39_rxon.channel) || |
947 | (priv->staging_rxon.air_propagation != | 374 | (priv->staging39_rxon.air_propagation != |
948 | priv->active_rxon.air_propagation) || | 375 | priv->active39_rxon.air_propagation) || |
949 | (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) | 376 | (priv->staging39_rxon.assoc_id != priv->active39_rxon.assoc_id)) |
950 | return 1; | 377 | return 1; |
951 | 378 | ||
952 | /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can | 379 | /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can |
@@ -954,31 +381,31 @@ static int iwl3945_full_rxon_required(struct iwl3945_priv *priv) | |||
954 | * flag transitions are allowed using RXON_ASSOC */ | 381 | * flag transitions are allowed using RXON_ASSOC */ |
955 | 382 | ||
956 | /* Check if we are not switching bands */ | 383 | /* Check if we are not switching bands */ |
957 | if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) != | 384 | if ((priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) != |
958 | (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)) | 385 | (priv->active39_rxon.flags & RXON_FLG_BAND_24G_MSK)) |
959 | return 1; | 386 | return 1; |
960 | 387 | ||
961 | /* Check if we are switching association toggle */ | 388 | /* Check if we are switching association toggle */ |
962 | if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) != | 389 | if ((priv->staging39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) != |
963 | (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) | 390 | (priv->active39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) |
964 | return 1; | 391 | return 1; |
965 | 392 | ||
966 | return 0; | 393 | return 0; |
967 | } | 394 | } |
968 | 395 | ||
969 | static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv) | 396 | static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) |
970 | { | 397 | { |
971 | int rc = 0; | 398 | int rc = 0; |
972 | struct iwl3945_rx_packet *res = NULL; | 399 | struct iwl_rx_packet *res = NULL; |
973 | struct iwl3945_rxon_assoc_cmd rxon_assoc; | 400 | struct iwl3945_rxon_assoc_cmd rxon_assoc; |
974 | struct iwl3945_host_cmd cmd = { | 401 | struct iwl_host_cmd cmd = { |
975 | .id = REPLY_RXON_ASSOC, | 402 | .id = REPLY_RXON_ASSOC, |
976 | .len = sizeof(rxon_assoc), | 403 | .len = sizeof(rxon_assoc), |
977 | .meta.flags = CMD_WANT_SKB, | 404 | .meta.flags = CMD_WANT_SKB, |
978 | .data = &rxon_assoc, | 405 | .data = &rxon_assoc, |
979 | }; | 406 | }; |
980 | const struct iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon; | 407 | const struct iwl3945_rxon_cmd *rxon1 = &priv->staging39_rxon; |
981 | const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon; | 408 | const struct iwl3945_rxon_cmd *rxon2 = &priv->active39_rxon; |
982 | 409 | ||
983 | if ((rxon1->flags == rxon2->flags) && | 410 | if ((rxon1->flags == rxon2->flags) && |
984 | (rxon1->filter_flags == rxon2->filter_flags) && | 411 | (rxon1->filter_flags == rxon2->filter_flags) && |
@@ -988,19 +415,19 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv) | |||
988 | return 0; | 415 | return 0; |
989 | } | 416 | } |
990 | 417 | ||
991 | rxon_assoc.flags = priv->staging_rxon.flags; | 418 | rxon_assoc.flags = priv->staging39_rxon.flags; |
992 | rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; | 419 | rxon_assoc.filter_flags = priv->staging39_rxon.filter_flags; |
993 | rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; | 420 | rxon_assoc.ofdm_basic_rates = priv->staging39_rxon.ofdm_basic_rates; |
994 | rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; | 421 | rxon_assoc.cck_basic_rates = priv->staging39_rxon.cck_basic_rates; |
995 | rxon_assoc.reserved = 0; | 422 | rxon_assoc.reserved = 0; |
996 | 423 | ||
997 | rc = iwl3945_send_cmd_sync(priv, &cmd); | 424 | rc = iwl_send_cmd_sync(priv, &cmd); |
998 | if (rc) | 425 | if (rc) |
999 | return rc; | 426 | return rc; |
1000 | 427 | ||
1001 | res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; | 428 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
1002 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 429 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
1003 | IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n"); | 430 | IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); |
1004 | rc = -EIO; | 431 | rc = -EIO; |
1005 | } | 432 | } |
1006 | 433 | ||
@@ -1011,6 +438,43 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv) | |||
1011 | } | 438 | } |
1012 | 439 | ||
1013 | /** | 440 | /** |
441 | * iwl3945_get_antenna_flags - Get antenna flags for RXON command | ||
442 | * @priv: eeprom and antenna fields are used to determine antenna flags | ||
443 | * | ||
444 | * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed | ||
445 | * iwl3945_mod_params.antenna specifies the antenna diversity mode: | ||
446 | * | ||
447 | * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself | ||
448 | * IWL_ANTENNA_MAIN - Force MAIN antenna | ||
449 | * IWL_ANTENNA_AUX - Force AUX antenna | ||
450 | */ | ||
451 | __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) | ||
452 | { | ||
453 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
454 | |||
455 | switch (iwl3945_mod_params.antenna) { | ||
456 | case IWL_ANTENNA_DIVERSITY: | ||
457 | return 0; | ||
458 | |||
459 | case IWL_ANTENNA_MAIN: | ||
460 | if (eeprom->antenna_switch_type) | ||
461 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; | ||
462 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; | ||
463 | |||
464 | case IWL_ANTENNA_AUX: | ||
465 | if (eeprom->antenna_switch_type) | ||
466 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK; | ||
467 | return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK; | ||
468 | } | ||
469 | |||
470 | /* bad antenna selector value */ | ||
471 | IWL_ERR(priv, "Bad antenna selector value (0x%x)\n", | ||
472 | iwl3945_mod_params.antenna); | ||
473 | |||
474 | return 0; /* "diversity" is default if error */ | ||
475 | } | ||
476 | |||
477 | /** | ||
1014 | * iwl3945_commit_rxon - commit staging_rxon to hardware | 478 | * iwl3945_commit_rxon - commit staging_rxon to hardware |
1015 | * | 479 | * |
1016 | * The RXON command in staging_rxon is committed to the hardware and | 480 | * The RXON command in staging_rxon is committed to the hardware and |
@@ -1018,26 +482,26 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv) | |||
1018 | * function correctly transitions out of the RXON_ASSOC_MSK state if | 482 | * function correctly transitions out of the RXON_ASSOC_MSK state if |
1019 | * a HW tune is required based on the RXON structure changes. | 483 | * a HW tune is required based on the RXON structure changes. |
1020 | */ | 484 | */ |
1021 | static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | 485 | static int iwl3945_commit_rxon(struct iwl_priv *priv) |
1022 | { | 486 | { |
1023 | /* cast away the const for active_rxon in this function */ | 487 | /* cast away the const for active_rxon in this function */ |
1024 | struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; | 488 | struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active39_rxon; |
1025 | int rc = 0; | 489 | int rc = 0; |
1026 | 490 | ||
1027 | if (!iwl3945_is_alive(priv)) | 491 | if (!iwl_is_alive(priv)) |
1028 | return -1; | 492 | return -1; |
1029 | 493 | ||
1030 | /* always get timestamp with Rx frame */ | 494 | /* always get timestamp with Rx frame */ |
1031 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; | 495 | priv->staging39_rxon.flags |= RXON_FLG_TSF2HOST_MSK; |
1032 | 496 | ||
1033 | /* select antenna */ | 497 | /* select antenna */ |
1034 | priv->staging_rxon.flags &= | 498 | priv->staging39_rxon.flags &= |
1035 | ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); | 499 | ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); |
1036 | priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv); | 500 | priv->staging39_rxon.flags |= iwl3945_get_antenna_flags(priv); |
1037 | 501 | ||
1038 | rc = iwl3945_check_rxon_cmd(&priv->staging_rxon); | 502 | rc = iwl3945_check_rxon_cmd(priv); |
1039 | if (rc) { | 503 | if (rc) { |
1040 | IWL_ERROR("Invalid RXON configuration. Not committing.\n"); | 504 | IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); |
1041 | return -EINVAL; | 505 | return -EINVAL; |
1042 | } | 506 | } |
1043 | 507 | ||
@@ -1047,12 +511,12 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1047 | if (!iwl3945_full_rxon_required(priv)) { | 511 | if (!iwl3945_full_rxon_required(priv)) { |
1048 | rc = iwl3945_send_rxon_assoc(priv); | 512 | rc = iwl3945_send_rxon_assoc(priv); |
1049 | if (rc) { | 513 | if (rc) { |
1050 | IWL_ERROR("Error setting RXON_ASSOC " | 514 | IWL_ERR(priv, "Error setting RXON_ASSOC " |
1051 | "configuration (%d).\n", rc); | 515 | "configuration (%d).\n", rc); |
1052 | return rc; | 516 | return rc; |
1053 | } | 517 | } |
1054 | 518 | ||
1055 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 519 | memcpy(active_rxon, &priv->staging39_rxon, sizeof(*active_rxon)); |
1056 | 520 | ||
1057 | return 0; | 521 | return 0; |
1058 | } | 522 | } |
@@ -1062,19 +526,19 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1062 | * we must clear the associated from the active configuration | 526 | * we must clear the associated from the active configuration |
1063 | * before we apply the new config */ | 527 | * before we apply the new config */ |
1064 | if (iwl3945_is_associated(priv) && | 528 | if (iwl3945_is_associated(priv) && |
1065 | (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) { | 529 | (priv->staging39_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) { |
1066 | IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); | 530 | IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); |
1067 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 531 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
1068 | 532 | ||
1069 | rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON, | 533 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, |
1070 | sizeof(struct iwl3945_rxon_cmd), | 534 | sizeof(struct iwl3945_rxon_cmd), |
1071 | &priv->active_rxon); | 535 | &priv->active39_rxon); |
1072 | 536 | ||
1073 | /* If the mask clearing failed then we set | 537 | /* If the mask clearing failed then we set |
1074 | * active_rxon back to what it was previously */ | 538 | * active_rxon back to what it was previously */ |
1075 | if (rc) { | 539 | if (rc) { |
1076 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; | 540 | active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; |
1077 | IWL_ERROR("Error clearing ASSOC_MSK on current " | 541 | IWL_ERR(priv, "Error clearing ASSOC_MSK on current " |
1078 | "configuration (%d).\n", rc); | 542 | "configuration (%d).\n", rc); |
1079 | return rc; | 543 | return rc; |
1080 | } | 544 | } |
@@ -1084,35 +548,35 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1084 | "* with%s RXON_FILTER_ASSOC_MSK\n" | 548 | "* with%s RXON_FILTER_ASSOC_MSK\n" |
1085 | "* channel = %d\n" | 549 | "* channel = %d\n" |
1086 | "* bssid = %pM\n", | 550 | "* bssid = %pM\n", |
1087 | ((priv->staging_rxon.filter_flags & | 551 | ((priv->staging39_rxon.filter_flags & |
1088 | RXON_FILTER_ASSOC_MSK) ? "" : "out"), | 552 | RXON_FILTER_ASSOC_MSK) ? "" : "out"), |
1089 | le16_to_cpu(priv->staging_rxon.channel), | 553 | le16_to_cpu(priv->staging39_rxon.channel), |
1090 | priv->staging_rxon.bssid_addr); | 554 | priv->staging_rxon.bssid_addr); |
1091 | 555 | ||
1092 | /* Apply the new configuration */ | 556 | /* Apply the new configuration */ |
1093 | rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON, | 557 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON, |
1094 | sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon); | 558 | sizeof(struct iwl3945_rxon_cmd), &priv->staging39_rxon); |
1095 | if (rc) { | 559 | if (rc) { |
1096 | IWL_ERROR("Error setting new configuration (%d).\n", rc); | 560 | IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); |
1097 | return rc; | 561 | return rc; |
1098 | } | 562 | } |
1099 | 563 | ||
1100 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 564 | memcpy(active_rxon, &priv->staging39_rxon, sizeof(*active_rxon)); |
1101 | 565 | ||
1102 | iwl3945_clear_stations_table(priv); | 566 | iwl3945_clear_stations_table(priv); |
1103 | 567 | ||
1104 | /* If we issue a new RXON command which required a tune then we must | 568 | /* If we issue a new RXON command which required a tune then we must |
1105 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 569 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
1106 | rc = iwl3945_hw_reg_send_txpower(priv); | 570 | rc = priv->cfg->ops->lib->send_tx_power(priv); |
1107 | if (rc) { | 571 | if (rc) { |
1108 | IWL_ERROR("Error setting Tx power (%d).\n", rc); | 572 | IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); |
1109 | return rc; | 573 | return rc; |
1110 | } | 574 | } |
1111 | 575 | ||
1112 | /* Add the broadcast address so we can send broadcast frames */ | 576 | /* Add the broadcast address so we can send broadcast frames */ |
1113 | if (iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0) == | 577 | if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) == |
1114 | IWL_INVALID_STATION) { | 578 | IWL_INVALID_STATION) { |
1115 | IWL_ERROR("Error adding BROADCAST address for transmit.\n"); | 579 | IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); |
1116 | return -EIO; | 580 | return -EIO; |
1117 | } | 581 | } |
1118 | 582 | ||
@@ -1120,185 +584,23 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1120 | * add the IWL_AP_ID to the station rate table */ | 584 | * add the IWL_AP_ID to the station rate table */ |
1121 | if (iwl3945_is_associated(priv) && | 585 | if (iwl3945_is_associated(priv) && |
1122 | (priv->iw_mode == NL80211_IFTYPE_STATION)) | 586 | (priv->iw_mode == NL80211_IFTYPE_STATION)) |
1123 | if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0) | 587 | if (iwl3945_add_station(priv, priv->active39_rxon.bssid_addr, 1, 0) |
1124 | == IWL_INVALID_STATION) { | 588 | == IWL_INVALID_STATION) { |
1125 | IWL_ERROR("Error adding AP address for transmit.\n"); | 589 | IWL_ERR(priv, "Error adding AP address for transmit\n"); |
1126 | return -EIO; | 590 | return -EIO; |
1127 | } | 591 | } |
1128 | 592 | ||
1129 | /* Init the hardware's rate fallback order based on the band */ | 593 | /* Init the hardware's rate fallback order based on the band */ |
1130 | rc = iwl3945_init_hw_rate_table(priv); | 594 | rc = iwl3945_init_hw_rate_table(priv); |
1131 | if (rc) { | 595 | if (rc) { |
1132 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); | 596 | IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); |
1133 | return -EIO; | 597 | return -EIO; |
1134 | } | 598 | } |
1135 | 599 | ||
1136 | return 0; | 600 | return 0; |
1137 | } | 601 | } |
1138 | 602 | ||
1139 | static int iwl3945_send_bt_config(struct iwl3945_priv *priv) | 603 | static int iwl3945_update_sta_key_info(struct iwl_priv *priv, |
1140 | { | ||
1141 | struct iwl3945_bt_cmd bt_cmd = { | ||
1142 | .flags = 3, | ||
1143 | .lead_time = 0xAA, | ||
1144 | .max_kill = 1, | ||
1145 | .kill_ack_mask = 0, | ||
1146 | .kill_cts_mask = 0, | ||
1147 | }; | ||
1148 | |||
1149 | return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG, | ||
1150 | sizeof(struct iwl3945_bt_cmd), &bt_cmd); | ||
1151 | } | ||
1152 | |||
1153 | static int iwl3945_send_scan_abort(struct iwl3945_priv *priv) | ||
1154 | { | ||
1155 | int rc = 0; | ||
1156 | struct iwl3945_rx_packet *res; | ||
1157 | struct iwl3945_host_cmd cmd = { | ||
1158 | .id = REPLY_SCAN_ABORT_CMD, | ||
1159 | .meta.flags = CMD_WANT_SKB, | ||
1160 | }; | ||
1161 | |||
1162 | /* If there isn't a scan actively going on in the hardware | ||
1163 | * then we are in between scan bands and not actually | ||
1164 | * actively scanning, so don't send the abort command */ | ||
1165 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
1166 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | rc = iwl3945_send_cmd_sync(priv, &cmd); | ||
1171 | if (rc) { | ||
1172 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
1173 | return rc; | ||
1174 | } | ||
1175 | |||
1176 | res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; | ||
1177 | if (res->u.status != CAN_ABORT_STATUS) { | ||
1178 | /* The scan abort will return 1 for success or | ||
1179 | * 2 for "failure". A failure condition can be | ||
1180 | * due to simply not being in an active scan which | ||
1181 | * can occur if we send the scan abort before we | ||
1182 | * the microcode has notified us that a scan is | ||
1183 | * completed. */ | ||
1184 | IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status); | ||
1185 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
1186 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
1187 | } | ||
1188 | |||
1189 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
1190 | |||
1191 | return rc; | ||
1192 | } | ||
1193 | |||
1194 | static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv, | ||
1195 | struct iwl3945_cmd *cmd, | ||
1196 | struct sk_buff *skb) | ||
1197 | { | ||
1198 | return 1; | ||
1199 | } | ||
1200 | |||
1201 | /* | ||
1202 | * CARD_STATE_CMD | ||
1203 | * | ||
1204 | * Use: Sets the device's internal card state to enable, disable, or halt | ||
1205 | * | ||
1206 | * When in the 'enable' state the card operates as normal. | ||
1207 | * When in the 'disable' state, the card enters into a low power mode. | ||
1208 | * When in the 'halt' state, the card is shut down and must be fully | ||
1209 | * restarted to come back on. | ||
1210 | */ | ||
1211 | static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag) | ||
1212 | { | ||
1213 | struct iwl3945_host_cmd cmd = { | ||
1214 | .id = REPLY_CARD_STATE_CMD, | ||
1215 | .len = sizeof(u32), | ||
1216 | .data = &flags, | ||
1217 | .meta.flags = meta_flag, | ||
1218 | }; | ||
1219 | |||
1220 | if (meta_flag & CMD_ASYNC) | ||
1221 | cmd.meta.u.callback = iwl3945_card_state_sync_callback; | ||
1222 | |||
1223 | return iwl3945_send_cmd(priv, &cmd); | ||
1224 | } | ||
1225 | |||
1226 | static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv, | ||
1227 | struct iwl3945_cmd *cmd, struct sk_buff *skb) | ||
1228 | { | ||
1229 | struct iwl3945_rx_packet *res = NULL; | ||
1230 | |||
1231 | if (!skb) { | ||
1232 | IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n"); | ||
1233 | return 1; | ||
1234 | } | ||
1235 | |||
1236 | res = (struct iwl3945_rx_packet *)skb->data; | ||
1237 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
1238 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | ||
1239 | res->hdr.flags); | ||
1240 | return 1; | ||
1241 | } | ||
1242 | |||
1243 | switch (res->u.add_sta.status) { | ||
1244 | case ADD_STA_SUCCESS_MSK: | ||
1245 | break; | ||
1246 | default: | ||
1247 | break; | ||
1248 | } | ||
1249 | |||
1250 | /* We didn't cache the SKB; let the caller free it */ | ||
1251 | return 1; | ||
1252 | } | ||
1253 | |||
1254 | int iwl3945_send_add_station(struct iwl3945_priv *priv, | ||
1255 | struct iwl3945_addsta_cmd *sta, u8 flags) | ||
1256 | { | ||
1257 | struct iwl3945_rx_packet *res = NULL; | ||
1258 | int rc = 0; | ||
1259 | struct iwl3945_host_cmd cmd = { | ||
1260 | .id = REPLY_ADD_STA, | ||
1261 | .len = sizeof(struct iwl3945_addsta_cmd), | ||
1262 | .meta.flags = flags, | ||
1263 | .data = sta, | ||
1264 | }; | ||
1265 | |||
1266 | if (flags & CMD_ASYNC) | ||
1267 | cmd.meta.u.callback = iwl3945_add_sta_sync_callback; | ||
1268 | else | ||
1269 | cmd.meta.flags |= CMD_WANT_SKB; | ||
1270 | |||
1271 | rc = iwl3945_send_cmd(priv, &cmd); | ||
1272 | |||
1273 | if (rc || (flags & CMD_ASYNC)) | ||
1274 | return rc; | ||
1275 | |||
1276 | res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; | ||
1277 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | ||
1278 | IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", | ||
1279 | res->hdr.flags); | ||
1280 | rc = -EIO; | ||
1281 | } | ||
1282 | |||
1283 | if (rc == 0) { | ||
1284 | switch (res->u.add_sta.status) { | ||
1285 | case ADD_STA_SUCCESS_MSK: | ||
1286 | IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); | ||
1287 | break; | ||
1288 | default: | ||
1289 | rc = -EIO; | ||
1290 | IWL_WARNING("REPLY_ADD_STA failed\n"); | ||
1291 | break; | ||
1292 | } | ||
1293 | } | ||
1294 | |||
1295 | priv->alloc_rxb_skb--; | ||
1296 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
1297 | |||
1298 | return rc; | ||
1299 | } | ||
1300 | |||
1301 | static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv, | ||
1302 | struct ieee80211_key_conf *keyconf, | 604 | struct ieee80211_key_conf *keyconf, |
1303 | u8 sta_id) | 605 | u8 sta_id) |
1304 | { | 606 | { |
@@ -1318,42 +620,45 @@ static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv, | |||
1318 | return -EINVAL; | 620 | return -EINVAL; |
1319 | } | 621 | } |
1320 | spin_lock_irqsave(&priv->sta_lock, flags); | 622 | spin_lock_irqsave(&priv->sta_lock, flags); |
1321 | priv->stations[sta_id].keyinfo.alg = keyconf->alg; | 623 | priv->stations_39[sta_id].keyinfo.alg = keyconf->alg; |
1322 | priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; | 624 | priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen; |
1323 | memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, | 625 | memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key, |
1324 | keyconf->keylen); | 626 | keyconf->keylen); |
1325 | 627 | ||
1326 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, | 628 | memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key, |
1327 | keyconf->keylen); | 629 | keyconf->keylen); |
1328 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 630 | priv->stations_39[sta_id].sta.key.key_flags = key_flags; |
1329 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 631 | priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
1330 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 632 | priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
1331 | 633 | ||
1332 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 634 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
1333 | 635 | ||
1334 | IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); | 636 | IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); |
1335 | iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0); | 637 | iwl_send_add_sta(priv, |
638 | (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0); | ||
1336 | return 0; | 639 | return 0; |
1337 | } | 640 | } |
1338 | 641 | ||
1339 | static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id) | 642 | static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) |
1340 | { | 643 | { |
1341 | unsigned long flags; | 644 | unsigned long flags; |
1342 | 645 | ||
1343 | spin_lock_irqsave(&priv->sta_lock, flags); | 646 | spin_lock_irqsave(&priv->sta_lock, flags); |
1344 | memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key)); | 647 | memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key)); |
1345 | memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_keyinfo)); | 648 | memset(&priv->stations_39[sta_id].sta.key, 0, |
1346 | priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; | 649 | sizeof(struct iwl4965_keyinfo)); |
1347 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 650 | priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; |
1348 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 651 | priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
652 | priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | ||
1349 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 653 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
1350 | 654 | ||
1351 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); | 655 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); |
1352 | iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0); | 656 | iwl_send_add_sta(priv, |
657 | (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0); | ||
1353 | return 0; | 658 | return 0; |
1354 | } | 659 | } |
1355 | 660 | ||
1356 | static void iwl3945_clear_free_frames(struct iwl3945_priv *priv) | 661 | static void iwl3945_clear_free_frames(struct iwl_priv *priv) |
1357 | { | 662 | { |
1358 | struct list_head *element; | 663 | struct list_head *element; |
1359 | 664 | ||
@@ -1368,20 +673,20 @@ static void iwl3945_clear_free_frames(struct iwl3945_priv *priv) | |||
1368 | } | 673 | } |
1369 | 674 | ||
1370 | if (priv->frames_count) { | 675 | if (priv->frames_count) { |
1371 | IWL_WARNING("%d frames still in use. Did we lose one?\n", | 676 | IWL_WARN(priv, "%d frames still in use. Did we lose one?\n", |
1372 | priv->frames_count); | 677 | priv->frames_count); |
1373 | priv->frames_count = 0; | 678 | priv->frames_count = 0; |
1374 | } | 679 | } |
1375 | } | 680 | } |
1376 | 681 | ||
1377 | static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv) | 682 | static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv) |
1378 | { | 683 | { |
1379 | struct iwl3945_frame *frame; | 684 | struct iwl3945_frame *frame; |
1380 | struct list_head *element; | 685 | struct list_head *element; |
1381 | if (list_empty(&priv->free_frames)) { | 686 | if (list_empty(&priv->free_frames)) { |
1382 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); | 687 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); |
1383 | if (!frame) { | 688 | if (!frame) { |
1384 | IWL_ERROR("Could not allocate frame!\n"); | 689 | IWL_ERR(priv, "Could not allocate frame!\n"); |
1385 | return NULL; | 690 | return NULL; |
1386 | } | 691 | } |
1387 | 692 | ||
@@ -1394,13 +699,13 @@ static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv) | |||
1394 | return list_entry(element, struct iwl3945_frame, list); | 699 | return list_entry(element, struct iwl3945_frame, list); |
1395 | } | 700 | } |
1396 | 701 | ||
1397 | static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame) | 702 | static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame) |
1398 | { | 703 | { |
1399 | memset(frame, 0, sizeof(*frame)); | 704 | memset(frame, 0, sizeof(*frame)); |
1400 | list_add(&frame->list, &priv->free_frames); | 705 | list_add(&frame->list, &priv->free_frames); |
1401 | } | 706 | } |
1402 | 707 | ||
1403 | unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv, | 708 | unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, |
1404 | struct ieee80211_hdr *hdr, | 709 | struct ieee80211_hdr *hdr, |
1405 | int left) | 710 | int left) |
1406 | { | 711 | { |
@@ -1418,13 +723,13 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv, | |||
1418 | return priv->ibss_beacon->len; | 723 | return priv->ibss_beacon->len; |
1419 | } | 724 | } |
1420 | 725 | ||
1421 | static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv) | 726 | static u8 iwl3945_rate_get_lowest_plcp(struct iwl_priv *priv) |
1422 | { | 727 | { |
1423 | u8 i; | 728 | u8 i; |
1424 | int rate_mask; | 729 | int rate_mask; |
1425 | 730 | ||
1426 | /* Set rate mask*/ | 731 | /* Set rate mask*/ |
1427 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) | 732 | if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) |
1428 | rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK; | 733 | rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK; |
1429 | else | 734 | else |
1430 | rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK; | 735 | rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK; |
@@ -1436,13 +741,13 @@ static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv) | |||
1436 | } | 741 | } |
1437 | 742 | ||
1438 | /* No valid rate was found. Assign the lowest one */ | 743 | /* No valid rate was found. Assign the lowest one */ |
1439 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) | 744 | if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) |
1440 | return IWL_RATE_1M_PLCP; | 745 | return IWL_RATE_1M_PLCP; |
1441 | else | 746 | else |
1442 | return IWL_RATE_6M_PLCP; | 747 | return IWL_RATE_6M_PLCP; |
1443 | } | 748 | } |
1444 | 749 | ||
1445 | static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv) | 750 | static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) |
1446 | { | 751 | { |
1447 | struct iwl3945_frame *frame; | 752 | struct iwl3945_frame *frame; |
1448 | unsigned int frame_size; | 753 | unsigned int frame_size; |
@@ -1452,7 +757,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv) | |||
1452 | frame = iwl3945_get_free_frame(priv); | 757 | frame = iwl3945_get_free_frame(priv); |
1453 | 758 | ||
1454 | if (!frame) { | 759 | if (!frame) { |
1455 | IWL_ERROR("Could not obtain free frame buffer for beacon " | 760 | IWL_ERR(priv, "Could not obtain free frame buffer for beacon " |
1456 | "command.\n"); | 761 | "command.\n"); |
1457 | return -ENOMEM; | 762 | return -ENOMEM; |
1458 | } | 763 | } |
@@ -1461,7 +766,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv) | |||
1461 | 766 | ||
1462 | frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); | 767 | frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); |
1463 | 768 | ||
1464 | rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, | 769 | rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, |
1465 | &frame->u.cmd[0]); | 770 | &frame->u.cmd[0]); |
1466 | 771 | ||
1467 | iwl3945_free_frame(priv, frame); | 772 | iwl3945_free_frame(priv, frame); |
@@ -1469,307 +774,27 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv) | |||
1469 | return rc; | 774 | return rc; |
1470 | } | 775 | } |
1471 | 776 | ||
1472 | /****************************************************************************** | 777 | static void iwl3945_unset_hw_params(struct iwl_priv *priv) |
1473 | * | ||
1474 | * EEPROM related functions | ||
1475 | * | ||
1476 | ******************************************************************************/ | ||
1477 | |||
1478 | static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac) | ||
1479 | { | ||
1480 | memcpy(mac, priv->eeprom.mac_address, 6); | ||
1481 | } | ||
1482 | |||
1483 | /* | ||
1484 | * Clear the OWNER_MSK, to establish driver (instead of uCode running on | ||
1485 | * embedded controller) as EEPROM reader; each read is a series of pulses | ||
1486 | * to/from the EEPROM chip, not a single event, so even reads could conflict | ||
1487 | * if they weren't arbitrated by some ownership mechanism. Here, the driver | ||
1488 | * simply claims ownership, which should be safe when this function is called | ||
1489 | * (i.e. before loading uCode!). | ||
1490 | */ | ||
1491 | static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv) | ||
1492 | { | 778 | { |
1493 | _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); | 779 | if (priv->shared_virt) |
1494 | return 0; | ||
1495 | } | ||
1496 | |||
1497 | /** | ||
1498 | * iwl3945_eeprom_init - read EEPROM contents | ||
1499 | * | ||
1500 | * Load the EEPROM contents from adapter into priv->eeprom | ||
1501 | * | ||
1502 | * NOTE: This routine uses the non-debug IO access functions. | ||
1503 | */ | ||
1504 | int iwl3945_eeprom_init(struct iwl3945_priv *priv) | ||
1505 | { | ||
1506 | u16 *e = (u16 *)&priv->eeprom; | ||
1507 | u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP); | ||
1508 | int sz = sizeof(priv->eeprom); | ||
1509 | int ret; | ||
1510 | u16 addr; | ||
1511 | |||
1512 | /* The EEPROM structure has several padding buffers within it | ||
1513 | * and when adding new EEPROM maps is subject to programmer errors | ||
1514 | * which may be very difficult to identify without explicitly | ||
1515 | * checking the resulting size of the eeprom map. */ | ||
1516 | BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE); | ||
1517 | |||
1518 | if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { | ||
1519 | IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); | ||
1520 | return -ENOENT; | ||
1521 | } | ||
1522 | |||
1523 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
1524 | ret = iwl3945_eeprom_acquire_semaphore(priv); | ||
1525 | if (ret < 0) { | ||
1526 | IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); | ||
1527 | return -ENOENT; | ||
1528 | } | ||
1529 | |||
1530 | /* eeprom is an array of 16bit values */ | ||
1531 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | ||
1532 | u32 r; | ||
1533 | |||
1534 | _iwl3945_write32(priv, CSR_EEPROM_REG, | ||
1535 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
1536 | _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD); | ||
1537 | ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG, | ||
1538 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
1539 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
1540 | if (ret < 0) { | ||
1541 | IWL_ERROR("Time out reading EEPROM[%d]\n", addr); | ||
1542 | return ret; | ||
1543 | } | ||
1544 | |||
1545 | r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG); | ||
1546 | e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); | ||
1547 | } | ||
1548 | |||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1552 | static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv) | ||
1553 | { | ||
1554 | if (priv->hw_setting.shared_virt) | ||
1555 | pci_free_consistent(priv->pci_dev, | 780 | pci_free_consistent(priv->pci_dev, |
1556 | sizeof(struct iwl3945_shared), | 781 | sizeof(struct iwl3945_shared), |
1557 | priv->hw_setting.shared_virt, | 782 | priv->shared_virt, |
1558 | priv->hw_setting.shared_phys); | 783 | priv->shared_phys); |
1559 | } | ||
1560 | |||
1561 | /** | ||
1562 | * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field | ||
1563 | * | ||
1564 | * return : set the bit for each supported rate insert in ie | ||
1565 | */ | ||
1566 | static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate, | ||
1567 | u16 basic_rate, int *left) | ||
1568 | { | ||
1569 | u16 ret_rates = 0, bit; | ||
1570 | int i; | ||
1571 | u8 *cnt = ie; | ||
1572 | u8 *rates = ie + 1; | ||
1573 | |||
1574 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { | ||
1575 | if (bit & supported_rate) { | ||
1576 | ret_rates |= bit; | ||
1577 | rates[*cnt] = iwl3945_rates[i].ieee | | ||
1578 | ((bit & basic_rate) ? 0x80 : 0x00); | ||
1579 | (*cnt)++; | ||
1580 | (*left)--; | ||
1581 | if ((*left <= 0) || | ||
1582 | (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) | ||
1583 | break; | ||
1584 | } | ||
1585 | } | ||
1586 | |||
1587 | return ret_rates; | ||
1588 | } | ||
1589 | |||
1590 | /** | ||
1591 | * iwl3945_fill_probe_req - fill in all required fields and IE for probe request | ||
1592 | */ | ||
1593 | static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv, | ||
1594 | struct ieee80211_mgmt *frame, | ||
1595 | int left) | ||
1596 | { | ||
1597 | int len = 0; | ||
1598 | u8 *pos = NULL; | ||
1599 | u16 active_rates, ret_rates, cck_rates; | ||
1600 | |||
1601 | /* Make sure there is enough space for the probe request, | ||
1602 | * two mandatory IEs and the data */ | ||
1603 | left -= 24; | ||
1604 | if (left < 0) | ||
1605 | return 0; | ||
1606 | len += 24; | ||
1607 | |||
1608 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | ||
1609 | memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN); | ||
1610 | memcpy(frame->sa, priv->mac_addr, ETH_ALEN); | ||
1611 | memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN); | ||
1612 | frame->seq_ctrl = 0; | ||
1613 | |||
1614 | /* fill in our indirect SSID IE */ | ||
1615 | /* ...next IE... */ | ||
1616 | |||
1617 | left -= 2; | ||
1618 | if (left < 0) | ||
1619 | return 0; | ||
1620 | len += 2; | ||
1621 | pos = &(frame->u.probe_req.variable[0]); | ||
1622 | *pos++ = WLAN_EID_SSID; | ||
1623 | *pos++ = 0; | ||
1624 | |||
1625 | /* fill in supported rate */ | ||
1626 | /* ...next IE... */ | ||
1627 | left -= 2; | ||
1628 | if (left < 0) | ||
1629 | return 0; | ||
1630 | |||
1631 | /* ... fill it in... */ | ||
1632 | *pos++ = WLAN_EID_SUPP_RATES; | ||
1633 | *pos = 0; | ||
1634 | |||
1635 | priv->active_rate = priv->rates_mask; | ||
1636 | active_rates = priv->active_rate; | ||
1637 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | ||
1638 | |||
1639 | cck_rates = IWL_CCK_RATES_MASK & active_rates; | ||
1640 | ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates, | ||
1641 | priv->active_rate_basic, &left); | ||
1642 | active_rates &= ~ret_rates; | ||
1643 | |||
1644 | ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates, | ||
1645 | priv->active_rate_basic, &left); | ||
1646 | active_rates &= ~ret_rates; | ||
1647 | |||
1648 | len += 2 + *pos; | ||
1649 | pos += (*pos) + 1; | ||
1650 | if (active_rates == 0) | ||
1651 | goto fill_end; | ||
1652 | |||
1653 | /* fill in supported extended rate */ | ||
1654 | /* ...next IE... */ | ||
1655 | left -= 2; | ||
1656 | if (left < 0) | ||
1657 | return 0; | ||
1658 | /* ... fill it in... */ | ||
1659 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
1660 | *pos = 0; | ||
1661 | iwl3945_supported_rate_to_ie(pos, active_rates, | ||
1662 | priv->active_rate_basic, &left); | ||
1663 | if (*pos > 0) | ||
1664 | len += 2 + *pos; | ||
1665 | |||
1666 | fill_end: | ||
1667 | return (u16)len; | ||
1668 | } | 784 | } |
1669 | 785 | ||
1670 | /* | 786 | /* |
1671 | * QoS support | 787 | * QoS support |
1672 | */ | 788 | */ |
1673 | static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, | 789 | static int iwl3945_send_qos_params_command(struct iwl_priv *priv, |
1674 | struct iwl3945_qosparam_cmd *qos) | 790 | struct iwl_qosparam_cmd *qos) |
1675 | { | 791 | { |
1676 | 792 | ||
1677 | return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM, | 793 | return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM, |
1678 | sizeof(struct iwl3945_qosparam_cmd), qos); | 794 | sizeof(struct iwl_qosparam_cmd), qos); |
1679 | } | 795 | } |
1680 | 796 | ||
1681 | static void iwl3945_reset_qos(struct iwl3945_priv *priv) | 797 | static void iwl3945_activate_qos(struct iwl_priv *priv, u8 force) |
1682 | { | ||
1683 | u16 cw_min = 15; | ||
1684 | u16 cw_max = 1023; | ||
1685 | u8 aifs = 2; | ||
1686 | u8 is_legacy = 0; | ||
1687 | unsigned long flags; | ||
1688 | int i; | ||
1689 | |||
1690 | spin_lock_irqsave(&priv->lock, flags); | ||
1691 | priv->qos_data.qos_active = 0; | ||
1692 | |||
1693 | /* QoS always active in AP and ADHOC mode | ||
1694 | * In STA mode wait for association | ||
1695 | */ | ||
1696 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC || | ||
1697 | priv->iw_mode == NL80211_IFTYPE_AP) | ||
1698 | priv->qos_data.qos_active = 1; | ||
1699 | else | ||
1700 | priv->qos_data.qos_active = 0; | ||
1701 | |||
1702 | |||
1703 | /* check for legacy mode */ | ||
1704 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
1705 | (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) || | ||
1706 | (priv->iw_mode == NL80211_IFTYPE_STATION && | ||
1707 | (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) { | ||
1708 | cw_min = 31; | ||
1709 | is_legacy = 1; | ||
1710 | } | ||
1711 | |||
1712 | if (priv->qos_data.qos_active) | ||
1713 | aifs = 3; | ||
1714 | |||
1715 | priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min); | ||
1716 | priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max); | ||
1717 | priv->qos_data.def_qos_parm.ac[0].aifsn = aifs; | ||
1718 | priv->qos_data.def_qos_parm.ac[0].edca_txop = 0; | ||
1719 | priv->qos_data.def_qos_parm.ac[0].reserved1 = 0; | ||
1720 | |||
1721 | if (priv->qos_data.qos_active) { | ||
1722 | i = 1; | ||
1723 | priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min); | ||
1724 | priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max); | ||
1725 | priv->qos_data.def_qos_parm.ac[i].aifsn = 7; | ||
1726 | priv->qos_data.def_qos_parm.ac[i].edca_txop = 0; | ||
1727 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
1728 | |||
1729 | i = 2; | ||
1730 | priv->qos_data.def_qos_parm.ac[i].cw_min = | ||
1731 | cpu_to_le16((cw_min + 1) / 2 - 1); | ||
1732 | priv->qos_data.def_qos_parm.ac[i].cw_max = | ||
1733 | cpu_to_le16(cw_max); | ||
1734 | priv->qos_data.def_qos_parm.ac[i].aifsn = 2; | ||
1735 | if (is_legacy) | ||
1736 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
1737 | cpu_to_le16(6016); | ||
1738 | else | ||
1739 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
1740 | cpu_to_le16(3008); | ||
1741 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
1742 | |||
1743 | i = 3; | ||
1744 | priv->qos_data.def_qos_parm.ac[i].cw_min = | ||
1745 | cpu_to_le16((cw_min + 1) / 4 - 1); | ||
1746 | priv->qos_data.def_qos_parm.ac[i].cw_max = | ||
1747 | cpu_to_le16((cw_max + 1) / 2 - 1); | ||
1748 | priv->qos_data.def_qos_parm.ac[i].aifsn = 2; | ||
1749 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
1750 | if (is_legacy) | ||
1751 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
1752 | cpu_to_le16(3264); | ||
1753 | else | ||
1754 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
1755 | cpu_to_le16(1504); | ||
1756 | } else { | ||
1757 | for (i = 1; i < 4; i++) { | ||
1758 | priv->qos_data.def_qos_parm.ac[i].cw_min = | ||
1759 | cpu_to_le16(cw_min); | ||
1760 | priv->qos_data.def_qos_parm.ac[i].cw_max = | ||
1761 | cpu_to_le16(cw_max); | ||
1762 | priv->qos_data.def_qos_parm.ac[i].aifsn = aifs; | ||
1763 | priv->qos_data.def_qos_parm.ac[i].edca_txop = 0; | ||
1764 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
1765 | } | ||
1766 | } | ||
1767 | IWL_DEBUG_QOS("set QoS to default \n"); | ||
1768 | |||
1769 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1770 | } | ||
1771 | |||
1772 | static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force) | ||
1773 | { | 798 | { |
1774 | unsigned long flags; | 799 | unsigned long flags; |
1775 | 800 | ||
@@ -1804,56 +829,42 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force) | |||
1804 | */ | 829 | */ |
1805 | #define MSEC_TO_USEC 1024 | 830 | #define MSEC_TO_USEC 1024 |
1806 | 831 | ||
1807 | #define NOSLP __constant_cpu_to_le32(0) | ||
1808 | #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | ||
1809 | #define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC) | ||
1810 | #define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \ | ||
1811 | __constant_cpu_to_le32(X1), \ | ||
1812 | __constant_cpu_to_le32(X2), \ | ||
1813 | __constant_cpu_to_le32(X3), \ | ||
1814 | __constant_cpu_to_le32(X4)} | ||
1815 | |||
1816 | 832 | ||
1817 | /* default power management (not Tx power) table values */ | 833 | /* default power management (not Tx power) table values */ |
1818 | /* for TIM 0-10 */ | 834 | /* for TIM 0-10 */ |
1819 | static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = { | 835 | static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = { |
1820 | {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 836 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, |
1821 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, | 837 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, |
1822 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0}, | 838 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0}, |
1823 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0}, | 839 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0}, |
1824 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1}, | 840 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1}, |
1825 | {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1} | 841 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1} |
1826 | }; | 842 | }; |
1827 | 843 | ||
1828 | /* for TIM > 10 */ | 844 | /* for TIM > 10 */ |
1829 | static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = { | 845 | static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = { |
1830 | {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, | 846 | {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, |
1831 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), | 847 | {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, |
1832 | SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, | 848 | {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, |
1833 | {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), | 849 | {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 6, 9, 9, 0xFF)}, 0}, |
1834 | SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, | 850 | {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, |
1835 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), | 851 | {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} |
1836 | SLP_VEC(2, 6, 9, 9, 0xFF)}, 0}, | ||
1837 | {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0}, | ||
1838 | {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), | ||
1839 | SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} | ||
1840 | }; | 852 | }; |
1841 | 853 | ||
1842 | int iwl3945_power_init_handle(struct iwl3945_priv *priv) | 854 | int iwl3945_power_init_handle(struct iwl_priv *priv) |
1843 | { | 855 | { |
1844 | int rc = 0, i; | 856 | int rc = 0, i; |
1845 | struct iwl3945_power_mgr *pow_data; | 857 | struct iwl_power_mgr *pow_data; |
1846 | int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC; | 858 | int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; |
1847 | u16 pci_pm; | 859 | u16 pci_pm; |
1848 | 860 | ||
1849 | IWL_DEBUG_POWER("Initialize power \n"); | 861 | IWL_DEBUG_POWER("Initialize power \n"); |
1850 | 862 | ||
1851 | pow_data = &(priv->power_data); | 863 | pow_data = &priv->power_data; |
1852 | 864 | ||
1853 | memset(pow_data, 0, sizeof(*pow_data)); | 865 | memset(pow_data, 0, sizeof(*pow_data)); |
1854 | 866 | ||
1855 | pow_data->active_index = IWL_POWER_RANGE_0; | 867 | pow_data->dtim_period = 1; |
1856 | pow_data->dtim_val = 0xffff; | ||
1857 | 868 | ||
1858 | memcpy(&pow_data->pwr_range_0[0], &range_0[0], size); | 869 | memcpy(&pow_data->pwr_range_0[0], &range_0[0], size); |
1859 | memcpy(&pow_data->pwr_range_1[0], &range_1[0], size); | 870 | memcpy(&pow_data->pwr_range_1[0], &range_1[0], size); |
@@ -1862,11 +873,11 @@ int iwl3945_power_init_handle(struct iwl3945_priv *priv) | |||
1862 | if (rc != 0) | 873 | if (rc != 0) |
1863 | return 0; | 874 | return 0; |
1864 | else { | 875 | else { |
1865 | struct iwl3945_powertable_cmd *cmd; | 876 | struct iwl_powertable_cmd *cmd; |
1866 | 877 | ||
1867 | IWL_DEBUG_POWER("adjust power command flags\n"); | 878 | IWL_DEBUG_POWER("adjust power command flags\n"); |
1868 | 879 | ||
1869 | for (i = 0; i < IWL_POWER_AC; i++) { | 880 | for (i = 0; i < IWL_POWER_MAX; i++) { |
1870 | cmd = &pow_data->pwr_range_0[i].cmd; | 881 | cmd = &pow_data->pwr_range_0[i].cmd; |
1871 | 882 | ||
1872 | if (pci_pm & 0x1) | 883 | if (pci_pm & 0x1) |
@@ -1878,56 +889,49 @@ int iwl3945_power_init_handle(struct iwl3945_priv *priv) | |||
1878 | return rc; | 889 | return rc; |
1879 | } | 890 | } |
1880 | 891 | ||
1881 | static int iwl3945_update_power_cmd(struct iwl3945_priv *priv, | 892 | static int iwl3945_update_power_cmd(struct iwl_priv *priv, |
1882 | struct iwl3945_powertable_cmd *cmd, u32 mode) | 893 | struct iwl_powertable_cmd *cmd, u32 mode) |
1883 | { | 894 | { |
1884 | int rc = 0, i; | 895 | struct iwl_power_mgr *pow_data; |
1885 | u8 skip; | 896 | struct iwl_power_vec_entry *range; |
1886 | u32 max_sleep = 0; | 897 | u32 max_sleep = 0; |
1887 | struct iwl3945_power_vec_entry *range; | 898 | int i; |
1888 | u8 period = 0; | 899 | u8 period = 0; |
1889 | struct iwl3945_power_mgr *pow_data; | 900 | bool skip; |
1890 | 901 | ||
1891 | if (mode > IWL_POWER_INDEX_5) { | 902 | if (mode > IWL_POWER_INDEX_5) { |
1892 | IWL_DEBUG_POWER("Error invalid power mode \n"); | 903 | IWL_DEBUG_POWER("Error invalid power mode \n"); |
1893 | return -1; | 904 | return -EINVAL; |
1894 | } | 905 | } |
1895 | pow_data = &(priv->power_data); | 906 | pow_data = &priv->power_data; |
1896 | 907 | ||
1897 | if (pow_data->active_index == IWL_POWER_RANGE_0) | 908 | if (pow_data->dtim_period < 10) |
1898 | range = &pow_data->pwr_range_0[0]; | 909 | range = &pow_data->pwr_range_0[0]; |
1899 | else | 910 | else |
1900 | range = &pow_data->pwr_range_1[1]; | 911 | range = &pow_data->pwr_range_1[1]; |
1901 | 912 | ||
1902 | memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd)); | 913 | memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd)); |
1903 | 914 | ||
1904 | #ifdef IWL_MAC80211_DISABLE | ||
1905 | if (priv->assoc_network != NULL) { | ||
1906 | unsigned long flags; | ||
1907 | |||
1908 | period = priv->assoc_network->tim.tim_period; | ||
1909 | } | ||
1910 | #endif /*IWL_MAC80211_DISABLE */ | ||
1911 | skip = range[mode].no_dtim; | ||
1912 | 915 | ||
1913 | if (period == 0) { | 916 | if (period == 0) { |
1914 | period = 1; | 917 | period = 1; |
1915 | skip = 0; | 918 | skip = false; |
919 | } else { | ||
920 | skip = !!range[mode].no_dtim; | ||
1916 | } | 921 | } |
1917 | 922 | ||
1918 | if (skip == 0) { | 923 | if (skip) { |
1919 | max_sleep = period; | ||
1920 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
1921 | } else { | ||
1922 | __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]; | 924 | __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1]; |
1923 | max_sleep = (le32_to_cpu(slp_itrvl) / period) * period; | 925 | max_sleep = (le32_to_cpu(slp_itrvl) / period) * period; |
1924 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; | 926 | cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK; |
927 | } else { | ||
928 | max_sleep = period; | ||
929 | cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; | ||
1925 | } | 930 | } |
1926 | 931 | ||
1927 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) { | 932 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) |
1928 | if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) | 933 | if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep) |
1929 | cmd->sleep_interval[i] = cpu_to_le32(max_sleep); | 934 | cmd->sleep_interval[i] = cpu_to_le32(max_sleep); |
1930 | } | ||
1931 | 935 | ||
1932 | IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags); | 936 | IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags); |
1933 | IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); | 937 | IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout)); |
@@ -1939,23 +943,23 @@ static int iwl3945_update_power_cmd(struct iwl3945_priv *priv, | |||
1939 | le32_to_cpu(cmd->sleep_interval[3]), | 943 | le32_to_cpu(cmd->sleep_interval[3]), |
1940 | le32_to_cpu(cmd->sleep_interval[4])); | 944 | le32_to_cpu(cmd->sleep_interval[4])); |
1941 | 945 | ||
1942 | return rc; | 946 | return 0; |
1943 | } | 947 | } |
1944 | 948 | ||
1945 | static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode) | 949 | static int iwl3945_send_power_mode(struct iwl_priv *priv, u32 mode) |
1946 | { | 950 | { |
1947 | u32 uninitialized_var(final_mode); | 951 | u32 uninitialized_var(final_mode); |
1948 | int rc; | 952 | int rc; |
1949 | struct iwl3945_powertable_cmd cmd; | 953 | struct iwl_powertable_cmd cmd; |
1950 | 954 | ||
1951 | /* If on battery, set to 3, | 955 | /* If on battery, set to 3, |
1952 | * if plugged into AC power, set to CAM ("continuously aware mode"), | 956 | * if plugged into AC power, set to CAM ("continuously aware mode"), |
1953 | * else user level */ | 957 | * else user level */ |
1954 | switch (mode) { | 958 | switch (mode) { |
1955 | case IWL_POWER_BATTERY: | 959 | case IWL39_POWER_BATTERY: |
1956 | final_mode = IWL_POWER_INDEX_3; | 960 | final_mode = IWL_POWER_INDEX_3; |
1957 | break; | 961 | break; |
1958 | case IWL_POWER_AC: | 962 | case IWL39_POWER_AC: |
1959 | final_mode = IWL_POWER_MODE_CAM; | 963 | final_mode = IWL_POWER_MODE_CAM; |
1960 | break; | 964 | break; |
1961 | default: | 965 | default: |
@@ -1965,7 +969,9 @@ static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode) | |||
1965 | 969 | ||
1966 | iwl3945_update_power_cmd(priv, &cmd, final_mode); | 970 | iwl3945_update_power_cmd(priv, &cmd, final_mode); |
1967 | 971 | ||
1968 | rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd); | 972 | /* FIXME use get_hcmd_size 3945 command is 4 bytes shorter */ |
973 | rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, | ||
974 | sizeof(struct iwl3945_powertable_cmd), &cmd); | ||
1969 | 975 | ||
1970 | if (final_mode == IWL_POWER_MODE_CAM) | 976 | if (final_mode == IWL_POWER_MODE_CAM) |
1971 | clear_bit(STATUS_POWER_PMI, &priv->status); | 977 | clear_bit(STATUS_POWER_PMI, &priv->status); |
@@ -1975,58 +981,6 @@ static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode) | |||
1975 | return rc; | 981 | return rc; |
1976 | } | 982 | } |
1977 | 983 | ||
1978 | /** | ||
1979 | * iwl3945_scan_cancel - Cancel any currently executing HW scan | ||
1980 | * | ||
1981 | * NOTE: priv->mutex is not required before calling this function | ||
1982 | */ | ||
1983 | static int iwl3945_scan_cancel(struct iwl3945_priv *priv) | ||
1984 | { | ||
1985 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
1986 | clear_bit(STATUS_SCANNING, &priv->status); | ||
1987 | return 0; | ||
1988 | } | ||
1989 | |||
1990 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
1991 | if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
1992 | IWL_DEBUG_SCAN("Queuing scan abort.\n"); | ||
1993 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
1994 | queue_work(priv->workqueue, &priv->abort_scan); | ||
1995 | |||
1996 | } else | ||
1997 | IWL_DEBUG_SCAN("Scan abort already in progress.\n"); | ||
1998 | |||
1999 | return test_bit(STATUS_SCANNING, &priv->status); | ||
2000 | } | ||
2001 | |||
2002 | return 0; | ||
2003 | } | ||
2004 | |||
2005 | /** | ||
2006 | * iwl3945_scan_cancel_timeout - Cancel any currently executing HW scan | ||
2007 | * @ms: amount of time to wait (in milliseconds) for scan to abort | ||
2008 | * | ||
2009 | * NOTE: priv->mutex must be held before calling this function | ||
2010 | */ | ||
2011 | static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms) | ||
2012 | { | ||
2013 | unsigned long now = jiffies; | ||
2014 | int ret; | ||
2015 | |||
2016 | ret = iwl3945_scan_cancel(priv); | ||
2017 | if (ret && ms) { | ||
2018 | mutex_unlock(&priv->mutex); | ||
2019 | while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && | ||
2020 | test_bit(STATUS_SCANNING, &priv->status)) | ||
2021 | msleep(1); | ||
2022 | mutex_lock(&priv->mutex); | ||
2023 | |||
2024 | return test_bit(STATUS_SCANNING, &priv->status); | ||
2025 | } | ||
2026 | |||
2027 | return ret; | ||
2028 | } | ||
2029 | |||
2030 | #define MAX_UCODE_BEACON_INTERVAL 1024 | 984 | #define MAX_UCODE_BEACON_INTERVAL 1024 |
2031 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) | 985 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) |
2032 | 986 | ||
@@ -2043,7 +997,7 @@ static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val) | |||
2043 | return cpu_to_le16(new_val); | 997 | return cpu_to_le16(new_val); |
2044 | } | 998 | } |
2045 | 999 | ||
2046 | static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv) | 1000 | static void iwl3945_setup_rxon_timing(struct iwl_priv *priv) |
2047 | { | 1001 | { |
2048 | u64 interval_tm_unit; | 1002 | u64 interval_tm_unit; |
2049 | u64 tsf, result; | 1003 | u64 tsf, result; |
@@ -2054,13 +1008,10 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv) | |||
2054 | conf = ieee80211_get_hw_conf(priv->hw); | 1008 | conf = ieee80211_get_hw_conf(priv->hw); |
2055 | 1009 | ||
2056 | spin_lock_irqsave(&priv->lock, flags); | 1010 | spin_lock_irqsave(&priv->lock, flags); |
2057 | priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1); | 1011 | priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp); |
2058 | priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0); | ||
2059 | |||
2060 | priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL; | 1012 | priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL; |
2061 | 1013 | ||
2062 | tsf = priv->timestamp1; | 1014 | tsf = priv->timestamp; |
2063 | tsf = ((tsf << 32) | priv->timestamp0); | ||
2064 | 1015 | ||
2065 | beacon_int = priv->beacon_int; | 1016 | beacon_int = priv->beacon_int; |
2066 | spin_unlock_irqrestore(&priv->lock, flags); | 1017 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -2099,9 +1050,9 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv) | |||
2099 | le16_to_cpu(priv->rxon_timing.atim_window)); | 1050 | le16_to_cpu(priv->rxon_timing.atim_window)); |
2100 | } | 1051 | } |
2101 | 1052 | ||
2102 | static int iwl3945_scan_initiate(struct iwl3945_priv *priv) | 1053 | static int iwl3945_scan_initiate(struct iwl_priv *priv) |
2103 | { | 1054 | { |
2104 | if (!iwl3945_is_ready_rf(priv)) { | 1055 | if (!iwl_is_ready_rf(priv)) { |
2105 | IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); | 1056 | IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); |
2106 | return -EIO; | 1057 | return -EIO; |
2107 | } | 1058 | } |
@@ -2131,9 +1082,9 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv) | |||
2131 | return 0; | 1082 | return 0; |
2132 | } | 1083 | } |
2133 | 1084 | ||
2134 | static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt) | 1085 | static int iwl3945_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) |
2135 | { | 1086 | { |
2136 | struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon; | 1087 | struct iwl3945_rxon_cmd *rxon = &priv->staging39_rxon; |
2137 | 1088 | ||
2138 | if (hw_decrypt) | 1089 | if (hw_decrypt) |
2139 | rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; | 1090 | rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; |
@@ -2143,64 +1094,64 @@ static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt) | |||
2143 | return 0; | 1094 | return 0; |
2144 | } | 1095 | } |
2145 | 1096 | ||
2146 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, | 1097 | static void iwl3945_set_flags_for_phymode(struct iwl_priv *priv, |
2147 | enum ieee80211_band band) | 1098 | enum ieee80211_band band) |
2148 | { | 1099 | { |
2149 | if (band == IEEE80211_BAND_5GHZ) { | 1100 | if (band == IEEE80211_BAND_5GHZ) { |
2150 | priv->staging_rxon.flags &= | 1101 | priv->staging39_rxon.flags &= |
2151 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 1102 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2152 | | RXON_FLG_CCK_MSK); | 1103 | | RXON_FLG_CCK_MSK); |
2153 | priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; | 1104 | priv->staging39_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; |
2154 | } else { | 1105 | } else { |
2155 | /* Copied from iwl3945_bg_post_associate() */ | 1106 | /* Copied from iwl3945_bg_post_associate() */ |
2156 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) | 1107 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) |
2157 | priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; | 1108 | priv->staging39_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; |
2158 | else | 1109 | else |
2159 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 1110 | priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
2160 | 1111 | ||
2161 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) | 1112 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) |
2162 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 1113 | priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
2163 | 1114 | ||
2164 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 1115 | priv->staging39_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
2165 | priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; | 1116 | priv->staging39_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; |
2166 | priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; | 1117 | priv->staging39_rxon.flags &= ~RXON_FLG_CCK_MSK; |
2167 | } | 1118 | } |
2168 | } | 1119 | } |
2169 | 1120 | ||
2170 | /* | 1121 | /* |
2171 | * initialize rxon structure with default values from eeprom | 1122 | * initialize rxon structure with default values from eeprom |
2172 | */ | 1123 | */ |
2173 | static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv, | 1124 | static void iwl3945_connection_init_rx_config(struct iwl_priv *priv, |
2174 | int mode) | 1125 | int mode) |
2175 | { | 1126 | { |
2176 | const struct iwl3945_channel_info *ch_info; | 1127 | const struct iwl_channel_info *ch_info; |
2177 | 1128 | ||
2178 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); | 1129 | memset(&priv->staging39_rxon, 0, sizeof(priv->staging39_rxon)); |
2179 | 1130 | ||
2180 | switch (mode) { | 1131 | switch (mode) { |
2181 | case NL80211_IFTYPE_AP: | 1132 | case NL80211_IFTYPE_AP: |
2182 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; | 1133 | priv->staging39_rxon.dev_type = RXON_DEV_TYPE_AP; |
2183 | break; | 1134 | break; |
2184 | 1135 | ||
2185 | case NL80211_IFTYPE_STATION: | 1136 | case NL80211_IFTYPE_STATION: |
2186 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS; | 1137 | priv->staging39_rxon.dev_type = RXON_DEV_TYPE_ESS; |
2187 | priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; | 1138 | priv->staging39_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; |
2188 | break; | 1139 | break; |
2189 | 1140 | ||
2190 | case NL80211_IFTYPE_ADHOC: | 1141 | case NL80211_IFTYPE_ADHOC: |
2191 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS; | 1142 | priv->staging39_rxon.dev_type = RXON_DEV_TYPE_IBSS; |
2192 | priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK; | 1143 | priv->staging39_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK; |
2193 | priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK | | 1144 | priv->staging39_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK | |
2194 | RXON_FILTER_ACCEPT_GRP_MSK; | 1145 | RXON_FILTER_ACCEPT_GRP_MSK; |
2195 | break; | 1146 | break; |
2196 | 1147 | ||
2197 | case NL80211_IFTYPE_MONITOR: | 1148 | case NL80211_IFTYPE_MONITOR: |
2198 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER; | 1149 | priv->staging39_rxon.dev_type = RXON_DEV_TYPE_SNIFFER; |
2199 | priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK | | 1150 | priv->staging39_rxon.filter_flags = RXON_FILTER_PROMISC_MSK | |
2200 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; | 1151 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; |
2201 | break; | 1152 | break; |
2202 | default: | 1153 | default: |
2203 | IWL_ERROR("Unsupported interface type %d\n", mode); | 1154 | IWL_ERR(priv, "Unsupported interface type %d\n", mode); |
2204 | break; | 1155 | break; |
2205 | } | 1156 | } |
2206 | 1157 | ||
@@ -2208,13 +1159,13 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv, | |||
2208 | /* TODO: Figure out when short_preamble would be set and cache from | 1159 | /* TODO: Figure out when short_preamble would be set and cache from |
2209 | * that */ | 1160 | * that */ |
2210 | if (!hw_to_local(priv->hw)->short_preamble) | 1161 | if (!hw_to_local(priv->hw)->short_preamble) |
2211 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | 1162 | priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; |
2212 | else | 1163 | else |
2213 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 1164 | priv->staging39_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2214 | #endif | 1165 | #endif |
2215 | 1166 | ||
2216 | ch_info = iwl3945_get_channel_info(priv, priv->band, | 1167 | ch_info = iwl_get_channel_info(priv, priv->band, |
2217 | le16_to_cpu(priv->active_rxon.channel)); | 1168 | le16_to_cpu(priv->active39_rxon.channel)); |
2218 | 1169 | ||
2219 | if (!ch_info) | 1170 | if (!ch_info) |
2220 | ch_info = &priv->channel_info[0]; | 1171 | ch_info = &priv->channel_info[0]; |
@@ -2226,7 +1177,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv, | |||
2226 | if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info))) | 1177 | if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info))) |
2227 | ch_info = &priv->channel_info[0]; | 1178 | ch_info = &priv->channel_info[0]; |
2228 | 1179 | ||
2229 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 1180 | priv->staging39_rxon.channel = cpu_to_le16(ch_info->channel); |
2230 | if (is_channel_a_band(ch_info)) | 1181 | if (is_channel_a_band(ch_info)) |
2231 | priv->band = IEEE80211_BAND_5GHZ; | 1182 | priv->band = IEEE80211_BAND_5GHZ; |
2232 | else | 1183 | else |
@@ -2234,40 +1185,40 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv, | |||
2234 | 1185 | ||
2235 | iwl3945_set_flags_for_phymode(priv, priv->band); | 1186 | iwl3945_set_flags_for_phymode(priv, priv->band); |
2236 | 1187 | ||
2237 | priv->staging_rxon.ofdm_basic_rates = | 1188 | priv->staging39_rxon.ofdm_basic_rates = |
2238 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 1189 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
2239 | priv->staging_rxon.cck_basic_rates = | 1190 | priv->staging39_rxon.cck_basic_rates = |
2240 | (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | 1191 | (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; |
2241 | } | 1192 | } |
2242 | 1193 | ||
2243 | static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | 1194 | static int iwl3945_set_mode(struct iwl_priv *priv, int mode) |
2244 | { | 1195 | { |
2245 | if (mode == NL80211_IFTYPE_ADHOC) { | 1196 | if (mode == NL80211_IFTYPE_ADHOC) { |
2246 | const struct iwl3945_channel_info *ch_info; | 1197 | const struct iwl_channel_info *ch_info; |
2247 | 1198 | ||
2248 | ch_info = iwl3945_get_channel_info(priv, | 1199 | ch_info = iwl_get_channel_info(priv, |
2249 | priv->band, | 1200 | priv->band, |
2250 | le16_to_cpu(priv->staging_rxon.channel)); | 1201 | le16_to_cpu(priv->staging39_rxon.channel)); |
2251 | 1202 | ||
2252 | if (!ch_info || !is_channel_ibss(ch_info)) { | 1203 | if (!ch_info || !is_channel_ibss(ch_info)) { |
2253 | IWL_ERROR("channel %d not IBSS channel\n", | 1204 | IWL_ERR(priv, "channel %d not IBSS channel\n", |
2254 | le16_to_cpu(priv->staging_rxon.channel)); | 1205 | le16_to_cpu(priv->staging39_rxon.channel)); |
2255 | return -EINVAL; | 1206 | return -EINVAL; |
2256 | } | 1207 | } |
2257 | } | 1208 | } |
2258 | 1209 | ||
2259 | iwl3945_connection_init_rx_config(priv, mode); | 1210 | iwl3945_connection_init_rx_config(priv, mode); |
2260 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 1211 | memcpy(priv->staging39_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
2261 | 1212 | ||
2262 | iwl3945_clear_stations_table(priv); | 1213 | iwl3945_clear_stations_table(priv); |
2263 | 1214 | ||
2264 | /* don't commit rxon if rf-kill is on*/ | 1215 | /* don't commit rxon if rf-kill is on*/ |
2265 | if (!iwl3945_is_ready_rf(priv)) | 1216 | if (!iwl_is_ready_rf(priv)) |
2266 | return -EAGAIN; | 1217 | return -EAGAIN; |
2267 | 1218 | ||
2268 | cancel_delayed_work(&priv->scan_check); | 1219 | cancel_delayed_work(&priv->scan_check); |
2269 | if (iwl3945_scan_cancel_timeout(priv, 100)) { | 1220 | if (iwl_scan_cancel_timeout(priv, 100)) { |
2270 | IWL_WARNING("Aborted scan still in progress after 100ms\n"); | 1221 | IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); |
2271 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 1222 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
2272 | return -EAGAIN; | 1223 | return -EAGAIN; |
2273 | } | 1224 | } |
@@ -2277,49 +1228,50 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | |||
2277 | return 0; | 1228 | return 0; |
2278 | } | 1229 | } |
2279 | 1230 | ||
2280 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, | 1231 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, |
2281 | struct ieee80211_tx_info *info, | 1232 | struct ieee80211_tx_info *info, |
2282 | struct iwl3945_cmd *cmd, | 1233 | struct iwl_cmd *cmd, |
2283 | struct sk_buff *skb_frag, | 1234 | struct sk_buff *skb_frag, |
2284 | int last_frag) | 1235 | int last_frag) |
2285 | { | 1236 | { |
1237 | struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; | ||
2286 | struct iwl3945_hw_key *keyinfo = | 1238 | struct iwl3945_hw_key *keyinfo = |
2287 | &priv->stations[info->control.hw_key->hw_key_idx].keyinfo; | 1239 | &priv->stations_39[info->control.hw_key->hw_key_idx].keyinfo; |
2288 | 1240 | ||
2289 | switch (keyinfo->alg) { | 1241 | switch (keyinfo->alg) { |
2290 | case ALG_CCMP: | 1242 | case ALG_CCMP: |
2291 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM; | 1243 | tx->sec_ctl = TX_CMD_SEC_CCM; |
2292 | memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen); | 1244 | memcpy(tx->key, keyinfo->key, keyinfo->keylen); |
2293 | IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n"); | 1245 | IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n"); |
2294 | break; | 1246 | break; |
2295 | 1247 | ||
2296 | case ALG_TKIP: | 1248 | case ALG_TKIP: |
2297 | #if 0 | 1249 | #if 0 |
2298 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP; | 1250 | tx->sec_ctl = TX_CMD_SEC_TKIP; |
2299 | 1251 | ||
2300 | if (last_frag) | 1252 | if (last_frag) |
2301 | memcpy(cmd->cmd.tx.tkip_mic.byte, skb_frag->tail - 8, | 1253 | memcpy(tx->tkip_mic.byte, skb_frag->tail - 8, |
2302 | 8); | 1254 | 8); |
2303 | else | 1255 | else |
2304 | memset(cmd->cmd.tx.tkip_mic.byte, 0, 8); | 1256 | memset(tx->tkip_mic.byte, 0, 8); |
2305 | #endif | 1257 | #endif |
2306 | break; | 1258 | break; |
2307 | 1259 | ||
2308 | case ALG_WEP: | 1260 | case ALG_WEP: |
2309 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP | | 1261 | tx->sec_ctl = TX_CMD_SEC_WEP | |
2310 | (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; | 1262 | (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; |
2311 | 1263 | ||
2312 | if (keyinfo->keylen == 13) | 1264 | if (keyinfo->keylen == 13) |
2313 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; | 1265 | tx->sec_ctl |= TX_CMD_SEC_KEY128; |
2314 | 1266 | ||
2315 | memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen); | 1267 | memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen); |
2316 | 1268 | ||
2317 | IWL_DEBUG_TX("Configuring packet for WEP encryption " | 1269 | IWL_DEBUG_TX("Configuring packet for WEP encryption " |
2318 | "with key %d\n", info->control.hw_key->hw_key_idx); | 1270 | "with key %d\n", info->control.hw_key->hw_key_idx); |
2319 | break; | 1271 | break; |
2320 | 1272 | ||
2321 | default: | 1273 | default: |
2322 | printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg); | 1274 | IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg); |
2323 | break; | 1275 | break; |
2324 | } | 1276 | } |
2325 | } | 1277 | } |
@@ -2327,17 +1279,17 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, | |||
2327 | /* | 1279 | /* |
2328 | * handle build REPLY_TX command notification. | 1280 | * handle build REPLY_TX command notification. |
2329 | */ | 1281 | */ |
2330 | static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | 1282 | static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, |
2331 | struct iwl3945_cmd *cmd, | 1283 | struct iwl_cmd *cmd, |
2332 | struct ieee80211_tx_info *info, | 1284 | struct ieee80211_tx_info *info, |
2333 | struct ieee80211_hdr *hdr, | 1285 | struct ieee80211_hdr *hdr, u8 std_id) |
2334 | int is_unicast, u8 std_id) | ||
2335 | { | 1286 | { |
1287 | struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; | ||
1288 | __le32 tx_flags = tx->tx_flags; | ||
2336 | __le16 fc = hdr->frame_control; | 1289 | __le16 fc = hdr->frame_control; |
2337 | __le32 tx_flags = cmd->cmd.tx.tx_flags; | ||
2338 | u8 rc_flags = info->control.rates[0].flags; | 1290 | u8 rc_flags = info->control.rates[0].flags; |
2339 | 1291 | ||
2340 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 1292 | tx->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
2341 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 1293 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
2342 | tx_flags |= TX_CMD_FLG_ACK_MSK; | 1294 | tx_flags |= TX_CMD_FLG_ACK_MSK; |
2343 | if (ieee80211_is_mgmt(fc)) | 1295 | if (ieee80211_is_mgmt(fc)) |
@@ -2350,13 +1302,13 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2350 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 1302 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
2351 | } | 1303 | } |
2352 | 1304 | ||
2353 | cmd->cmd.tx.sta_id = std_id; | 1305 | tx->sta_id = std_id; |
2354 | if (ieee80211_has_morefrags(fc)) | 1306 | if (ieee80211_has_morefrags(fc)) |
2355 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; | 1307 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; |
2356 | 1308 | ||
2357 | if (ieee80211_is_data_qos(fc)) { | 1309 | if (ieee80211_is_data_qos(fc)) { |
2358 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 1310 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
2359 | cmd->cmd.tx.tid_tspec = qc[0] & 0xf; | 1311 | tx->tid_tspec = qc[0] & 0xf; |
2360 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; | 1312 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; |
2361 | } else { | 1313 | } else { |
2362 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 1314 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
@@ -2376,25 +1328,25 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2376 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); | 1328 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); |
2377 | if (ieee80211_is_mgmt(fc)) { | 1329 | if (ieee80211_is_mgmt(fc)) { |
2378 | if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) | 1330 | if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) |
2379 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); | 1331 | tx->timeout.pm_frame_timeout = cpu_to_le16(3); |
2380 | else | 1332 | else |
2381 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); | 1333 | tx->timeout.pm_frame_timeout = cpu_to_le16(2); |
2382 | } else { | 1334 | } else { |
2383 | cmd->cmd.tx.timeout.pm_frame_timeout = 0; | 1335 | tx->timeout.pm_frame_timeout = 0; |
2384 | #ifdef CONFIG_IWL3945_LEDS | 1336 | #ifdef CONFIG_IWL3945_LEDS |
2385 | priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len); | 1337 | priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len); |
2386 | #endif | 1338 | #endif |
2387 | } | 1339 | } |
2388 | 1340 | ||
2389 | cmd->cmd.tx.driver_txop = 0; | 1341 | tx->driver_txop = 0; |
2390 | cmd->cmd.tx.tx_flags = tx_flags; | 1342 | tx->tx_flags = tx_flags; |
2391 | cmd->cmd.tx.next_frame_len = 0; | 1343 | tx->next_frame_len = 0; |
2392 | } | 1344 | } |
2393 | 1345 | ||
2394 | /** | 1346 | /** |
2395 | * iwl3945_get_sta_id - Find station's index within station table | 1347 | * iwl3945_get_sta_id - Find station's index within station table |
2396 | */ | 1348 | */ |
2397 | static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr) | 1349 | static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) |
2398 | { | 1350 | { |
2399 | int sta_id; | 1351 | int sta_id; |
2400 | u16 fc = le16_to_cpu(hdr->frame_control); | 1352 | u16 fc = le16_to_cpu(hdr->frame_control); |
@@ -2402,7 +1354,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2402 | /* If this frame is broadcast or management, use broadcast station id */ | 1354 | /* If this frame is broadcast or management, use broadcast station id */ |
2403 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || | 1355 | if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || |
2404 | is_multicast_ether_addr(hdr->addr1)) | 1356 | is_multicast_ether_addr(hdr->addr1)) |
2405 | return priv->hw_setting.bcast_sta_id; | 1357 | return priv->hw_params.bcast_sta_id; |
2406 | 1358 | ||
2407 | switch (priv->iw_mode) { | 1359 | switch (priv->iw_mode) { |
2408 | 1360 | ||
@@ -2416,7 +1368,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2416 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); | 1368 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); |
2417 | if (sta_id != IWL_INVALID_STATION) | 1369 | if (sta_id != IWL_INVALID_STATION) |
2418 | return sta_id; | 1370 | return sta_id; |
2419 | return priv->hw_setting.bcast_sta_id; | 1371 | return priv->hw_params.bcast_sta_id; |
2420 | 1372 | ||
2421 | /* If this frame is going out to an IBSS network, find the station, | 1373 | /* If this frame is going out to an IBSS network, find the station, |
2422 | * or create a new station table entry */ | 1374 | * or create a new station table entry */ |
@@ -2434,35 +1386,35 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2434 | IWL_DEBUG_DROP("Station %pM not in station map. " | 1386 | IWL_DEBUG_DROP("Station %pM not in station map. " |
2435 | "Defaulting to broadcast...\n", | 1387 | "Defaulting to broadcast...\n", |
2436 | hdr->addr1); | 1388 | hdr->addr1); |
2437 | iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | 1389 | iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); |
2438 | return priv->hw_setting.bcast_sta_id; | 1390 | return priv->hw_params.bcast_sta_id; |
2439 | } | 1391 | } |
2440 | /* If we are in monitor mode, use BCAST. This is required for | 1392 | /* If we are in monitor mode, use BCAST. This is required for |
2441 | * packet injection. */ | 1393 | * packet injection. */ |
2442 | case NL80211_IFTYPE_MONITOR: | 1394 | case NL80211_IFTYPE_MONITOR: |
2443 | return priv->hw_setting.bcast_sta_id; | 1395 | return priv->hw_params.bcast_sta_id; |
2444 | 1396 | ||
2445 | default: | 1397 | default: |
2446 | IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode); | 1398 | IWL_WARN(priv, "Unknown mode of operation: %d\n", |
2447 | return priv->hw_setting.bcast_sta_id; | 1399 | priv->iw_mode); |
1400 | return priv->hw_params.bcast_sta_id; | ||
2448 | } | 1401 | } |
2449 | } | 1402 | } |
2450 | 1403 | ||
2451 | /* | 1404 | /* |
2452 | * start REPLY_TX command process | 1405 | * start REPLY_TX command process |
2453 | */ | 1406 | */ |
2454 | static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | 1407 | static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) |
2455 | { | 1408 | { |
2456 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1409 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2457 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1410 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2458 | struct iwl3945_tfd_frame *tfd; | 1411 | struct iwl3945_tx_cmd *tx; |
2459 | u32 *control_flags; | 1412 | struct iwl_tx_queue *txq = NULL; |
2460 | int txq_id = skb_get_queue_mapping(skb); | 1413 | struct iwl_queue *q = NULL; |
2461 | struct iwl3945_tx_queue *txq = NULL; | 1414 | struct iwl_cmd *out_cmd = NULL; |
2462 | struct iwl3945_queue *q = NULL; | ||
2463 | dma_addr_t phys_addr; | 1415 | dma_addr_t phys_addr; |
2464 | dma_addr_t txcmd_phys; | 1416 | dma_addr_t txcmd_phys; |
2465 | struct iwl3945_cmd *out_cmd = NULL; | 1417 | int txq_id = skb_get_queue_mapping(skb); |
2466 | u16 len, idx, len_org, hdr_len; | 1418 | u16 len, idx, len_org, hdr_len; |
2467 | u8 id; | 1419 | u8 id; |
2468 | u8 unicast; | 1420 | u8 unicast; |
@@ -2476,13 +1428,13 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2476 | int rc; | 1428 | int rc; |
2477 | 1429 | ||
2478 | spin_lock_irqsave(&priv->lock, flags); | 1430 | spin_lock_irqsave(&priv->lock, flags); |
2479 | if (iwl3945_is_rfkill(priv)) { | 1431 | if (iwl_is_rfkill(priv)) { |
2480 | IWL_DEBUG_DROP("Dropping - RF KILL\n"); | 1432 | IWL_DEBUG_DROP("Dropping - RF KILL\n"); |
2481 | goto drop_unlock; | 1433 | goto drop_unlock; |
2482 | } | 1434 | } |
2483 | 1435 | ||
2484 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { | 1436 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2485 | IWL_ERROR("ERROR: No TX rate available.\n"); | 1437 | IWL_ERR(priv, "ERROR: No TX rate available.\n"); |
2486 | goto drop_unlock; | 1438 | goto drop_unlock; |
2487 | } | 1439 | } |
2488 | 1440 | ||
@@ -2491,7 +1443,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2491 | 1443 | ||
2492 | fc = hdr->frame_control; | 1444 | fc = hdr->frame_control; |
2493 | 1445 | ||
2494 | #ifdef CONFIG_IWL3945_DEBUG | 1446 | #ifdef CONFIG_IWLWIFI_DEBUG |
2495 | if (ieee80211_is_auth(fc)) | 1447 | if (ieee80211_is_auth(fc)) |
2496 | IWL_DEBUG_TX("Sending AUTH frame\n"); | 1448 | IWL_DEBUG_TX("Sending AUTH frame\n"); |
2497 | else if (ieee80211_is_assoc_req(fc)) | 1449 | else if (ieee80211_is_assoc_req(fc)) |
@@ -2526,7 +1478,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2526 | if (ieee80211_is_data_qos(fc)) { | 1478 | if (ieee80211_is_data_qos(fc)) { |
2527 | qc = ieee80211_get_qos_ctl(hdr); | 1479 | qc = ieee80211_get_qos_ctl(hdr); |
2528 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 1480 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
2529 | seq_number = priv->stations[sta_id].tid[tid].seq_number & | 1481 | seq_number = priv->stations_39[sta_id].tid[tid].seq_number & |
2530 | IEEE80211_SCTL_SEQ; | 1482 | IEEE80211_SCTL_SEQ; |
2531 | hdr->seq_ctrl = cpu_to_le16(seq_number) | | 1483 | hdr->seq_ctrl = cpu_to_le16(seq_number) | |
2532 | (hdr->seq_ctrl & | 1484 | (hdr->seq_ctrl & |
@@ -2540,20 +1492,17 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2540 | 1492 | ||
2541 | spin_lock_irqsave(&priv->lock, flags); | 1493 | spin_lock_irqsave(&priv->lock, flags); |
2542 | 1494 | ||
2543 | /* Set up first empty TFD within this queue's circular TFD buffer */ | ||
2544 | tfd = &txq->bd[q->write_ptr]; | ||
2545 | memset(tfd, 0, sizeof(*tfd)); | ||
2546 | control_flags = (u32 *) tfd; | ||
2547 | idx = get_cmd_index(q, q->write_ptr, 0); | 1495 | idx = get_cmd_index(q, q->write_ptr, 0); |
2548 | 1496 | ||
2549 | /* Set up driver data for this TFD */ | 1497 | /* Set up driver data for this TFD */ |
2550 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info)); | 1498 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); |
2551 | txq->txb[q->write_ptr].skb[0] = skb; | 1499 | txq->txb[q->write_ptr].skb[0] = skb; |
2552 | 1500 | ||
2553 | /* Init first empty entry in queue's array of Tx/cmd buffers */ | 1501 | /* Init first empty entry in queue's array of Tx/cmd buffers */ |
2554 | out_cmd = &txq->cmd[idx]; | 1502 | out_cmd = txq->cmd[idx]; |
1503 | tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; | ||
2555 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); | 1504 | memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); |
2556 | memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); | 1505 | memset(tx, 0, sizeof(*tx)); |
2557 | 1506 | ||
2558 | /* | 1507 | /* |
2559 | * Set up the Tx-command (not MAC!) header. | 1508 | * Set up the Tx-command (not MAC!) header. |
@@ -2566,7 +1515,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2566 | INDEX_TO_SEQ(q->write_ptr))); | 1515 | INDEX_TO_SEQ(q->write_ptr))); |
2567 | 1516 | ||
2568 | /* Copy MAC header from skb into command buffer */ | 1517 | /* Copy MAC header from skb into command buffer */ |
2569 | memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); | 1518 | memcpy(tx->hdr, hdr, hdr_len); |
2570 | 1519 | ||
2571 | /* | 1520 | /* |
2572 | * Use the first empty entry in this queue's command buffer array | 1521 | * Use the first empty entry in this queue's command buffer array |
@@ -2577,8 +1526,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2577 | * of the MAC header (device reads on dword boundaries). | 1526 | * of the MAC header (device reads on dword boundaries). |
2578 | * We'll tell device about this padding later. | 1527 | * We'll tell device about this padding later. |
2579 | */ | 1528 | */ |
2580 | len = priv->hw_setting.tx_cmd_len + | 1529 | len = sizeof(struct iwl3945_tx_cmd) + |
2581 | sizeof(struct iwl3945_cmd_header) + hdr_len; | 1530 | sizeof(struct iwl_cmd_header) + hdr_len; |
2582 | 1531 | ||
2583 | len_org = len; | 1532 | len_org = len; |
2584 | len = (len + 3) & ~3; | 1533 | len = (len + 3) & ~3; |
@@ -2590,12 +1539,19 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2590 | 1539 | ||
2591 | /* Physical address of this Tx command's header (not MAC header!), | 1540 | /* Physical address of this Tx command's header (not MAC header!), |
2592 | * within command buffer array. */ | 1541 | * within command buffer array. */ |
2593 | txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx + | 1542 | txcmd_phys = pci_map_single(priv->pci_dev, |
2594 | offsetof(struct iwl3945_cmd, hdr); | 1543 | out_cmd, sizeof(struct iwl_cmd), |
1544 | PCI_DMA_TODEVICE); | ||
1545 | pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); | ||
1546 | pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd)); | ||
1547 | /* Add buffer containing Tx command and MAC(!) header to TFD's | ||
1548 | * first entry */ | ||
1549 | txcmd_phys += offsetof(struct iwl_cmd, hdr); | ||
2595 | 1550 | ||
2596 | /* Add buffer containing Tx command and MAC(!) header to TFD's | 1551 | /* Add buffer containing Tx command and MAC(!) header to TFD's |
2597 | * first entry */ | 1552 | * first entry */ |
2598 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 1553 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
1554 | txcmd_phys, len, 1, 0); | ||
2599 | 1555 | ||
2600 | if (info->control.hw_key) | 1556 | if (info->control.hw_key) |
2601 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); | 1557 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); |
@@ -2606,60 +1562,52 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2606 | if (len) { | 1562 | if (len) { |
2607 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, | 1563 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, |
2608 | len, PCI_DMA_TODEVICE); | 1564 | len, PCI_DMA_TODEVICE); |
2609 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); | 1565 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
1566 | phys_addr, len, | ||
1567 | 0, U32_PAD(len)); | ||
2610 | } | 1568 | } |
2611 | 1569 | ||
2612 | if (!len) | ||
2613 | /* If there is no payload, then we use only one Tx buffer */ | ||
2614 | *control_flags = TFD_CTL_COUNT_SET(1); | ||
2615 | else | ||
2616 | /* Else use 2 buffers. | ||
2617 | * Tell 3945 about any padding after MAC header */ | ||
2618 | *control_flags = TFD_CTL_COUNT_SET(2) | | ||
2619 | TFD_CTL_PAD_SET(U32_PAD(len)); | ||
2620 | |||
2621 | /* Total # bytes to be transmitted */ | 1570 | /* Total # bytes to be transmitted */ |
2622 | len = (u16)skb->len; | 1571 | len = (u16)skb->len; |
2623 | out_cmd->cmd.tx.len = cpu_to_le16(len); | 1572 | tx->len = cpu_to_le16(len); |
2624 | 1573 | ||
2625 | /* TODO need this for burst mode later on */ | 1574 | /* TODO need this for burst mode later on */ |
2626 | iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id); | 1575 | iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id); |
2627 | 1576 | ||
2628 | /* set is_hcca to 0; it probably will never be implemented */ | 1577 | /* set is_hcca to 0; it probably will never be implemented */ |
2629 | iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); | 1578 | iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); |
2630 | 1579 | ||
2631 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | 1580 | tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; |
2632 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | 1581 | tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; |
2633 | 1582 | ||
2634 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | 1583 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
2635 | txq->need_update = 1; | 1584 | txq->need_update = 1; |
2636 | if (qc) | 1585 | if (qc) |
2637 | priv->stations[sta_id].tid[tid].seq_number = seq_number; | 1586 | priv->stations_39[sta_id].tid[tid].seq_number = seq_number; |
2638 | } else { | 1587 | } else { |
2639 | wait_write_ptr = 1; | 1588 | wait_write_ptr = 1; |
2640 | txq->need_update = 0; | 1589 | txq->need_update = 0; |
2641 | } | 1590 | } |
2642 | 1591 | ||
2643 | iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, | 1592 | iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx)); |
2644 | sizeof(out_cmd->cmd.tx)); | ||
2645 | 1593 | ||
2646 | iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, | 1594 | iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr, |
2647 | ieee80211_hdrlen(fc)); | 1595 | ieee80211_hdrlen(fc)); |
2648 | 1596 | ||
2649 | /* Tell device the write index *just past* this latest filled TFD */ | 1597 | /* Tell device the write index *just past* this latest filled TFD */ |
2650 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1598 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
2651 | rc = iwl3945_tx_queue_update_write_ptr(priv, txq); | 1599 | rc = iwl_txq_update_write_ptr(priv, txq); |
2652 | spin_unlock_irqrestore(&priv->lock, flags); | 1600 | spin_unlock_irqrestore(&priv->lock, flags); |
2653 | 1601 | ||
2654 | if (rc) | 1602 | if (rc) |
2655 | return rc; | 1603 | return rc; |
2656 | 1604 | ||
2657 | if ((iwl3945_queue_space(q) < q->high_mark) | 1605 | if ((iwl_queue_space(q) < q->high_mark) |
2658 | && priv->mac80211_registered) { | 1606 | && priv->mac80211_registered) { |
2659 | if (wait_write_ptr) { | 1607 | if (wait_write_ptr) { |
2660 | spin_lock_irqsave(&priv->lock, flags); | 1608 | spin_lock_irqsave(&priv->lock, flags); |
2661 | txq->need_update = 1; | 1609 | txq->need_update = 1; |
2662 | iwl3945_tx_queue_update_write_ptr(priv, txq); | 1610 | iwl_txq_update_write_ptr(priv, txq); |
2663 | spin_unlock_irqrestore(&priv->lock, flags); | 1611 | spin_unlock_irqrestore(&priv->lock, flags); |
2664 | } | 1612 | } |
2665 | 1613 | ||
@@ -2674,15 +1622,15 @@ drop: | |||
2674 | return -1; | 1622 | return -1; |
2675 | } | 1623 | } |
2676 | 1624 | ||
2677 | static void iwl3945_set_rate(struct iwl3945_priv *priv) | 1625 | static void iwl3945_set_rate(struct iwl_priv *priv) |
2678 | { | 1626 | { |
2679 | const struct ieee80211_supported_band *sband = NULL; | 1627 | const struct ieee80211_supported_band *sband = NULL; |
2680 | struct ieee80211_rate *rate; | 1628 | struct ieee80211_rate *rate; |
2681 | int i; | 1629 | int i; |
2682 | 1630 | ||
2683 | sband = iwl3945_get_band(priv, priv->band); | 1631 | sband = iwl_get_hw_mode(priv, priv->band); |
2684 | if (!sband) { | 1632 | if (!sband) { |
2685 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 1633 | IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n"); |
2686 | return; | 1634 | return; |
2687 | } | 1635 | } |
2688 | 1636 | ||
@@ -2711,24 +1659,24 @@ static void iwl3945_set_rate(struct iwl3945_priv *priv) | |||
2711 | * OFDM | 1659 | * OFDM |
2712 | */ | 1660 | */ |
2713 | if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK) | 1661 | if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK) |
2714 | priv->staging_rxon.cck_basic_rates = | 1662 | priv->staging39_rxon.cck_basic_rates = |
2715 | ((priv->active_rate_basic & | 1663 | ((priv->active_rate_basic & |
2716 | IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF; | 1664 | IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF; |
2717 | else | 1665 | else |
2718 | priv->staging_rxon.cck_basic_rates = | 1666 | priv->staging39_rxon.cck_basic_rates = |
2719 | (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | 1667 | (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; |
2720 | 1668 | ||
2721 | if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK) | 1669 | if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK) |
2722 | priv->staging_rxon.ofdm_basic_rates = | 1670 | priv->staging39_rxon.ofdm_basic_rates = |
2723 | ((priv->active_rate_basic & | 1671 | ((priv->active_rate_basic & |
2724 | (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >> | 1672 | (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >> |
2725 | IWL_FIRST_OFDM_RATE) & 0xFF; | 1673 | IWL_FIRST_OFDM_RATE) & 0xFF; |
2726 | else | 1674 | else |
2727 | priv->staging_rxon.ofdm_basic_rates = | 1675 | priv->staging39_rxon.ofdm_basic_rates = |
2728 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 1676 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
2729 | } | 1677 | } |
2730 | 1678 | ||
2731 | static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) | 1679 | static void iwl3945_radio_kill_sw(struct iwl_priv *priv, int disable_radio) |
2732 | { | 1680 | { |
2733 | unsigned long flags; | 1681 | unsigned long flags; |
2734 | 1682 | ||
@@ -2739,21 +1687,21 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) | |||
2739 | disable_radio ? "OFF" : "ON"); | 1687 | disable_radio ? "OFF" : "ON"); |
2740 | 1688 | ||
2741 | if (disable_radio) { | 1689 | if (disable_radio) { |
2742 | iwl3945_scan_cancel(priv); | 1690 | iwl_scan_cancel(priv); |
2743 | /* FIXME: This is a workaround for AP */ | 1691 | /* FIXME: This is a workaround for AP */ |
2744 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | 1692 | if (priv->iw_mode != NL80211_IFTYPE_AP) { |
2745 | spin_lock_irqsave(&priv->lock, flags); | 1693 | spin_lock_irqsave(&priv->lock, flags); |
2746 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET, | 1694 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, |
2747 | CSR_UCODE_SW_BIT_RFKILL); | 1695 | CSR_UCODE_SW_BIT_RFKILL); |
2748 | spin_unlock_irqrestore(&priv->lock, flags); | 1696 | spin_unlock_irqrestore(&priv->lock, flags); |
2749 | iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0); | 1697 | iwl_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0); |
2750 | set_bit(STATUS_RF_KILL_SW, &priv->status); | 1698 | set_bit(STATUS_RF_KILL_SW, &priv->status); |
2751 | } | 1699 | } |
2752 | return; | 1700 | return; |
2753 | } | 1701 | } |
2754 | 1702 | ||
2755 | spin_lock_irqsave(&priv->lock, flags); | 1703 | spin_lock_irqsave(&priv->lock, flags); |
2756 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 1704 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
2757 | 1705 | ||
2758 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | 1706 | clear_bit(STATUS_RF_KILL_SW, &priv->status); |
2759 | spin_unlock_irqrestore(&priv->lock, flags); | 1707 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -2762,9 +1710,9 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) | |||
2762 | msleep(10); | 1710 | msleep(10); |
2763 | 1711 | ||
2764 | spin_lock_irqsave(&priv->lock, flags); | 1712 | spin_lock_irqsave(&priv->lock, flags); |
2765 | iwl3945_read32(priv, CSR_UCODE_DRV_GP1); | 1713 | iwl_read32(priv, CSR_UCODE_DRV_GP1); |
2766 | if (!iwl3945_grab_nic_access(priv)) | 1714 | if (!iwl_grab_nic_access(priv)) |
2767 | iwl3945_release_nic_access(priv); | 1715 | iwl_release_nic_access(priv); |
2768 | spin_unlock_irqrestore(&priv->lock, flags); | 1716 | spin_unlock_irqrestore(&priv->lock, flags); |
2769 | 1717 | ||
2770 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | 1718 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { |
@@ -2778,13 +1726,13 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) | |||
2778 | return; | 1726 | return; |
2779 | } | 1727 | } |
2780 | 1728 | ||
2781 | void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb, | 1729 | void iwl3945_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, |
2782 | u32 decrypt_res, struct ieee80211_rx_status *stats) | 1730 | u32 decrypt_res, struct ieee80211_rx_status *stats) |
2783 | { | 1731 | { |
2784 | u16 fc = | 1732 | u16 fc = |
2785 | le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control); | 1733 | le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control); |
2786 | 1734 | ||
2787 | if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) | 1735 | if (priv->active39_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) |
2788 | return; | 1736 | return; |
2789 | 1737 | ||
2790 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | 1738 | if (!(fc & IEEE80211_FCTL_PROTECTED)) |
@@ -2863,13 +1811,13 @@ static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) | |||
2863 | return cpu_to_le32(res); | 1811 | return cpu_to_le32(res); |
2864 | } | 1812 | } |
2865 | 1813 | ||
2866 | static int iwl3945_get_measurement(struct iwl3945_priv *priv, | 1814 | static int iwl3945_get_measurement(struct iwl_priv *priv, |
2867 | struct ieee80211_measurement_params *params, | 1815 | struct ieee80211_measurement_params *params, |
2868 | u8 type) | 1816 | u8 type) |
2869 | { | 1817 | { |
2870 | struct iwl3945_spectrum_cmd spectrum; | 1818 | struct iwl_spectrum_cmd spectrum; |
2871 | struct iwl3945_rx_packet *res; | 1819 | struct iwl_rx_packet *res; |
2872 | struct iwl3945_host_cmd cmd = { | 1820 | struct iwl_host_cmd cmd = { |
2873 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, | 1821 | .id = REPLY_SPECTRUM_MEASUREMENT_CMD, |
2874 | .data = (void *)&spectrum, | 1822 | .data = (void *)&spectrum, |
2875 | .meta.flags = CMD_WANT_SKB, | 1823 | .meta.flags = CMD_WANT_SKB, |
@@ -2905,17 +1853,17 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv, | |||
2905 | spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); | 1853 | spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); |
2906 | spectrum.channels[0].channel = params->channel; | 1854 | spectrum.channels[0].channel = params->channel; |
2907 | spectrum.channels[0].type = type; | 1855 | spectrum.channels[0].type = type; |
2908 | if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK) | 1856 | if (priv->active39_rxon.flags & RXON_FLG_BAND_24G_MSK) |
2909 | spectrum.flags |= RXON_FLG_BAND_24G_MSK | | 1857 | spectrum.flags |= RXON_FLG_BAND_24G_MSK | |
2910 | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; | 1858 | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; |
2911 | 1859 | ||
2912 | rc = iwl3945_send_cmd_sync(priv, &cmd); | 1860 | rc = iwl_send_cmd_sync(priv, &cmd); |
2913 | if (rc) | 1861 | if (rc) |
2914 | return rc; | 1862 | return rc; |
2915 | 1863 | ||
2916 | res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; | 1864 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; |
2917 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { | 1865 | if (res->hdr.flags & IWL_CMD_FAILED_MSK) { |
2918 | IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); | 1866 | IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); |
2919 | rc = -EIO; | 1867 | rc = -EIO; |
2920 | } | 1868 | } |
2921 | 1869 | ||
@@ -2942,11 +1890,11 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv, | |||
2942 | } | 1890 | } |
2943 | #endif | 1891 | #endif |
2944 | 1892 | ||
2945 | static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv, | 1893 | static void iwl3945_rx_reply_alive(struct iwl_priv *priv, |
2946 | struct iwl3945_rx_mem_buffer *rxb) | 1894 | struct iwl_rx_mem_buffer *rxb) |
2947 | { | 1895 | { |
2948 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 1896 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
2949 | struct iwl3945_alive_resp *palive; | 1897 | struct iwl_alive_resp *palive; |
2950 | struct delayed_work *pwork; | 1898 | struct delayed_work *pwork; |
2951 | 1899 | ||
2952 | palive = &pkt->u.alive_frame; | 1900 | palive = &pkt->u.alive_frame; |
@@ -2958,14 +1906,13 @@ static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv, | |||
2958 | 1906 | ||
2959 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) { | 1907 | if (palive->ver_subtype == INITIALIZE_SUBTYPE) { |
2960 | IWL_DEBUG_INFO("Initialization Alive received.\n"); | 1908 | IWL_DEBUG_INFO("Initialization Alive received.\n"); |
2961 | memcpy(&priv->card_alive_init, | 1909 | memcpy(&priv->card_alive_init, &pkt->u.alive_frame, |
2962 | &pkt->u.alive_frame, | 1910 | sizeof(struct iwl_alive_resp)); |
2963 | sizeof(struct iwl3945_init_alive_resp)); | ||
2964 | pwork = &priv->init_alive_start; | 1911 | pwork = &priv->init_alive_start; |
2965 | } else { | 1912 | } else { |
2966 | IWL_DEBUG_INFO("Runtime Alive received.\n"); | 1913 | IWL_DEBUG_INFO("Runtime Alive received.\n"); |
2967 | memcpy(&priv->card_alive, &pkt->u.alive_frame, | 1914 | memcpy(&priv->card_alive, &pkt->u.alive_frame, |
2968 | sizeof(struct iwl3945_alive_resp)); | 1915 | sizeof(struct iwl_alive_resp)); |
2969 | pwork = &priv->alive_start; | 1916 | pwork = &priv->alive_start; |
2970 | iwl3945_disable_events(priv); | 1917 | iwl3945_disable_events(priv); |
2971 | } | 1918 | } |
@@ -2976,24 +1923,26 @@ static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv, | |||
2976 | queue_delayed_work(priv->workqueue, pwork, | 1923 | queue_delayed_work(priv->workqueue, pwork, |
2977 | msecs_to_jiffies(5)); | 1924 | msecs_to_jiffies(5)); |
2978 | else | 1925 | else |
2979 | IWL_WARNING("uCode did not respond OK.\n"); | 1926 | IWL_WARN(priv, "uCode did not respond OK.\n"); |
2980 | } | 1927 | } |
2981 | 1928 | ||
2982 | static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv, | 1929 | static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv, |
2983 | struct iwl3945_rx_mem_buffer *rxb) | 1930 | struct iwl_rx_mem_buffer *rxb) |
2984 | { | 1931 | { |
2985 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 1932 | #ifdef CONFIG_IWLWIFI_DEBUG |
1933 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; | ||
1934 | #endif | ||
2986 | 1935 | ||
2987 | IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); | 1936 | IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); |
2988 | return; | 1937 | return; |
2989 | } | 1938 | } |
2990 | 1939 | ||
2991 | static void iwl3945_rx_reply_error(struct iwl3945_priv *priv, | 1940 | static void iwl3945_rx_reply_error(struct iwl_priv *priv, |
2992 | struct iwl3945_rx_mem_buffer *rxb) | 1941 | struct iwl_rx_mem_buffer *rxb) |
2993 | { | 1942 | { |
2994 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 1943 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
2995 | 1944 | ||
2996 | IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " | 1945 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " |
2997 | "seq 0x%04X ser 0x%08X\n", | 1946 | "seq 0x%04X ser 0x%08X\n", |
2998 | le32_to_cpu(pkt->u.err_resp.error_type), | 1947 | le32_to_cpu(pkt->u.err_resp.error_type), |
2999 | get_cmd_string(pkt->u.err_resp.cmd_id), | 1948 | get_cmd_string(pkt->u.err_resp.cmd_id), |
@@ -3004,23 +1953,23 @@ static void iwl3945_rx_reply_error(struct iwl3945_priv *priv, | |||
3004 | 1953 | ||
3005 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 1954 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x |
3006 | 1955 | ||
3007 | static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb) | 1956 | static void iwl3945_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
3008 | { | 1957 | { |
3009 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 1958 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3010 | struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon; | 1959 | struct iwl3945_rxon_cmd *rxon = (void *)&priv->active39_rxon; |
3011 | struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif); | 1960 | struct iwl_csa_notification *csa = &(pkt->u.csa_notif); |
3012 | IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", | 1961 | IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", |
3013 | le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); | 1962 | le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); |
3014 | rxon->channel = csa->channel; | 1963 | rxon->channel = csa->channel; |
3015 | priv->staging_rxon.channel = csa->channel; | 1964 | priv->staging39_rxon.channel = csa->channel; |
3016 | } | 1965 | } |
3017 | 1966 | ||
3018 | static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv, | 1967 | static void iwl3945_rx_spectrum_measure_notif(struct iwl_priv *priv, |
3019 | struct iwl3945_rx_mem_buffer *rxb) | 1968 | struct iwl_rx_mem_buffer *rxb) |
3020 | { | 1969 | { |
3021 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 1970 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
3022 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 1971 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3023 | struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif); | 1972 | struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); |
3024 | 1973 | ||
3025 | if (!report->state) { | 1974 | if (!report->state) { |
3026 | IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO, | 1975 | IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO, |
@@ -3033,38 +1982,39 @@ static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv, | |||
3033 | #endif | 1982 | #endif |
3034 | } | 1983 | } |
3035 | 1984 | ||
3036 | static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv, | 1985 | static void iwl3945_rx_pm_sleep_notif(struct iwl_priv *priv, |
3037 | struct iwl3945_rx_mem_buffer *rxb) | 1986 | struct iwl_rx_mem_buffer *rxb) |
3038 | { | 1987 | { |
3039 | #ifdef CONFIG_IWL3945_DEBUG | 1988 | #ifdef CONFIG_IWLWIFI_DEBUG |
3040 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 1989 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3041 | struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif); | 1990 | struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); |
3042 | IWL_DEBUG_RX("sleep mode: %d, src: %d\n", | 1991 | IWL_DEBUG_RX("sleep mode: %d, src: %d\n", |
3043 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); | 1992 | sleep->pm_sleep_mode, sleep->pm_wakeup_src); |
3044 | #endif | 1993 | #endif |
3045 | } | 1994 | } |
3046 | 1995 | ||
3047 | static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv, | 1996 | static void iwl3945_rx_pm_debug_statistics_notif(struct iwl_priv *priv, |
3048 | struct iwl3945_rx_mem_buffer *rxb) | 1997 | struct iwl_rx_mem_buffer *rxb) |
3049 | { | 1998 | { |
3050 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 1999 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3051 | IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " | 2000 | IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " |
3052 | "notification for %s:\n", | 2001 | "notification for %s:\n", |
3053 | le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); | 2002 | le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); |
3054 | iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); | 2003 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, |
2004 | le32_to_cpu(pkt->len)); | ||
3055 | } | 2005 | } |
3056 | 2006 | ||
3057 | static void iwl3945_bg_beacon_update(struct work_struct *work) | 2007 | static void iwl3945_bg_beacon_update(struct work_struct *work) |
3058 | { | 2008 | { |
3059 | struct iwl3945_priv *priv = | 2009 | struct iwl_priv *priv = |
3060 | container_of(work, struct iwl3945_priv, beacon_update); | 2010 | container_of(work, struct iwl_priv, beacon_update); |
3061 | struct sk_buff *beacon; | 2011 | struct sk_buff *beacon; |
3062 | 2012 | ||
3063 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ | 2013 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ |
3064 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); | 2014 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); |
3065 | 2015 | ||
3066 | if (!beacon) { | 2016 | if (!beacon) { |
3067 | IWL_ERROR("update beacon failed\n"); | 2017 | IWL_ERR(priv, "update beacon failed\n"); |
3068 | return; | 2018 | return; |
3069 | } | 2019 | } |
3070 | 2020 | ||
@@ -3079,11 +2029,11 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) | |||
3079 | iwl3945_send_beacon_cmd(priv); | 2029 | iwl3945_send_beacon_cmd(priv); |
3080 | } | 2030 | } |
3081 | 2031 | ||
3082 | static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv, | 2032 | static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, |
3083 | struct iwl3945_rx_mem_buffer *rxb) | 2033 | struct iwl_rx_mem_buffer *rxb) |
3084 | { | 2034 | { |
3085 | #ifdef CONFIG_IWL3945_DEBUG | 2035 | #ifdef CONFIG_IWLWIFI_DEBUG |
3086 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 2036 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3087 | struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); | 2037 | struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); |
3088 | u8 rate = beacon->beacon_notify_hdr.rate; | 2038 | u8 rate = beacon->beacon_notify_hdr.rate; |
3089 | 2039 | ||
@@ -3102,25 +2052,25 @@ static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv, | |||
3102 | } | 2052 | } |
3103 | 2053 | ||
3104 | /* Service response to REPLY_SCAN_CMD (0x80) */ | 2054 | /* Service response to REPLY_SCAN_CMD (0x80) */ |
3105 | static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv, | 2055 | static void iwl3945_rx_reply_scan(struct iwl_priv *priv, |
3106 | struct iwl3945_rx_mem_buffer *rxb) | 2056 | struct iwl_rx_mem_buffer *rxb) |
3107 | { | 2057 | { |
3108 | #ifdef CONFIG_IWL3945_DEBUG | 2058 | #ifdef CONFIG_IWLWIFI_DEBUG |
3109 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 2059 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3110 | struct iwl3945_scanreq_notification *notif = | 2060 | struct iwl_scanreq_notification *notif = |
3111 | (struct iwl3945_scanreq_notification *)pkt->u.raw; | 2061 | (struct iwl_scanreq_notification *)pkt->u.raw; |
3112 | 2062 | ||
3113 | IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); | 2063 | IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); |
3114 | #endif | 2064 | #endif |
3115 | } | 2065 | } |
3116 | 2066 | ||
3117 | /* Service SCAN_START_NOTIFICATION (0x82) */ | 2067 | /* Service SCAN_START_NOTIFICATION (0x82) */ |
3118 | static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv, | 2068 | static void iwl3945_rx_scan_start_notif(struct iwl_priv *priv, |
3119 | struct iwl3945_rx_mem_buffer *rxb) | 2069 | struct iwl_rx_mem_buffer *rxb) |
3120 | { | 2070 | { |
3121 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 2071 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3122 | struct iwl3945_scanstart_notification *notif = | 2072 | struct iwl_scanstart_notification *notif = |
3123 | (struct iwl3945_scanstart_notification *)pkt->u.raw; | 2073 | (struct iwl_scanstart_notification *)pkt->u.raw; |
3124 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | 2074 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); |
3125 | IWL_DEBUG_SCAN("Scan start: " | 2075 | IWL_DEBUG_SCAN("Scan start: " |
3126 | "%d [802.11%s] " | 2076 | "%d [802.11%s] " |
@@ -3132,12 +2082,14 @@ static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv, | |||
3132 | } | 2082 | } |
3133 | 2083 | ||
3134 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | 2084 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ |
3135 | static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv, | 2085 | static void iwl3945_rx_scan_results_notif(struct iwl_priv *priv, |
3136 | struct iwl3945_rx_mem_buffer *rxb) | 2086 | struct iwl_rx_mem_buffer *rxb) |
3137 | { | 2087 | { |
3138 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 2088 | #ifdef CONFIG_IWLWIFI_DEBUG |
3139 | struct iwl3945_scanresults_notification *notif = | 2089 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3140 | (struct iwl3945_scanresults_notification *)pkt->u.raw; | 2090 | struct iwl_scanresults_notification *notif = |
2091 | (struct iwl_scanresults_notification *)pkt->u.raw; | ||
2092 | #endif | ||
3141 | 2093 | ||
3142 | IWL_DEBUG_SCAN("Scan ch.res: " | 2094 | IWL_DEBUG_SCAN("Scan ch.res: " |
3143 | "%d [802.11%s] " | 2095 | "%d [802.11%s] " |
@@ -3157,11 +2109,13 @@ static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv, | |||
3157 | } | 2109 | } |
3158 | 2110 | ||
3159 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ | 2111 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ |
3160 | static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, | 2112 | static void iwl3945_rx_scan_complete_notif(struct iwl_priv *priv, |
3161 | struct iwl3945_rx_mem_buffer *rxb) | 2113 | struct iwl_rx_mem_buffer *rxb) |
3162 | { | 2114 | { |
3163 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 2115 | #ifdef CONFIG_IWLWIFI_DEBUG |
3164 | struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | 2116 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
2117 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | ||
2118 | #endif | ||
3165 | 2119 | ||
3166 | IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | 2120 | IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", |
3167 | scan_notif->scanned_channels, | 2121 | scan_notif->scanned_channels, |
@@ -3220,10 +2174,10 @@ reschedule: | |||
3220 | 2174 | ||
3221 | /* Handle notification from uCode that card's power state is changing | 2175 | /* Handle notification from uCode that card's power state is changing |
3222 | * due to software, hardware, or critical temperature RFKILL */ | 2176 | * due to software, hardware, or critical temperature RFKILL */ |
3223 | static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv, | 2177 | static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, |
3224 | struct iwl3945_rx_mem_buffer *rxb) | 2178 | struct iwl_rx_mem_buffer *rxb) |
3225 | { | 2179 | { |
3226 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | 2180 | struct iwl_rx_packet *pkt = (void *)rxb->skb->data; |
3227 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); | 2181 | u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); |
3228 | unsigned long status = priv->status; | 2182 | unsigned long status = priv->status; |
3229 | 2183 | ||
@@ -3231,7 +2185,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv, | |||
3231 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", | 2185 | (flags & HW_CARD_DISABLED) ? "Kill" : "On", |
3232 | (flags & SW_CARD_DISABLED) ? "Kill" : "On"); | 2186 | (flags & SW_CARD_DISABLED) ? "Kill" : "On"); |
3233 | 2187 | ||
3234 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET, | 2188 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, |
3235 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 2189 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
3236 | 2190 | ||
3237 | if (flags & HW_CARD_DISABLED) | 2191 | if (flags & HW_CARD_DISABLED) |
@@ -3245,7 +2199,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv, | |||
3245 | else | 2199 | else |
3246 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | 2200 | clear_bit(STATUS_RF_KILL_SW, &priv->status); |
3247 | 2201 | ||
3248 | iwl3945_scan_cancel(priv); | 2202 | iwl_scan_cancel(priv); |
3249 | 2203 | ||
3250 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 2204 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
3251 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 2205 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || |
@@ -3265,7 +2219,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv, | |||
3265 | * This function chains into the hardware specific files for them to setup | 2219 | * This function chains into the hardware specific files for them to setup |
3266 | * any hardware specific handlers as well. | 2220 | * any hardware specific handlers as well. |
3267 | */ | 2221 | */ |
3268 | static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv) | 2222 | static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) |
3269 | { | 2223 | { |
3270 | priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive; | 2224 | priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive; |
3271 | priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; | 2225 | priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; |
@@ -3303,15 +2257,15 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv) | |||
3303 | * When FW advances 'R' index, all entries between old and new 'R' index | 2257 | * When FW advances 'R' index, all entries between old and new 'R' index |
3304 | * need to be reclaimed. | 2258 | * need to be reclaimed. |
3305 | */ | 2259 | */ |
3306 | static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv, | 2260 | static void iwl3945_cmd_queue_reclaim(struct iwl_priv *priv, |
3307 | int txq_id, int index) | 2261 | int txq_id, int index) |
3308 | { | 2262 | { |
3309 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; | 2263 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
3310 | struct iwl3945_queue *q = &txq->q; | 2264 | struct iwl_queue *q = &txq->q; |
3311 | int nfreed = 0; | 2265 | int nfreed = 0; |
3312 | 2266 | ||
3313 | if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) { | 2267 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { |
3314 | IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " | 2268 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " |
3315 | "is out of range [0-%d] %d %d.\n", txq_id, | 2269 | "is out of range [0-%d] %d %d.\n", txq_id, |
3316 | index, q->n_bd, q->write_ptr, q->read_ptr); | 2270 | index, q->n_bd, q->write_ptr, q->read_ptr); |
3317 | return; | 2271 | return; |
@@ -3320,7 +2274,7 @@ static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv, | |||
3320 | for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; | 2274 | for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; |
3321 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 2275 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
3322 | if (nfreed > 1) { | 2276 | if (nfreed > 1) { |
3323 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | 2277 | IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", index, |
3324 | q->write_ptr, q->read_ptr); | 2278 | q->write_ptr, q->read_ptr); |
3325 | queue_work(priv->workqueue, &priv->restart); | 2279 | queue_work(priv->workqueue, &priv->restart); |
3326 | break; | 2280 | break; |
@@ -3338,21 +2292,28 @@ static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv, | |||
3338 | * will be executed. The attached skb (if present) will only be freed | 2292 | * will be executed. The attached skb (if present) will only be freed |
3339 | * if the callback returns 1 | 2293 | * if the callback returns 1 |
3340 | */ | 2294 | */ |
3341 | static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv, | 2295 | static void iwl3945_tx_cmd_complete(struct iwl_priv *priv, |
3342 | struct iwl3945_rx_mem_buffer *rxb) | 2296 | struct iwl_rx_mem_buffer *rxb) |
3343 | { | 2297 | { |
3344 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; | 2298 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3345 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 2299 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
3346 | int txq_id = SEQ_TO_QUEUE(sequence); | 2300 | int txq_id = SEQ_TO_QUEUE(sequence); |
3347 | int index = SEQ_TO_INDEX(sequence); | 2301 | int index = SEQ_TO_INDEX(sequence); |
3348 | int huge = sequence & SEQ_HUGE_FRAME; | 2302 | int huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); |
3349 | int cmd_index; | 2303 | int cmd_index; |
3350 | struct iwl3945_cmd *cmd; | 2304 | struct iwl_cmd *cmd; |
3351 | 2305 | ||
3352 | BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); | 2306 | if (WARN(txq_id != IWL_CMD_QUEUE_NUM, |
2307 | "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n", | ||
2308 | txq_id, sequence, | ||
2309 | priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr, | ||
2310 | priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) { | ||
2311 | iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32); | ||
2312 | return; | ||
2313 | } | ||
3353 | 2314 | ||
3354 | cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); | 2315 | cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); |
3355 | cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; | 2316 | cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; |
3356 | 2317 | ||
3357 | /* Input error checking is done when commands are added to queue. */ | 2318 | /* Input error checking is done when commands are added to queue. */ |
3358 | if (cmd->meta.flags & CMD_WANT_SKB) { | 2319 | if (cmd->meta.flags & CMD_WANT_SKB) { |
@@ -3417,7 +2378,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv, | |||
3417 | * | 2378 | * |
3418 | * Driver sequence: | 2379 | * Driver sequence: |
3419 | * | 2380 | * |
3420 | * iwl3945_rx_queue_alloc() Allocates rx_free | ||
3421 | * iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls | 2381 | * iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls |
3422 | * iwl3945_rx_queue_restock | 2382 | * iwl3945_rx_queue_restock |
3423 | * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx | 2383 | * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx |
@@ -3426,7 +2386,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv, | |||
3426 | * are available, schedules iwl3945_rx_replenish | 2386 | * are available, schedules iwl3945_rx_replenish |
3427 | * | 2387 | * |
3428 | * -- enable interrupts -- | 2388 | * -- enable interrupts -- |
3429 | * ISR - iwl3945_rx() Detach iwl3945_rx_mem_buffers from pool up to the | 2389 | * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the |
3430 | * READ INDEX, detaching the SKB from the pool. | 2390 | * READ INDEX, detaching the SKB from the pool. |
3431 | * Moves the packet buffer from queue to rx_used. | 2391 | * Moves the packet buffer from queue to rx_used. |
3432 | * Calls iwl3945_rx_queue_restock to refill any empty | 2392 | * Calls iwl3945_rx_queue_restock to refill any empty |
@@ -3436,70 +2396,9 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv, | |||
3436 | */ | 2396 | */ |
3437 | 2397 | ||
3438 | /** | 2398 | /** |
3439 | * iwl3945_rx_queue_space - Return number of free slots available in queue. | ||
3440 | */ | ||
3441 | static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q) | ||
3442 | { | ||
3443 | int s = q->read - q->write; | ||
3444 | if (s <= 0) | ||
3445 | s += RX_QUEUE_SIZE; | ||
3446 | /* keep some buffer to not confuse full and empty queue */ | ||
3447 | s -= 2; | ||
3448 | if (s < 0) | ||
3449 | s = 0; | ||
3450 | return s; | ||
3451 | } | ||
3452 | |||
3453 | /** | ||
3454 | * iwl3945_rx_queue_update_write_ptr - Update the write pointer for the RX queue | ||
3455 | */ | ||
3456 | int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q) | ||
3457 | { | ||
3458 | u32 reg = 0; | ||
3459 | int rc = 0; | ||
3460 | unsigned long flags; | ||
3461 | |||
3462 | spin_lock_irqsave(&q->lock, flags); | ||
3463 | |||
3464 | if (q->need_update == 0) | ||
3465 | goto exit_unlock; | ||
3466 | |||
3467 | /* If power-saving is in use, make sure device is awake */ | ||
3468 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
3469 | reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1); | ||
3470 | |||
3471 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
3472 | iwl3945_set_bit(priv, CSR_GP_CNTRL, | ||
3473 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
3474 | goto exit_unlock; | ||
3475 | } | ||
3476 | |||
3477 | rc = iwl3945_grab_nic_access(priv); | ||
3478 | if (rc) | ||
3479 | goto exit_unlock; | ||
3480 | |||
3481 | /* Device expects a multiple of 8 */ | ||
3482 | iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
3483 | q->write & ~0x7); | ||
3484 | iwl3945_release_nic_access(priv); | ||
3485 | |||
3486 | /* Else device is assumed to be awake */ | ||
3487 | } else | ||
3488 | /* Device expects a multiple of 8 */ | ||
3489 | iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); | ||
3490 | |||
3491 | |||
3492 | q->need_update = 0; | ||
3493 | |||
3494 | exit_unlock: | ||
3495 | spin_unlock_irqrestore(&q->lock, flags); | ||
3496 | return rc; | ||
3497 | } | ||
3498 | |||
3499 | /** | ||
3500 | * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | 2399 | * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr |
3501 | */ | 2400 | */ |
3502 | static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv, | 2401 | static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv, |
3503 | dma_addr_t dma_addr) | 2402 | dma_addr_t dma_addr) |
3504 | { | 2403 | { |
3505 | return cpu_to_le32((u32)dma_addr); | 2404 | return cpu_to_le32((u32)dma_addr); |
@@ -3516,24 +2415,24 @@ static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv, | |||
3516 | * also updates the memory address in the firmware to reference the new | 2415 | * also updates the memory address in the firmware to reference the new |
3517 | * target buffer. | 2416 | * target buffer. |
3518 | */ | 2417 | */ |
3519 | static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv) | 2418 | static int iwl3945_rx_queue_restock(struct iwl_priv *priv) |
3520 | { | 2419 | { |
3521 | struct iwl3945_rx_queue *rxq = &priv->rxq; | 2420 | struct iwl_rx_queue *rxq = &priv->rxq; |
3522 | struct list_head *element; | 2421 | struct list_head *element; |
3523 | struct iwl3945_rx_mem_buffer *rxb; | 2422 | struct iwl_rx_mem_buffer *rxb; |
3524 | unsigned long flags; | 2423 | unsigned long flags; |
3525 | int write, rc; | 2424 | int write, rc; |
3526 | 2425 | ||
3527 | spin_lock_irqsave(&rxq->lock, flags); | 2426 | spin_lock_irqsave(&rxq->lock, flags); |
3528 | write = rxq->write & ~0x7; | 2427 | write = rxq->write & ~0x7; |
3529 | while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | 2428 | while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { |
3530 | /* Get next free Rx buffer, remove from free list */ | 2429 | /* Get next free Rx buffer, remove from free list */ |
3531 | element = rxq->rx_free.next; | 2430 | element = rxq->rx_free.next; |
3532 | rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); | 2431 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); |
3533 | list_del(element); | 2432 | list_del(element); |
3534 | 2433 | ||
3535 | /* Point to Rx buffer via next RBD in circular buffer */ | 2434 | /* Point to Rx buffer via next RBD in circular buffer */ |
3536 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr); | 2435 | rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr); |
3537 | rxq->queue[rxq->write] = rxb; | 2436 | rxq->queue[rxq->write] = rxb; |
3538 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 2437 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
3539 | rxq->free_count--; | 2438 | rxq->free_count--; |
@@ -3552,7 +2451,7 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv) | |||
3552 | spin_lock_irqsave(&rxq->lock, flags); | 2451 | spin_lock_irqsave(&rxq->lock, flags); |
3553 | rxq->need_update = 1; | 2452 | rxq->need_update = 1; |
3554 | spin_unlock_irqrestore(&rxq->lock, flags); | 2453 | spin_unlock_irqrestore(&rxq->lock, flags); |
3555 | rc = iwl3945_rx_queue_update_write_ptr(priv, rxq); | 2454 | rc = iwl_rx_queue_update_write_ptr(priv, rxq); |
3556 | if (rc) | 2455 | if (rc) |
3557 | return rc; | 2456 | return rc; |
3558 | } | 2457 | } |
@@ -3568,24 +2467,24 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv) | |||
3568 | * Also restock the Rx queue via iwl3945_rx_queue_restock. | 2467 | * Also restock the Rx queue via iwl3945_rx_queue_restock. |
3569 | * This is called as a scheduled work item (except for during initialization) | 2468 | * This is called as a scheduled work item (except for during initialization) |
3570 | */ | 2469 | */ |
3571 | static void iwl3945_rx_allocate(struct iwl3945_priv *priv) | 2470 | static void iwl3945_rx_allocate(struct iwl_priv *priv) |
3572 | { | 2471 | { |
3573 | struct iwl3945_rx_queue *rxq = &priv->rxq; | 2472 | struct iwl_rx_queue *rxq = &priv->rxq; |
3574 | struct list_head *element; | 2473 | struct list_head *element; |
3575 | struct iwl3945_rx_mem_buffer *rxb; | 2474 | struct iwl_rx_mem_buffer *rxb; |
3576 | unsigned long flags; | 2475 | unsigned long flags; |
3577 | spin_lock_irqsave(&rxq->lock, flags); | 2476 | spin_lock_irqsave(&rxq->lock, flags); |
3578 | while (!list_empty(&rxq->rx_used)) { | 2477 | while (!list_empty(&rxq->rx_used)) { |
3579 | element = rxq->rx_used.next; | 2478 | element = rxq->rx_used.next; |
3580 | rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); | 2479 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); |
3581 | 2480 | ||
3582 | /* Alloc a new receive buffer */ | 2481 | /* Alloc a new receive buffer */ |
3583 | rxb->skb = | 2482 | rxb->skb = |
3584 | alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC); | 2483 | alloc_skb(priv->hw_params.rx_buf_size, |
2484 | __GFP_NOWARN | GFP_ATOMIC); | ||
3585 | if (!rxb->skb) { | 2485 | if (!rxb->skb) { |
3586 | if (net_ratelimit()) | 2486 | if (net_ratelimit()) |
3587 | printk(KERN_CRIT DRV_NAME | 2487 | IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); |
3588 | ": Can not allocate SKB buffers\n"); | ||
3589 | /* We don't reschedule replenish work here -- we will | 2488 | /* We don't reschedule replenish work here -- we will |
3590 | * call the restock method and if it still needs | 2489 | * call the restock method and if it still needs |
3591 | * more buffers it will schedule replenish */ | 2490 | * more buffers it will schedule replenish */ |
@@ -3604,9 +2503,10 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv) | |||
3604 | list_del(element); | 2503 | list_del(element); |
3605 | 2504 | ||
3606 | /* Get physical address of RB/SKB */ | 2505 | /* Get physical address of RB/SKB */ |
3607 | rxb->dma_addr = | 2506 | rxb->real_dma_addr = pci_map_single(priv->pci_dev, |
3608 | pci_map_single(priv->pci_dev, rxb->skb->data, | 2507 | rxb->skb->data, |
3609 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 2508 | priv->hw_params.rx_buf_size, |
2509 | PCI_DMA_FROMDEVICE); | ||
3610 | list_add_tail(&rxb->list, &rxq->rx_free); | 2510 | list_add_tail(&rxb->list, &rxq->rx_free); |
3611 | rxq->free_count++; | 2511 | rxq->free_count++; |
3612 | } | 2512 | } |
@@ -3618,7 +2518,7 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv) | |||
3618 | */ | 2518 | */ |
3619 | static void __iwl3945_rx_replenish(void *data) | 2519 | static void __iwl3945_rx_replenish(void *data) |
3620 | { | 2520 | { |
3621 | struct iwl3945_priv *priv = data; | 2521 | struct iwl_priv *priv = data; |
3622 | 2522 | ||
3623 | iwl3945_rx_allocate(priv); | 2523 | iwl3945_rx_allocate(priv); |
3624 | iwl3945_rx_queue_restock(priv); | 2524 | iwl3945_rx_queue_restock(priv); |
@@ -3627,7 +2527,7 @@ static void __iwl3945_rx_replenish(void *data) | |||
3627 | 2527 | ||
3628 | void iwl3945_rx_replenish(void *data) | 2528 | void iwl3945_rx_replenish(void *data) |
3629 | { | 2529 | { |
3630 | struct iwl3945_priv *priv = data; | 2530 | struct iwl_priv *priv = data; |
3631 | unsigned long flags; | 2531 | unsigned long flags; |
3632 | 2532 | ||
3633 | iwl3945_rx_allocate(priv); | 2533 | iwl3945_rx_allocate(priv); |
@@ -3637,84 +2537,6 @@ void iwl3945_rx_replenish(void *data) | |||
3637 | spin_unlock_irqrestore(&priv->lock, flags); | 2537 | spin_unlock_irqrestore(&priv->lock, flags); |
3638 | } | 2538 | } |
3639 | 2539 | ||
3640 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. | ||
3641 | * If an SKB has been detached, the POOL needs to have its SKB set to NULL | ||
3642 | * This free routine walks the list of POOL entries and if SKB is set to | ||
3643 | * non NULL it is unmapped and freed | ||
3644 | */ | ||
3645 | static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq) | ||
3646 | { | ||
3647 | int i; | ||
3648 | for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { | ||
3649 | if (rxq->pool[i].skb != NULL) { | ||
3650 | pci_unmap_single(priv->pci_dev, | ||
3651 | rxq->pool[i].dma_addr, | ||
3652 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | ||
3653 | dev_kfree_skb(rxq->pool[i].skb); | ||
3654 | } | ||
3655 | } | ||
3656 | |||
3657 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | ||
3658 | rxq->dma_addr); | ||
3659 | rxq->bd = NULL; | ||
3660 | } | ||
3661 | |||
3662 | int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv) | ||
3663 | { | ||
3664 | struct iwl3945_rx_queue *rxq = &priv->rxq; | ||
3665 | struct pci_dev *dev = priv->pci_dev; | ||
3666 | int i; | ||
3667 | |||
3668 | spin_lock_init(&rxq->lock); | ||
3669 | INIT_LIST_HEAD(&rxq->rx_free); | ||
3670 | INIT_LIST_HEAD(&rxq->rx_used); | ||
3671 | |||
3672 | /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
3673 | rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); | ||
3674 | if (!rxq->bd) | ||
3675 | return -ENOMEM; | ||
3676 | |||
3677 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
3678 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) | ||
3679 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
3680 | |||
3681 | /* Set us so that we have processed and used all buffers, but have | ||
3682 | * not restocked the Rx queue with fresh buffers */ | ||
3683 | rxq->read = rxq->write = 0; | ||
3684 | rxq->free_count = 0; | ||
3685 | rxq->need_update = 0; | ||
3686 | return 0; | ||
3687 | } | ||
3688 | |||
3689 | void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq) | ||
3690 | { | ||
3691 | unsigned long flags; | ||
3692 | int i; | ||
3693 | spin_lock_irqsave(&rxq->lock, flags); | ||
3694 | INIT_LIST_HEAD(&rxq->rx_free); | ||
3695 | INIT_LIST_HEAD(&rxq->rx_used); | ||
3696 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
3697 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
3698 | /* In the reset function, these buffers may have been allocated | ||
3699 | * to an SKB, so we need to unmap and free potential storage */ | ||
3700 | if (rxq->pool[i].skb != NULL) { | ||
3701 | pci_unmap_single(priv->pci_dev, | ||
3702 | rxq->pool[i].dma_addr, | ||
3703 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | ||
3704 | priv->alloc_rxb_skb--; | ||
3705 | dev_kfree_skb(rxq->pool[i].skb); | ||
3706 | rxq->pool[i].skb = NULL; | ||
3707 | } | ||
3708 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
3709 | } | ||
3710 | |||
3711 | /* Set us so that we have processed and used all buffers, but have | ||
3712 | * not restocked the Rx queue with fresh buffers */ | ||
3713 | rxq->read = rxq->write = 0; | ||
3714 | rxq->free_count = 0; | ||
3715 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
3716 | } | ||
3717 | |||
3718 | /* Convert linear signal-to-noise ratio into dB */ | 2540 | /* Convert linear signal-to-noise ratio into dB */ |
3719 | static u8 ratio2dB[100] = { | 2541 | static u8 ratio2dB[100] = { |
3720 | /* 0 1 2 3 4 5 6 7 8 9 */ | 2542 | /* 0 1 2 3 4 5 6 7 8 9 */ |
@@ -3800,11 +2622,11 @@ int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm) | |||
3800 | * the appropriate handlers, including command responses, | 2622 | * the appropriate handlers, including command responses, |
3801 | * frame-received notifications, and other notifications. | 2623 | * frame-received notifications, and other notifications. |
3802 | */ | 2624 | */ |
3803 | static void iwl3945_rx_handle(struct iwl3945_priv *priv) | 2625 | static void iwl3945_rx_handle(struct iwl_priv *priv) |
3804 | { | 2626 | { |
3805 | struct iwl3945_rx_mem_buffer *rxb; | 2627 | struct iwl_rx_mem_buffer *rxb; |
3806 | struct iwl3945_rx_packet *pkt; | 2628 | struct iwl_rx_packet *pkt; |
3807 | struct iwl3945_rx_queue *rxq = &priv->rxq; | 2629 | struct iwl_rx_queue *rxq = &priv->rxq; |
3808 | u32 r, i; | 2630 | u32 r, i; |
3809 | int reclaim; | 2631 | int reclaim; |
3810 | unsigned long flags; | 2632 | unsigned long flags; |
@@ -3813,10 +2635,10 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
3813 | 2635 | ||
3814 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 2636 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
3815 | * buffer that the driver may process (last buffer filled by ucode). */ | 2637 | * buffer that the driver may process (last buffer filled by ucode). */ |
3816 | r = iwl3945_hw_get_rx_read(priv); | 2638 | r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; |
3817 | i = rxq->read; | 2639 | i = rxq->read; |
3818 | 2640 | ||
3819 | if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) | 2641 | if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) |
3820 | fill_rx = 1; | 2642 | fill_rx = 1; |
3821 | /* Rx interrupt, but nothing sent from uCode */ | 2643 | /* Rx interrupt, but nothing sent from uCode */ |
3822 | if (i == r) | 2644 | if (i == r) |
@@ -3832,10 +2654,10 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
3832 | 2654 | ||
3833 | rxq->queue[i] = NULL; | 2655 | rxq->queue[i] = NULL; |
3834 | 2656 | ||
3835 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, | 2657 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr, |
3836 | IWL_RX_BUF_SIZE, | 2658 | priv->hw_params.rx_buf_size, |
3837 | PCI_DMA_FROMDEVICE); | 2659 | PCI_DMA_FROMDEVICE); |
3838 | pkt = (struct iwl3945_rx_packet *)rxb->skb->data; | 2660 | pkt = (struct iwl_rx_packet *)rxb->skb->data; |
3839 | 2661 | ||
3840 | /* Reclaim a command buffer only if this packet is a response | 2662 | /* Reclaim a command buffer only if this packet is a response |
3841 | * to a (driver-originated) command. | 2663 | * to a (driver-originated) command. |
@@ -3851,13 +2673,13 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
3851 | * handle those that need handling via function in | 2673 | * handle those that need handling via function in |
3852 | * rx_handlers table. See iwl3945_setup_rx_handlers() */ | 2674 | * rx_handlers table. See iwl3945_setup_rx_handlers() */ |
3853 | if (priv->rx_handlers[pkt->hdr.cmd]) { | 2675 | if (priv->rx_handlers[pkt->hdr.cmd]) { |
3854 | IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, | 2676 | IWL_DEBUG(IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR, |
3855 | "r = %d, i = %d, %s, 0x%02x\n", r, i, | 2677 | "r = %d, i = %d, %s, 0x%02x\n", r, i, |
3856 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 2678 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); |
3857 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); | 2679 | priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); |
3858 | } else { | 2680 | } else { |
3859 | /* No handling needed */ | 2681 | /* No handling needed */ |
3860 | IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, | 2682 | IWL_DEBUG(IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR, |
3861 | "r %d i %d No handler needed for %s, 0x%02x\n", | 2683 | "r %d i %d No handler needed for %s, 0x%02x\n", |
3862 | r, i, get_cmd_string(pkt->hdr.cmd), | 2684 | r, i, get_cmd_string(pkt->hdr.cmd), |
3863 | pkt->hdr.cmd); | 2685 | pkt->hdr.cmd); |
@@ -3865,12 +2687,12 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
3865 | 2687 | ||
3866 | if (reclaim) { | 2688 | if (reclaim) { |
3867 | /* Invoke any callbacks, transfer the skb to caller, and | 2689 | /* Invoke any callbacks, transfer the skb to caller, and |
3868 | * fire off the (possibly) blocking iwl3945_send_cmd() | 2690 | * fire off the (possibly) blocking iwl_send_cmd() |
3869 | * as we reclaim the driver command queue */ | 2691 | * as we reclaim the driver command queue */ |
3870 | if (rxb && rxb->skb) | 2692 | if (rxb && rxb->skb) |
3871 | iwl3945_tx_cmd_complete(priv, rxb); | 2693 | iwl3945_tx_cmd_complete(priv, rxb); |
3872 | else | 2694 | else |
3873 | IWL_WARNING("Claim null rxb?\n"); | 2695 | IWL_WARN(priv, "Claim null rxb?\n"); |
3874 | } | 2696 | } |
3875 | 2697 | ||
3876 | /* For now we just don't re-use anything. We can tweak this | 2698 | /* For now we just don't re-use anything. We can tweak this |
@@ -3882,8 +2704,9 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
3882 | rxb->skb = NULL; | 2704 | rxb->skb = NULL; |
3883 | } | 2705 | } |
3884 | 2706 | ||
3885 | pci_unmap_single(priv->pci_dev, rxb->dma_addr, | 2707 | pci_unmap_single(priv->pci_dev, rxb->real_dma_addr, |
3886 | IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 2708 | priv->hw_params.rx_buf_size, |
2709 | PCI_DMA_FROMDEVICE); | ||
3887 | spin_lock_irqsave(&rxq->lock, flags); | 2710 | spin_lock_irqsave(&rxq->lock, flags); |
3888 | list_add_tail(&rxb->list, &priv->rxq.rx_used); | 2711 | list_add_tail(&rxb->list, &priv->rxq.rx_used); |
3889 | spin_unlock_irqrestore(&rxq->lock, flags); | 2712 | spin_unlock_irqrestore(&rxq->lock, flags); |
@@ -3905,57 +2728,12 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv) | |||
3905 | iwl3945_rx_queue_restock(priv); | 2728 | iwl3945_rx_queue_restock(priv); |
3906 | } | 2729 | } |
3907 | 2730 | ||
3908 | /** | 2731 | #ifdef CONFIG_IWLWIFI_DEBUG |
3909 | * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware | 2732 | static void iwl3945_print_rx_config_cmd(struct iwl_priv *priv, |
3910 | */ | 2733 | struct iwl3945_rxon_cmd *rxon) |
3911 | static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv, | ||
3912 | struct iwl3945_tx_queue *txq) | ||
3913 | { | ||
3914 | u32 reg = 0; | ||
3915 | int rc = 0; | ||
3916 | int txq_id = txq->q.id; | ||
3917 | |||
3918 | if (txq->need_update == 0) | ||
3919 | return rc; | ||
3920 | |||
3921 | /* if we're trying to save power */ | ||
3922 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
3923 | /* wake up nic if it's powered down ... | ||
3924 | * uCode will wake up, and interrupt us again, so next | ||
3925 | * time we'll skip this part. */ | ||
3926 | reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1); | ||
3927 | |||
3928 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
3929 | IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg); | ||
3930 | iwl3945_set_bit(priv, CSR_GP_CNTRL, | ||
3931 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
3932 | return rc; | ||
3933 | } | ||
3934 | |||
3935 | /* restore this queue's parameters in nic hardware. */ | ||
3936 | rc = iwl3945_grab_nic_access(priv); | ||
3937 | if (rc) | ||
3938 | return rc; | ||
3939 | iwl3945_write_direct32(priv, HBUS_TARG_WRPTR, | ||
3940 | txq->q.write_ptr | (txq_id << 8)); | ||
3941 | iwl3945_release_nic_access(priv); | ||
3942 | |||
3943 | /* else not in power-save mode, uCode will never sleep when we're | ||
3944 | * trying to tx (during RFKILL, we're not trying to tx). */ | ||
3945 | } else | ||
3946 | iwl3945_write32(priv, HBUS_TARG_WRPTR, | ||
3947 | txq->q.write_ptr | (txq_id << 8)); | ||
3948 | |||
3949 | txq->need_update = 0; | ||
3950 | |||
3951 | return rc; | ||
3952 | } | ||
3953 | |||
3954 | #ifdef CONFIG_IWL3945_DEBUG | ||
3955 | static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon) | ||
3956 | { | 2734 | { |
3957 | IWL_DEBUG_RADIO("RX CONFIG:\n"); | 2735 | IWL_DEBUG_RADIO("RX CONFIG:\n"); |
3958 | iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); | 2736 | iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); |
3959 | IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); | 2737 | IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); |
3960 | IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); | 2738 | IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); |
3961 | IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", | 2739 | IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", |
@@ -3970,16 +2748,16 @@ static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon) | |||
3970 | } | 2748 | } |
3971 | #endif | 2749 | #endif |
3972 | 2750 | ||
3973 | static void iwl3945_enable_interrupts(struct iwl3945_priv *priv) | 2751 | static void iwl3945_enable_interrupts(struct iwl_priv *priv) |
3974 | { | 2752 | { |
3975 | IWL_DEBUG_ISR("Enabling interrupts\n"); | 2753 | IWL_DEBUG_ISR("Enabling interrupts\n"); |
3976 | set_bit(STATUS_INT_ENABLED, &priv->status); | 2754 | set_bit(STATUS_INT_ENABLED, &priv->status); |
3977 | iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); | 2755 | iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); |
3978 | } | 2756 | } |
3979 | 2757 | ||
3980 | 2758 | ||
3981 | /* call this function to flush any scheduled tasklet */ | 2759 | /* call this function to flush any scheduled tasklet */ |
3982 | static inline void iwl_synchronize_irq(struct iwl3945_priv *priv) | 2760 | static inline void iwl_synchronize_irq(struct iwl_priv *priv) |
3983 | { | 2761 | { |
3984 | /* wait to make sure we flush pending tasklet*/ | 2762 | /* wait to make sure we flush pending tasklet*/ |
3985 | synchronize_irq(priv->pci_dev->irq); | 2763 | synchronize_irq(priv->pci_dev->irq); |
@@ -3987,17 +2765,17 @@ static inline void iwl_synchronize_irq(struct iwl3945_priv *priv) | |||
3987 | } | 2765 | } |
3988 | 2766 | ||
3989 | 2767 | ||
3990 | static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv) | 2768 | static inline void iwl3945_disable_interrupts(struct iwl_priv *priv) |
3991 | { | 2769 | { |
3992 | clear_bit(STATUS_INT_ENABLED, &priv->status); | 2770 | clear_bit(STATUS_INT_ENABLED, &priv->status); |
3993 | 2771 | ||
3994 | /* disable interrupts from uCode/NIC to host */ | 2772 | /* disable interrupts from uCode/NIC to host */ |
3995 | iwl3945_write32(priv, CSR_INT_MASK, 0x00000000); | 2773 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); |
3996 | 2774 | ||
3997 | /* acknowledge/clear/reset any interrupts still pending | 2775 | /* acknowledge/clear/reset any interrupts still pending |
3998 | * from uCode or flow handler (Rx/Tx DMA) */ | 2776 | * from uCode or flow handler (Rx/Tx DMA) */ |
3999 | iwl3945_write32(priv, CSR_INT, 0xffffffff); | 2777 | iwl_write32(priv, CSR_INT, 0xffffffff); |
4000 | iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); | 2778 | iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); |
4001 | IWL_DEBUG_ISR("Disabled interrupts\n"); | 2779 | IWL_DEBUG_ISR("Disabled interrupts\n"); |
4002 | } | 2780 | } |
4003 | 2781 | ||
@@ -4024,7 +2802,7 @@ static const char *desc_lookup(int i) | |||
4024 | #define ERROR_START_OFFSET (1 * sizeof(u32)) | 2802 | #define ERROR_START_OFFSET (1 * sizeof(u32)) |
4025 | #define ERROR_ELEM_SIZE (7 * sizeof(u32)) | 2803 | #define ERROR_ELEM_SIZE (7 * sizeof(u32)) |
4026 | 2804 | ||
4027 | static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv) | 2805 | static void iwl3945_dump_nic_error_log(struct iwl_priv *priv) |
4028 | { | 2806 | { |
4029 | u32 i; | 2807 | u32 i; |
4030 | u32 desc, time, count, base, data1; | 2808 | u32 desc, time, count, base, data1; |
@@ -4034,49 +2812,50 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv) | |||
4034 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); | 2812 | base = le32_to_cpu(priv->card_alive.error_event_table_ptr); |
4035 | 2813 | ||
4036 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { | 2814 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { |
4037 | IWL_ERROR("Not valid error log pointer 0x%08X\n", base); | 2815 | IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base); |
4038 | return; | 2816 | return; |
4039 | } | 2817 | } |
4040 | 2818 | ||
4041 | rc = iwl3945_grab_nic_access(priv); | 2819 | rc = iwl_grab_nic_access(priv); |
4042 | if (rc) { | 2820 | if (rc) { |
4043 | IWL_WARNING("Can not read from adapter at this time.\n"); | 2821 | IWL_WARN(priv, "Can not read from adapter at this time.\n"); |
4044 | return; | 2822 | return; |
4045 | } | 2823 | } |
4046 | 2824 | ||
4047 | count = iwl3945_read_targ_mem(priv, base); | 2825 | count = iwl_read_targ_mem(priv, base); |
4048 | 2826 | ||
4049 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { | 2827 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { |
4050 | IWL_ERROR("Start IWL Error Log Dump:\n"); | 2828 | IWL_ERR(priv, "Start IWL Error Log Dump:\n"); |
4051 | IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count); | 2829 | IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", |
2830 | priv->status, count); | ||
4052 | } | 2831 | } |
4053 | 2832 | ||
4054 | IWL_ERROR("Desc Time asrtPC blink2 " | 2833 | IWL_ERR(priv, "Desc Time asrtPC blink2 " |
4055 | "ilink1 nmiPC Line\n"); | 2834 | "ilink1 nmiPC Line\n"); |
4056 | for (i = ERROR_START_OFFSET; | 2835 | for (i = ERROR_START_OFFSET; |
4057 | i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET; | 2836 | i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET; |
4058 | i += ERROR_ELEM_SIZE) { | 2837 | i += ERROR_ELEM_SIZE) { |
4059 | desc = iwl3945_read_targ_mem(priv, base + i); | 2838 | desc = iwl_read_targ_mem(priv, base + i); |
4060 | time = | 2839 | time = |
4061 | iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32)); | 2840 | iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32)); |
4062 | blink1 = | 2841 | blink1 = |
4063 | iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32)); | 2842 | iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32)); |
4064 | blink2 = | 2843 | blink2 = |
4065 | iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32)); | 2844 | iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32)); |
4066 | ilink1 = | 2845 | ilink1 = |
4067 | iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32)); | 2846 | iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32)); |
4068 | ilink2 = | 2847 | ilink2 = |
4069 | iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32)); | 2848 | iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32)); |
4070 | data1 = | 2849 | data1 = |
4071 | iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32)); | 2850 | iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32)); |
4072 | 2851 | ||
4073 | IWL_ERROR | 2852 | IWL_ERR(priv, |
4074 | ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", | 2853 | "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", |
4075 | desc_lookup(desc), desc, time, blink1, blink2, | 2854 | desc_lookup(desc), desc, time, blink1, blink2, |
4076 | ilink1, ilink2, data1); | 2855 | ilink1, ilink2, data1); |
4077 | } | 2856 | } |
4078 | 2857 | ||
4079 | iwl3945_release_nic_access(priv); | 2858 | iwl_release_nic_access(priv); |
4080 | 2859 | ||
4081 | } | 2860 | } |
4082 | 2861 | ||
@@ -4085,9 +2864,9 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv) | |||
4085 | /** | 2864 | /** |
4086 | * iwl3945_print_event_log - Dump error event log to syslog | 2865 | * iwl3945_print_event_log - Dump error event log to syslog |
4087 | * | 2866 | * |
4088 | * NOTE: Must be called with iwl3945_grab_nic_access() already obtained! | 2867 | * NOTE: Must be called with iwl_grab_nic_access() already obtained! |
4089 | */ | 2868 | */ |
4090 | static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx, | 2869 | static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, |
4091 | u32 num_events, u32 mode) | 2870 | u32 num_events, u32 mode) |
4092 | { | 2871 | { |
4093 | u32 i; | 2872 | u32 i; |
@@ -4111,21 +2890,22 @@ static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx, | |||
4111 | /* "time" is actually "data" for mode 0 (no timestamp). | 2890 | /* "time" is actually "data" for mode 0 (no timestamp). |
4112 | * place event id # at far right for easier visual parsing. */ | 2891 | * place event id # at far right for easier visual parsing. */ |
4113 | for (i = 0; i < num_events; i++) { | 2892 | for (i = 0; i < num_events; i++) { |
4114 | ev = iwl3945_read_targ_mem(priv, ptr); | 2893 | ev = iwl_read_targ_mem(priv, ptr); |
4115 | ptr += sizeof(u32); | 2894 | ptr += sizeof(u32); |
4116 | time = iwl3945_read_targ_mem(priv, ptr); | 2895 | time = iwl_read_targ_mem(priv, ptr); |
4117 | ptr += sizeof(u32); | 2896 | ptr += sizeof(u32); |
4118 | if (mode == 0) | 2897 | if (mode == 0) { |
4119 | IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */ | 2898 | /* data, ev */ |
4120 | else { | 2899 | IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); |
4121 | data = iwl3945_read_targ_mem(priv, ptr); | 2900 | } else { |
2901 | data = iwl_read_targ_mem(priv, ptr); | ||
4122 | ptr += sizeof(u32); | 2902 | ptr += sizeof(u32); |
4123 | IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev); | 2903 | IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); |
4124 | } | 2904 | } |
4125 | } | 2905 | } |
4126 | } | 2906 | } |
4127 | 2907 | ||
4128 | static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv) | 2908 | static void iwl3945_dump_nic_event_log(struct iwl_priv *priv) |
4129 | { | 2909 | { |
4130 | int rc; | 2910 | int rc; |
4131 | u32 base; /* SRAM byte address of event log header */ | 2911 | u32 base; /* SRAM byte address of event log header */ |
@@ -4137,32 +2917,32 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv) | |||
4137 | 2917 | ||
4138 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); | 2918 | base = le32_to_cpu(priv->card_alive.log_event_table_ptr); |
4139 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { | 2919 | if (!iwl3945_hw_valid_rtc_data_addr(base)) { |
4140 | IWL_ERROR("Invalid event log pointer 0x%08X\n", base); | 2920 | IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); |
4141 | return; | 2921 | return; |
4142 | } | 2922 | } |
4143 | 2923 | ||
4144 | rc = iwl3945_grab_nic_access(priv); | 2924 | rc = iwl_grab_nic_access(priv); |
4145 | if (rc) { | 2925 | if (rc) { |
4146 | IWL_WARNING("Can not read from adapter at this time.\n"); | 2926 | IWL_WARN(priv, "Can not read from adapter at this time.\n"); |
4147 | return; | 2927 | return; |
4148 | } | 2928 | } |
4149 | 2929 | ||
4150 | /* event log header */ | 2930 | /* event log header */ |
4151 | capacity = iwl3945_read_targ_mem(priv, base); | 2931 | capacity = iwl_read_targ_mem(priv, base); |
4152 | mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32))); | 2932 | mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32))); |
4153 | num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32))); | 2933 | num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); |
4154 | next_entry = iwl3945_read_targ_mem(priv, base + (3 * sizeof(u32))); | 2934 | next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); |
4155 | 2935 | ||
4156 | size = num_wraps ? capacity : next_entry; | 2936 | size = num_wraps ? capacity : next_entry; |
4157 | 2937 | ||
4158 | /* bail out if nothing in log */ | 2938 | /* bail out if nothing in log */ |
4159 | if (size == 0) { | 2939 | if (size == 0) { |
4160 | IWL_ERROR("Start IWL Event Log Dump: nothing in log\n"); | 2940 | IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); |
4161 | iwl3945_release_nic_access(priv); | 2941 | iwl_release_nic_access(priv); |
4162 | return; | 2942 | return; |
4163 | } | 2943 | } |
4164 | 2944 | ||
4165 | IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n", | 2945 | IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n", |
4166 | size, num_wraps); | 2946 | size, num_wraps); |
4167 | 2947 | ||
4168 | /* if uCode has wrapped back to top of log, start at the oldest entry, | 2948 | /* if uCode has wrapped back to top of log, start at the oldest entry, |
@@ -4174,13 +2954,13 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv) | |||
4174 | /* (then/else) start at top of log */ | 2954 | /* (then/else) start at top of log */ |
4175 | iwl3945_print_event_log(priv, 0, next_entry, mode); | 2955 | iwl3945_print_event_log(priv, 0, next_entry, mode); |
4176 | 2956 | ||
4177 | iwl3945_release_nic_access(priv); | 2957 | iwl_release_nic_access(priv); |
4178 | } | 2958 | } |
4179 | 2959 | ||
4180 | /** | 2960 | /** |
4181 | * iwl3945_irq_handle_error - called for HW or SW error interrupt from card | 2961 | * iwl3945_irq_handle_error - called for HW or SW error interrupt from card |
4182 | */ | 2962 | */ |
4183 | static void iwl3945_irq_handle_error(struct iwl3945_priv *priv) | 2963 | static void iwl3945_irq_handle_error(struct iwl_priv *priv) |
4184 | { | 2964 | { |
4185 | /* Set the FW error flag -- cleared on iwl3945_down */ | 2965 | /* Set the FW error flag -- cleared on iwl3945_down */ |
4186 | set_bit(STATUS_FW_ERROR, &priv->status); | 2966 | set_bit(STATUS_FW_ERROR, &priv->status); |
@@ -4188,11 +2968,11 @@ static void iwl3945_irq_handle_error(struct iwl3945_priv *priv) | |||
4188 | /* Cancel currently queued command. */ | 2968 | /* Cancel currently queued command. */ |
4189 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 2969 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
4190 | 2970 | ||
4191 | #ifdef CONFIG_IWL3945_DEBUG | 2971 | #ifdef CONFIG_IWLWIFI_DEBUG |
4192 | if (iwl3945_debug_level & IWL_DL_FW_ERRORS) { | 2972 | if (priv->debug_level & IWL_DL_FW_ERRORS) { |
4193 | iwl3945_dump_nic_error_log(priv); | 2973 | iwl3945_dump_nic_error_log(priv); |
4194 | iwl3945_dump_nic_event_log(priv); | 2974 | iwl3945_dump_nic_event_log(priv); |
4195 | iwl3945_print_rx_config_cmd(&priv->staging_rxon); | 2975 | iwl3945_print_rx_config_cmd(priv, &priv->staging39_rxon); |
4196 | } | 2976 | } |
4197 | #endif | 2977 | #endif |
4198 | 2978 | ||
@@ -4207,37 +2987,38 @@ static void iwl3945_irq_handle_error(struct iwl3945_priv *priv) | |||
4207 | "Restarting adapter due to uCode error.\n"); | 2987 | "Restarting adapter due to uCode error.\n"); |
4208 | 2988 | ||
4209 | if (iwl3945_is_associated(priv)) { | 2989 | if (iwl3945_is_associated(priv)) { |
4210 | memcpy(&priv->recovery_rxon, &priv->active_rxon, | 2990 | memcpy(&priv->recovery39_rxon, &priv->active39_rxon, |
4211 | sizeof(priv->recovery_rxon)); | 2991 | sizeof(priv->recovery39_rxon)); |
4212 | priv->error_recovering = 1; | 2992 | priv->error_recovering = 1; |
4213 | } | 2993 | } |
4214 | queue_work(priv->workqueue, &priv->restart); | 2994 | if (priv->cfg->mod_params->restart_fw) |
2995 | queue_work(priv->workqueue, &priv->restart); | ||
4215 | } | 2996 | } |
4216 | } | 2997 | } |
4217 | 2998 | ||
4218 | static void iwl3945_error_recovery(struct iwl3945_priv *priv) | 2999 | static void iwl3945_error_recovery(struct iwl_priv *priv) |
4219 | { | 3000 | { |
4220 | unsigned long flags; | 3001 | unsigned long flags; |
4221 | 3002 | ||
4222 | memcpy(&priv->staging_rxon, &priv->recovery_rxon, | 3003 | memcpy(&priv->staging39_rxon, &priv->recovery39_rxon, |
4223 | sizeof(priv->staging_rxon)); | 3004 | sizeof(priv->staging39_rxon)); |
4224 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3005 | priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
4225 | iwl3945_commit_rxon(priv); | 3006 | iwl3945_commit_rxon(priv); |
4226 | 3007 | ||
4227 | iwl3945_add_station(priv, priv->bssid, 1, 0); | 3008 | iwl3945_add_station(priv, priv->bssid, 1, 0); |
4228 | 3009 | ||
4229 | spin_lock_irqsave(&priv->lock, flags); | 3010 | spin_lock_irqsave(&priv->lock, flags); |
4230 | priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); | 3011 | priv->assoc_id = le16_to_cpu(priv->staging39_rxon.assoc_id); |
4231 | priv->error_recovering = 0; | 3012 | priv->error_recovering = 0; |
4232 | spin_unlock_irqrestore(&priv->lock, flags); | 3013 | spin_unlock_irqrestore(&priv->lock, flags); |
4233 | } | 3014 | } |
4234 | 3015 | ||
4235 | static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | 3016 | static void iwl3945_irq_tasklet(struct iwl_priv *priv) |
4236 | { | 3017 | { |
4237 | u32 inta, handled = 0; | 3018 | u32 inta, handled = 0; |
4238 | u32 inta_fh; | 3019 | u32 inta_fh; |
4239 | unsigned long flags; | 3020 | unsigned long flags; |
4240 | #ifdef CONFIG_IWL3945_DEBUG | 3021 | #ifdef CONFIG_IWLWIFI_DEBUG |
4241 | u32 inta_mask; | 3022 | u32 inta_mask; |
4242 | #endif | 3023 | #endif |
4243 | 3024 | ||
@@ -4246,19 +3027,19 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4246 | /* Ack/clear/reset pending uCode interrupts. | 3027 | /* Ack/clear/reset pending uCode interrupts. |
4247 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | 3028 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, |
4248 | * and will clear only when CSR_FH_INT_STATUS gets cleared. */ | 3029 | * and will clear only when CSR_FH_INT_STATUS gets cleared. */ |
4249 | inta = iwl3945_read32(priv, CSR_INT); | 3030 | inta = iwl_read32(priv, CSR_INT); |
4250 | iwl3945_write32(priv, CSR_INT, inta); | 3031 | iwl_write32(priv, CSR_INT, inta); |
4251 | 3032 | ||
4252 | /* Ack/clear/reset pending flow-handler (DMA) interrupts. | 3033 | /* Ack/clear/reset pending flow-handler (DMA) interrupts. |
4253 | * Any new interrupts that happen after this, either while we're | 3034 | * Any new interrupts that happen after this, either while we're |
4254 | * in this tasklet, or later, will show up in next ISR/tasklet. */ | 3035 | * in this tasklet, or later, will show up in next ISR/tasklet. */ |
4255 | inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS); | 3036 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); |
4256 | iwl3945_write32(priv, CSR_FH_INT_STATUS, inta_fh); | 3037 | iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); |
4257 | 3038 | ||
4258 | #ifdef CONFIG_IWL3945_DEBUG | 3039 | #ifdef CONFIG_IWLWIFI_DEBUG |
4259 | if (iwl3945_debug_level & IWL_DL_ISR) { | 3040 | if (priv->debug_level & IWL_DL_ISR) { |
4260 | /* just for debug */ | 3041 | /* just for debug */ |
4261 | inta_mask = iwl3945_read32(priv, CSR_INT_MASK); | 3042 | inta_mask = iwl_read32(priv, CSR_INT_MASK); |
4262 | IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", | 3043 | IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", |
4263 | inta, inta_mask, inta_fh); | 3044 | inta, inta_mask, inta_fh); |
4264 | } | 3045 | } |
@@ -4275,7 +3056,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4275 | 3056 | ||
4276 | /* Now service all interrupt bits discovered above. */ | 3057 | /* Now service all interrupt bits discovered above. */ |
4277 | if (inta & CSR_INT_BIT_HW_ERR) { | 3058 | if (inta & CSR_INT_BIT_HW_ERR) { |
4278 | IWL_ERROR("Microcode HW error detected. Restarting.\n"); | 3059 | IWL_ERR(priv, "Microcode HW error detected. Restarting.\n"); |
4279 | 3060 | ||
4280 | /* Tell the device to stop sending interrupts */ | 3061 | /* Tell the device to stop sending interrupts */ |
4281 | iwl3945_disable_interrupts(priv); | 3062 | iwl3945_disable_interrupts(priv); |
@@ -4289,8 +3070,8 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4289 | return; | 3070 | return; |
4290 | } | 3071 | } |
4291 | 3072 | ||
4292 | #ifdef CONFIG_IWL3945_DEBUG | 3073 | #ifdef CONFIG_IWLWIFI_DEBUG |
4293 | if (iwl3945_debug_level & (IWL_DL_ISR)) { | 3074 | if (priv->debug_level & (IWL_DL_ISR)) { |
4294 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ | 3075 | /* NIC fires this, but we don't use it, redundant with WAKEUP */ |
4295 | if (inta & CSR_INT_BIT_SCD) | 3076 | if (inta & CSR_INT_BIT_SCD) |
4296 | IWL_DEBUG_ISR("Scheduler finished to transmit " | 3077 | IWL_DEBUG_ISR("Scheduler finished to transmit " |
@@ -4306,8 +3087,8 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4306 | 3087 | ||
4307 | /* Error detected by uCode */ | 3088 | /* Error detected by uCode */ |
4308 | if (inta & CSR_INT_BIT_SW_ERR) { | 3089 | if (inta & CSR_INT_BIT_SW_ERR) { |
4309 | IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n", | 3090 | IWL_ERR(priv, "Microcode SW error detected. " |
4310 | inta); | 3091 | "Restarting 0x%X.\n", inta); |
4311 | iwl3945_irq_handle_error(priv); | 3092 | iwl3945_irq_handle_error(priv); |
4312 | handled |= CSR_INT_BIT_SW_ERR; | 3093 | handled |= CSR_INT_BIT_SW_ERR; |
4313 | } | 3094 | } |
@@ -4315,13 +3096,13 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4315 | /* uCode wakes up after power-down sleep */ | 3096 | /* uCode wakes up after power-down sleep */ |
4316 | if (inta & CSR_INT_BIT_WAKEUP) { | 3097 | if (inta & CSR_INT_BIT_WAKEUP) { |
4317 | IWL_DEBUG_ISR("Wakeup interrupt\n"); | 3098 | IWL_DEBUG_ISR("Wakeup interrupt\n"); |
4318 | iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq); | 3099 | iwl_rx_queue_update_write_ptr(priv, &priv->rxq); |
4319 | iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]); | 3100 | iwl_txq_update_write_ptr(priv, &priv->txq[0]); |
4320 | iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]); | 3101 | iwl_txq_update_write_ptr(priv, &priv->txq[1]); |
4321 | iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]); | 3102 | iwl_txq_update_write_ptr(priv, &priv->txq[2]); |
4322 | iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]); | 3103 | iwl_txq_update_write_ptr(priv, &priv->txq[3]); |
4323 | iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]); | 3104 | iwl_txq_update_write_ptr(priv, &priv->txq[4]); |
4324 | iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]); | 3105 | iwl_txq_update_write_ptr(priv, &priv->txq[5]); |
4325 | 3106 | ||
4326 | handled |= CSR_INT_BIT_WAKEUP; | 3107 | handled |= CSR_INT_BIT_WAKEUP; |
4327 | } | 3108 | } |
@@ -4337,23 +3118,22 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4337 | if (inta & CSR_INT_BIT_FH_TX) { | 3118 | if (inta & CSR_INT_BIT_FH_TX) { |
4338 | IWL_DEBUG_ISR("Tx interrupt\n"); | 3119 | IWL_DEBUG_ISR("Tx interrupt\n"); |
4339 | 3120 | ||
4340 | iwl3945_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); | 3121 | iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); |
4341 | if (!iwl3945_grab_nic_access(priv)) { | 3122 | if (!iwl_grab_nic_access(priv)) { |
4342 | iwl3945_write_direct32(priv, | 3123 | iwl_write_direct32(priv, FH39_TCSR_CREDIT |
4343 | FH_TCSR_CREDIT | 3124 | (FH39_SRVC_CHNL), 0x0); |
4344 | (ALM_FH_SRVC_CHNL), 0x0); | 3125 | iwl_release_nic_access(priv); |
4345 | iwl3945_release_nic_access(priv); | ||
4346 | } | 3126 | } |
4347 | handled |= CSR_INT_BIT_FH_TX; | 3127 | handled |= CSR_INT_BIT_FH_TX; |
4348 | } | 3128 | } |
4349 | 3129 | ||
4350 | if (inta & ~handled) | 3130 | if (inta & ~handled) |
4351 | IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); | 3131 | IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); |
4352 | 3132 | ||
4353 | if (inta & ~CSR_INI_SET_MASK) { | 3133 | if (inta & ~CSR_INI_SET_MASK) { |
4354 | IWL_WARNING("Disabled INTA bits 0x%08x were pending\n", | 3134 | IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", |
4355 | inta & ~CSR_INI_SET_MASK); | 3135 | inta & ~CSR_INI_SET_MASK); |
4356 | IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh); | 3136 | IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); |
4357 | } | 3137 | } |
4358 | 3138 | ||
4359 | /* Re-enable all interrupts */ | 3139 | /* Re-enable all interrupts */ |
@@ -4361,11 +3141,11 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4361 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 3141 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
4362 | iwl3945_enable_interrupts(priv); | 3142 | iwl3945_enable_interrupts(priv); |
4363 | 3143 | ||
4364 | #ifdef CONFIG_IWL3945_DEBUG | 3144 | #ifdef CONFIG_IWLWIFI_DEBUG |
4365 | if (iwl3945_debug_level & (IWL_DL_ISR)) { | 3145 | if (priv->debug_level & (IWL_DL_ISR)) { |
4366 | inta = iwl3945_read32(priv, CSR_INT); | 3146 | inta = iwl_read32(priv, CSR_INT); |
4367 | inta_mask = iwl3945_read32(priv, CSR_INT_MASK); | 3147 | inta_mask = iwl_read32(priv, CSR_INT_MASK); |
4368 | inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS); | 3148 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); |
4369 | IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " | 3149 | IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " |
4370 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); | 3150 | "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); |
4371 | } | 3151 | } |
@@ -4375,7 +3155,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4375 | 3155 | ||
4376 | static irqreturn_t iwl3945_isr(int irq, void *data) | 3156 | static irqreturn_t iwl3945_isr(int irq, void *data) |
4377 | { | 3157 | { |
4378 | struct iwl3945_priv *priv = data; | 3158 | struct iwl_priv *priv = data; |
4379 | u32 inta, inta_mask; | 3159 | u32 inta, inta_mask; |
4380 | u32 inta_fh; | 3160 | u32 inta_fh; |
4381 | if (!priv) | 3161 | if (!priv) |
@@ -4387,12 +3167,12 @@ static irqreturn_t iwl3945_isr(int irq, void *data) | |||
4387 | * back-to-back ISRs and sporadic interrupts from our NIC. | 3167 | * back-to-back ISRs and sporadic interrupts from our NIC. |
4388 | * If we have something to service, the tasklet will re-enable ints. | 3168 | * If we have something to service, the tasklet will re-enable ints. |
4389 | * If we *don't* have something, we'll re-enable before leaving here. */ | 3169 | * If we *don't* have something, we'll re-enable before leaving here. */ |
4390 | inta_mask = iwl3945_read32(priv, CSR_INT_MASK); /* just for debug */ | 3170 | inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ |
4391 | iwl3945_write32(priv, CSR_INT_MASK, 0x00000000); | 3171 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); |
4392 | 3172 | ||
4393 | /* Discover which interrupts are active/pending */ | 3173 | /* Discover which interrupts are active/pending */ |
4394 | inta = iwl3945_read32(priv, CSR_INT); | 3174 | inta = iwl_read32(priv, CSR_INT); |
4395 | inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS); | 3175 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); |
4396 | 3176 | ||
4397 | /* Ignore interrupt if there's nothing in NIC to service. | 3177 | /* Ignore interrupt if there's nothing in NIC to service. |
4398 | * This may be due to IRQ shared with another device, | 3178 | * This may be due to IRQ shared with another device, |
@@ -4404,7 +3184,7 @@ static irqreturn_t iwl3945_isr(int irq, void *data) | |||
4404 | 3184 | ||
4405 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | 3185 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { |
4406 | /* Hardware disappeared */ | 3186 | /* Hardware disappeared */ |
4407 | IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta); | 3187 | IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); |
4408 | goto unplugged; | 3188 | goto unplugged; |
4409 | } | 3189 | } |
4410 | 3190 | ||
@@ -4430,337 +3210,26 @@ unplugged: | |||
4430 | return IRQ_NONE; | 3210 | return IRQ_NONE; |
4431 | } | 3211 | } |
4432 | 3212 | ||
4433 | /************************** EEPROM BANDS **************************** | 3213 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, |
4434 | * | ||
4435 | * The iwl3945_eeprom_band definitions below provide the mapping from the | ||
4436 | * EEPROM contents to the specific channel number supported for each | ||
4437 | * band. | ||
4438 | * | ||
4439 | * For example, iwl3945_priv->eeprom.band_3_channels[4] from the band_3 | ||
4440 | * definition below maps to physical channel 42 in the 5.2GHz spectrum. | ||
4441 | * The specific geography and calibration information for that channel | ||
4442 | * is contained in the eeprom map itself. | ||
4443 | * | ||
4444 | * During init, we copy the eeprom information and channel map | ||
4445 | * information into priv->channel_info_24/52 and priv->channel_map_24/52 | ||
4446 | * | ||
4447 | * channel_map_24/52 provides the index in the channel_info array for a | ||
4448 | * given channel. We have to have two separate maps as there is channel | ||
4449 | * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and | ||
4450 | * band_2 | ||
4451 | * | ||
4452 | * A value of 0xff stored in the channel_map indicates that the channel | ||
4453 | * is not supported by the hardware at all. | ||
4454 | * | ||
4455 | * A value of 0xfe in the channel_map indicates that the channel is not | ||
4456 | * valid for Tx with the current hardware. This means that | ||
4457 | * while the system can tune and receive on a given channel, it may not | ||
4458 | * be able to associate or transmit any frames on that | ||
4459 | * channel. There is no corresponding channel information for that | ||
4460 | * entry. | ||
4461 | * | ||
4462 | *********************************************************************/ | ||
4463 | |||
4464 | /* 2.4 GHz */ | ||
4465 | static const u8 iwl3945_eeprom_band_1[14] = { | ||
4466 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 | ||
4467 | }; | ||
4468 | |||
4469 | /* 5.2 GHz bands */ | ||
4470 | static const u8 iwl3945_eeprom_band_2[] = { /* 4915-5080MHz */ | ||
4471 | 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 | ||
4472 | }; | ||
4473 | |||
4474 | static const u8 iwl3945_eeprom_band_3[] = { /* 5170-5320MHz */ | ||
4475 | 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 | ||
4476 | }; | ||
4477 | |||
4478 | static const u8 iwl3945_eeprom_band_4[] = { /* 5500-5700MHz */ | ||
4479 | 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 | ||
4480 | }; | ||
4481 | |||
4482 | static const u8 iwl3945_eeprom_band_5[] = { /* 5725-5825MHz */ | ||
4483 | 145, 149, 153, 157, 161, 165 | ||
4484 | }; | ||
4485 | |||
4486 | static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int band, | ||
4487 | int *eeprom_ch_count, | ||
4488 | const struct iwl3945_eeprom_channel | ||
4489 | **eeprom_ch_info, | ||
4490 | const u8 **eeprom_ch_index) | ||
4491 | { | ||
4492 | switch (band) { | ||
4493 | case 1: /* 2.4GHz band */ | ||
4494 | *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1); | ||
4495 | *eeprom_ch_info = priv->eeprom.band_1_channels; | ||
4496 | *eeprom_ch_index = iwl3945_eeprom_band_1; | ||
4497 | break; | ||
4498 | case 2: /* 4.9GHz band */ | ||
4499 | *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2); | ||
4500 | *eeprom_ch_info = priv->eeprom.band_2_channels; | ||
4501 | *eeprom_ch_index = iwl3945_eeprom_band_2; | ||
4502 | break; | ||
4503 | case 3: /* 5.2GHz band */ | ||
4504 | *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3); | ||
4505 | *eeprom_ch_info = priv->eeprom.band_3_channels; | ||
4506 | *eeprom_ch_index = iwl3945_eeprom_band_3; | ||
4507 | break; | ||
4508 | case 4: /* 5.5GHz band */ | ||
4509 | *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4); | ||
4510 | *eeprom_ch_info = priv->eeprom.band_4_channels; | ||
4511 | *eeprom_ch_index = iwl3945_eeprom_band_4; | ||
4512 | break; | ||
4513 | case 5: /* 5.7GHz band */ | ||
4514 | *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5); | ||
4515 | *eeprom_ch_info = priv->eeprom.band_5_channels; | ||
4516 | *eeprom_ch_index = iwl3945_eeprom_band_5; | ||
4517 | break; | ||
4518 | default: | ||
4519 | BUG(); | ||
4520 | return; | ||
4521 | } | ||
4522 | } | ||
4523 | |||
4524 | /** | ||
4525 | * iwl3945_get_channel_info - Find driver's private channel info | ||
4526 | * | ||
4527 | * Based on band and channel number. | ||
4528 | */ | ||
4529 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, | ||
4530 | enum ieee80211_band band, u16 channel) | ||
4531 | { | ||
4532 | int i; | ||
4533 | |||
4534 | switch (band) { | ||
4535 | case IEEE80211_BAND_5GHZ: | ||
4536 | for (i = 14; i < priv->channel_count; i++) { | ||
4537 | if (priv->channel_info[i].channel == channel) | ||
4538 | return &priv->channel_info[i]; | ||
4539 | } | ||
4540 | break; | ||
4541 | |||
4542 | case IEEE80211_BAND_2GHZ: | ||
4543 | if (channel >= 1 && channel <= 14) | ||
4544 | return &priv->channel_info[channel - 1]; | ||
4545 | break; | ||
4546 | case IEEE80211_NUM_BANDS: | ||
4547 | WARN_ON(1); | ||
4548 | } | ||
4549 | |||
4550 | return NULL; | ||
4551 | } | ||
4552 | |||
4553 | #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ | ||
4554 | ? # x " " : "") | ||
4555 | |||
4556 | /** | ||
4557 | * iwl3945_init_channel_map - Set up driver's info for all possible channels | ||
4558 | */ | ||
4559 | static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | ||
4560 | { | ||
4561 | int eeprom_ch_count = 0; | ||
4562 | const u8 *eeprom_ch_index = NULL; | ||
4563 | const struct iwl3945_eeprom_channel *eeprom_ch_info = NULL; | ||
4564 | int band, ch; | ||
4565 | struct iwl3945_channel_info *ch_info; | ||
4566 | |||
4567 | if (priv->channel_count) { | ||
4568 | IWL_DEBUG_INFO("Channel map already initialized.\n"); | ||
4569 | return 0; | ||
4570 | } | ||
4571 | |||
4572 | if (priv->eeprom.version < 0x2f) { | ||
4573 | IWL_WARNING("Unsupported EEPROM version: 0x%04X\n", | ||
4574 | priv->eeprom.version); | ||
4575 | return -EINVAL; | ||
4576 | } | ||
4577 | |||
4578 | IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n"); | ||
4579 | |||
4580 | priv->channel_count = | ||
4581 | ARRAY_SIZE(iwl3945_eeprom_band_1) + | ||
4582 | ARRAY_SIZE(iwl3945_eeprom_band_2) + | ||
4583 | ARRAY_SIZE(iwl3945_eeprom_band_3) + | ||
4584 | ARRAY_SIZE(iwl3945_eeprom_band_4) + | ||
4585 | ARRAY_SIZE(iwl3945_eeprom_band_5); | ||
4586 | |||
4587 | IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count); | ||
4588 | |||
4589 | priv->channel_info = kzalloc(sizeof(struct iwl3945_channel_info) * | ||
4590 | priv->channel_count, GFP_KERNEL); | ||
4591 | if (!priv->channel_info) { | ||
4592 | IWL_ERROR("Could not allocate channel_info\n"); | ||
4593 | priv->channel_count = 0; | ||
4594 | return -ENOMEM; | ||
4595 | } | ||
4596 | |||
4597 | ch_info = priv->channel_info; | ||
4598 | |||
4599 | /* Loop through the 5 EEPROM bands adding them in order to the | ||
4600 | * channel map we maintain (that contains additional information than | ||
4601 | * what just in the EEPROM) */ | ||
4602 | for (band = 1; band <= 5; band++) { | ||
4603 | |||
4604 | iwl3945_init_band_reference(priv, band, &eeprom_ch_count, | ||
4605 | &eeprom_ch_info, &eeprom_ch_index); | ||
4606 | |||
4607 | /* Loop through each band adding each of the channels */ | ||
4608 | for (ch = 0; ch < eeprom_ch_count; ch++) { | ||
4609 | ch_info->channel = eeprom_ch_index[ch]; | ||
4610 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : | ||
4611 | IEEE80211_BAND_5GHZ; | ||
4612 | |||
4613 | /* permanently store EEPROM's channel regulatory flags | ||
4614 | * and max power in channel info database. */ | ||
4615 | ch_info->eeprom = eeprom_ch_info[ch]; | ||
4616 | |||
4617 | /* Copy the run-time flags so they are there even on | ||
4618 | * invalid channels */ | ||
4619 | ch_info->flags = eeprom_ch_info[ch].flags; | ||
4620 | |||
4621 | if (!(is_channel_valid(ch_info))) { | ||
4622 | IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - " | ||
4623 | "No traffic\n", | ||
4624 | ch_info->channel, | ||
4625 | ch_info->flags, | ||
4626 | is_channel_a_band(ch_info) ? | ||
4627 | "5.2" : "2.4"); | ||
4628 | ch_info++; | ||
4629 | continue; | ||
4630 | } | ||
4631 | |||
4632 | /* Initialize regulatory-based run-time data */ | ||
4633 | ch_info->max_power_avg = ch_info->curr_txpow = | ||
4634 | eeprom_ch_info[ch].max_power_avg; | ||
4635 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; | ||
4636 | ch_info->min_power = 0; | ||
4637 | |||
4638 | IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x" | ||
4639 | " %ddBm): Ad-Hoc %ssupported\n", | ||
4640 | ch_info->channel, | ||
4641 | is_channel_a_band(ch_info) ? | ||
4642 | "5.2" : "2.4", | ||
4643 | CHECK_AND_PRINT(VALID), | ||
4644 | CHECK_AND_PRINT(IBSS), | ||
4645 | CHECK_AND_PRINT(ACTIVE), | ||
4646 | CHECK_AND_PRINT(RADAR), | ||
4647 | CHECK_AND_PRINT(WIDE), | ||
4648 | CHECK_AND_PRINT(DFS), | ||
4649 | eeprom_ch_info[ch].flags, | ||
4650 | eeprom_ch_info[ch].max_power_avg, | ||
4651 | ((eeprom_ch_info[ch]. | ||
4652 | flags & EEPROM_CHANNEL_IBSS) | ||
4653 | && !(eeprom_ch_info[ch]. | ||
4654 | flags & EEPROM_CHANNEL_RADAR)) | ||
4655 | ? "" : "not "); | ||
4656 | |||
4657 | /* Set the user_txpower_limit to the highest power | ||
4658 | * supported by any channel */ | ||
4659 | if (eeprom_ch_info[ch].max_power_avg > | ||
4660 | priv->user_txpower_limit) | ||
4661 | priv->user_txpower_limit = | ||
4662 | eeprom_ch_info[ch].max_power_avg; | ||
4663 | |||
4664 | ch_info++; | ||
4665 | } | ||
4666 | } | ||
4667 | |||
4668 | /* Set up txpower settings in driver for all channels */ | ||
4669 | if (iwl3945_txpower_set_from_eeprom(priv)) | ||
4670 | return -EIO; | ||
4671 | |||
4672 | return 0; | ||
4673 | } | ||
4674 | |||
4675 | /* | ||
4676 | * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map | ||
4677 | */ | ||
4678 | static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | ||
4679 | { | ||
4680 | kfree(priv->channel_info); | ||
4681 | priv->channel_count = 0; | ||
4682 | } | ||
4683 | |||
4684 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | ||
4685 | * sending probe req. This should be set long enough to hear probe responses | ||
4686 | * from more than one AP. */ | ||
4687 | #define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */ | ||
4688 | #define IWL_ACTIVE_DWELL_TIME_52 (20) | ||
4689 | |||
4690 | #define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3) | ||
4691 | #define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2) | ||
4692 | |||
4693 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
4694 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
4695 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
4696 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
4697 | * no other traffic). | ||
4698 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
4699 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | ||
4700 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */ | ||
4701 | |||
4702 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. | ||
4703 | * Must be set longer than active dwell time. | ||
4704 | * For the most reliable scan, set > AP beacon interval (typically 100msec). */ | ||
4705 | #define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ | ||
4706 | #define IWL_PASSIVE_DWELL_TIME_52 (10) | ||
4707 | #define IWL_PASSIVE_DWELL_BASE (100) | ||
4708 | #define IWL_CHANNEL_TUNE_TIME 5 | ||
4709 | |||
4710 | #define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1))) | ||
4711 | |||
4712 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, | ||
4713 | enum ieee80211_band band, | ||
4714 | u8 n_probes) | ||
4715 | { | ||
4716 | if (band == IEEE80211_BAND_5GHZ) | ||
4717 | return IWL_ACTIVE_DWELL_TIME_52 + | ||
4718 | IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1); | ||
4719 | else | ||
4720 | return IWL_ACTIVE_DWELL_TIME_24 + | ||
4721 | IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); | ||
4722 | } | ||
4723 | |||
4724 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, | ||
4725 | enum ieee80211_band band) | ||
4726 | { | ||
4727 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? | ||
4728 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | ||
4729 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | ||
4730 | |||
4731 | if (iwl3945_is_associated(priv)) { | ||
4732 | /* If we're associated, we clamp the maximum passive | ||
4733 | * dwell time to be 98% of the beacon interval (minus | ||
4734 | * 2 * channel tune time) */ | ||
4735 | passive = priv->beacon_int; | ||
4736 | if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) | ||
4737 | passive = IWL_PASSIVE_DWELL_BASE; | ||
4738 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | ||
4739 | } | ||
4740 | |||
4741 | return passive; | ||
4742 | } | ||
4743 | |||
4744 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | ||
4745 | enum ieee80211_band band, | 3214 | enum ieee80211_band band, |
4746 | u8 is_active, u8 n_probes, | 3215 | u8 is_active, u8 n_probes, |
4747 | struct iwl3945_scan_channel *scan_ch) | 3216 | struct iwl3945_scan_channel *scan_ch) |
4748 | { | 3217 | { |
4749 | const struct ieee80211_channel *channels = NULL; | 3218 | const struct ieee80211_channel *channels = NULL; |
4750 | const struct ieee80211_supported_band *sband; | 3219 | const struct ieee80211_supported_band *sband; |
4751 | const struct iwl3945_channel_info *ch_info; | 3220 | const struct iwl_channel_info *ch_info; |
4752 | u16 passive_dwell = 0; | 3221 | u16 passive_dwell = 0; |
4753 | u16 active_dwell = 0; | 3222 | u16 active_dwell = 0; |
4754 | int added, i; | 3223 | int added, i; |
4755 | 3224 | ||
4756 | sband = iwl3945_get_band(priv, band); | 3225 | sband = iwl_get_hw_mode(priv, band); |
4757 | if (!sband) | 3226 | if (!sband) |
4758 | return 0; | 3227 | return 0; |
4759 | 3228 | ||
4760 | channels = sband->channels; | 3229 | channels = sband->channels; |
4761 | 3230 | ||
4762 | active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes); | 3231 | active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); |
4763 | passive_dwell = iwl3945_get_passive_dwell_time(priv, band); | 3232 | passive_dwell = iwl_get_passive_dwell_time(priv, band); |
4764 | 3233 | ||
4765 | if (passive_dwell <= active_dwell) | 3234 | if (passive_dwell <= active_dwell) |
4766 | passive_dwell = active_dwell + 1; | 3235 | passive_dwell = active_dwell + 1; |
@@ -4771,7 +3240,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4771 | 3240 | ||
4772 | scan_ch->channel = channels[i].hw_value; | 3241 | scan_ch->channel = channels[i].hw_value; |
4773 | 3242 | ||
4774 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); | 3243 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); |
4775 | if (!is_channel_valid(ch_info)) { | 3244 | if (!is_channel_valid(ch_info)) { |
4776 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", | 3245 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
4777 | scan_ch->channel); | 3246 | scan_ch->channel); |
@@ -4798,12 +3267,12 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4798 | * hearing clear Rx packet).*/ | 3267 | * hearing clear Rx packet).*/ |
4799 | if (IWL_UCODE_API(priv->ucode_ver) >= 2) { | 3268 | if (IWL_UCODE_API(priv->ucode_ver) >= 2) { |
4800 | if (n_probes) | 3269 | if (n_probes) |
4801 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); | 3270 | scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); |
4802 | } else { | 3271 | } else { |
4803 | /* uCode v1 does not allow setting direct probe bits on | 3272 | /* uCode v1 does not allow setting direct probe bits on |
4804 | * passive channel. */ | 3273 | * passive channel. */ |
4805 | if ((scan_ch->type & 1) && n_probes) | 3274 | if ((scan_ch->type & 1) && n_probes) |
4806 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); | 3275 | scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes); |
4807 | } | 3276 | } |
4808 | 3277 | ||
4809 | /* Set txpower levels to defaults */ | 3278 | /* Set txpower levels to defaults */ |
@@ -4835,7 +3304,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4835 | return added; | 3304 | return added; |
4836 | } | 3305 | } |
4837 | 3306 | ||
4838 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | 3307 | static void iwl3945_init_hw_rates(struct iwl_priv *priv, |
4839 | struct ieee80211_rate *rates) | 3308 | struct ieee80211_rate *rates) |
4840 | { | 3309 | { |
4841 | int i; | 3310 | int i; |
@@ -4845,7 +3314,7 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | |||
4845 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | 3314 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
4846 | rates[i].hw_value_short = i; | 3315 | rates[i].hw_value_short = i; |
4847 | rates[i].flags = 0; | 3316 | rates[i].flags = 0; |
4848 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { | 3317 | if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
4849 | /* | 3318 | /* |
4850 | * If CCK != 1M then set short preamble rate flag. | 3319 | * If CCK != 1M then set short preamble rate flag. |
4851 | */ | 3320 | */ |
@@ -4855,145 +3324,13 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | |||
4855 | } | 3324 | } |
4856 | } | 3325 | } |
4857 | 3326 | ||
4858 | /** | ||
4859 | * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom | ||
4860 | */ | ||
4861 | static int iwl3945_init_geos(struct iwl3945_priv *priv) | ||
4862 | { | ||
4863 | struct iwl3945_channel_info *ch; | ||
4864 | struct ieee80211_supported_band *sband; | ||
4865 | struct ieee80211_channel *channels; | ||
4866 | struct ieee80211_channel *geo_ch; | ||
4867 | struct ieee80211_rate *rates; | ||
4868 | int i = 0; | ||
4869 | |||
4870 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||
4871 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
4872 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | ||
4873 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4874 | return 0; | ||
4875 | } | ||
4876 | |||
4877 | channels = kzalloc(sizeof(struct ieee80211_channel) * | ||
4878 | priv->channel_count, GFP_KERNEL); | ||
4879 | if (!channels) | ||
4880 | return -ENOMEM; | ||
4881 | |||
4882 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)), | ||
4883 | GFP_KERNEL); | ||
4884 | if (!rates) { | ||
4885 | kfree(channels); | ||
4886 | return -ENOMEM; | ||
4887 | } | ||
4888 | |||
4889 | /* 5.2GHz channels start after the 2.4GHz channels */ | ||
4890 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4891 | sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; | ||
4892 | /* just OFDM */ | ||
4893 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | ||
4894 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; | ||
4895 | |||
4896 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4897 | sband->channels = channels; | ||
4898 | /* OFDM & CCK */ | ||
4899 | sband->bitrates = rates; | ||
4900 | sband->n_bitrates = IWL_RATE_COUNT; | ||
4901 | |||
4902 | priv->ieee_channels = channels; | ||
4903 | priv->ieee_rates = rates; | ||
4904 | |||
4905 | iwl3945_init_hw_rates(priv, rates); | ||
4906 | |||
4907 | for (i = 0; i < priv->channel_count; i++) { | ||
4908 | ch = &priv->channel_info[i]; | ||
4909 | |||
4910 | /* FIXME: might be removed if scan is OK*/ | ||
4911 | if (!is_channel_valid(ch)) | ||
4912 | continue; | ||
4913 | |||
4914 | if (is_channel_a_band(ch)) | ||
4915 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4916 | else | ||
4917 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4918 | |||
4919 | geo_ch = &sband->channels[sband->n_channels++]; | ||
4920 | |||
4921 | geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel); | ||
4922 | geo_ch->max_power = ch->max_power_avg; | ||
4923 | geo_ch->max_antenna_gain = 0xff; | ||
4924 | geo_ch->hw_value = ch->channel; | ||
4925 | |||
4926 | if (is_channel_valid(ch)) { | ||
4927 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) | ||
4928 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; | ||
4929 | |||
4930 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
4931 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
4932 | |||
4933 | if (ch->flags & EEPROM_CHANNEL_RADAR) | ||
4934 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | ||
4935 | |||
4936 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | ||
4937 | priv->max_channel_txpower_limit = | ||
4938 | ch->max_power_avg; | ||
4939 | } else { | ||
4940 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
4941 | } | ||
4942 | |||
4943 | /* Save flags for reg domain usage */ | ||
4944 | geo_ch->orig_flags = geo_ch->flags; | ||
4945 | |||
4946 | IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n", | ||
4947 | ch->channel, geo_ch->center_freq, | ||
4948 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
4949 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
4950 | "restricted" : "valid", | ||
4951 | geo_ch->flags); | ||
4952 | } | ||
4953 | |||
4954 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||
4955 | priv->cfg->sku & IWL_SKU_A) { | ||
4956 | printk(KERN_INFO DRV_NAME | ||
4957 | ": Incorrectly detected BG card as ABG. Please send " | ||
4958 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | ||
4959 | priv->pci_dev->device, priv->pci_dev->subsystem_device); | ||
4960 | priv->cfg->sku &= ~IWL_SKU_A; | ||
4961 | } | ||
4962 | |||
4963 | printk(KERN_INFO DRV_NAME | ||
4964 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | ||
4965 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | ||
4966 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
4967 | |||
4968 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
4969 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
4970 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
4971 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
4972 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
4973 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
4974 | |||
4975 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4976 | |||
4977 | return 0; | ||
4978 | } | ||
4979 | |||
4980 | /* | ||
4981 | * iwl3945_free_geos - undo allocations in iwl3945_init_geos | ||
4982 | */ | ||
4983 | static void iwl3945_free_geos(struct iwl3945_priv *priv) | ||
4984 | { | ||
4985 | kfree(priv->ieee_channels); | ||
4986 | kfree(priv->ieee_rates); | ||
4987 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
4988 | } | ||
4989 | |||
4990 | /****************************************************************************** | 3327 | /****************************************************************************** |
4991 | * | 3328 | * |
4992 | * uCode download functions | 3329 | * uCode download functions |
4993 | * | 3330 | * |
4994 | ******************************************************************************/ | 3331 | ******************************************************************************/ |
4995 | 3332 | ||
4996 | static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv) | 3333 | static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv) |
4997 | { | 3334 | { |
4998 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); | 3335 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); |
4999 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); | 3336 | iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); |
@@ -5007,7 +3344,7 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv) | |||
5007 | * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, | 3344 | * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, |
5008 | * looking at all data. | 3345 | * looking at all data. |
5009 | */ | 3346 | */ |
5010 | static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len) | 3347 | static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len) |
5011 | { | 3348 | { |
5012 | u32 val; | 3349 | u32 val; |
5013 | u32 save_len = len; | 3350 | u32 save_len = len; |
@@ -5016,20 +3353,21 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3 | |||
5016 | 3353 | ||
5017 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | 3354 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); |
5018 | 3355 | ||
5019 | rc = iwl3945_grab_nic_access(priv); | 3356 | rc = iwl_grab_nic_access(priv); |
5020 | if (rc) | 3357 | if (rc) |
5021 | return rc; | 3358 | return rc; |
5022 | 3359 | ||
5023 | iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); | 3360 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
3361 | IWL39_RTC_INST_LOWER_BOUND); | ||
5024 | 3362 | ||
5025 | errcnt = 0; | 3363 | errcnt = 0; |
5026 | for (; len > 0; len -= sizeof(u32), image++) { | 3364 | for (; len > 0; len -= sizeof(u32), image++) { |
5027 | /* read data comes through single port, auto-incr addr */ | 3365 | /* read data comes through single port, auto-incr addr */ |
5028 | /* NOTE: Use the debugless read so we don't flood kernel log | 3366 | /* NOTE: Use the debugless read so we don't flood kernel log |
5029 | * if IWL_DL_IO is set */ | 3367 | * if IWL_DL_IO is set */ |
5030 | val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 3368 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
5031 | if (val != le32_to_cpu(*image)) { | 3369 | if (val != le32_to_cpu(*image)) { |
5032 | IWL_ERROR("uCode INST section is invalid at " | 3370 | IWL_ERR(priv, "uCode INST section is invalid at " |
5033 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 3371 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
5034 | save_len - len, val, le32_to_cpu(*image)); | 3372 | save_len - len, val, le32_to_cpu(*image)); |
5035 | rc = -EIO; | 3373 | rc = -EIO; |
@@ -5039,7 +3377,7 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3 | |||
5039 | } | 3377 | } |
5040 | } | 3378 | } |
5041 | 3379 | ||
5042 | iwl3945_release_nic_access(priv); | 3380 | iwl_release_nic_access(priv); |
5043 | 3381 | ||
5044 | if (!errcnt) | 3382 | if (!errcnt) |
5045 | IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n"); | 3383 | IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n"); |
@@ -5053,7 +3391,7 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3 | |||
5053 | * using sample data 100 bytes apart. If these sample points are good, | 3391 | * using sample data 100 bytes apart. If these sample points are good, |
5054 | * it's a pretty good bet that everything between them is good, too. | 3392 | * it's a pretty good bet that everything between them is good, too. |
5055 | */ | 3393 | */ |
5056 | static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, u32 len) | 3394 | static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) |
5057 | { | 3395 | { |
5058 | u32 val; | 3396 | u32 val; |
5059 | int rc = 0; | 3397 | int rc = 0; |
@@ -5062,7 +3400,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, | |||
5062 | 3400 | ||
5063 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); | 3401 | IWL_DEBUG_INFO("ucode inst image size is %u\n", len); |
5064 | 3402 | ||
5065 | rc = iwl3945_grab_nic_access(priv); | 3403 | rc = iwl_grab_nic_access(priv); |
5066 | if (rc) | 3404 | if (rc) |
5067 | return rc; | 3405 | return rc; |
5068 | 3406 | ||
@@ -5070,12 +3408,12 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, | |||
5070 | /* read data comes through single port, auto-incr addr */ | 3408 | /* read data comes through single port, auto-incr addr */ |
5071 | /* NOTE: Use the debugless read so we don't flood kernel log | 3409 | /* NOTE: Use the debugless read so we don't flood kernel log |
5072 | * if IWL_DL_IO is set */ | 3410 | * if IWL_DL_IO is set */ |
5073 | iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, | 3411 | iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, |
5074 | i + RTC_INST_LOWER_BOUND); | 3412 | i + IWL39_RTC_INST_LOWER_BOUND); |
5075 | val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT); | 3413 | val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); |
5076 | if (val != le32_to_cpu(*image)) { | 3414 | if (val != le32_to_cpu(*image)) { |
5077 | #if 0 /* Enable this if you want to see details */ | 3415 | #if 0 /* Enable this if you want to see details */ |
5078 | IWL_ERROR("uCode INST section is invalid at " | 3416 | IWL_ERR(priv, "uCode INST section is invalid at " |
5079 | "offset 0x%x, is 0x%x, s/b 0x%x\n", | 3417 | "offset 0x%x, is 0x%x, s/b 0x%x\n", |
5080 | i, val, *image); | 3418 | i, val, *image); |
5081 | #endif | 3419 | #endif |
@@ -5086,7 +3424,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, | |||
5086 | } | 3424 | } |
5087 | } | 3425 | } |
5088 | 3426 | ||
5089 | iwl3945_release_nic_access(priv); | 3427 | iwl_release_nic_access(priv); |
5090 | 3428 | ||
5091 | return rc; | 3429 | return rc; |
5092 | } | 3430 | } |
@@ -5096,7 +3434,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, | |||
5096 | * iwl3945_verify_ucode - determine which instruction image is in SRAM, | 3434 | * iwl3945_verify_ucode - determine which instruction image is in SRAM, |
5097 | * and verify its contents | 3435 | * and verify its contents |
5098 | */ | 3436 | */ |
5099 | static int iwl3945_verify_ucode(struct iwl3945_priv *priv) | 3437 | static int iwl3945_verify_ucode(struct iwl_priv *priv) |
5100 | { | 3438 | { |
5101 | __le32 *image; | 3439 | __le32 *image; |
5102 | u32 len; | 3440 | u32 len; |
@@ -5129,7 +3467,7 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv) | |||
5129 | return 0; | 3467 | return 0; |
5130 | } | 3468 | } |
5131 | 3469 | ||
5132 | IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); | 3470 | IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); |
5133 | 3471 | ||
5134 | /* Since nothing seems to match, show first several data entries in | 3472 | /* Since nothing seems to match, show first several data entries in |
5135 | * instruction SRAM, so maybe visual inspection will give a clue. | 3473 | * instruction SRAM, so maybe visual inspection will give a clue. |
@@ -5141,160 +3479,10 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv) | |||
5141 | return rc; | 3479 | return rc; |
5142 | } | 3480 | } |
5143 | 3481 | ||
5144 | 3482 | static void iwl3945_nic_start(struct iwl_priv *priv) | |
5145 | /* check contents of special bootstrap uCode SRAM */ | ||
5146 | static int iwl3945_verify_bsm(struct iwl3945_priv *priv) | ||
5147 | { | ||
5148 | __le32 *image = priv->ucode_boot.v_addr; | ||
5149 | u32 len = priv->ucode_boot.len; | ||
5150 | u32 reg; | ||
5151 | u32 val; | ||
5152 | |||
5153 | IWL_DEBUG_INFO("Begin verify bsm\n"); | ||
5154 | |||
5155 | /* verify BSM SRAM contents */ | ||
5156 | val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG); | ||
5157 | for (reg = BSM_SRAM_LOWER_BOUND; | ||
5158 | reg < BSM_SRAM_LOWER_BOUND + len; | ||
5159 | reg += sizeof(u32), image++) { | ||
5160 | val = iwl3945_read_prph(priv, reg); | ||
5161 | if (val != le32_to_cpu(*image)) { | ||
5162 | IWL_ERROR("BSM uCode verification failed at " | ||
5163 | "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", | ||
5164 | BSM_SRAM_LOWER_BOUND, | ||
5165 | reg - BSM_SRAM_LOWER_BOUND, len, | ||
5166 | val, le32_to_cpu(*image)); | ||
5167 | return -EIO; | ||
5168 | } | ||
5169 | } | ||
5170 | |||
5171 | IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n"); | ||
5172 | |||
5173 | return 0; | ||
5174 | } | ||
5175 | |||
5176 | /** | ||
5177 | * iwl3945_load_bsm - Load bootstrap instructions | ||
5178 | * | ||
5179 | * BSM operation: | ||
5180 | * | ||
5181 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program | ||
5182 | * in special SRAM that does not power down during RFKILL. When powering back | ||
5183 | * up after power-saving sleeps (or during initial uCode load), the BSM loads | ||
5184 | * the bootstrap program into the on-board processor, and starts it. | ||
5185 | * | ||
5186 | * The bootstrap program loads (via DMA) instructions and data for a new | ||
5187 | * program from host DRAM locations indicated by the host driver in the | ||
5188 | * BSM_DRAM_* registers. Once the new program is loaded, it starts | ||
5189 | * automatically. | ||
5190 | * | ||
5191 | * When initializing the NIC, the host driver points the BSM to the | ||
5192 | * "initialize" uCode image. This uCode sets up some internal data, then | ||
5193 | * notifies host via "initialize alive" that it is complete. | ||
5194 | * | ||
5195 | * The host then replaces the BSM_DRAM_* pointer values to point to the | ||
5196 | * normal runtime uCode instructions and a backup uCode data cache buffer | ||
5197 | * (filled initially with starting data values for the on-board processor), | ||
5198 | * then triggers the "initialize" uCode to load and launch the runtime uCode, | ||
5199 | * which begins normal operation. | ||
5200 | * | ||
5201 | * When doing a power-save shutdown, runtime uCode saves data SRAM into | ||
5202 | * the backup data cache in DRAM before SRAM is powered down. | ||
5203 | * | ||
5204 | * When powering back up, the BSM loads the bootstrap program. This reloads | ||
5205 | * the runtime uCode instructions and the backup data cache into SRAM, | ||
5206 | * and re-launches the runtime uCode from where it left off. | ||
5207 | */ | ||
5208 | static int iwl3945_load_bsm(struct iwl3945_priv *priv) | ||
5209 | { | ||
5210 | __le32 *image = priv->ucode_boot.v_addr; | ||
5211 | u32 len = priv->ucode_boot.len; | ||
5212 | dma_addr_t pinst; | ||
5213 | dma_addr_t pdata; | ||
5214 | u32 inst_len; | ||
5215 | u32 data_len; | ||
5216 | int rc; | ||
5217 | int i; | ||
5218 | u32 done; | ||
5219 | u32 reg_offset; | ||
5220 | |||
5221 | IWL_DEBUG_INFO("Begin load bsm\n"); | ||
5222 | |||
5223 | /* make sure bootstrap program is no larger than BSM's SRAM size */ | ||
5224 | if (len > IWL_MAX_BSM_SIZE) | ||
5225 | return -EINVAL; | ||
5226 | |||
5227 | /* Tell bootstrap uCode where to find the "Initialize" uCode | ||
5228 | * in host DRAM ... host DRAM physical address bits 31:0 for 3945. | ||
5229 | * NOTE: iwl3945_initialize_alive_start() will replace these values, | ||
5230 | * after the "initialize" uCode has run, to point to | ||
5231 | * runtime/protocol instructions and backup data cache. */ | ||
5232 | pinst = priv->ucode_init.p_addr; | ||
5233 | pdata = priv->ucode_init_data.p_addr; | ||
5234 | inst_len = priv->ucode_init.len; | ||
5235 | data_len = priv->ucode_init_data.len; | ||
5236 | |||
5237 | rc = iwl3945_grab_nic_access(priv); | ||
5238 | if (rc) | ||
5239 | return rc; | ||
5240 | |||
5241 | iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | ||
5242 | iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | ||
5243 | iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); | ||
5244 | iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); | ||
5245 | |||
5246 | /* Fill BSM memory with bootstrap instructions */ | ||
5247 | for (reg_offset = BSM_SRAM_LOWER_BOUND; | ||
5248 | reg_offset < BSM_SRAM_LOWER_BOUND + len; | ||
5249 | reg_offset += sizeof(u32), image++) | ||
5250 | _iwl3945_write_prph(priv, reg_offset, | ||
5251 | le32_to_cpu(*image)); | ||
5252 | |||
5253 | rc = iwl3945_verify_bsm(priv); | ||
5254 | if (rc) { | ||
5255 | iwl3945_release_nic_access(priv); | ||
5256 | return rc; | ||
5257 | } | ||
5258 | |||
5259 | /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ | ||
5260 | iwl3945_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); | ||
5261 | iwl3945_write_prph(priv, BSM_WR_MEM_DST_REG, | ||
5262 | RTC_INST_LOWER_BOUND); | ||
5263 | iwl3945_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); | ||
5264 | |||
5265 | /* Load bootstrap code into instruction SRAM now, | ||
5266 | * to prepare to load "initialize" uCode */ | ||
5267 | iwl3945_write_prph(priv, BSM_WR_CTRL_REG, | ||
5268 | BSM_WR_CTRL_REG_BIT_START); | ||
5269 | |||
5270 | /* Wait for load of bootstrap uCode to finish */ | ||
5271 | for (i = 0; i < 100; i++) { | ||
5272 | done = iwl3945_read_prph(priv, BSM_WR_CTRL_REG); | ||
5273 | if (!(done & BSM_WR_CTRL_REG_BIT_START)) | ||
5274 | break; | ||
5275 | udelay(10); | ||
5276 | } | ||
5277 | if (i < 100) | ||
5278 | IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i); | ||
5279 | else { | ||
5280 | IWL_ERROR("BSM write did not complete!\n"); | ||
5281 | return -EIO; | ||
5282 | } | ||
5283 | |||
5284 | /* Enable future boot loads whenever power management unit triggers it | ||
5285 | * (e.g. when powering back up after power-save shutdown) */ | ||
5286 | iwl3945_write_prph(priv, BSM_WR_CTRL_REG, | ||
5287 | BSM_WR_CTRL_REG_BIT_START_EN); | ||
5288 | |||
5289 | iwl3945_release_nic_access(priv); | ||
5290 | |||
5291 | return 0; | ||
5292 | } | ||
5293 | |||
5294 | static void iwl3945_nic_start(struct iwl3945_priv *priv) | ||
5295 | { | 3483 | { |
5296 | /* Remove all resets to allow NIC to operate */ | 3484 | /* Remove all resets to allow NIC to operate */ |
5297 | iwl3945_write32(priv, CSR_RESET, 0); | 3485 | iwl_write32(priv, CSR_RESET, 0); |
5298 | } | 3486 | } |
5299 | 3487 | ||
5300 | /** | 3488 | /** |
@@ -5302,9 +3490,9 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv) | |||
5302 | * | 3490 | * |
5303 | * Copy into buffers for card to fetch via bus-mastering | 3491 | * Copy into buffers for card to fetch via bus-mastering |
5304 | */ | 3492 | */ |
5305 | static int iwl3945_read_ucode(struct iwl3945_priv *priv) | 3493 | static int iwl3945_read_ucode(struct iwl_priv *priv) |
5306 | { | 3494 | { |
5307 | struct iwl3945_ucode *ucode; | 3495 | struct iwl_ucode *ucode; |
5308 | int ret = -EINVAL, index; | 3496 | int ret = -EINVAL, index; |
5309 | const struct firmware *ucode_raw; | 3497 | const struct firmware *ucode_raw; |
5310 | /* firmware file name contains uCode/driver compatibility version */ | 3498 | /* firmware file name contains uCode/driver compatibility version */ |
@@ -5322,7 +3510,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5322 | sprintf(buf, "%s%u%s", name_pre, index, ".ucode"); | 3510 | sprintf(buf, "%s%u%s", name_pre, index, ".ucode"); |
5323 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); | 3511 | ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev); |
5324 | if (ret < 0) { | 3512 | if (ret < 0) { |
5325 | IWL_ERROR("%s firmware file req failed: Reason %d\n", | 3513 | IWL_ERR(priv, "%s firmware file req failed: %d\n", |
5326 | buf, ret); | 3514 | buf, ret); |
5327 | if (ret == -ENOENT) | 3515 | if (ret == -ENOENT) |
5328 | continue; | 3516 | continue; |
@@ -5330,7 +3518,9 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5330 | goto error; | 3518 | goto error; |
5331 | } else { | 3519 | } else { |
5332 | if (index < api_max) | 3520 | if (index < api_max) |
5333 | IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n", | 3521 | IWL_ERR(priv, "Loaded firmware %s, " |
3522 | "which is deprecated. " | ||
3523 | " Please use API v%u instead.\n", | ||
5334 | buf, api_max); | 3524 | buf, api_max); |
5335 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", | 3525 | IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n", |
5336 | buf, ucode_raw->size); | 3526 | buf, ucode_raw->size); |
@@ -5343,7 +3533,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5343 | 3533 | ||
5344 | /* Make sure that we got at least our header! */ | 3534 | /* Make sure that we got at least our header! */ |
5345 | if (ucode_raw->size < sizeof(*ucode)) { | 3535 | if (ucode_raw->size < sizeof(*ucode)) { |
5346 | IWL_ERROR("File size way too small!\n"); | 3536 | IWL_ERR(priv, "File size way too small!\n"); |
5347 | ret = -EINVAL; | 3537 | ret = -EINVAL; |
5348 | goto err_release; | 3538 | goto err_release; |
5349 | } | 3539 | } |
@@ -5364,7 +3554,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5364 | * on the API version read from firware header from here on forward */ | 3554 | * on the API version read from firware header from here on forward */ |
5365 | 3555 | ||
5366 | if (api_ver < api_min || api_ver > api_max) { | 3556 | if (api_ver < api_min || api_ver > api_max) { |
5367 | IWL_ERROR("Driver unable to support your firmware API. " | 3557 | IWL_ERR(priv, "Driver unable to support your firmware API. " |
5368 | "Driver supports v%u, firmware is v%u.\n", | 3558 | "Driver supports v%u, firmware is v%u.\n", |
5369 | api_max, api_ver); | 3559 | api_max, api_ver); |
5370 | priv->ucode_ver = 0; | 3560 | priv->ucode_ver = 0; |
@@ -5372,16 +3562,17 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5372 | goto err_release; | 3562 | goto err_release; |
5373 | } | 3563 | } |
5374 | if (api_ver != api_max) | 3564 | if (api_ver != api_max) |
5375 | IWL_ERROR("Firmware has old API version. Expected %u, " | 3565 | IWL_ERR(priv, "Firmware has old API version. Expected %u, " |
5376 | "got %u. New firmware can be obtained " | 3566 | "got %u. New firmware can be obtained " |
5377 | "from http://www.intellinuxwireless.org.\n", | 3567 | "from http://www.intellinuxwireless.org.\n", |
5378 | api_max, api_ver); | 3568 | api_max, api_ver); |
5379 | 3569 | ||
5380 | printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n", | 3570 | IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n", |
5381 | IWL_UCODE_MAJOR(priv->ucode_ver), | 3571 | IWL_UCODE_MAJOR(priv->ucode_ver), |
5382 | IWL_UCODE_MINOR(priv->ucode_ver), | 3572 | IWL_UCODE_MINOR(priv->ucode_ver), |
5383 | IWL_UCODE_API(priv->ucode_ver), | 3573 | IWL_UCODE_API(priv->ucode_ver), |
5384 | IWL_UCODE_SERIAL(priv->ucode_ver)); | 3574 | IWL_UCODE_SERIAL(priv->ucode_ver)); |
3575 | |||
5385 | IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", | 3576 | IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n", |
5386 | priv->ucode_ver); | 3577 | priv->ucode_ver); |
5387 | IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size); | 3578 | IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size); |
@@ -5403,32 +3594,32 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5403 | } | 3594 | } |
5404 | 3595 | ||
5405 | /* Verify that uCode images will fit in card's SRAM */ | 3596 | /* Verify that uCode images will fit in card's SRAM */ |
5406 | if (inst_size > IWL_MAX_INST_SIZE) { | 3597 | if (inst_size > IWL39_MAX_INST_SIZE) { |
5407 | IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n", | 3598 | IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n", |
5408 | inst_size); | 3599 | inst_size); |
5409 | ret = -EINVAL; | 3600 | ret = -EINVAL; |
5410 | goto err_release; | 3601 | goto err_release; |
5411 | } | 3602 | } |
5412 | 3603 | ||
5413 | if (data_size > IWL_MAX_DATA_SIZE) { | 3604 | if (data_size > IWL39_MAX_DATA_SIZE) { |
5414 | IWL_DEBUG_INFO("uCode data len %d too large to fit in\n", | 3605 | IWL_DEBUG_INFO("uCode data len %d too large to fit in\n", |
5415 | data_size); | 3606 | data_size); |
5416 | ret = -EINVAL; | 3607 | ret = -EINVAL; |
5417 | goto err_release; | 3608 | goto err_release; |
5418 | } | 3609 | } |
5419 | if (init_size > IWL_MAX_INST_SIZE) { | 3610 | if (init_size > IWL39_MAX_INST_SIZE) { |
5420 | IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n", | 3611 | IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n", |
5421 | init_size); | 3612 | init_size); |
5422 | ret = -EINVAL; | 3613 | ret = -EINVAL; |
5423 | goto err_release; | 3614 | goto err_release; |
5424 | } | 3615 | } |
5425 | if (init_data_size > IWL_MAX_DATA_SIZE) { | 3616 | if (init_data_size > IWL39_MAX_DATA_SIZE) { |
5426 | IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n", | 3617 | IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n", |
5427 | init_data_size); | 3618 | init_data_size); |
5428 | ret = -EINVAL; | 3619 | ret = -EINVAL; |
5429 | goto err_release; | 3620 | goto err_release; |
5430 | } | 3621 | } |
5431 | if (boot_size > IWL_MAX_BSM_SIZE) { | 3622 | if (boot_size > IWL39_MAX_BSM_SIZE) { |
5432 | IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n", | 3623 | IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n", |
5433 | boot_size); | 3624 | boot_size); |
5434 | ret = -EINVAL; | 3625 | ret = -EINVAL; |
@@ -5522,7 +3713,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5522 | return 0; | 3713 | return 0; |
5523 | 3714 | ||
5524 | err_pci_alloc: | 3715 | err_pci_alloc: |
5525 | IWL_ERROR("failed to allocate pci memory\n"); | 3716 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
5526 | ret = -ENOMEM; | 3717 | ret = -ENOMEM; |
5527 | iwl3945_dealloc_ucode_pci(priv); | 3718 | iwl3945_dealloc_ucode_pci(priv); |
5528 | 3719 | ||
@@ -5543,7 +3734,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5543 | * We need to replace them to load runtime uCode inst and data, | 3734 | * We need to replace them to load runtime uCode inst and data, |
5544 | * and to save runtime data when powering down. | 3735 | * and to save runtime data when powering down. |
5545 | */ | 3736 | */ |
5546 | static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv) | 3737 | static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv) |
5547 | { | 3738 | { |
5548 | dma_addr_t pinst; | 3739 | dma_addr_t pinst; |
5549 | dma_addr_t pdata; | 3740 | dma_addr_t pdata; |
@@ -5555,24 +3746,24 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv) | |||
5555 | pdata = priv->ucode_data_backup.p_addr; | 3746 | pdata = priv->ucode_data_backup.p_addr; |
5556 | 3747 | ||
5557 | spin_lock_irqsave(&priv->lock, flags); | 3748 | spin_lock_irqsave(&priv->lock, flags); |
5558 | rc = iwl3945_grab_nic_access(priv); | 3749 | rc = iwl_grab_nic_access(priv); |
5559 | if (rc) { | 3750 | if (rc) { |
5560 | spin_unlock_irqrestore(&priv->lock, flags); | 3751 | spin_unlock_irqrestore(&priv->lock, flags); |
5561 | return rc; | 3752 | return rc; |
5562 | } | 3753 | } |
5563 | 3754 | ||
5564 | /* Tell bootstrap uCode where to find image to load */ | 3755 | /* Tell bootstrap uCode where to find image to load */ |
5565 | iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); | 3756 | iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); |
5566 | iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); | 3757 | iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); |
5567 | iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, | 3758 | iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, |
5568 | priv->ucode_data.len); | 3759 | priv->ucode_data.len); |
5569 | 3760 | ||
5570 | /* Inst byte count must be last to set up, bit 31 signals uCode | 3761 | /* Inst byte count must be last to set up, bit 31 signals uCode |
5571 | * that all new ptr/size info is in place */ | 3762 | * that all new ptr/size info is in place */ |
5572 | iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, | 3763 | iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, |
5573 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); | 3764 | priv->ucode_code.len | BSM_DRAM_INST_LOAD); |
5574 | 3765 | ||
5575 | iwl3945_release_nic_access(priv); | 3766 | iwl_release_nic_access(priv); |
5576 | 3767 | ||
5577 | spin_unlock_irqrestore(&priv->lock, flags); | 3768 | spin_unlock_irqrestore(&priv->lock, flags); |
5578 | 3769 | ||
@@ -5588,7 +3779,7 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv) | |||
5588 | * | 3779 | * |
5589 | * Tell "initialize" uCode to go ahead and load the runtime uCode. | 3780 | * Tell "initialize" uCode to go ahead and load the runtime uCode. |
5590 | */ | 3781 | */ |
5591 | static void iwl3945_init_alive_start(struct iwl3945_priv *priv) | 3782 | static void iwl3945_init_alive_start(struct iwl_priv *priv) |
5592 | { | 3783 | { |
5593 | /* Check alive response for "valid" sign from uCode */ | 3784 | /* Check alive response for "valid" sign from uCode */ |
5594 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { | 3785 | if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { |
@@ -5634,7 +3825,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, | |||
5634 | * from protocol/runtime uCode (initialization uCode's | 3825 | * from protocol/runtime uCode (initialization uCode's |
5635 | * Alive gets handled by iwl3945_init_alive_start()). | 3826 | * Alive gets handled by iwl3945_init_alive_start()). |
5636 | */ | 3827 | */ |
5637 | static void iwl3945_alive_start(struct iwl3945_priv *priv) | 3828 | static void iwl3945_alive_start(struct iwl_priv *priv) |
5638 | { | 3829 | { |
5639 | int rc = 0; | 3830 | int rc = 0; |
5640 | int thermal_spin = 0; | 3831 | int thermal_spin = 0; |
@@ -5661,15 +3852,15 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5661 | 3852 | ||
5662 | iwl3945_clear_stations_table(priv); | 3853 | iwl3945_clear_stations_table(priv); |
5663 | 3854 | ||
5664 | rc = iwl3945_grab_nic_access(priv); | 3855 | rc = iwl_grab_nic_access(priv); |
5665 | if (rc) { | 3856 | if (rc) { |
5666 | IWL_WARNING("Can not read RFKILL status from adapter\n"); | 3857 | IWL_WARN(priv, "Can not read RFKILL status from adapter\n"); |
5667 | return; | 3858 | return; |
5668 | } | 3859 | } |
5669 | 3860 | ||
5670 | rfkill = iwl3945_read_prph(priv, APMG_RFKILL_REG); | 3861 | rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); |
5671 | IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill); | 3862 | IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill); |
5672 | iwl3945_release_nic_access(priv); | 3863 | iwl_release_nic_access(priv); |
5673 | 3864 | ||
5674 | if (rfkill & 0x1) { | 3865 | if (rfkill & 0x1) { |
5675 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 3866 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
@@ -5692,7 +3883,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5692 | /* Clear out the uCode error bit if it is set */ | 3883 | /* Clear out the uCode error bit if it is set */ |
5693 | clear_bit(STATUS_FW_ERROR, &priv->status); | 3884 | clear_bit(STATUS_FW_ERROR, &priv->status); |
5694 | 3885 | ||
5695 | if (iwl3945_is_rfkill(priv)) | 3886 | if (iwl_is_rfkill(priv)) |
5696 | return; | 3887 | return; |
5697 | 3888 | ||
5698 | ieee80211_wake_queues(priv->hw); | 3889 | ieee80211_wake_queues(priv->hw); |
@@ -5704,19 +3895,19 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5704 | 3895 | ||
5705 | if (iwl3945_is_associated(priv)) { | 3896 | if (iwl3945_is_associated(priv)) { |
5706 | struct iwl3945_rxon_cmd *active_rxon = | 3897 | struct iwl3945_rxon_cmd *active_rxon = |
5707 | (struct iwl3945_rxon_cmd *)(&priv->active_rxon); | 3898 | (struct iwl3945_rxon_cmd *)(&priv->active39_rxon); |
5708 | 3899 | ||
5709 | memcpy(&priv->staging_rxon, &priv->active_rxon, | 3900 | memcpy(&priv->staging39_rxon, &priv->active39_rxon, |
5710 | sizeof(priv->staging_rxon)); | 3901 | sizeof(priv->staging39_rxon)); |
5711 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3902 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
5712 | } else { | 3903 | } else { |
5713 | /* Initialize our rx_config data */ | 3904 | /* Initialize our rx_config data */ |
5714 | iwl3945_connection_init_rx_config(priv, priv->iw_mode); | 3905 | iwl3945_connection_init_rx_config(priv, priv->iw_mode); |
5715 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 3906 | memcpy(priv->staging39_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
5716 | } | 3907 | } |
5717 | 3908 | ||
5718 | /* Configure Bluetooth device coexistence support */ | 3909 | /* Configure Bluetooth device coexistence support */ |
5719 | iwl3945_send_bt_config(priv); | 3910 | iwl_send_bt_config(priv); |
5720 | 3911 | ||
5721 | /* Configure the adapter for unassociated operation */ | 3912 | /* Configure the adapter for unassociated operation */ |
5722 | iwl3945_commit_rxon(priv); | 3913 | iwl3945_commit_rxon(priv); |
@@ -5746,9 +3937,9 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5746 | queue_work(priv->workqueue, &priv->restart); | 3937 | queue_work(priv->workqueue, &priv->restart); |
5747 | } | 3938 | } |
5748 | 3939 | ||
5749 | static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv); | 3940 | static void iwl3945_cancel_deferred_work(struct iwl_priv *priv); |
5750 | 3941 | ||
5751 | static void __iwl3945_down(struct iwl3945_priv *priv) | 3942 | static void __iwl3945_down(struct iwl_priv *priv) |
5752 | { | 3943 | { |
5753 | unsigned long flags; | 3944 | unsigned long flags; |
5754 | int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); | 3945 | int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); |
@@ -5773,7 +3964,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5773 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | 3964 | clear_bit(STATUS_EXIT_PENDING, &priv->status); |
5774 | 3965 | ||
5775 | /* stop and reset the on-board processor */ | 3966 | /* stop and reset the on-board processor */ |
5776 | iwl3945_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 3967 | iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
5777 | 3968 | ||
5778 | /* tell the device to stop sending interrupts */ | 3969 | /* tell the device to stop sending interrupts */ |
5779 | spin_lock_irqsave(&priv->lock, flags); | 3970 | spin_lock_irqsave(&priv->lock, flags); |
@@ -5786,7 +3977,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5786 | 3977 | ||
5787 | /* If we have not previously called iwl3945_init() then | 3978 | /* If we have not previously called iwl3945_init() then |
5788 | * clear all bits but the RF Kill and SUSPEND bits and return */ | 3979 | * clear all bits but the RF Kill and SUSPEND bits and return */ |
5789 | if (!iwl3945_is_init(priv)) { | 3980 | if (!iwl_is_init(priv)) { |
5790 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 3981 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
5791 | STATUS_RF_KILL_HW | | 3982 | STATUS_RF_KILL_HW | |
5792 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | 3983 | test_bit(STATUS_RF_KILL_SW, &priv->status) << |
@@ -5815,29 +4006,31 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5815 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 4006 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
5816 | STATUS_EXIT_PENDING; | 4007 | STATUS_EXIT_PENDING; |
5817 | 4008 | ||
4009 | priv->cfg->ops->lib->apm_ops.reset(priv); | ||
5818 | spin_lock_irqsave(&priv->lock, flags); | 4010 | spin_lock_irqsave(&priv->lock, flags); |
5819 | iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 4011 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
5820 | spin_unlock_irqrestore(&priv->lock, flags); | 4012 | spin_unlock_irqrestore(&priv->lock, flags); |
5821 | 4013 | ||
5822 | iwl3945_hw_txq_ctx_stop(priv); | 4014 | iwl3945_hw_txq_ctx_stop(priv); |
5823 | iwl3945_hw_rxq_stop(priv); | 4015 | iwl3945_hw_rxq_stop(priv); |
5824 | 4016 | ||
5825 | spin_lock_irqsave(&priv->lock, flags); | 4017 | spin_lock_irqsave(&priv->lock, flags); |
5826 | if (!iwl3945_grab_nic_access(priv)) { | 4018 | if (!iwl_grab_nic_access(priv)) { |
5827 | iwl3945_write_prph(priv, APMG_CLK_DIS_REG, | 4019 | iwl_write_prph(priv, APMG_CLK_DIS_REG, |
5828 | APMG_CLK_VAL_DMA_CLK_RQT); | 4020 | APMG_CLK_VAL_DMA_CLK_RQT); |
5829 | iwl3945_release_nic_access(priv); | 4021 | iwl_release_nic_access(priv); |
5830 | } | 4022 | } |
5831 | spin_unlock_irqrestore(&priv->lock, flags); | 4023 | spin_unlock_irqrestore(&priv->lock, flags); |
5832 | 4024 | ||
5833 | udelay(5); | 4025 | udelay(5); |
5834 | 4026 | ||
5835 | iwl3945_hw_nic_stop_master(priv); | 4027 | if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) |
5836 | iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | 4028 | priv->cfg->ops->lib->apm_ops.stop(priv); |
5837 | iwl3945_hw_nic_reset(priv); | 4029 | else |
4030 | priv->cfg->ops->lib->apm_ops.reset(priv); | ||
5838 | 4031 | ||
5839 | exit: | 4032 | exit: |
5840 | memset(&priv->card_alive, 0, sizeof(struct iwl3945_alive_resp)); | 4033 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); |
5841 | 4034 | ||
5842 | if (priv->ibss_beacon) | 4035 | if (priv->ibss_beacon) |
5843 | dev_kfree_skb(priv->ibss_beacon); | 4036 | dev_kfree_skb(priv->ibss_beacon); |
@@ -5847,7 +4040,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5847 | iwl3945_clear_free_frames(priv); | 4040 | iwl3945_clear_free_frames(priv); |
5848 | } | 4041 | } |
5849 | 4042 | ||
5850 | static void iwl3945_down(struct iwl3945_priv *priv) | 4043 | static void iwl3945_down(struct iwl_priv *priv) |
5851 | { | 4044 | { |
5852 | mutex_lock(&priv->mutex); | 4045 | mutex_lock(&priv->mutex); |
5853 | __iwl3945_down(priv); | 4046 | __iwl3945_down(priv); |
@@ -5858,58 +4051,58 @@ static void iwl3945_down(struct iwl3945_priv *priv) | |||
5858 | 4051 | ||
5859 | #define MAX_HW_RESTARTS 5 | 4052 | #define MAX_HW_RESTARTS 5 |
5860 | 4053 | ||
5861 | static int __iwl3945_up(struct iwl3945_priv *priv) | 4054 | static int __iwl3945_up(struct iwl_priv *priv) |
5862 | { | 4055 | { |
5863 | int rc, i; | 4056 | int rc, i; |
5864 | 4057 | ||
5865 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 4058 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
5866 | IWL_WARNING("Exit pending; will not bring the NIC up\n"); | 4059 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); |
5867 | return -EIO; | 4060 | return -EIO; |
5868 | } | 4061 | } |
5869 | 4062 | ||
5870 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | 4063 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { |
5871 | IWL_WARNING("Radio disabled by SW RF kill (module " | 4064 | IWL_WARN(priv, "Radio disabled by SW RF kill (module " |
5872 | "parameter)\n"); | 4065 | "parameter)\n"); |
5873 | return -ENODEV; | 4066 | return -ENODEV; |
5874 | } | 4067 | } |
5875 | 4068 | ||
5876 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { | 4069 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { |
5877 | IWL_ERROR("ucode not available for device bring up\n"); | 4070 | IWL_ERR(priv, "ucode not available for device bring up\n"); |
5878 | return -EIO; | 4071 | return -EIO; |
5879 | } | 4072 | } |
5880 | 4073 | ||
5881 | /* If platform's RF_KILL switch is NOT set to KILL */ | 4074 | /* If platform's RF_KILL switch is NOT set to KILL */ |
5882 | if (iwl3945_read32(priv, CSR_GP_CNTRL) & | 4075 | if (iwl_read32(priv, CSR_GP_CNTRL) & |
5883 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 4076 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
5884 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 4077 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
5885 | else { | 4078 | else { |
5886 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 4079 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
5887 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { | 4080 | if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { |
5888 | IWL_WARNING("Radio disabled by HW RF Kill switch\n"); | 4081 | IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); |
5889 | return -ENODEV; | 4082 | return -ENODEV; |
5890 | } | 4083 | } |
5891 | } | 4084 | } |
5892 | 4085 | ||
5893 | iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); | 4086 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
5894 | 4087 | ||
5895 | rc = iwl3945_hw_nic_init(priv); | 4088 | rc = iwl3945_hw_nic_init(priv); |
5896 | if (rc) { | 4089 | if (rc) { |
5897 | IWL_ERROR("Unable to int nic\n"); | 4090 | IWL_ERR(priv, "Unable to int nic\n"); |
5898 | return rc; | 4091 | return rc; |
5899 | } | 4092 | } |
5900 | 4093 | ||
5901 | /* make sure rfkill handshake bits are cleared */ | 4094 | /* make sure rfkill handshake bits are cleared */ |
5902 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 4095 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
5903 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, | 4096 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, |
5904 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | 4097 | CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); |
5905 | 4098 | ||
5906 | /* clear (again), then enable host interrupts */ | 4099 | /* clear (again), then enable host interrupts */ |
5907 | iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); | 4100 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
5908 | iwl3945_enable_interrupts(priv); | 4101 | iwl3945_enable_interrupts(priv); |
5909 | 4102 | ||
5910 | /* really make sure rfkill handshake bits are cleared */ | 4103 | /* really make sure rfkill handshake bits are cleared */ |
5911 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 4104 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
5912 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 4105 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
5913 | 4106 | ||
5914 | /* Copy original ucode data image from disk into backup cache. | 4107 | /* Copy original ucode data image from disk into backup cache. |
5915 | * This will be used to initialize the on-board processor's | 4108 | * This will be used to initialize the on-board processor's |
@@ -5928,10 +4121,11 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
5928 | /* load bootstrap state machine, | 4121 | /* load bootstrap state machine, |
5929 | * load bootstrap program into processor's memory, | 4122 | * load bootstrap program into processor's memory, |
5930 | * prepare to load the "initialize" uCode */ | 4123 | * prepare to load the "initialize" uCode */ |
5931 | rc = iwl3945_load_bsm(priv); | 4124 | priv->cfg->ops->lib->load_ucode(priv); |
5932 | 4125 | ||
5933 | if (rc) { | 4126 | if (rc) { |
5934 | IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc); | 4127 | IWL_ERR(priv, |
4128 | "Unable to set up bootstrap uCode: %d\n", rc); | ||
5935 | continue; | 4129 | continue; |
5936 | } | 4130 | } |
5937 | 4131 | ||
@@ -5949,7 +4143,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
5949 | 4143 | ||
5950 | /* tried to restart and config the device for as long as our | 4144 | /* tried to restart and config the device for as long as our |
5951 | * patience could withstand */ | 4145 | * patience could withstand */ |
5952 | IWL_ERROR("Unable to initialize device after %d attempts.\n", i); | 4146 | IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); |
5953 | return -EIO; | 4147 | return -EIO; |
5954 | } | 4148 | } |
5955 | 4149 | ||
@@ -5962,8 +4156,8 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
5962 | 4156 | ||
5963 | static void iwl3945_bg_init_alive_start(struct work_struct *data) | 4157 | static void iwl3945_bg_init_alive_start(struct work_struct *data) |
5964 | { | 4158 | { |
5965 | struct iwl3945_priv *priv = | 4159 | struct iwl_priv *priv = |
5966 | container_of(data, struct iwl3945_priv, init_alive_start.work); | 4160 | container_of(data, struct iwl_priv, init_alive_start.work); |
5967 | 4161 | ||
5968 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4162 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
5969 | return; | 4163 | return; |
@@ -5975,8 +4169,8 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data) | |||
5975 | 4169 | ||
5976 | static void iwl3945_bg_alive_start(struct work_struct *data) | 4170 | static void iwl3945_bg_alive_start(struct work_struct *data) |
5977 | { | 4171 | { |
5978 | struct iwl3945_priv *priv = | 4172 | struct iwl_priv *priv = |
5979 | container_of(data, struct iwl3945_priv, alive_start.work); | 4173 | container_of(data, struct iwl_priv, alive_start.work); |
5980 | 4174 | ||
5981 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4175 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
5982 | return; | 4176 | return; |
@@ -5986,66 +4180,31 @@ static void iwl3945_bg_alive_start(struct work_struct *data) | |||
5986 | mutex_unlock(&priv->mutex); | 4180 | mutex_unlock(&priv->mutex); |
5987 | } | 4181 | } |
5988 | 4182 | ||
5989 | static void iwl3945_bg_rf_kill(struct work_struct *work) | 4183 | static void iwl3945_rfkill_poll(struct work_struct *data) |
5990 | { | 4184 | { |
5991 | struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, rf_kill); | 4185 | struct iwl_priv *priv = |
5992 | 4186 | container_of(data, struct iwl_priv, rfkill_poll.work); | |
5993 | wake_up_interruptible(&priv->wait_command_queue); | 4187 | unsigned long status = priv->status; |
5994 | |||
5995 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
5996 | return; | ||
5997 | 4188 | ||
5998 | mutex_lock(&priv->mutex); | 4189 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
4190 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
4191 | else | ||
4192 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
5999 | 4193 | ||
6000 | if (!iwl3945_is_rfkill(priv)) { | 4194 | if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) |
6001 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, | 4195 | queue_work(priv->workqueue, &priv->rf_kill); |
6002 | "HW and/or SW RF Kill no longer active, restarting " | ||
6003 | "device\n"); | ||
6004 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
6005 | queue_work(priv->workqueue, &priv->restart); | ||
6006 | } else { | ||
6007 | 4196 | ||
6008 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | 4197 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
6009 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " | 4198 | round_jiffies_relative(2 * HZ)); |
6010 | "disabled by SW switch\n"); | ||
6011 | else | ||
6012 | IWL_WARNING("Radio Frequency Kill Switch is On:\n" | ||
6013 | "Kill switch must be turned off for " | ||
6014 | "wireless networking to work.\n"); | ||
6015 | } | ||
6016 | 4199 | ||
6017 | mutex_unlock(&priv->mutex); | ||
6018 | iwl3945_rfkill_set_hw_state(priv); | ||
6019 | } | 4200 | } |
6020 | 4201 | ||
6021 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 4202 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
6022 | |||
6023 | static void iwl3945_bg_scan_check(struct work_struct *data) | ||
6024 | { | ||
6025 | struct iwl3945_priv *priv = | ||
6026 | container_of(data, struct iwl3945_priv, scan_check.work); | ||
6027 | |||
6028 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
6029 | return; | ||
6030 | |||
6031 | mutex_lock(&priv->mutex); | ||
6032 | if (test_bit(STATUS_SCANNING, &priv->status) || | ||
6033 | test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
6034 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, | ||
6035 | "Scan completion watchdog resetting adapter (%dms)\n", | ||
6036 | jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); | ||
6037 | |||
6038 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
6039 | iwl3945_send_scan_abort(priv); | ||
6040 | } | ||
6041 | mutex_unlock(&priv->mutex); | ||
6042 | } | ||
6043 | |||
6044 | static void iwl3945_bg_request_scan(struct work_struct *data) | 4203 | static void iwl3945_bg_request_scan(struct work_struct *data) |
6045 | { | 4204 | { |
6046 | struct iwl3945_priv *priv = | 4205 | struct iwl_priv *priv = |
6047 | container_of(data, struct iwl3945_priv, request_scan); | 4206 | container_of(data, struct iwl_priv, request_scan); |
6048 | struct iwl3945_host_cmd cmd = { | 4207 | struct iwl_host_cmd cmd = { |
6049 | .id = REPLY_SCAN_CMD, | 4208 | .id = REPLY_SCAN_CMD, |
6050 | .len = sizeof(struct iwl3945_scan_cmd), | 4209 | .len = sizeof(struct iwl3945_scan_cmd), |
6051 | .meta.flags = CMD_SIZE_HUGE, | 4210 | .meta.flags = CMD_SIZE_HUGE, |
@@ -6061,8 +4220,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6061 | 4220 | ||
6062 | mutex_lock(&priv->mutex); | 4221 | mutex_lock(&priv->mutex); |
6063 | 4222 | ||
6064 | if (!iwl3945_is_ready(priv)) { | 4223 | if (!iwl_is_ready(priv)) { |
6065 | IWL_WARNING("request scan called when driver not ready.\n"); | 4224 | IWL_WARN(priv, "request scan called when driver not ready.\n"); |
6066 | goto done; | 4225 | goto done; |
6067 | } | 4226 | } |
6068 | 4227 | ||
@@ -6090,7 +4249,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6090 | goto done; | 4249 | goto done; |
6091 | } | 4250 | } |
6092 | 4251 | ||
6093 | if (iwl3945_is_rfkill(priv)) { | 4252 | if (iwl_is_rfkill(priv)) { |
6094 | IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); | 4253 | IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); |
6095 | goto done; | 4254 | goto done; |
6096 | } | 4255 | } |
@@ -6168,11 +4327,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6168 | 4327 | ||
6169 | /* We don't build a direct scan probe request; the uCode will do | 4328 | /* We don't build a direct scan probe request; the uCode will do |
6170 | * that based on the direct_mask added to each channel entry */ | 4329 | * that based on the direct_mask added to each channel entry */ |
6171 | scan->tx_cmd.len = cpu_to_le16( | ||
6172 | iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, | ||
6173 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | ||
6174 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | 4330 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; |
6175 | scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; | 4331 | scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; |
6176 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 4332 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
6177 | 4333 | ||
6178 | /* flags + rate selection */ | 4334 | /* flags + rate selection */ |
@@ -6187,10 +4343,15 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6187 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 4343 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6188 | band = IEEE80211_BAND_5GHZ; | 4344 | band = IEEE80211_BAND_5GHZ; |
6189 | } else { | 4345 | } else { |
6190 | IWL_WARNING("Invalid scan band count\n"); | 4346 | IWL_WARN(priv, "Invalid scan band count\n"); |
6191 | goto done; | 4347 | goto done; |
6192 | } | 4348 | } |
6193 | 4349 | ||
4350 | scan->tx_cmd.len = cpu_to_le16( | ||
4351 | iwl_fill_probe_req(priv, band, | ||
4352 | (struct ieee80211_mgmt *)scan->data, | ||
4353 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | ||
4354 | |||
6194 | /* select Rx antennas */ | 4355 | /* select Rx antennas */ |
6195 | scan->flags |= iwl3945_get_antenna_flags(priv); | 4356 | scan->flags |= iwl3945_get_antenna_flags(priv); |
6196 | 4357 | ||
@@ -6213,7 +4374,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6213 | scan->len = cpu_to_le16(cmd.len); | 4374 | scan->len = cpu_to_le16(cmd.len); |
6214 | 4375 | ||
6215 | set_bit(STATUS_SCAN_HW, &priv->status); | 4376 | set_bit(STATUS_SCAN_HW, &priv->status); |
6216 | rc = iwl3945_send_cmd_sync(priv, &cmd); | 4377 | rc = iwl_send_cmd_sync(priv, &cmd); |
6217 | if (rc) | 4378 | if (rc) |
6218 | goto done; | 4379 | goto done; |
6219 | 4380 | ||
@@ -6239,7 +4400,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6239 | 4400 | ||
6240 | static void iwl3945_bg_up(struct work_struct *data) | 4401 | static void iwl3945_bg_up(struct work_struct *data) |
6241 | { | 4402 | { |
6242 | struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, up); | 4403 | struct iwl_priv *priv = container_of(data, struct iwl_priv, up); |
6243 | 4404 | ||
6244 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4405 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6245 | return; | 4406 | return; |
@@ -6247,12 +4408,12 @@ static void iwl3945_bg_up(struct work_struct *data) | |||
6247 | mutex_lock(&priv->mutex); | 4408 | mutex_lock(&priv->mutex); |
6248 | __iwl3945_up(priv); | 4409 | __iwl3945_up(priv); |
6249 | mutex_unlock(&priv->mutex); | 4410 | mutex_unlock(&priv->mutex); |
6250 | iwl3945_rfkill_set_hw_state(priv); | 4411 | iwl_rfkill_set_hw_state(priv); |
6251 | } | 4412 | } |
6252 | 4413 | ||
6253 | static void iwl3945_bg_restart(struct work_struct *data) | 4414 | static void iwl3945_bg_restart(struct work_struct *data) |
6254 | { | 4415 | { |
6255 | struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, restart); | 4416 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); |
6256 | 4417 | ||
6257 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4418 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6258 | return; | 4419 | return; |
@@ -6263,8 +4424,8 @@ static void iwl3945_bg_restart(struct work_struct *data) | |||
6263 | 4424 | ||
6264 | static void iwl3945_bg_rx_replenish(struct work_struct *data) | 4425 | static void iwl3945_bg_rx_replenish(struct work_struct *data) |
6265 | { | 4426 | { |
6266 | struct iwl3945_priv *priv = | 4427 | struct iwl_priv *priv = |
6267 | container_of(data, struct iwl3945_priv, rx_replenish); | 4428 | container_of(data, struct iwl_priv, rx_replenish); |
6268 | 4429 | ||
6269 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4430 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6270 | return; | 4431 | return; |
@@ -6276,19 +4437,19 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) | |||
6276 | 4437 | ||
6277 | #define IWL_DELAY_NEXT_SCAN (HZ*2) | 4438 | #define IWL_DELAY_NEXT_SCAN (HZ*2) |
6278 | 4439 | ||
6279 | static void iwl3945_post_associate(struct iwl3945_priv *priv) | 4440 | static void iwl3945_post_associate(struct iwl_priv *priv) |
6280 | { | 4441 | { |
6281 | int rc = 0; | 4442 | int rc = 0; |
6282 | struct ieee80211_conf *conf = NULL; | 4443 | struct ieee80211_conf *conf = NULL; |
6283 | 4444 | ||
6284 | if (priv->iw_mode == NL80211_IFTYPE_AP) { | 4445 | if (priv->iw_mode == NL80211_IFTYPE_AP) { |
6285 | IWL_ERROR("%s Should not be called in AP mode\n", __func__); | 4446 | IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); |
6286 | return; | 4447 | return; |
6287 | } | 4448 | } |
6288 | 4449 | ||
6289 | 4450 | ||
6290 | IWL_DEBUG_ASSOC("Associated as %d to: %pM\n", | 4451 | IWL_DEBUG_ASSOC("Associated as %d to: %pM\n", |
6291 | priv->assoc_id, priv->active_rxon.bssid_addr); | 4452 | priv->assoc_id, priv->active39_rxon.bssid_addr); |
6292 | 4453 | ||
6293 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 4454 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6294 | return; | 4455 | return; |
@@ -6296,41 +4457,41 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv) | |||
6296 | if (!priv->vif || !priv->is_open) | 4457 | if (!priv->vif || !priv->is_open) |
6297 | return; | 4458 | return; |
6298 | 4459 | ||
6299 | iwl3945_scan_cancel_timeout(priv, 200); | 4460 | iwl_scan_cancel_timeout(priv, 200); |
6300 | 4461 | ||
6301 | conf = ieee80211_get_hw_conf(priv->hw); | 4462 | conf = ieee80211_get_hw_conf(priv->hw); |
6302 | 4463 | ||
6303 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 4464 | priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
6304 | iwl3945_commit_rxon(priv); | 4465 | iwl3945_commit_rxon(priv); |
6305 | 4466 | ||
6306 | memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd)); | 4467 | memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); |
6307 | iwl3945_setup_rxon_timing(priv); | 4468 | iwl3945_setup_rxon_timing(priv); |
6308 | rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING, | 4469 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, |
6309 | sizeof(priv->rxon_timing), &priv->rxon_timing); | 4470 | sizeof(priv->rxon_timing), &priv->rxon_timing); |
6310 | if (rc) | 4471 | if (rc) |
6311 | IWL_WARNING("REPLY_RXON_TIMING failed - " | 4472 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
6312 | "Attempting to continue.\n"); | 4473 | "Attempting to continue.\n"); |
6313 | 4474 | ||
6314 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 4475 | priv->staging39_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
6315 | 4476 | ||
6316 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 4477 | priv->staging39_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
6317 | 4478 | ||
6318 | IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n", | 4479 | IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n", |
6319 | priv->assoc_id, priv->beacon_int); | 4480 | priv->assoc_id, priv->beacon_int); |
6320 | 4481 | ||
6321 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) | 4482 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) |
6322 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 4483 | priv->staging39_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
6323 | else | 4484 | else |
6324 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | 4485 | priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; |
6325 | 4486 | ||
6326 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { | 4487 | if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) { |
6327 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) | 4488 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) |
6328 | priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; | 4489 | priv->staging39_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; |
6329 | else | 4490 | else |
6330 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 4491 | priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
6331 | 4492 | ||
6332 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) | 4493 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) |
6333 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 4494 | priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
6334 | 4495 | ||
6335 | } | 4496 | } |
6336 | 4497 | ||
@@ -6355,7 +4516,7 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv) | |||
6355 | break; | 4516 | break; |
6356 | 4517 | ||
6357 | default: | 4518 | default: |
6358 | IWL_ERROR("%s Should not be called in %d mode\n", | 4519 | IWL_ERR(priv, "%s Should not be called in %d mode\n", |
6359 | __func__, priv->iw_mode); | 4520 | __func__, priv->iw_mode); |
6360 | break; | 4521 | break; |
6361 | } | 4522 | } |
@@ -6366,45 +4527,8 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv) | |||
6366 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 4527 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
6367 | } | 4528 | } |
6368 | 4529 | ||
6369 | static void iwl3945_bg_abort_scan(struct work_struct *work) | ||
6370 | { | ||
6371 | struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan); | ||
6372 | |||
6373 | if (!iwl3945_is_ready(priv)) | ||
6374 | return; | ||
6375 | |||
6376 | mutex_lock(&priv->mutex); | ||
6377 | |||
6378 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
6379 | iwl3945_send_scan_abort(priv); | ||
6380 | |||
6381 | mutex_unlock(&priv->mutex); | ||
6382 | } | ||
6383 | |||
6384 | static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed); | 4530 | static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed); |
6385 | 4531 | ||
6386 | static void iwl3945_bg_scan_completed(struct work_struct *work) | ||
6387 | { | ||
6388 | struct iwl3945_priv *priv = | ||
6389 | container_of(work, struct iwl3945_priv, scan_completed); | ||
6390 | |||
6391 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n"); | ||
6392 | |||
6393 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
6394 | return; | ||
6395 | |||
6396 | if (test_bit(STATUS_CONF_PENDING, &priv->status)) | ||
6397 | iwl3945_mac_config(priv->hw, 0); | ||
6398 | |||
6399 | ieee80211_scan_completed(priv->hw); | ||
6400 | |||
6401 | /* Since setting the TXPOWER may have been deferred while | ||
6402 | * performing the scan, fire one off */ | ||
6403 | mutex_lock(&priv->mutex); | ||
6404 | iwl3945_hw_reg_send_txpower(priv); | ||
6405 | mutex_unlock(&priv->mutex); | ||
6406 | } | ||
6407 | |||
6408 | /***************************************************************************** | 4532 | /***************************************************************************** |
6409 | * | 4533 | * |
6410 | * mac80211 entry point functions | 4534 | * mac80211 entry point functions |
@@ -6415,36 +4539,22 @@ static void iwl3945_bg_scan_completed(struct work_struct *work) | |||
6415 | 4539 | ||
6416 | static int iwl3945_mac_start(struct ieee80211_hw *hw) | 4540 | static int iwl3945_mac_start(struct ieee80211_hw *hw) |
6417 | { | 4541 | { |
6418 | struct iwl3945_priv *priv = hw->priv; | 4542 | struct iwl_priv *priv = hw->priv; |
6419 | int ret; | 4543 | int ret; |
6420 | 4544 | ||
6421 | IWL_DEBUG_MAC80211("enter\n"); | 4545 | IWL_DEBUG_MAC80211("enter\n"); |
6422 | 4546 | ||
6423 | if (pci_enable_device(priv->pci_dev)) { | ||
6424 | IWL_ERROR("Fail to pci_enable_device\n"); | ||
6425 | return -ENODEV; | ||
6426 | } | ||
6427 | pci_restore_state(priv->pci_dev); | ||
6428 | pci_enable_msi(priv->pci_dev); | ||
6429 | |||
6430 | ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED, | ||
6431 | DRV_NAME, priv); | ||
6432 | if (ret) { | ||
6433 | IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq); | ||
6434 | goto out_disable_msi; | ||
6435 | } | ||
6436 | |||
6437 | /* we should be verifying the device is ready to be opened */ | 4547 | /* we should be verifying the device is ready to be opened */ |
6438 | mutex_lock(&priv->mutex); | 4548 | mutex_lock(&priv->mutex); |
6439 | 4549 | ||
6440 | memset(&priv->staging_rxon, 0, sizeof(struct iwl3945_rxon_cmd)); | 4550 | memset(&priv->staging39_rxon, 0, sizeof(struct iwl3945_rxon_cmd)); |
6441 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | 4551 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... |
6442 | * ucode filename and max sizes are card-specific. */ | 4552 | * ucode filename and max sizes are card-specific. */ |
6443 | 4553 | ||
6444 | if (!priv->ucode_code.len) { | 4554 | if (!priv->ucode_code.len) { |
6445 | ret = iwl3945_read_ucode(priv); | 4555 | ret = iwl3945_read_ucode(priv); |
6446 | if (ret) { | 4556 | if (ret) { |
6447 | IWL_ERROR("Could not read microcode: %d\n", ret); | 4557 | IWL_ERR(priv, "Could not read microcode: %d\n", ret); |
6448 | mutex_unlock(&priv->mutex); | 4558 | mutex_unlock(&priv->mutex); |
6449 | goto out_release_irq; | 4559 | goto out_release_irq; |
6450 | } | 4560 | } |
@@ -6454,7 +4564,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
6454 | 4564 | ||
6455 | mutex_unlock(&priv->mutex); | 4565 | mutex_unlock(&priv->mutex); |
6456 | 4566 | ||
6457 | iwl3945_rfkill_set_hw_state(priv); | 4567 | iwl_rfkill_set_hw_state(priv); |
6458 | 4568 | ||
6459 | if (ret) | 4569 | if (ret) |
6460 | goto out_release_irq; | 4570 | goto out_release_irq; |
@@ -6471,22 +4581,23 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
6471 | UCODE_READY_TIMEOUT); | 4581 | UCODE_READY_TIMEOUT); |
6472 | if (!ret) { | 4582 | if (!ret) { |
6473 | if (!test_bit(STATUS_READY, &priv->status)) { | 4583 | if (!test_bit(STATUS_READY, &priv->status)) { |
6474 | IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n", | 4584 | IWL_ERR(priv, |
6475 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | 4585 | "Wait for START_ALIVE timeout after %dms.\n", |
4586 | jiffies_to_msecs(UCODE_READY_TIMEOUT)); | ||
6476 | ret = -ETIMEDOUT; | 4587 | ret = -ETIMEDOUT; |
6477 | goto out_release_irq; | 4588 | goto out_release_irq; |
6478 | } | 4589 | } |
6479 | } | 4590 | } |
6480 | 4591 | ||
4592 | /* ucode is running and will send rfkill notifications, | ||
4593 | * no need to poll the killswitch state anymore */ | ||
4594 | cancel_delayed_work(&priv->rfkill_poll); | ||
4595 | |||
6481 | priv->is_open = 1; | 4596 | priv->is_open = 1; |
6482 | IWL_DEBUG_MAC80211("leave\n"); | 4597 | IWL_DEBUG_MAC80211("leave\n"); |
6483 | return 0; | 4598 | return 0; |
6484 | 4599 | ||
6485 | out_release_irq: | 4600 | out_release_irq: |
6486 | free_irq(priv->pci_dev->irq, priv); | ||
6487 | out_disable_msi: | ||
6488 | pci_disable_msi(priv->pci_dev); | ||
6489 | pci_disable_device(priv->pci_dev); | ||
6490 | priv->is_open = 0; | 4601 | priv->is_open = 0; |
6491 | IWL_DEBUG_MAC80211("leave - failed\n"); | 4602 | IWL_DEBUG_MAC80211("leave - failed\n"); |
6492 | return ret; | 4603 | return ret; |
@@ -6494,7 +4605,7 @@ out_disable_msi: | |||
6494 | 4605 | ||
6495 | static void iwl3945_mac_stop(struct ieee80211_hw *hw) | 4606 | static void iwl3945_mac_stop(struct ieee80211_hw *hw) |
6496 | { | 4607 | { |
6497 | struct iwl3945_priv *priv = hw->priv; | 4608 | struct iwl_priv *priv = hw->priv; |
6498 | 4609 | ||
6499 | IWL_DEBUG_MAC80211("enter\n"); | 4610 | IWL_DEBUG_MAC80211("enter\n"); |
6500 | 4611 | ||
@@ -6505,29 +4616,29 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) | |||
6505 | 4616 | ||
6506 | priv->is_open = 0; | 4617 | priv->is_open = 0; |
6507 | 4618 | ||
6508 | if (iwl3945_is_ready_rf(priv)) { | 4619 | if (iwl_is_ready_rf(priv)) { |
6509 | /* stop mac, cancel any scan request and clear | 4620 | /* stop mac, cancel any scan request and clear |
6510 | * RXON_FILTER_ASSOC_MSK BIT | 4621 | * RXON_FILTER_ASSOC_MSK BIT |
6511 | */ | 4622 | */ |
6512 | mutex_lock(&priv->mutex); | 4623 | mutex_lock(&priv->mutex); |
6513 | iwl3945_scan_cancel_timeout(priv, 100); | 4624 | iwl_scan_cancel_timeout(priv, 100); |
6514 | mutex_unlock(&priv->mutex); | 4625 | mutex_unlock(&priv->mutex); |
6515 | } | 4626 | } |
6516 | 4627 | ||
6517 | iwl3945_down(priv); | 4628 | iwl3945_down(priv); |
6518 | 4629 | ||
6519 | flush_workqueue(priv->workqueue); | 4630 | flush_workqueue(priv->workqueue); |
6520 | free_irq(priv->pci_dev->irq, priv); | 4631 | |
6521 | pci_disable_msi(priv->pci_dev); | 4632 | /* start polling the killswitch state again */ |
6522 | pci_save_state(priv->pci_dev); | 4633 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
6523 | pci_disable_device(priv->pci_dev); | 4634 | round_jiffies_relative(2 * HZ)); |
6524 | 4635 | ||
6525 | IWL_DEBUG_MAC80211("leave\n"); | 4636 | IWL_DEBUG_MAC80211("leave\n"); |
6526 | } | 4637 | } |
6527 | 4638 | ||
6528 | static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 4639 | static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
6529 | { | 4640 | { |
6530 | struct iwl3945_priv *priv = hw->priv; | 4641 | struct iwl_priv *priv = hw->priv; |
6531 | 4642 | ||
6532 | IWL_DEBUG_MAC80211("enter\n"); | 4643 | IWL_DEBUG_MAC80211("enter\n"); |
6533 | 4644 | ||
@@ -6544,7 +4655,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
6544 | static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, | 4655 | static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, |
6545 | struct ieee80211_if_init_conf *conf) | 4656 | struct ieee80211_if_init_conf *conf) |
6546 | { | 4657 | { |
6547 | struct iwl3945_priv *priv = hw->priv; | 4658 | struct iwl_priv *priv = hw->priv; |
6548 | unsigned long flags; | 4659 | unsigned long flags; |
6549 | 4660 | ||
6550 | IWL_DEBUG_MAC80211("enter: type %d\n", conf->type); | 4661 | IWL_DEBUG_MAC80211("enter: type %d\n", conf->type); |
@@ -6567,7 +4678,7 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, | |||
6567 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | 4678 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); |
6568 | } | 4679 | } |
6569 | 4680 | ||
6570 | if (iwl3945_is_ready(priv)) | 4681 | if (iwl_is_ready(priv)) |
6571 | iwl3945_set_mode(priv, conf->type); | 4682 | iwl3945_set_mode(priv, conf->type); |
6572 | 4683 | ||
6573 | mutex_unlock(&priv->mutex); | 4684 | mutex_unlock(&priv->mutex); |
@@ -6585,8 +4696,8 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, | |||
6585 | */ | 4696 | */ |
6586 | static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) | 4697 | static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) |
6587 | { | 4698 | { |
6588 | struct iwl3945_priv *priv = hw->priv; | 4699 | struct iwl_priv *priv = hw->priv; |
6589 | const struct iwl3945_channel_info *ch_info; | 4700 | const struct iwl_channel_info *ch_info; |
6590 | struct ieee80211_conf *conf = &hw->conf; | 4701 | struct ieee80211_conf *conf = &hw->conf; |
6591 | unsigned long flags; | 4702 | unsigned long flags; |
6592 | int ret = 0; | 4703 | int ret = 0; |
@@ -6594,13 +4705,13 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
6594 | mutex_lock(&priv->mutex); | 4705 | mutex_lock(&priv->mutex); |
6595 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); | 4706 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
6596 | 4707 | ||
6597 | if (!iwl3945_is_ready(priv)) { | 4708 | if (!iwl_is_ready(priv)) { |
6598 | IWL_DEBUG_MAC80211("leave - not ready\n"); | 4709 | IWL_DEBUG_MAC80211("leave - not ready\n"); |
6599 | ret = -EIO; | 4710 | ret = -EIO; |
6600 | goto out; | 4711 | goto out; |
6601 | } | 4712 | } |
6602 | 4713 | ||
6603 | if (unlikely(!iwl3945_param_disable_hw_scan && | 4714 | if (unlikely(!iwl3945_mod_params.disable_hw_scan && |
6604 | test_bit(STATUS_SCANNING, &priv->status))) { | 4715 | test_bit(STATUS_SCANNING, &priv->status))) { |
6605 | IWL_DEBUG_MAC80211("leave - scanning\n"); | 4716 | IWL_DEBUG_MAC80211("leave - scanning\n"); |
6606 | set_bit(STATUS_CONF_PENDING, &priv->status); | 4717 | set_bit(STATUS_CONF_PENDING, &priv->status); |
@@ -6610,8 +4721,8 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
6610 | 4721 | ||
6611 | spin_lock_irqsave(&priv->lock, flags); | 4722 | spin_lock_irqsave(&priv->lock, flags); |
6612 | 4723 | ||
6613 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, | 4724 | ch_info = iwl_get_channel_info(priv, conf->channel->band, |
6614 | conf->channel->hw_value); | 4725 | conf->channel->hw_value); |
6615 | if (!is_channel_valid(ch_info)) { | 4726 | if (!is_channel_valid(ch_info)) { |
6616 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n", | 4727 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n", |
6617 | conf->channel->hw_value, conf->channel->band); | 4728 | conf->channel->hw_value, conf->channel->band); |
@@ -6646,7 +4757,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
6646 | goto out; | 4757 | goto out; |
6647 | } | 4758 | } |
6648 | 4759 | ||
6649 | if (iwl3945_is_rfkill(priv)) { | 4760 | if (iwl_is_rfkill(priv)) { |
6650 | IWL_DEBUG_MAC80211("leave - RF kill\n"); | 4761 | IWL_DEBUG_MAC80211("leave - RF kill\n"); |
6651 | ret = -EIO; | 4762 | ret = -EIO; |
6652 | goto out; | 4763 | goto out; |
@@ -6654,8 +4765,8 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
6654 | 4765 | ||
6655 | iwl3945_set_rate(priv); | 4766 | iwl3945_set_rate(priv); |
6656 | 4767 | ||
6657 | if (memcmp(&priv->active_rxon, | 4768 | if (memcmp(&priv->active39_rxon, |
6658 | &priv->staging_rxon, sizeof(priv->staging_rxon))) | 4769 | &priv->staging39_rxon, sizeof(priv->staging39_rxon))) |
6659 | iwl3945_commit_rxon(priv); | 4770 | iwl3945_commit_rxon(priv); |
6660 | else | 4771 | else |
6661 | IWL_DEBUG_INFO("No re-sending same RXON configuration.\n"); | 4772 | IWL_DEBUG_INFO("No re-sending same RXON configuration.\n"); |
@@ -6668,7 +4779,7 @@ out: | |||
6668 | return ret; | 4779 | return ret; |
6669 | } | 4780 | } |
6670 | 4781 | ||
6671 | static void iwl3945_config_ap(struct iwl3945_priv *priv) | 4782 | static void iwl3945_config_ap(struct iwl_priv *priv) |
6672 | { | 4783 | { |
6673 | int rc = 0; | 4784 | int rc = 0; |
6674 | 4785 | ||
@@ -6679,44 +4790,45 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6679 | if (!(iwl3945_is_associated(priv))) { | 4790 | if (!(iwl3945_is_associated(priv))) { |
6680 | 4791 | ||
6681 | /* RXON - unassoc (to set timing command) */ | 4792 | /* RXON - unassoc (to set timing command) */ |
6682 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 4793 | priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
6683 | iwl3945_commit_rxon(priv); | 4794 | iwl3945_commit_rxon(priv); |
6684 | 4795 | ||
6685 | /* RXON Timing */ | 4796 | /* RXON Timing */ |
6686 | memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd)); | 4797 | memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); |
6687 | iwl3945_setup_rxon_timing(priv); | 4798 | iwl3945_setup_rxon_timing(priv); |
6688 | rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING, | 4799 | rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, |
6689 | sizeof(priv->rxon_timing), &priv->rxon_timing); | 4800 | sizeof(priv->rxon_timing), |
4801 | &priv->rxon_timing); | ||
6690 | if (rc) | 4802 | if (rc) |
6691 | IWL_WARNING("REPLY_RXON_TIMING failed - " | 4803 | IWL_WARN(priv, "REPLY_RXON_TIMING failed - " |
6692 | "Attempting to continue.\n"); | 4804 | "Attempting to continue.\n"); |
6693 | 4805 | ||
6694 | /* FIXME: what should be the assoc_id for AP? */ | 4806 | /* FIXME: what should be the assoc_id for AP? */ |
6695 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 4807 | priv->staging39_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
6696 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) | 4808 | if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) |
6697 | priv->staging_rxon.flags |= | 4809 | priv->staging39_rxon.flags |= |
6698 | RXON_FLG_SHORT_PREAMBLE_MSK; | 4810 | RXON_FLG_SHORT_PREAMBLE_MSK; |
6699 | else | 4811 | else |
6700 | priv->staging_rxon.flags &= | 4812 | priv->staging39_rxon.flags &= |
6701 | ~RXON_FLG_SHORT_PREAMBLE_MSK; | 4813 | ~RXON_FLG_SHORT_PREAMBLE_MSK; |
6702 | 4814 | ||
6703 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { | 4815 | if (priv->staging39_rxon.flags & RXON_FLG_BAND_24G_MSK) { |
6704 | if (priv->assoc_capability & | 4816 | if (priv->assoc_capability & |
6705 | WLAN_CAPABILITY_SHORT_SLOT_TIME) | 4817 | WLAN_CAPABILITY_SHORT_SLOT_TIME) |
6706 | priv->staging_rxon.flags |= | 4818 | priv->staging39_rxon.flags |= |
6707 | RXON_FLG_SHORT_SLOT_MSK; | 4819 | RXON_FLG_SHORT_SLOT_MSK; |
6708 | else | 4820 | else |
6709 | priv->staging_rxon.flags &= | 4821 | priv->staging39_rxon.flags &= |
6710 | ~RXON_FLG_SHORT_SLOT_MSK; | 4822 | ~RXON_FLG_SHORT_SLOT_MSK; |
6711 | 4823 | ||
6712 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) | 4824 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) |
6713 | priv->staging_rxon.flags &= | 4825 | priv->staging39_rxon.flags &= |
6714 | ~RXON_FLG_SHORT_SLOT_MSK; | 4826 | ~RXON_FLG_SHORT_SLOT_MSK; |
6715 | } | 4827 | } |
6716 | /* restore RXON assoc */ | 4828 | /* restore RXON assoc */ |
6717 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 4829 | priv->staging39_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
6718 | iwl3945_commit_rxon(priv); | 4830 | iwl3945_commit_rxon(priv); |
6719 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); | 4831 | iwl3945_add_station(priv, iwl_bcast_addr, 0, 0); |
6720 | } | 4832 | } |
6721 | iwl3945_send_beacon_cmd(priv); | 4833 | iwl3945_send_beacon_cmd(priv); |
6722 | 4834 | ||
@@ -6727,9 +4839,9 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6727 | 4839 | ||
6728 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | 4840 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, |
6729 | struct ieee80211_vif *vif, | 4841 | struct ieee80211_vif *vif, |
6730 | struct ieee80211_if_conf *conf) | 4842 | struct ieee80211_if_conf *conf) |
6731 | { | 4843 | { |
6732 | struct iwl3945_priv *priv = hw->priv; | 4844 | struct iwl_priv *priv = hw->priv; |
6733 | int rc; | 4845 | int rc; |
6734 | 4846 | ||
6735 | if (conf == NULL) | 4847 | if (conf == NULL) |
@@ -6753,7 +4865,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6753 | return rc; | 4865 | return rc; |
6754 | } | 4866 | } |
6755 | 4867 | ||
6756 | if (!iwl3945_is_alive(priv)) | 4868 | if (!iwl_is_alive(priv)) |
6757 | return -EAGAIN; | 4869 | return -EAGAIN; |
6758 | 4870 | ||
6759 | mutex_lock(&priv->mutex); | 4871 | mutex_lock(&priv->mutex); |
@@ -6781,21 +4893,21 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6781 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); | 4893 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
6782 | } | 4894 | } |
6783 | 4895 | ||
6784 | if (iwl3945_is_rfkill(priv)) | 4896 | if (iwl_is_rfkill(priv)) |
6785 | goto done; | 4897 | goto done; |
6786 | 4898 | ||
6787 | if (conf->bssid && !is_zero_ether_addr(conf->bssid) && | 4899 | if (conf->bssid && !is_zero_ether_addr(conf->bssid) && |
6788 | !is_multicast_ether_addr(conf->bssid)) { | 4900 | !is_multicast_ether_addr(conf->bssid)) { |
6789 | /* If there is currently a HW scan going on in the background | 4901 | /* If there is currently a HW scan going on in the background |
6790 | * then we need to cancel it else the RXON below will fail. */ | 4902 | * then we need to cancel it else the RXON below will fail. */ |
6791 | if (iwl3945_scan_cancel_timeout(priv, 100)) { | 4903 | if (iwl_scan_cancel_timeout(priv, 100)) { |
6792 | IWL_WARNING("Aborted scan still in progress " | 4904 | IWL_WARN(priv, "Aborted scan still in progress " |
6793 | "after 100ms\n"); | 4905 | "after 100ms\n"); |
6794 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 4906 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
6795 | mutex_unlock(&priv->mutex); | 4907 | mutex_unlock(&priv->mutex); |
6796 | return -EAGAIN; | 4908 | return -EAGAIN; |
6797 | } | 4909 | } |
6798 | memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN); | 4910 | memcpy(priv->staging39_rxon.bssid_addr, conf->bssid, ETH_ALEN); |
6799 | 4911 | ||
6800 | /* TODO: Audit driver for usage of these members and see | 4912 | /* TODO: Audit driver for usage of these members and see |
6801 | * if mac80211 deprecates them (priv->bssid looks like it | 4913 | * if mac80211 deprecates them (priv->bssid looks like it |
@@ -6809,12 +4921,12 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6809 | rc = iwl3945_commit_rxon(priv); | 4921 | rc = iwl3945_commit_rxon(priv); |
6810 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) | 4922 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) |
6811 | iwl3945_add_station(priv, | 4923 | iwl3945_add_station(priv, |
6812 | priv->active_rxon.bssid_addr, 1, 0); | 4924 | priv->active39_rxon.bssid_addr, 1, 0); |
6813 | } | 4925 | } |
6814 | 4926 | ||
6815 | } else { | 4927 | } else { |
6816 | iwl3945_scan_cancel_timeout(priv, 100); | 4928 | iwl_scan_cancel_timeout(priv, 100); |
6817 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 4929 | priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
6818 | iwl3945_commit_rxon(priv); | 4930 | iwl3945_commit_rxon(priv); |
6819 | } | 4931 | } |
6820 | 4932 | ||
@@ -6830,8 +4942,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, | |||
6830 | unsigned int *total_flags, | 4942 | unsigned int *total_flags, |
6831 | int mc_count, struct dev_addr_list *mc_list) | 4943 | int mc_count, struct dev_addr_list *mc_list) |
6832 | { | 4944 | { |
6833 | struct iwl3945_priv *priv = hw->priv; | 4945 | struct iwl_priv *priv = hw->priv; |
6834 | __le32 *filter_flags = &priv->staging_rxon.filter_flags; | 4946 | __le32 *filter_flags = &priv->staging39_rxon.filter_flags; |
6835 | 4947 | ||
6836 | IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", | 4948 | IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n", |
6837 | changed_flags, *total_flags); | 4949 | changed_flags, *total_flags); |
@@ -6874,15 +4986,15 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, | |||
6874 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | 4986 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, |
6875 | struct ieee80211_if_init_conf *conf) | 4987 | struct ieee80211_if_init_conf *conf) |
6876 | { | 4988 | { |
6877 | struct iwl3945_priv *priv = hw->priv; | 4989 | struct iwl_priv *priv = hw->priv; |
6878 | 4990 | ||
6879 | IWL_DEBUG_MAC80211("enter\n"); | 4991 | IWL_DEBUG_MAC80211("enter\n"); |
6880 | 4992 | ||
6881 | mutex_lock(&priv->mutex); | 4993 | mutex_lock(&priv->mutex); |
6882 | 4994 | ||
6883 | if (iwl3945_is_ready_rf(priv)) { | 4995 | if (iwl_is_ready_rf(priv)) { |
6884 | iwl3945_scan_cancel_timeout(priv, 100); | 4996 | iwl_scan_cancel_timeout(priv, 100); |
6885 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 4997 | priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
6886 | iwl3945_commit_rxon(priv); | 4998 | iwl3945_commit_rxon(priv); |
6887 | } | 4999 | } |
6888 | if (priv->vif == conf->vif) { | 5000 | if (priv->vif == conf->vif) { |
@@ -6901,7 +5013,7 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw, | |||
6901 | struct ieee80211_bss_conf *bss_conf, | 5013 | struct ieee80211_bss_conf *bss_conf, |
6902 | u32 changes) | 5014 | u32 changes) |
6903 | { | 5015 | { |
6904 | struct iwl3945_priv *priv = hw->priv; | 5016 | struct iwl_priv *priv = hw->priv; |
6905 | 5017 | ||
6906 | IWL_DEBUG_MAC80211("changes = 0x%X\n", changes); | 5018 | IWL_DEBUG_MAC80211("changes = 0x%X\n", changes); |
6907 | 5019 | ||
@@ -6909,17 +5021,17 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw, | |||
6909 | IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n", | 5021 | IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n", |
6910 | bss_conf->use_short_preamble); | 5022 | bss_conf->use_short_preamble); |
6911 | if (bss_conf->use_short_preamble) | 5023 | if (bss_conf->use_short_preamble) |
6912 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 5024 | priv->staging39_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
6913 | else | 5025 | else |
6914 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | 5026 | priv->staging39_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; |
6915 | } | 5027 | } |
6916 | 5028 | ||
6917 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | 5029 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { |
6918 | IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot); | 5030 | IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot); |
6919 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) | 5031 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) |
6920 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | 5032 | priv->staging39_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; |
6921 | else | 5033 | else |
6922 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 5034 | priv->staging39_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
6923 | } | 5035 | } |
6924 | 5036 | ||
6925 | if (changes & BSS_CHANGED_ASSOC) { | 5037 | if (changes & BSS_CHANGED_ASSOC) { |
@@ -6931,10 +5043,9 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw, | |||
6931 | if (bss_conf->assoc) { | 5043 | if (bss_conf->assoc) { |
6932 | priv->assoc_id = bss_conf->aid; | 5044 | priv->assoc_id = bss_conf->aid; |
6933 | priv->beacon_int = bss_conf->beacon_int; | 5045 | priv->beacon_int = bss_conf->beacon_int; |
6934 | priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF; | 5046 | priv->timestamp = bss_conf->timestamp; |
6935 | priv->timestamp1 = (bss_conf->timestamp >> 32) & | ||
6936 | 0xFFFFFFFF; | ||
6937 | priv->assoc_capability = bss_conf->assoc_capability; | 5047 | priv->assoc_capability = bss_conf->assoc_capability; |
5048 | priv->power_data.dtim_period = bss_conf->dtim_period; | ||
6938 | priv->next_scan_jiffies = jiffies + | 5049 | priv->next_scan_jiffies = jiffies + |
6939 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | 5050 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; |
6940 | mutex_lock(&priv->mutex); | 5051 | mutex_lock(&priv->mutex); |
@@ -6955,7 +5066,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
6955 | { | 5066 | { |
6956 | int rc = 0; | 5067 | int rc = 0; |
6957 | unsigned long flags; | 5068 | unsigned long flags; |
6958 | struct iwl3945_priv *priv = hw->priv; | 5069 | struct iwl_priv *priv = hw->priv; |
6959 | DECLARE_SSID_BUF(ssid_buf); | 5070 | DECLARE_SSID_BUF(ssid_buf); |
6960 | 5071 | ||
6961 | IWL_DEBUG_MAC80211("enter\n"); | 5072 | IWL_DEBUG_MAC80211("enter\n"); |
@@ -6963,7 +5074,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
6963 | mutex_lock(&priv->mutex); | 5074 | mutex_lock(&priv->mutex); |
6964 | spin_lock_irqsave(&priv->lock, flags); | 5075 | spin_lock_irqsave(&priv->lock, flags); |
6965 | 5076 | ||
6966 | if (!iwl3945_is_ready_rf(priv)) { | 5077 | if (!iwl_is_ready_rf(priv)) { |
6967 | rc = -EIO; | 5078 | rc = -EIO; |
6968 | IWL_DEBUG_MAC80211("leave - not ready or exit pending\n"); | 5079 | IWL_DEBUG_MAC80211("leave - not ready or exit pending\n"); |
6969 | goto out_unlock; | 5080 | goto out_unlock; |
@@ -7005,24 +5116,23 @@ out_unlock: | |||
7005 | } | 5116 | } |
7006 | 5117 | ||
7007 | static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 5118 | static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
7008 | const u8 *local_addr, const u8 *addr, | 5119 | struct ieee80211_vif *vif, |
7009 | struct ieee80211_key_conf *key) | 5120 | struct ieee80211_sta *sta, |
5121 | struct ieee80211_key_conf *key) | ||
7010 | { | 5122 | { |
7011 | struct iwl3945_priv *priv = hw->priv; | 5123 | struct iwl_priv *priv = hw->priv; |
7012 | int rc = 0; | 5124 | const u8 *addr; |
5125 | int ret; | ||
7013 | u8 sta_id; | 5126 | u8 sta_id; |
7014 | 5127 | ||
7015 | IWL_DEBUG_MAC80211("enter\n"); | 5128 | IWL_DEBUG_MAC80211("enter\n"); |
7016 | 5129 | ||
7017 | if (!iwl3945_param_hwcrypto) { | 5130 | if (iwl3945_mod_params.sw_crypto) { |
7018 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); | 5131 | IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); |
7019 | return -EOPNOTSUPP; | 5132 | return -EOPNOTSUPP; |
7020 | } | 5133 | } |
7021 | 5134 | ||
7022 | if (is_zero_ether_addr(addr)) | 5135 | addr = sta ? sta->addr : iwl_bcast_addr; |
7023 | /* only support pairwise keys */ | ||
7024 | return -EOPNOTSUPP; | ||
7025 | |||
7026 | sta_id = iwl3945_hw_find_station(priv, addr); | 5136 | sta_id = iwl3945_hw_find_station(priv, addr); |
7027 | if (sta_id == IWL_INVALID_STATION) { | 5137 | if (sta_id == IWL_INVALID_STATION) { |
7028 | IWL_DEBUG_MAC80211("leave - %pM not in station map.\n", | 5138 | IWL_DEBUG_MAC80211("leave - %pM not in station map.\n", |
@@ -7032,12 +5142,12 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
7032 | 5142 | ||
7033 | mutex_lock(&priv->mutex); | 5143 | mutex_lock(&priv->mutex); |
7034 | 5144 | ||
7035 | iwl3945_scan_cancel_timeout(priv, 100); | 5145 | iwl_scan_cancel_timeout(priv, 100); |
7036 | 5146 | ||
7037 | switch (cmd) { | 5147 | switch (cmd) { |
7038 | case SET_KEY: | 5148 | case SET_KEY: |
7039 | rc = iwl3945_update_sta_key_info(priv, key, sta_id); | 5149 | ret = iwl3945_update_sta_key_info(priv, key, sta_id); |
7040 | if (!rc) { | 5150 | if (!ret) { |
7041 | iwl3945_set_rxon_hwcrypto(priv, 1); | 5151 | iwl3945_set_rxon_hwcrypto(priv, 1); |
7042 | iwl3945_commit_rxon(priv); | 5152 | iwl3945_commit_rxon(priv); |
7043 | key->hw_key_idx = sta_id; | 5153 | key->hw_key_idx = sta_id; |
@@ -7046,33 +5156,33 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
7046 | } | 5156 | } |
7047 | break; | 5157 | break; |
7048 | case DISABLE_KEY: | 5158 | case DISABLE_KEY: |
7049 | rc = iwl3945_clear_sta_key_info(priv, sta_id); | 5159 | ret = iwl3945_clear_sta_key_info(priv, sta_id); |
7050 | if (!rc) { | 5160 | if (!ret) { |
7051 | iwl3945_set_rxon_hwcrypto(priv, 0); | 5161 | iwl3945_set_rxon_hwcrypto(priv, 0); |
7052 | iwl3945_commit_rxon(priv); | 5162 | iwl3945_commit_rxon(priv); |
7053 | IWL_DEBUG_MAC80211("disable hwcrypto key\n"); | 5163 | IWL_DEBUG_MAC80211("disable hwcrypto key\n"); |
7054 | } | 5164 | } |
7055 | break; | 5165 | break; |
7056 | default: | 5166 | default: |
7057 | rc = -EINVAL; | 5167 | ret = -EINVAL; |
7058 | } | 5168 | } |
7059 | 5169 | ||
7060 | IWL_DEBUG_MAC80211("leave\n"); | 5170 | IWL_DEBUG_MAC80211("leave\n"); |
7061 | mutex_unlock(&priv->mutex); | 5171 | mutex_unlock(&priv->mutex); |
7062 | 5172 | ||
7063 | return rc; | 5173 | return ret; |
7064 | } | 5174 | } |
7065 | 5175 | ||
7066 | static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | 5176 | static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, |
7067 | const struct ieee80211_tx_queue_params *params) | 5177 | const struct ieee80211_tx_queue_params *params) |
7068 | { | 5178 | { |
7069 | struct iwl3945_priv *priv = hw->priv; | 5179 | struct iwl_priv *priv = hw->priv; |
7070 | unsigned long flags; | 5180 | unsigned long flags; |
7071 | int q; | 5181 | int q; |
7072 | 5182 | ||
7073 | IWL_DEBUG_MAC80211("enter\n"); | 5183 | IWL_DEBUG_MAC80211("enter\n"); |
7074 | 5184 | ||
7075 | if (!iwl3945_is_ready_rf(priv)) { | 5185 | if (!iwl_is_ready_rf(priv)) { |
7076 | IWL_DEBUG_MAC80211("leave - RF not ready\n"); | 5186 | IWL_DEBUG_MAC80211("leave - RF not ready\n"); |
7077 | return -EIO; | 5187 | return -EIO; |
7078 | } | 5188 | } |
@@ -7112,15 +5222,15 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
7112 | static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, | 5222 | static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, |
7113 | struct ieee80211_tx_queue_stats *stats) | 5223 | struct ieee80211_tx_queue_stats *stats) |
7114 | { | 5224 | { |
7115 | struct iwl3945_priv *priv = hw->priv; | 5225 | struct iwl_priv *priv = hw->priv; |
7116 | int i, avail; | 5226 | int i, avail; |
7117 | struct iwl3945_tx_queue *txq; | 5227 | struct iwl_tx_queue *txq; |
7118 | struct iwl3945_queue *q; | 5228 | struct iwl_queue *q; |
7119 | unsigned long flags; | 5229 | unsigned long flags; |
7120 | 5230 | ||
7121 | IWL_DEBUG_MAC80211("enter\n"); | 5231 | IWL_DEBUG_MAC80211("enter\n"); |
7122 | 5232 | ||
7123 | if (!iwl3945_is_ready_rf(priv)) { | 5233 | if (!iwl_is_ready_rf(priv)) { |
7124 | IWL_DEBUG_MAC80211("leave - RF not ready\n"); | 5234 | IWL_DEBUG_MAC80211("leave - RF not ready\n"); |
7125 | return -EIO; | 5235 | return -EIO; |
7126 | } | 5236 | } |
@@ -7130,7 +5240,7 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
7130 | for (i = 0; i < AC_NUM; i++) { | 5240 | for (i = 0; i < AC_NUM; i++) { |
7131 | txq = &priv->txq[i]; | 5241 | txq = &priv->txq[i]; |
7132 | q = &txq->q; | 5242 | q = &txq->q; |
7133 | avail = iwl3945_queue_space(q); | 5243 | avail = iwl_queue_space(q); |
7134 | 5244 | ||
7135 | stats[i].len = q->n_window - avail; | 5245 | stats[i].len = q->n_window - avail; |
7136 | stats[i].limit = q->n_window - q->high_mark; | 5246 | stats[i].limit = q->n_window - q->high_mark; |
@@ -7144,29 +5254,19 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
7144 | return 0; | 5254 | return 0; |
7145 | } | 5255 | } |
7146 | 5256 | ||
7147 | static int iwl3945_mac_get_stats(struct ieee80211_hw *hw, | ||
7148 | struct ieee80211_low_level_stats *stats) | ||
7149 | { | ||
7150 | IWL_DEBUG_MAC80211("enter\n"); | ||
7151 | IWL_DEBUG_MAC80211("leave\n"); | ||
7152 | |||
7153 | return 0; | ||
7154 | } | ||
7155 | |||
7156 | static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | 5257 | static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) |
7157 | { | 5258 | { |
7158 | struct iwl3945_priv *priv = hw->priv; | 5259 | struct iwl_priv *priv = hw->priv; |
7159 | unsigned long flags; | 5260 | unsigned long flags; |
7160 | 5261 | ||
7161 | mutex_lock(&priv->mutex); | 5262 | mutex_lock(&priv->mutex); |
7162 | IWL_DEBUG_MAC80211("enter\n"); | 5263 | IWL_DEBUG_MAC80211("enter\n"); |
7163 | 5264 | ||
7164 | iwl3945_reset_qos(priv); | 5265 | iwl_reset_qos(priv); |
7165 | 5266 | ||
7166 | spin_lock_irqsave(&priv->lock, flags); | 5267 | spin_lock_irqsave(&priv->lock, flags); |
7167 | priv->assoc_id = 0; | 5268 | priv->assoc_id = 0; |
7168 | priv->assoc_capability = 0; | 5269 | priv->assoc_capability = 0; |
7169 | priv->call_post_assoc_from_beacon = 0; | ||
7170 | 5270 | ||
7171 | /* new association get rid of ibss beacon skb */ | 5271 | /* new association get rid of ibss beacon skb */ |
7172 | if (priv->ibss_beacon) | 5272 | if (priv->ibss_beacon) |
@@ -7175,14 +5275,13 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7175 | priv->ibss_beacon = NULL; | 5275 | priv->ibss_beacon = NULL; |
7176 | 5276 | ||
7177 | priv->beacon_int = priv->hw->conf.beacon_int; | 5277 | priv->beacon_int = priv->hw->conf.beacon_int; |
7178 | priv->timestamp1 = 0; | 5278 | priv->timestamp = 0; |
7179 | priv->timestamp0 = 0; | ||
7180 | if ((priv->iw_mode == NL80211_IFTYPE_STATION)) | 5279 | if ((priv->iw_mode == NL80211_IFTYPE_STATION)) |
7181 | priv->beacon_int = 0; | 5280 | priv->beacon_int = 0; |
7182 | 5281 | ||
7183 | spin_unlock_irqrestore(&priv->lock, flags); | 5282 | spin_unlock_irqrestore(&priv->lock, flags); |
7184 | 5283 | ||
7185 | if (!iwl3945_is_ready_rf(priv)) { | 5284 | if (!iwl_is_ready_rf(priv)) { |
7186 | IWL_DEBUG_MAC80211("leave - not ready\n"); | 5285 | IWL_DEBUG_MAC80211("leave - not ready\n"); |
7187 | mutex_unlock(&priv->mutex); | 5286 | mutex_unlock(&priv->mutex); |
7188 | return; | 5287 | return; |
@@ -7192,8 +5291,8 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7192 | * clear RXON_FILTER_ASSOC_MSK bit | 5291 | * clear RXON_FILTER_ASSOC_MSK bit |
7193 | */ | 5292 | */ |
7194 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | 5293 | if (priv->iw_mode != NL80211_IFTYPE_AP) { |
7195 | iwl3945_scan_cancel_timeout(priv, 100); | 5294 | iwl_scan_cancel_timeout(priv, 100); |
7196 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 5295 | priv->staging39_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
7197 | iwl3945_commit_rxon(priv); | 5296 | iwl3945_commit_rxon(priv); |
7198 | } | 5297 | } |
7199 | 5298 | ||
@@ -7215,12 +5314,12 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7215 | 5314 | ||
7216 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | 5315 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) |
7217 | { | 5316 | { |
7218 | struct iwl3945_priv *priv = hw->priv; | 5317 | struct iwl_priv *priv = hw->priv; |
7219 | unsigned long flags; | 5318 | unsigned long flags; |
7220 | 5319 | ||
7221 | IWL_DEBUG_MAC80211("enter\n"); | 5320 | IWL_DEBUG_MAC80211("enter\n"); |
7222 | 5321 | ||
7223 | if (!iwl3945_is_ready_rf(priv)) { | 5322 | if (!iwl_is_ready_rf(priv)) { |
7224 | IWL_DEBUG_MAC80211("leave - RF not ready\n"); | 5323 | IWL_DEBUG_MAC80211("leave - RF not ready\n"); |
7225 | return -EIO; | 5324 | return -EIO; |
7226 | } | 5325 | } |
@@ -7242,7 +5341,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7242 | IWL_DEBUG_MAC80211("leave\n"); | 5341 | IWL_DEBUG_MAC80211("leave\n"); |
7243 | spin_unlock_irqrestore(&priv->lock, flags); | 5342 | spin_unlock_irqrestore(&priv->lock, flags); |
7244 | 5343 | ||
7245 | iwl3945_reset_qos(priv); | 5344 | iwl_reset_qos(priv); |
7246 | 5345 | ||
7247 | iwl3945_post_associate(priv); | 5346 | iwl3945_post_associate(priv); |
7248 | 5347 | ||
@@ -7256,7 +5355,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7256 | * | 5355 | * |
7257 | *****************************************************************************/ | 5356 | *****************************************************************************/ |
7258 | 5357 | ||
7259 | #ifdef CONFIG_IWL3945_DEBUG | 5358 | #ifdef CONFIG_IWLWIFI_DEBUG |
7260 | 5359 | ||
7261 | /* | 5360 | /* |
7262 | * The following adds a new attribute to the sysfs representation | 5361 | * The following adds a new attribute to the sysfs representation |
@@ -7265,38 +5364,41 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7265 | * | 5364 | * |
7266 | * See the level definitions in iwl for details. | 5365 | * See the level definitions in iwl for details. |
7267 | */ | 5366 | */ |
7268 | 5367 | static ssize_t show_debug_level(struct device *d, | |
7269 | static ssize_t show_debug_level(struct device_driver *d, char *buf) | 5368 | struct device_attribute *attr, char *buf) |
7270 | { | 5369 | { |
7271 | return sprintf(buf, "0x%08X\n", iwl3945_debug_level); | 5370 | struct iwl_priv *priv = d->driver_data; |
5371 | |||
5372 | return sprintf(buf, "0x%08X\n", priv->debug_level); | ||
7272 | } | 5373 | } |
7273 | static ssize_t store_debug_level(struct device_driver *d, | 5374 | static ssize_t store_debug_level(struct device *d, |
5375 | struct device_attribute *attr, | ||
7274 | const char *buf, size_t count) | 5376 | const char *buf, size_t count) |
7275 | { | 5377 | { |
7276 | char *p = (char *)buf; | 5378 | struct iwl_priv *priv = d->driver_data; |
7277 | u32 val; | 5379 | unsigned long val; |
5380 | int ret; | ||
7278 | 5381 | ||
7279 | val = simple_strtoul(p, &p, 0); | 5382 | ret = strict_strtoul(buf, 0, &val); |
7280 | if (p == buf) | 5383 | if (ret) |
7281 | printk(KERN_INFO DRV_NAME | 5384 | IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf); |
7282 | ": %s is not in hex or decimal form.\n", buf); | ||
7283 | else | 5385 | else |
7284 | iwl3945_debug_level = val; | 5386 | priv->debug_level = val; |
7285 | 5387 | ||
7286 | return strnlen(buf, count); | 5388 | return strnlen(buf, count); |
7287 | } | 5389 | } |
7288 | 5390 | ||
7289 | static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | 5391 | static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, |
7290 | show_debug_level, store_debug_level); | 5392 | show_debug_level, store_debug_level); |
7291 | 5393 | ||
7292 | #endif /* CONFIG_IWL3945_DEBUG */ | 5394 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
7293 | 5395 | ||
7294 | static ssize_t show_temperature(struct device *d, | 5396 | static ssize_t show_temperature(struct device *d, |
7295 | struct device_attribute *attr, char *buf) | 5397 | struct device_attribute *attr, char *buf) |
7296 | { | 5398 | { |
7297 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5399 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7298 | 5400 | ||
7299 | if (!iwl3945_is_alive(priv)) | 5401 | if (!iwl_is_alive(priv)) |
7300 | return -EAGAIN; | 5402 | return -EAGAIN; |
7301 | 5403 | ||
7302 | return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv)); | 5404 | return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv)); |
@@ -7307,22 +5409,21 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | |||
7307 | static ssize_t show_tx_power(struct device *d, | 5409 | static ssize_t show_tx_power(struct device *d, |
7308 | struct device_attribute *attr, char *buf) | 5410 | struct device_attribute *attr, char *buf) |
7309 | { | 5411 | { |
7310 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5412 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7311 | return sprintf(buf, "%d\n", priv->user_txpower_limit); | 5413 | return sprintf(buf, "%d\n", priv->tx_power_user_lmt); |
7312 | } | 5414 | } |
7313 | 5415 | ||
7314 | static ssize_t store_tx_power(struct device *d, | 5416 | static ssize_t store_tx_power(struct device *d, |
7315 | struct device_attribute *attr, | 5417 | struct device_attribute *attr, |
7316 | const char *buf, size_t count) | 5418 | const char *buf, size_t count) |
7317 | { | 5419 | { |
7318 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5420 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7319 | char *p = (char *)buf; | 5421 | char *p = (char *)buf; |
7320 | u32 val; | 5422 | u32 val; |
7321 | 5423 | ||
7322 | val = simple_strtoul(p, &p, 10); | 5424 | val = simple_strtoul(p, &p, 10); |
7323 | if (p == buf) | 5425 | if (p == buf) |
7324 | printk(KERN_INFO DRV_NAME | 5426 | IWL_INFO(priv, ": %s is not in decimal form.\n", buf); |
7325 | ": %s is not in decimal form.\n", buf); | ||
7326 | else | 5427 | else |
7327 | iwl3945_hw_reg_set_txpower(priv, val); | 5428 | iwl3945_hw_reg_set_txpower(priv, val); |
7328 | 5429 | ||
@@ -7334,27 +5435,27 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); | |||
7334 | static ssize_t show_flags(struct device *d, | 5435 | static ssize_t show_flags(struct device *d, |
7335 | struct device_attribute *attr, char *buf) | 5436 | struct device_attribute *attr, char *buf) |
7336 | { | 5437 | { |
7337 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5438 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7338 | 5439 | ||
7339 | return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); | 5440 | return sprintf(buf, "0x%04X\n", priv->active39_rxon.flags); |
7340 | } | 5441 | } |
7341 | 5442 | ||
7342 | static ssize_t store_flags(struct device *d, | 5443 | static ssize_t store_flags(struct device *d, |
7343 | struct device_attribute *attr, | 5444 | struct device_attribute *attr, |
7344 | const char *buf, size_t count) | 5445 | const char *buf, size_t count) |
7345 | { | 5446 | { |
7346 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5447 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7347 | u32 flags = simple_strtoul(buf, NULL, 0); | 5448 | u32 flags = simple_strtoul(buf, NULL, 0); |
7348 | 5449 | ||
7349 | mutex_lock(&priv->mutex); | 5450 | mutex_lock(&priv->mutex); |
7350 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { | 5451 | if (le32_to_cpu(priv->staging39_rxon.flags) != flags) { |
7351 | /* Cancel any currently running scans... */ | 5452 | /* Cancel any currently running scans... */ |
7352 | if (iwl3945_scan_cancel_timeout(priv, 100)) | 5453 | if (iwl_scan_cancel_timeout(priv, 100)) |
7353 | IWL_WARNING("Could not cancel scan.\n"); | 5454 | IWL_WARN(priv, "Could not cancel scan.\n"); |
7354 | else { | 5455 | else { |
7355 | IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", | 5456 | IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", |
7356 | flags); | 5457 | flags); |
7357 | priv->staging_rxon.flags = cpu_to_le32(flags); | 5458 | priv->staging39_rxon.flags = cpu_to_le32(flags); |
7358 | iwl3945_commit_rxon(priv); | 5459 | iwl3945_commit_rxon(priv); |
7359 | } | 5460 | } |
7360 | } | 5461 | } |
@@ -7368,28 +5469,28 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); | |||
7368 | static ssize_t show_filter_flags(struct device *d, | 5469 | static ssize_t show_filter_flags(struct device *d, |
7369 | struct device_attribute *attr, char *buf) | 5470 | struct device_attribute *attr, char *buf) |
7370 | { | 5471 | { |
7371 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5472 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7372 | 5473 | ||
7373 | return sprintf(buf, "0x%04X\n", | 5474 | return sprintf(buf, "0x%04X\n", |
7374 | le32_to_cpu(priv->active_rxon.filter_flags)); | 5475 | le32_to_cpu(priv->active39_rxon.filter_flags)); |
7375 | } | 5476 | } |
7376 | 5477 | ||
7377 | static ssize_t store_filter_flags(struct device *d, | 5478 | static ssize_t store_filter_flags(struct device *d, |
7378 | struct device_attribute *attr, | 5479 | struct device_attribute *attr, |
7379 | const char *buf, size_t count) | 5480 | const char *buf, size_t count) |
7380 | { | 5481 | { |
7381 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5482 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7382 | u32 filter_flags = simple_strtoul(buf, NULL, 0); | 5483 | u32 filter_flags = simple_strtoul(buf, NULL, 0); |
7383 | 5484 | ||
7384 | mutex_lock(&priv->mutex); | 5485 | mutex_lock(&priv->mutex); |
7385 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { | 5486 | if (le32_to_cpu(priv->staging39_rxon.filter_flags) != filter_flags) { |
7386 | /* Cancel any currently running scans... */ | 5487 | /* Cancel any currently running scans... */ |
7387 | if (iwl3945_scan_cancel_timeout(priv, 100)) | 5488 | if (iwl_scan_cancel_timeout(priv, 100)) |
7388 | IWL_WARNING("Could not cancel scan.\n"); | 5489 | IWL_WARN(priv, "Could not cancel scan.\n"); |
7389 | else { | 5490 | else { |
7390 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " | 5491 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " |
7391 | "0x%04X\n", filter_flags); | 5492 | "0x%04X\n", filter_flags); |
7392 | priv->staging_rxon.filter_flags = | 5493 | priv->staging39_rxon.filter_flags = |
7393 | cpu_to_le32(filter_flags); | 5494 | cpu_to_le32(filter_flags); |
7394 | iwl3945_commit_rxon(priv); | 5495 | iwl3945_commit_rxon(priv); |
7395 | } | 5496 | } |
@@ -7407,8 +5508,8 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | |||
7407 | static ssize_t show_measurement(struct device *d, | 5508 | static ssize_t show_measurement(struct device *d, |
7408 | struct device_attribute *attr, char *buf) | 5509 | struct device_attribute *attr, char *buf) |
7409 | { | 5510 | { |
7410 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5511 | struct iwl_priv *priv = dev_get_drvdata(d); |
7411 | struct iwl3945_spectrum_notification measure_report; | 5512 | struct iwl_spectrum_notification measure_report; |
7412 | u32 size = sizeof(measure_report), len = 0, ofs = 0; | 5513 | u32 size = sizeof(measure_report), len = 0, ofs = 0; |
7413 | u8 *data = (u8 *)&measure_report; | 5514 | u8 *data = (u8 *)&measure_report; |
7414 | unsigned long flags; | 5515 | unsigned long flags; |
@@ -7440,9 +5541,9 @@ static ssize_t store_measurement(struct device *d, | |||
7440 | struct device_attribute *attr, | 5541 | struct device_attribute *attr, |
7441 | const char *buf, size_t count) | 5542 | const char *buf, size_t count) |
7442 | { | 5543 | { |
7443 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5544 | struct iwl_priv *priv = dev_get_drvdata(d); |
7444 | struct ieee80211_measurement_params params = { | 5545 | struct ieee80211_measurement_params params = { |
7445 | .channel = le16_to_cpu(priv->active_rxon.channel), | 5546 | .channel = le16_to_cpu(priv->active39_rxon.channel), |
7446 | .start_time = cpu_to_le64(priv->last_tsf), | 5547 | .start_time = cpu_to_le64(priv->last_tsf), |
7447 | .duration = cpu_to_le16(1), | 5548 | .duration = cpu_to_le16(1), |
7448 | }; | 5549 | }; |
@@ -7479,7 +5580,7 @@ static ssize_t store_retry_rate(struct device *d, | |||
7479 | struct device_attribute *attr, | 5580 | struct device_attribute *attr, |
7480 | const char *buf, size_t count) | 5581 | const char *buf, size_t count) |
7481 | { | 5582 | { |
7482 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5583 | struct iwl_priv *priv = dev_get_drvdata(d); |
7483 | 5584 | ||
7484 | priv->retry_rate = simple_strtoul(buf, NULL, 0); | 5585 | priv->retry_rate = simple_strtoul(buf, NULL, 0); |
7485 | if (priv->retry_rate <= 0) | 5586 | if (priv->retry_rate <= 0) |
@@ -7491,7 +5592,7 @@ static ssize_t store_retry_rate(struct device *d, | |||
7491 | static ssize_t show_retry_rate(struct device *d, | 5592 | static ssize_t show_retry_rate(struct device *d, |
7492 | struct device_attribute *attr, char *buf) | 5593 | struct device_attribute *attr, char *buf) |
7493 | { | 5594 | { |
7494 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5595 | struct iwl_priv *priv = dev_get_drvdata(d); |
7495 | return sprintf(buf, "%d", priv->retry_rate); | 5596 | return sprintf(buf, "%d", priv->retry_rate); |
7496 | } | 5597 | } |
7497 | 5598 | ||
@@ -7502,20 +5603,21 @@ static ssize_t store_power_level(struct device *d, | |||
7502 | struct device_attribute *attr, | 5603 | struct device_attribute *attr, |
7503 | const char *buf, size_t count) | 5604 | const char *buf, size_t count) |
7504 | { | 5605 | { |
7505 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5606 | struct iwl_priv *priv = dev_get_drvdata(d); |
7506 | int rc; | 5607 | int rc; |
7507 | int mode; | 5608 | int mode; |
7508 | 5609 | ||
7509 | mode = simple_strtoul(buf, NULL, 0); | 5610 | mode = simple_strtoul(buf, NULL, 0); |
7510 | mutex_lock(&priv->mutex); | 5611 | mutex_lock(&priv->mutex); |
7511 | 5612 | ||
7512 | if (!iwl3945_is_ready(priv)) { | 5613 | if (!iwl_is_ready(priv)) { |
7513 | rc = -EAGAIN; | 5614 | rc = -EAGAIN; |
7514 | goto out; | 5615 | goto out; |
7515 | } | 5616 | } |
7516 | 5617 | ||
7517 | if ((mode < 1) || (mode > IWL_POWER_LIMIT) || (mode == IWL_POWER_AC)) | 5618 | if ((mode < 1) || (mode > IWL39_POWER_LIMIT) || |
7518 | mode = IWL_POWER_AC; | 5619 | (mode == IWL39_POWER_AC)) |
5620 | mode = IWL39_POWER_AC; | ||
7519 | else | 5621 | else |
7520 | mode |= IWL_POWER_ENABLED; | 5622 | mode |= IWL_POWER_ENABLED; |
7521 | 5623 | ||
@@ -7556,17 +5658,17 @@ static const s32 period_duration[] = { | |||
7556 | static ssize_t show_power_level(struct device *d, | 5658 | static ssize_t show_power_level(struct device *d, |
7557 | struct device_attribute *attr, char *buf) | 5659 | struct device_attribute *attr, char *buf) |
7558 | { | 5660 | { |
7559 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5661 | struct iwl_priv *priv = dev_get_drvdata(d); |
7560 | int level = IWL_POWER_LEVEL(priv->power_mode); | 5662 | int level = IWL_POWER_LEVEL(priv->power_mode); |
7561 | char *p = buf; | 5663 | char *p = buf; |
7562 | 5664 | ||
7563 | p += sprintf(p, "%d ", level); | 5665 | p += sprintf(p, "%d ", level); |
7564 | switch (level) { | 5666 | switch (level) { |
7565 | case IWL_POWER_MODE_CAM: | 5667 | case IWL_POWER_MODE_CAM: |
7566 | case IWL_POWER_AC: | 5668 | case IWL39_POWER_AC: |
7567 | p += sprintf(p, "(AC)"); | 5669 | p += sprintf(p, "(AC)"); |
7568 | break; | 5670 | break; |
7569 | case IWL_POWER_BATTERY: | 5671 | case IWL39_POWER_BATTERY: |
7570 | p += sprintf(p, "(BATTERY)"); | 5672 | p += sprintf(p, "(BATTERY)"); |
7571 | break; | 5673 | break; |
7572 | default: | 5674 | default: |
@@ -7600,17 +5702,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | |||
7600 | static ssize_t show_statistics(struct device *d, | 5702 | static ssize_t show_statistics(struct device *d, |
7601 | struct device_attribute *attr, char *buf) | 5703 | struct device_attribute *attr, char *buf) |
7602 | { | 5704 | { |
7603 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5705 | struct iwl_priv *priv = dev_get_drvdata(d); |
7604 | u32 size = sizeof(struct iwl3945_notif_statistics); | 5706 | u32 size = sizeof(struct iwl3945_notif_statistics); |
7605 | u32 len = 0, ofs = 0; | 5707 | u32 len = 0, ofs = 0; |
7606 | u8 *data = (u8 *)&priv->statistics; | 5708 | u8 *data = (u8 *)&priv->statistics_39; |
7607 | int rc = 0; | 5709 | int rc = 0; |
7608 | 5710 | ||
7609 | if (!iwl3945_is_alive(priv)) | 5711 | if (!iwl_is_alive(priv)) |
7610 | return -EAGAIN; | 5712 | return -EAGAIN; |
7611 | 5713 | ||
7612 | mutex_lock(&priv->mutex); | 5714 | mutex_lock(&priv->mutex); |
7613 | rc = iwl3945_send_statistics_request(priv); | 5715 | rc = iwl_send_statistics_request(priv, 0); |
7614 | mutex_unlock(&priv->mutex); | 5716 | mutex_unlock(&priv->mutex); |
7615 | 5717 | ||
7616 | if (rc) { | 5718 | if (rc) { |
@@ -7638,12 +5740,12 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); | |||
7638 | static ssize_t show_antenna(struct device *d, | 5740 | static ssize_t show_antenna(struct device *d, |
7639 | struct device_attribute *attr, char *buf) | 5741 | struct device_attribute *attr, char *buf) |
7640 | { | 5742 | { |
7641 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5743 | struct iwl_priv *priv = dev_get_drvdata(d); |
7642 | 5744 | ||
7643 | if (!iwl3945_is_alive(priv)) | 5745 | if (!iwl_is_alive(priv)) |
7644 | return -EAGAIN; | 5746 | return -EAGAIN; |
7645 | 5747 | ||
7646 | return sprintf(buf, "%d\n", priv->antenna); | 5748 | return sprintf(buf, "%d\n", iwl3945_mod_params.antenna); |
7647 | } | 5749 | } |
7648 | 5750 | ||
7649 | static ssize_t store_antenna(struct device *d, | 5751 | static ssize_t store_antenna(struct device *d, |
@@ -7651,7 +5753,7 @@ static ssize_t store_antenna(struct device *d, | |||
7651 | const char *buf, size_t count) | 5753 | const char *buf, size_t count) |
7652 | { | 5754 | { |
7653 | int ant; | 5755 | int ant; |
7654 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 5756 | struct iwl_priv *priv = dev_get_drvdata(d); |
7655 | 5757 | ||
7656 | if (count == 0) | 5758 | if (count == 0) |
7657 | return 0; | 5759 | return 0; |
@@ -7663,7 +5765,7 @@ static ssize_t store_antenna(struct device *d, | |||
7663 | 5765 | ||
7664 | if ((ant >= 0) && (ant <= 2)) { | 5766 | if ((ant >= 0) && (ant <= 2)) { |
7665 | IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant); | 5767 | IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant); |
7666 | priv->antenna = (enum iwl3945_antenna)ant; | 5768 | iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant; |
7667 | } else | 5769 | } else |
7668 | IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant); | 5770 | IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant); |
7669 | 5771 | ||
@@ -7676,8 +5778,8 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); | |||
7676 | static ssize_t show_status(struct device *d, | 5778 | static ssize_t show_status(struct device *d, |
7677 | struct device_attribute *attr, char *buf) | 5779 | struct device_attribute *attr, char *buf) |
7678 | { | 5780 | { |
7679 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | 5781 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
7680 | if (!iwl3945_is_alive(priv)) | 5782 | if (!iwl_is_alive(priv)) |
7681 | return -EAGAIN; | 5783 | return -EAGAIN; |
7682 | return sprintf(buf, "0x%08x\n", (int)priv->status); | 5784 | return sprintf(buf, "0x%08x\n", (int)priv->status); |
7683 | } | 5785 | } |
@@ -7691,7 +5793,7 @@ static ssize_t dump_error_log(struct device *d, | |||
7691 | char *p = (char *)buf; | 5793 | char *p = (char *)buf; |
7692 | 5794 | ||
7693 | if (p[0] == '1') | 5795 | if (p[0] == '1') |
7694 | iwl3945_dump_nic_error_log((struct iwl3945_priv *)d->driver_data); | 5796 | iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data); |
7695 | 5797 | ||
7696 | return strnlen(buf, count); | 5798 | return strnlen(buf, count); |
7697 | } | 5799 | } |
@@ -7705,7 +5807,7 @@ static ssize_t dump_event_log(struct device *d, | |||
7705 | char *p = (char *)buf; | 5807 | char *p = (char *)buf; |
7706 | 5808 | ||
7707 | if (p[0] == '1') | 5809 | if (p[0] == '1') |
7708 | iwl3945_dump_nic_event_log((struct iwl3945_priv *)d->driver_data); | 5810 | iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data); |
7709 | 5811 | ||
7710 | return strnlen(buf, count); | 5812 | return strnlen(buf, count); |
7711 | } | 5813 | } |
@@ -7718,7 +5820,7 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); | |||
7718 | * | 5820 | * |
7719 | *****************************************************************************/ | 5821 | *****************************************************************************/ |
7720 | 5822 | ||
7721 | static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) | 5823 | static void iwl3945_setup_deferred_work(struct iwl_priv *priv) |
7722 | { | 5824 | { |
7723 | priv->workqueue = create_workqueue(DRV_NAME); | 5825 | priv->workqueue = create_workqueue(DRV_NAME); |
7724 | 5826 | ||
@@ -7727,14 +5829,15 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) | |||
7727 | INIT_WORK(&priv->up, iwl3945_bg_up); | 5829 | INIT_WORK(&priv->up, iwl3945_bg_up); |
7728 | INIT_WORK(&priv->restart, iwl3945_bg_restart); | 5830 | INIT_WORK(&priv->restart, iwl3945_bg_restart); |
7729 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); | 5831 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); |
7730 | INIT_WORK(&priv->scan_completed, iwl3945_bg_scan_completed); | 5832 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); |
7731 | INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan); | ||
7732 | INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); | ||
7733 | INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); | ||
7734 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 5833 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
7735 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 5834 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
7736 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 5835 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
7737 | INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); | 5836 | INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll); |
5837 | INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); | ||
5838 | INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan); | ||
5839 | INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); | ||
5840 | INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); | ||
7738 | 5841 | ||
7739 | iwl3945_hw_setup_deferred_work(priv); | 5842 | iwl3945_hw_setup_deferred_work(priv); |
7740 | 5843 | ||
@@ -7742,7 +5845,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) | |||
7742 | iwl3945_irq_tasklet, (unsigned long)priv); | 5845 | iwl3945_irq_tasklet, (unsigned long)priv); |
7743 | } | 5846 | } |
7744 | 5847 | ||
7745 | static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv) | 5848 | static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) |
7746 | { | 5849 | { |
7747 | iwl3945_hw_cancel_deferred_work(priv); | 5850 | iwl3945_hw_cancel_deferred_work(priv); |
7748 | 5851 | ||
@@ -7768,7 +5871,9 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
7768 | &dev_attr_status.attr, | 5871 | &dev_attr_status.attr, |
7769 | &dev_attr_temperature.attr, | 5872 | &dev_attr_temperature.attr, |
7770 | &dev_attr_tx_power.attr, | 5873 | &dev_attr_tx_power.attr, |
7771 | 5874 | #ifdef CONFIG_IWLWIFI_DEBUG | |
5875 | &dev_attr_debug_level.attr, | ||
5876 | #endif | ||
7772 | NULL | 5877 | NULL |
7773 | }; | 5878 | }; |
7774 | 5879 | ||
@@ -7787,7 +5892,6 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
7787 | .config_interface = iwl3945_mac_config_interface, | 5892 | .config_interface = iwl3945_mac_config_interface, |
7788 | .configure_filter = iwl3945_configure_filter, | 5893 | .configure_filter = iwl3945_configure_filter, |
7789 | .set_key = iwl3945_mac_set_key, | 5894 | .set_key = iwl3945_mac_set_key, |
7790 | .get_stats = iwl3945_mac_get_stats, | ||
7791 | .get_tx_stats = iwl3945_mac_get_tx_stats, | 5895 | .get_tx_stats = iwl3945_mac_get_tx_stats, |
7792 | .conf_tx = iwl3945_mac_conf_tx, | 5896 | .conf_tx = iwl3945_mac_conf_tx, |
7793 | .reset_tsf = iwl3945_mac_reset_tsf, | 5897 | .reset_tsf = iwl3945_mac_reset_tsf, |
@@ -7795,59 +5899,136 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
7795 | .hw_scan = iwl3945_mac_hw_scan | 5899 | .hw_scan = iwl3945_mac_hw_scan |
7796 | }; | 5900 | }; |
7797 | 5901 | ||
5902 | static int iwl3945_init_drv(struct iwl_priv *priv) | ||
5903 | { | ||
5904 | int ret; | ||
5905 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | ||
5906 | |||
5907 | priv->retry_rate = 1; | ||
5908 | priv->ibss_beacon = NULL; | ||
5909 | |||
5910 | spin_lock_init(&priv->lock); | ||
5911 | spin_lock_init(&priv->power_data.lock); | ||
5912 | spin_lock_init(&priv->sta_lock); | ||
5913 | spin_lock_init(&priv->hcmd_lock); | ||
5914 | |||
5915 | INIT_LIST_HEAD(&priv->free_frames); | ||
5916 | |||
5917 | mutex_init(&priv->mutex); | ||
5918 | |||
5919 | /* Clear the driver's (not device's) station table */ | ||
5920 | iwl3945_clear_stations_table(priv); | ||
5921 | |||
5922 | priv->data_retry_limit = -1; | ||
5923 | priv->ieee_channels = NULL; | ||
5924 | priv->ieee_rates = NULL; | ||
5925 | priv->band = IEEE80211_BAND_2GHZ; | ||
5926 | |||
5927 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
5928 | |||
5929 | iwl_reset_qos(priv); | ||
5930 | |||
5931 | priv->qos_data.qos_active = 0; | ||
5932 | priv->qos_data.qos_cap.val = 0; | ||
5933 | |||
5934 | priv->rates_mask = IWL_RATES_MASK; | ||
5935 | /* If power management is turned on, default to AC mode */ | ||
5936 | priv->power_mode = IWL39_POWER_AC; | ||
5937 | priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; | ||
5938 | |||
5939 | if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { | ||
5940 | IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", | ||
5941 | eeprom->version); | ||
5942 | ret = -EINVAL; | ||
5943 | goto err; | ||
5944 | } | ||
5945 | ret = iwl_init_channel_map(priv); | ||
5946 | if (ret) { | ||
5947 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); | ||
5948 | goto err; | ||
5949 | } | ||
5950 | |||
5951 | /* Set up txpower settings in driver for all channels */ | ||
5952 | if (iwl3945_txpower_set_from_eeprom(priv)) { | ||
5953 | ret = -EIO; | ||
5954 | goto err_free_channel_map; | ||
5955 | } | ||
5956 | |||
5957 | ret = iwlcore_init_geos(priv); | ||
5958 | if (ret) { | ||
5959 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); | ||
5960 | goto err_free_channel_map; | ||
5961 | } | ||
5962 | iwl3945_init_hw_rates(priv, priv->ieee_rates); | ||
5963 | |||
5964 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | ||
5965 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
5966 | &priv->bands[IEEE80211_BAND_2GHZ]; | ||
5967 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | ||
5968 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
5969 | &priv->bands[IEEE80211_BAND_5GHZ]; | ||
5970 | |||
5971 | return 0; | ||
5972 | |||
5973 | err_free_channel_map: | ||
5974 | iwl_free_channel_map(priv); | ||
5975 | err: | ||
5976 | return ret; | ||
5977 | } | ||
5978 | |||
7798 | static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 5979 | static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
7799 | { | 5980 | { |
7800 | int err = 0; | 5981 | int err = 0; |
7801 | struct iwl3945_priv *priv; | 5982 | struct iwl_priv *priv; |
7802 | struct ieee80211_hw *hw; | 5983 | struct ieee80211_hw *hw; |
7803 | struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data); | 5984 | struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); |
5985 | struct iwl3945_eeprom *eeprom; | ||
7804 | unsigned long flags; | 5986 | unsigned long flags; |
7805 | 5987 | ||
7806 | /*********************** | 5988 | /*********************** |
7807 | * 1. Allocating HW data | 5989 | * 1. Allocating HW data |
7808 | * ********************/ | 5990 | * ********************/ |
7809 | 5991 | ||
7810 | /* Disabling hardware scan means that mac80211 will perform scans | ||
7811 | * "the hard way", rather than using device's scan. */ | ||
7812 | if (iwl3945_param_disable_hw_scan) { | ||
7813 | IWL_DEBUG_INFO("Disabling hw_scan\n"); | ||
7814 | iwl3945_hw_ops.hw_scan = NULL; | ||
7815 | } | ||
7816 | |||
7817 | if ((iwl3945_param_queues_num > IWL39_MAX_NUM_QUEUES) || | ||
7818 | (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) { | ||
7819 | IWL_ERROR("invalid queues_num, should be between %d and %d\n", | ||
7820 | IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); | ||
7821 | err = -EINVAL; | ||
7822 | goto out; | ||
7823 | } | ||
7824 | |||
7825 | /* mac80211 allocates memory for this device instance, including | 5992 | /* mac80211 allocates memory for this device instance, including |
7826 | * space for this driver's private structure */ | 5993 | * space for this driver's private structure */ |
7827 | hw = ieee80211_alloc_hw(sizeof(struct iwl3945_priv), &iwl3945_hw_ops); | 5994 | hw = iwl_alloc_all(cfg, &iwl3945_hw_ops); |
7828 | if (hw == NULL) { | 5995 | if (hw == NULL) { |
7829 | IWL_ERROR("Can not allocate network device\n"); | 5996 | printk(KERN_ERR DRV_NAME "Can not allocate network device\n"); |
7830 | err = -ENOMEM; | 5997 | err = -ENOMEM; |
7831 | goto out; | 5998 | goto out; |
7832 | } | 5999 | } |
7833 | 6000 | priv = hw->priv; | |
7834 | SET_IEEE80211_DEV(hw, &pdev->dev); | 6001 | SET_IEEE80211_DEV(hw, &pdev->dev); |
7835 | 6002 | ||
7836 | priv = hw->priv; | 6003 | if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) || |
7837 | priv->hw = hw; | 6004 | (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) { |
7838 | priv->pci_dev = pdev; | 6005 | IWL_ERR(priv, |
7839 | priv->cfg = cfg; | 6006 | "invalid queues_num, should be between %d and %d\n", |
6007 | IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES); | ||
6008 | err = -EINVAL; | ||
6009 | goto out; | ||
6010 | } | ||
6011 | |||
6012 | /* | ||
6013 | * Disabling hardware scan means that mac80211 will perform scans | ||
6014 | * "the hard way", rather than using device's scan. | ||
6015 | */ | ||
6016 | if (iwl3945_mod_params.disable_hw_scan) { | ||
6017 | IWL_DEBUG_INFO("Disabling hw_scan\n"); | ||
6018 | iwl3945_hw_ops.hw_scan = NULL; | ||
6019 | } | ||
6020 | |||
7840 | 6021 | ||
7841 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); | 6022 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); |
7842 | hw->rate_control_algorithm = "iwl-3945-rs"; | 6023 | priv->cfg = cfg; |
7843 | hw->sta_data_size = sizeof(struct iwl3945_sta_priv); | 6024 | priv->pci_dev = pdev; |
7844 | 6025 | ||
7845 | /* Select antenna (may be helpful if only one antenna is connected) */ | 6026 | #ifdef CONFIG_IWLWIFI_DEBUG |
7846 | priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna; | 6027 | priv->debug_level = iwl3945_mod_params.debug; |
7847 | #ifdef CONFIG_IWL3945_DEBUG | ||
7848 | iwl3945_debug_level = iwl3945_param_debug; | ||
7849 | atomic_set(&priv->restrict_refcnt, 0); | 6028 | atomic_set(&priv->restrict_refcnt, 0); |
7850 | #endif | 6029 | #endif |
6030 | hw->rate_control_algorithm = "iwl-3945-rs"; | ||
6031 | hw->sta_data_size = sizeof(struct iwl3945_sta_priv); | ||
7851 | 6032 | ||
7852 | /* Tell mac80211 our characteristics */ | 6033 | /* Tell mac80211 our characteristics */ |
7853 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | 6034 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
@@ -7857,7 +6038,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7857 | BIT(NL80211_IFTYPE_STATION) | | 6038 | BIT(NL80211_IFTYPE_STATION) | |
7858 | BIT(NL80211_IFTYPE_ADHOC); | 6039 | BIT(NL80211_IFTYPE_ADHOC); |
7859 | 6040 | ||
7860 | hw->wiphy->fw_handles_regulatory = true; | 6041 | hw->wiphy->custom_regulatory = true; |
7861 | 6042 | ||
7862 | /* 4 EDCA QOS priorities */ | 6043 | /* 4 EDCA QOS priorities */ |
7863 | hw->queues = 4; | 6044 | hw->queues = 4; |
@@ -7876,7 +6057,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7876 | if (!err) | 6057 | if (!err) |
7877 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | 6058 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); |
7878 | if (err) { | 6059 | if (err) { |
7879 | printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n"); | 6060 | IWL_WARN(priv, "No suitable DMA available.\n"); |
7880 | goto out_pci_disable_device; | 6061 | goto out_pci_disable_device; |
7881 | } | 6062 | } |
7882 | 6063 | ||
@@ -7902,29 +6083,26 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7902 | * PCI Tx retries from interfering with C3 CPU state */ | 6083 | * PCI Tx retries from interfering with C3 CPU state */ |
7903 | pci_write_config_byte(pdev, 0x41, 0x00); | 6084 | pci_write_config_byte(pdev, 0x41, 0x00); |
7904 | 6085 | ||
7905 | /* nic init */ | 6086 | /* amp init */ |
7906 | iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 6087 | err = priv->cfg->ops->lib->apm_ops.init(priv); |
7907 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | ||
7908 | |||
7909 | iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
7910 | err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL, | ||
7911 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | ||
7912 | if (err < 0) { | 6088 | if (err < 0) { |
7913 | IWL_DEBUG_INFO("Failed to init the card\n"); | 6089 | IWL_DEBUG_INFO("Failed to init APMG\n"); |
7914 | goto out_remove_sysfs; | 6090 | goto out_iounmap; |
7915 | } | 6091 | } |
7916 | 6092 | ||
7917 | /*********************** | 6093 | /*********************** |
7918 | * 4. Read EEPROM | 6094 | * 4. Read EEPROM |
7919 | * ********************/ | 6095 | * ********************/ |
6096 | |||
7920 | /* Read the EEPROM */ | 6097 | /* Read the EEPROM */ |
7921 | err = iwl3945_eeprom_init(priv); | 6098 | err = iwl_eeprom_init(priv); |
7922 | if (err) { | 6099 | if (err) { |
7923 | IWL_ERROR("Unable to init EEPROM\n"); | 6100 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
7924 | goto out_remove_sysfs; | 6101 | goto out_remove_sysfs; |
7925 | } | 6102 | } |
7926 | /* MAC Address location in EEPROM same for 3945/4965 */ | 6103 | /* MAC Address location in EEPROM same for 3945/4965 */ |
7927 | get_eeprom_mac(priv, priv->mac_addr); | 6104 | eeprom = (struct iwl3945_eeprom *)priv->eeprom; |
6105 | memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN); | ||
7928 | IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr); | 6106 | IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr); |
7929 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); | 6107 | SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); |
7930 | 6108 | ||
@@ -7932,60 +6110,23 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7932 | * 5. Setup HW Constants | 6110 | * 5. Setup HW Constants |
7933 | * ********************/ | 6111 | * ********************/ |
7934 | /* Device-specific setup */ | 6112 | /* Device-specific setup */ |
7935 | if (iwl3945_hw_set_hw_setting(priv)) { | 6113 | if (iwl3945_hw_set_hw_params(priv)) { |
7936 | IWL_ERROR("failed to set hw settings\n"); | 6114 | IWL_ERR(priv, "failed to set hw settings\n"); |
7937 | goto out_iounmap; | 6115 | goto out_iounmap; |
7938 | } | 6116 | } |
7939 | 6117 | ||
7940 | /*********************** | 6118 | /*********************** |
7941 | * 6. Setup priv | 6119 | * 6. Setup priv |
7942 | * ********************/ | 6120 | * ********************/ |
7943 | priv->retry_rate = 1; | ||
7944 | priv->ibss_beacon = NULL; | ||
7945 | |||
7946 | spin_lock_init(&priv->lock); | ||
7947 | spin_lock_init(&priv->power_data.lock); | ||
7948 | spin_lock_init(&priv->sta_lock); | ||
7949 | spin_lock_init(&priv->hcmd_lock); | ||
7950 | |||
7951 | INIT_LIST_HEAD(&priv->free_frames); | ||
7952 | mutex_init(&priv->mutex); | ||
7953 | |||
7954 | /* Clear the driver's (not device's) station table */ | ||
7955 | iwl3945_clear_stations_table(priv); | ||
7956 | |||
7957 | priv->data_retry_limit = -1; | ||
7958 | priv->ieee_channels = NULL; | ||
7959 | priv->ieee_rates = NULL; | ||
7960 | priv->band = IEEE80211_BAND_2GHZ; | ||
7961 | |||
7962 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
7963 | |||
7964 | iwl3945_reset_qos(priv); | ||
7965 | |||
7966 | priv->qos_data.qos_active = 0; | ||
7967 | priv->qos_data.qos_cap.val = 0; | ||
7968 | |||
7969 | |||
7970 | priv->rates_mask = IWL_RATES_MASK; | ||
7971 | /* If power management is turned on, default to AC mode */ | ||
7972 | priv->power_mode = IWL_POWER_AC; | ||
7973 | priv->user_txpower_limit = IWL_DEFAULT_TX_POWER; | ||
7974 | 6121 | ||
7975 | err = iwl3945_init_channel_map(priv); | 6122 | err = iwl3945_init_drv(priv); |
7976 | if (err) { | 6123 | if (err) { |
7977 | IWL_ERROR("initializing regulatory failed: %d\n", err); | 6124 | IWL_ERR(priv, "initializing driver failed\n"); |
7978 | goto out_release_irq; | 6125 | goto out_free_geos; |
7979 | } | ||
7980 | |||
7981 | err = iwl3945_init_geos(priv); | ||
7982 | if (err) { | ||
7983 | IWL_ERROR("initializing geos failed: %d\n", err); | ||
7984 | goto out_free_channel_map; | ||
7985 | } | 6126 | } |
7986 | 6127 | ||
7987 | printk(KERN_INFO DRV_NAME | 6128 | IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", |
7988 | ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name); | 6129 | priv->cfg->name); |
7989 | 6130 | ||
7990 | /*********************************** | 6131 | /*********************************** |
7991 | * 7. Initialize Module Parameters | 6132 | * 7. Initialize Module Parameters |
@@ -7993,7 +6134,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7993 | 6134 | ||
7994 | /* Initialize module parameter values here */ | 6135 | /* Initialize module parameter values here */ |
7995 | /* Disable radio (SW RF KILL) via parameter when loading driver */ | 6136 | /* Disable radio (SW RF KILL) via parameter when loading driver */ |
7996 | if (iwl3945_param_disable) { | 6137 | if (iwl3945_mod_params.disable) { |
7997 | set_bit(STATUS_RF_KILL_SW, &priv->status); | 6138 | set_bit(STATUS_RF_KILL_SW, &priv->status); |
7998 | IWL_DEBUG_INFO("Radio disabled.\n"); | 6139 | IWL_DEBUG_INFO("Radio disabled.\n"); |
7999 | } | 6140 | } |
@@ -8007,56 +6148,61 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8007 | iwl3945_disable_interrupts(priv); | 6148 | iwl3945_disable_interrupts(priv); |
8008 | spin_unlock_irqrestore(&priv->lock, flags); | 6149 | spin_unlock_irqrestore(&priv->lock, flags); |
8009 | 6150 | ||
6151 | pci_enable_msi(priv->pci_dev); | ||
6152 | |||
6153 | err = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED, | ||
6154 | DRV_NAME, priv); | ||
6155 | if (err) { | ||
6156 | IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq); | ||
6157 | goto out_disable_msi; | ||
6158 | } | ||
6159 | |||
8010 | err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 6160 | err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
8011 | if (err) { | 6161 | if (err) { |
8012 | IWL_ERROR("failed to create sysfs device attributes\n"); | 6162 | IWL_ERR(priv, "failed to create sysfs device attributes\n"); |
8013 | goto out_free_geos; | 6163 | goto out_release_irq; |
8014 | } | 6164 | } |
8015 | 6165 | ||
8016 | iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); | 6166 | iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
8017 | iwl3945_setup_deferred_work(priv); | 6167 | iwl3945_setup_deferred_work(priv); |
8018 | iwl3945_setup_rx_handlers(priv); | 6168 | iwl3945_setup_rx_handlers(priv); |
8019 | 6169 | ||
8020 | /*********************** | ||
8021 | * 9. Conclude | ||
8022 | * ********************/ | ||
8023 | pci_save_state(pdev); | ||
8024 | pci_disable_device(pdev); | ||
8025 | |||
8026 | /********************************* | 6170 | /********************************* |
8027 | * 10. Setup and Register mac80211 | 6171 | * 9. Setup and Register mac80211 |
8028 | * *******************************/ | 6172 | * *******************************/ |
8029 | 6173 | ||
8030 | err = ieee80211_register_hw(priv->hw); | 6174 | err = ieee80211_register_hw(priv->hw); |
8031 | if (err) { | 6175 | if (err) { |
8032 | IWL_ERROR("Failed to register network device (error %d)\n", err); | 6176 | IWL_ERR(priv, "Failed to register network device: %d\n", err); |
8033 | goto out_remove_sysfs; | 6177 | goto out_remove_sysfs; |
8034 | } | 6178 | } |
8035 | 6179 | ||
8036 | priv->hw->conf.beacon_int = 100; | 6180 | priv->hw->conf.beacon_int = 100; |
8037 | priv->mac80211_registered = 1; | 6181 | priv->mac80211_registered = 1; |
8038 | 6182 | ||
8039 | 6183 | err = iwl_rfkill_init(priv); | |
8040 | err = iwl3945_rfkill_init(priv); | ||
8041 | if (err) | 6184 | if (err) |
8042 | IWL_ERROR("Unable to initialize RFKILL system. " | 6185 | IWL_ERR(priv, "Unable to initialize RFKILL system. " |
8043 | "Ignoring error: %d\n", err); | 6186 | "Ignoring error: %d\n", err); |
8044 | 6187 | ||
6188 | /* Start monitoring the killswitch */ | ||
6189 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | ||
6190 | 2 * HZ); | ||
6191 | |||
8045 | return 0; | 6192 | return 0; |
8046 | 6193 | ||
8047 | out_remove_sysfs: | 6194 | out_remove_sysfs: |
8048 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 6195 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
8049 | out_free_geos: | 6196 | out_free_geos: |
8050 | iwl3945_free_geos(priv); | 6197 | iwlcore_free_geos(priv); |
8051 | out_free_channel_map: | ||
8052 | iwl3945_free_channel_map(priv); | ||
8053 | |||
8054 | 6198 | ||
8055 | out_release_irq: | 6199 | out_release_irq: |
6200 | free_irq(priv->pci_dev->irq, priv); | ||
8056 | destroy_workqueue(priv->workqueue); | 6201 | destroy_workqueue(priv->workqueue); |
8057 | priv->workqueue = NULL; | 6202 | priv->workqueue = NULL; |
8058 | iwl3945_unset_hw_setting(priv); | 6203 | iwl3945_unset_hw_params(priv); |
8059 | 6204 | out_disable_msi: | |
6205 | pci_disable_msi(priv->pci_dev); | ||
8060 | out_iounmap: | 6206 | out_iounmap: |
8061 | pci_iounmap(pdev, priv->hw_base); | 6207 | pci_iounmap(pdev, priv->hw_base); |
8062 | out_pci_release_regions: | 6208 | out_pci_release_regions: |
@@ -8072,7 +6218,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8072 | 6218 | ||
8073 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | 6219 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) |
8074 | { | 6220 | { |
8075 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 6221 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
8076 | unsigned long flags; | 6222 | unsigned long flags; |
8077 | 6223 | ||
8078 | if (!priv) | 6224 | if (!priv) |
@@ -8082,7 +6228,12 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8082 | 6228 | ||
8083 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 6229 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
8084 | 6230 | ||
8085 | iwl3945_down(priv); | 6231 | if (priv->mac80211_registered) { |
6232 | ieee80211_unregister_hw(priv->hw); | ||
6233 | priv->mac80211_registered = 0; | ||
6234 | } else { | ||
6235 | iwl3945_down(priv); | ||
6236 | } | ||
8086 | 6237 | ||
8087 | /* make sure we flush any pending irq or | 6238 | /* make sure we flush any pending irq or |
8088 | * tasklet for the driver | 6239 | * tasklet for the driver |
@@ -8095,19 +6246,18 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8095 | 6246 | ||
8096 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 6247 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
8097 | 6248 | ||
8098 | iwl3945_rfkill_unregister(priv); | 6249 | iwl_rfkill_unregister(priv); |
6250 | cancel_delayed_work(&priv->rfkill_poll); | ||
6251 | |||
8099 | iwl3945_dealloc_ucode_pci(priv); | 6252 | iwl3945_dealloc_ucode_pci(priv); |
8100 | 6253 | ||
8101 | if (priv->rxq.bd) | 6254 | if (priv->rxq.bd) |
8102 | iwl3945_rx_queue_free(priv, &priv->rxq); | 6255 | iwl_rx_queue_free(priv, &priv->rxq); |
8103 | iwl3945_hw_txq_ctx_free(priv); | 6256 | iwl3945_hw_txq_ctx_free(priv); |
8104 | 6257 | ||
8105 | iwl3945_unset_hw_setting(priv); | 6258 | iwl3945_unset_hw_params(priv); |
8106 | iwl3945_clear_stations_table(priv); | 6259 | iwl3945_clear_stations_table(priv); |
8107 | 6260 | ||
8108 | if (priv->mac80211_registered) | ||
8109 | ieee80211_unregister_hw(priv->hw); | ||
8110 | |||
8111 | /*netif_stop_queue(dev); */ | 6261 | /*netif_stop_queue(dev); */ |
8112 | flush_workqueue(priv->workqueue); | 6262 | flush_workqueue(priv->workqueue); |
8113 | 6263 | ||
@@ -8117,13 +6267,16 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8117 | destroy_workqueue(priv->workqueue); | 6267 | destroy_workqueue(priv->workqueue); |
8118 | priv->workqueue = NULL; | 6268 | priv->workqueue = NULL; |
8119 | 6269 | ||
6270 | free_irq(pdev->irq, priv); | ||
6271 | pci_disable_msi(pdev); | ||
6272 | |||
8120 | pci_iounmap(pdev, priv->hw_base); | 6273 | pci_iounmap(pdev, priv->hw_base); |
8121 | pci_release_regions(pdev); | 6274 | pci_release_regions(pdev); |
8122 | pci_disable_device(pdev); | 6275 | pci_disable_device(pdev); |
8123 | pci_set_drvdata(pdev, NULL); | 6276 | pci_set_drvdata(pdev, NULL); |
8124 | 6277 | ||
8125 | iwl3945_free_channel_map(priv); | 6278 | iwl_free_channel_map(priv); |
8126 | iwl3945_free_geos(priv); | 6279 | iwlcore_free_geos(priv); |
8127 | kfree(priv->scan); | 6280 | kfree(priv->scan); |
8128 | if (priv->ibss_beacon) | 6281 | if (priv->ibss_beacon) |
8129 | dev_kfree_skb(priv->ibss_beacon); | 6282 | dev_kfree_skb(priv->ibss_beacon); |
@@ -8135,14 +6288,15 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8135 | 6288 | ||
8136 | static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 6289 | static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
8137 | { | 6290 | { |
8138 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 6291 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
8139 | 6292 | ||
8140 | if (priv->is_open) { | 6293 | if (priv->is_open) { |
8141 | set_bit(STATUS_IN_SUSPEND, &priv->status); | 6294 | set_bit(STATUS_IN_SUSPEND, &priv->status); |
8142 | iwl3945_mac_stop(priv->hw); | 6295 | iwl3945_mac_stop(priv->hw); |
8143 | priv->is_open = 1; | 6296 | priv->is_open = 1; |
8144 | } | 6297 | } |
8145 | 6298 | pci_save_state(pdev); | |
6299 | pci_disable_device(pdev); | ||
8146 | pci_set_power_state(pdev, PCI_D3hot); | 6300 | pci_set_power_state(pdev, PCI_D3hot); |
8147 | 6301 | ||
8148 | return 0; | 6302 | return 0; |
@@ -8150,9 +6304,11 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
8150 | 6304 | ||
8151 | static int iwl3945_pci_resume(struct pci_dev *pdev) | 6305 | static int iwl3945_pci_resume(struct pci_dev *pdev) |
8152 | { | 6306 | { |
8153 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 6307 | struct iwl_priv *priv = pci_get_drvdata(pdev); |
8154 | 6308 | ||
8155 | pci_set_power_state(pdev, PCI_D0); | 6309 | pci_set_power_state(pdev, PCI_D0); |
6310 | pci_enable_device(pdev); | ||
6311 | pci_restore_state(pdev); | ||
8156 | 6312 | ||
8157 | if (priv->is_open) | 6313 | if (priv->is_open) |
8158 | iwl3945_mac_start(priv->hw); | 6314 | iwl3945_mac_start(priv->hw); |
@@ -8163,114 +6319,6 @@ static int iwl3945_pci_resume(struct pci_dev *pdev) | |||
8163 | 6319 | ||
8164 | #endif /* CONFIG_PM */ | 6320 | #endif /* CONFIG_PM */ |
8165 | 6321 | ||
8166 | /*************** RFKILL FUNCTIONS **********/ | ||
8167 | #ifdef CONFIG_IWL3945_RFKILL | ||
8168 | /* software rf-kill from user */ | ||
8169 | static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | ||
8170 | { | ||
8171 | struct iwl3945_priv *priv = data; | ||
8172 | int err = 0; | ||
8173 | |||
8174 | if (!priv->rfkill) | ||
8175 | return 0; | ||
8176 | |||
8177 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
8178 | return 0; | ||
8179 | |||
8180 | IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state); | ||
8181 | mutex_lock(&priv->mutex); | ||
8182 | |||
8183 | switch (state) { | ||
8184 | case RFKILL_STATE_UNBLOCKED: | ||
8185 | if (iwl3945_is_rfkill_hw(priv)) { | ||
8186 | err = -EBUSY; | ||
8187 | goto out_unlock; | ||
8188 | } | ||
8189 | iwl3945_radio_kill_sw(priv, 0); | ||
8190 | break; | ||
8191 | case RFKILL_STATE_SOFT_BLOCKED: | ||
8192 | iwl3945_radio_kill_sw(priv, 1); | ||
8193 | break; | ||
8194 | default: | ||
8195 | IWL_WARNING("we received unexpected RFKILL state %d\n", state); | ||
8196 | break; | ||
8197 | } | ||
8198 | out_unlock: | ||
8199 | mutex_unlock(&priv->mutex); | ||
8200 | |||
8201 | return err; | ||
8202 | } | ||
8203 | |||
8204 | int iwl3945_rfkill_init(struct iwl3945_priv *priv) | ||
8205 | { | ||
8206 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
8207 | int ret = 0; | ||
8208 | |||
8209 | BUG_ON(device == NULL); | ||
8210 | |||
8211 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); | ||
8212 | priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | ||
8213 | if (!priv->rfkill) { | ||
8214 | IWL_ERROR("Unable to allocate rfkill device.\n"); | ||
8215 | ret = -ENOMEM; | ||
8216 | goto error; | ||
8217 | } | ||
8218 | |||
8219 | priv->rfkill->name = priv->cfg->name; | ||
8220 | priv->rfkill->data = priv; | ||
8221 | priv->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
8222 | priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill; | ||
8223 | priv->rfkill->user_claim_unsupported = 1; | ||
8224 | |||
8225 | priv->rfkill->dev.class->suspend = NULL; | ||
8226 | priv->rfkill->dev.class->resume = NULL; | ||
8227 | |||
8228 | ret = rfkill_register(priv->rfkill); | ||
8229 | if (ret) { | ||
8230 | IWL_ERROR("Unable to register rfkill: %d\n", ret); | ||
8231 | goto freed_rfkill; | ||
8232 | } | ||
8233 | |||
8234 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8235 | return ret; | ||
8236 | |||
8237 | freed_rfkill: | ||
8238 | if (priv->rfkill != NULL) | ||
8239 | rfkill_free(priv->rfkill); | ||
8240 | priv->rfkill = NULL; | ||
8241 | |||
8242 | error: | ||
8243 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8244 | return ret; | ||
8245 | } | ||
8246 | |||
8247 | void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) | ||
8248 | { | ||
8249 | if (priv->rfkill) | ||
8250 | rfkill_unregister(priv->rfkill); | ||
8251 | |||
8252 | priv->rfkill = NULL; | ||
8253 | } | ||
8254 | |||
8255 | /* set rf-kill to the right state. */ | ||
8256 | void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) | ||
8257 | { | ||
8258 | |||
8259 | if (!priv->rfkill) | ||
8260 | return; | ||
8261 | |||
8262 | if (iwl3945_is_rfkill_hw(priv)) { | ||
8263 | rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); | ||
8264 | return; | ||
8265 | } | ||
8266 | |||
8267 | if (!iwl3945_is_rfkill_sw(priv)) | ||
8268 | rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED); | ||
8269 | else | ||
8270 | rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); | ||
8271 | } | ||
8272 | #endif | ||
8273 | |||
8274 | /***************************************************************************** | 6322 | /***************************************************************************** |
8275 | * | 6323 | * |
8276 | * driver and module entry point | 6324 | * driver and module entry point |
@@ -8297,29 +6345,19 @@ static int __init iwl3945_init(void) | |||
8297 | 6345 | ||
8298 | ret = iwl3945_rate_control_register(); | 6346 | ret = iwl3945_rate_control_register(); |
8299 | if (ret) { | 6347 | if (ret) { |
8300 | IWL_ERROR("Unable to register rate control algorithm: %d\n", ret); | 6348 | printk(KERN_ERR DRV_NAME |
6349 | "Unable to register rate control algorithm: %d\n", ret); | ||
8301 | return ret; | 6350 | return ret; |
8302 | } | 6351 | } |
8303 | 6352 | ||
8304 | ret = pci_register_driver(&iwl3945_driver); | 6353 | ret = pci_register_driver(&iwl3945_driver); |
8305 | if (ret) { | 6354 | if (ret) { |
8306 | IWL_ERROR("Unable to initialize PCI module\n"); | 6355 | printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n"); |
8307 | goto error_register; | 6356 | goto error_register; |
8308 | } | 6357 | } |
8309 | #ifdef CONFIG_IWL3945_DEBUG | ||
8310 | ret = driver_create_file(&iwl3945_driver.driver, &driver_attr_debug_level); | ||
8311 | if (ret) { | ||
8312 | IWL_ERROR("Unable to create driver sysfs file\n"); | ||
8313 | goto error_debug; | ||
8314 | } | ||
8315 | #endif | ||
8316 | 6358 | ||
8317 | return ret; | 6359 | return ret; |
8318 | 6360 | ||
8319 | #ifdef CONFIG_IWL3945_DEBUG | ||
8320 | error_debug: | ||
8321 | pci_unregister_driver(&iwl3945_driver); | ||
8322 | #endif | ||
8323 | error_register: | 6361 | error_register: |
8324 | iwl3945_rate_control_unregister(); | 6362 | iwl3945_rate_control_unregister(); |
8325 | return ret; | 6363 | return ret; |
@@ -8327,29 +6365,29 @@ error_register: | |||
8327 | 6365 | ||
8328 | static void __exit iwl3945_exit(void) | 6366 | static void __exit iwl3945_exit(void) |
8329 | { | 6367 | { |
8330 | #ifdef CONFIG_IWL3945_DEBUG | ||
8331 | driver_remove_file(&iwl3945_driver.driver, &driver_attr_debug_level); | ||
8332 | #endif | ||
8333 | pci_unregister_driver(&iwl3945_driver); | 6368 | pci_unregister_driver(&iwl3945_driver); |
8334 | iwl3945_rate_control_unregister(); | 6369 | iwl3945_rate_control_unregister(); |
8335 | } | 6370 | } |
8336 | 6371 | ||
8337 | MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); | 6372 | MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); |
8338 | 6373 | ||
8339 | module_param_named(antenna, iwl3945_param_antenna, int, 0444); | 6374 | module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444); |
8340 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 6375 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
8341 | module_param_named(disable, iwl3945_param_disable, int, 0444); | 6376 | module_param_named(disable, iwl3945_mod_params.disable, int, 0444); |
8342 | MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); | 6377 | MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); |
8343 | module_param_named(hwcrypto, iwl3945_param_hwcrypto, int, 0444); | 6378 | module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444); |
8344 | MODULE_PARM_DESC(hwcrypto, | 6379 | MODULE_PARM_DESC(swcrypto, |
8345 | "using hardware crypto engine (default 0 [software])\n"); | 6380 | "using software crypto (default 1 [software])\n"); |
8346 | module_param_named(debug, iwl3945_param_debug, uint, 0444); | 6381 | module_param_named(debug, iwl3945_mod_params.debug, uint, 0444); |
8347 | MODULE_PARM_DESC(debug, "debug output mask"); | 6382 | MODULE_PARM_DESC(debug, "debug output mask"); |
8348 | module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444); | 6383 | module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444); |
8349 | MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); | 6384 | MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); |
8350 | 6385 | ||
8351 | module_param_named(queues_num, iwl3945_param_queues_num, int, 0444); | 6386 | module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444); |
8352 | MODULE_PARM_DESC(queues_num, "number of hw queues."); | 6387 | MODULE_PARM_DESC(queues_num, "number of hw queues."); |
8353 | 6388 | ||
6389 | module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444); | ||
6390 | MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); | ||
6391 | |||
8354 | module_exit(iwl3945_exit); | 6392 | module_exit(iwl3945_exit); |
8355 | module_init(iwl3945_init); | 6393 | module_init(iwl3945_init); |
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile index 02080a3682a9..0b6918584503 100644 --- a/drivers/net/wireless/libertas/Makefile +++ b/drivers/net/wireless/libertas/Makefile | |||
@@ -4,8 +4,10 @@ libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o 11d.o \ | |||
4 | usb8xxx-objs += if_usb.o | 4 | usb8xxx-objs += if_usb.o |
5 | libertas_cs-objs += if_cs.o | 5 | libertas_cs-objs += if_cs.o |
6 | libertas_sdio-objs += if_sdio.o | 6 | libertas_sdio-objs += if_sdio.o |
7 | libertas_spi-objs += if_spi.o | ||
7 | 8 | ||
8 | obj-$(CONFIG_LIBERTAS) += libertas.o | 9 | obj-$(CONFIG_LIBERTAS) += libertas.o |
9 | obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o | 10 | obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o |
10 | obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o | 11 | obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o |
11 | obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o | 12 | obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o |
13 | obj-$(CONFIG_LIBERTAS_SPI) += libertas_spi.o | ||
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index c364e4c01d1b..6388b05df4fc 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h | |||
@@ -41,6 +41,7 @@ | |||
41 | #define LBS_DEB_HEX 0x00200000 | 41 | #define LBS_DEB_HEX 0x00200000 |
42 | #define LBS_DEB_SDIO 0x00400000 | 42 | #define LBS_DEB_SDIO 0x00400000 |
43 | #define LBS_DEB_SYSFS 0x00800000 | 43 | #define LBS_DEB_SYSFS 0x00800000 |
44 | #define LBS_DEB_SPI 0x01000000 | ||
44 | 45 | ||
45 | extern unsigned int lbs_debug; | 46 | extern unsigned int lbs_debug; |
46 | 47 | ||
@@ -84,6 +85,7 @@ do { if ((lbs_debug & (grp)) == (grp)) \ | |||
84 | #define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args) | 85 | #define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args) |
85 | #define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args) | 86 | #define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args) |
86 | #define lbs_deb_sysfs(fmt, args...) LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args) | 87 | #define lbs_deb_sysfs(fmt, args...) LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args) |
88 | #define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args) | ||
87 | 89 | ||
88 | #define lbs_pr_info(format, args...) \ | 90 | #define lbs_pr_info(format, args...) \ |
89 | printk(KERN_INFO DRV_NAME": " format, ## args) | 91 | printk(KERN_INFO DRV_NAME": " format, ## args) |
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index 277ff1975bde..d4457ef808a6 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h | |||
@@ -66,6 +66,7 @@ | |||
66 | #define CMD_802_11_LED_GPIO_CTRL 0x004e | 66 | #define CMD_802_11_LED_GPIO_CTRL 0x004e |
67 | #define CMD_802_11_EEPROM_ACCESS 0x0059 | 67 | #define CMD_802_11_EEPROM_ACCESS 0x0059 |
68 | #define CMD_802_11_BAND_CONFIG 0x0058 | 68 | #define CMD_802_11_BAND_CONFIG 0x0058 |
69 | #define CMD_GSPI_BUS_CONFIG 0x005a | ||
69 | #define CMD_802_11D_DOMAIN_INFO 0x005b | 70 | #define CMD_802_11D_DOMAIN_INFO 0x005b |
70 | #define CMD_802_11_KEY_MATERIAL 0x005e | 71 | #define CMD_802_11_KEY_MATERIAL 0x005e |
71 | #define CMD_802_11_SLEEP_PARAMS 0x0066 | 72 | #define CMD_802_11_SLEEP_PARAMS 0x0066 |
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index f6a79a653b7b..a899aeb676bb 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h | |||
@@ -221,6 +221,14 @@ struct cmd_ds_mac_multicast_adr { | |||
221 | u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE]; | 221 | u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE]; |
222 | } __attribute__ ((packed)); | 222 | } __attribute__ ((packed)); |
223 | 223 | ||
224 | struct cmd_ds_gspi_bus_config { | ||
225 | struct cmd_header hdr; | ||
226 | __le16 action; | ||
227 | __le16 bus_delay_mode; | ||
228 | __le16 host_time_delay_to_read_port; | ||
229 | __le16 host_time_delay_to_read_register; | ||
230 | } __attribute__ ((packed)); | ||
231 | |||
224 | struct cmd_ds_802_11_authenticate { | 232 | struct cmd_ds_802_11_authenticate { |
225 | u8 macaddr[ETH_ALEN]; | 233 | u8 macaddr[ETH_ALEN]; |
226 | u8 authtype; | 234 | u8 authtype; |
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 842a08d1f106..8f8934a5ba3a 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r | |||
151 | for (i = 0; i < 100000; i++) { | 151 | for (i = 0; i < 100000; i++) { |
152 | u8 val = if_cs_read8(card, addr); | 152 | u8 val = if_cs_read8(card, addr); |
153 | if (val == reg) | 153 | if (val == reg) |
154 | return i; | 154 | return 0; |
155 | udelay(5); | 155 | udelay(5); |
156 | } | 156 | } |
157 | return -ETIME; | 157 | return -ETIME; |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c new file mode 100644 index 000000000000..7c02ea314fd1 --- /dev/null +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -0,0 +1,1203 @@ | |||
1 | /* | ||
2 | * linux/drivers/net/wireless/libertas/if_spi.c | ||
3 | * | ||
4 | * Driver for Marvell SPI WLAN cards. | ||
5 | * | ||
6 | * Copyright 2008 Analog Devices Inc. | ||
7 | * | ||
8 | * Authors: | ||
9 | * Andrey Yurovsky <andrey@cozybit.com> | ||
10 | * Colin McCabe <colin@cozybit.com> | ||
11 | * | ||
12 | * Inspired by if_sdio.c, Copyright 2007-2008 Pierre Ossman | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | */ | ||
19 | |||
20 | #include <linux/moduleparam.h> | ||
21 | #include <linux/firmware.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/kthread.h> | ||
25 | #include <linux/list.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/spi/libertas_spi.h> | ||
28 | #include <linux/spi/spi.h> | ||
29 | |||
30 | #include "host.h" | ||
31 | #include "decl.h" | ||
32 | #include "defs.h" | ||
33 | #include "dev.h" | ||
34 | #include "if_spi.h" | ||
35 | |||
36 | struct if_spi_packet { | ||
37 | struct list_head list; | ||
38 | u16 blen; | ||
39 | u8 buffer[0] __attribute__((aligned(4))); | ||
40 | }; | ||
41 | |||
42 | struct if_spi_card { | ||
43 | struct spi_device *spi; | ||
44 | struct lbs_private *priv; | ||
45 | |||
46 | char helper_fw_name[FIRMWARE_NAME_MAX]; | ||
47 | char main_fw_name[FIRMWARE_NAME_MAX]; | ||
48 | |||
49 | /* The card ID and card revision, as reported by the hardware. */ | ||
50 | u16 card_id; | ||
51 | u8 card_rev; | ||
52 | |||
53 | /* Pin number for our GPIO chip-select. */ | ||
54 | /* TODO: Once the generic SPI layer has some additional features, we | ||
55 | * should take this out and use the normal chip select here. | ||
56 | * We need support for chip select delays, and not dropping chipselect | ||
57 | * after each word. */ | ||
58 | int gpio_cs; | ||
59 | |||
60 | /* The last time that we initiated an SPU operation */ | ||
61 | unsigned long prev_xfer_time; | ||
62 | |||
63 | int use_dummy_writes; | ||
64 | unsigned long spu_port_delay; | ||
65 | unsigned long spu_reg_delay; | ||
66 | |||
67 | /* Handles all SPI communication (except for FW load) */ | ||
68 | struct task_struct *spi_thread; | ||
69 | int run_thread; | ||
70 | |||
71 | /* Used to wake up the spi_thread */ | ||
72 | struct semaphore spi_ready; | ||
73 | struct semaphore spi_thread_terminated; | ||
74 | |||
75 | u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; | ||
76 | |||
77 | /* A buffer of incoming packets from libertas core. | ||
78 | * Since we can't sleep in hw_host_to_card, we have to buffer | ||
79 | * them. */ | ||
80 | struct list_head cmd_packet_list; | ||
81 | struct list_head data_packet_list; | ||
82 | |||
83 | /* Protects cmd_packet_list and data_packet_list */ | ||
84 | spinlock_t buffer_lock; | ||
85 | }; | ||
86 | |||
87 | static void free_if_spi_card(struct if_spi_card *card) | ||
88 | { | ||
89 | struct list_head *cursor, *next; | ||
90 | struct if_spi_packet *packet; | ||
91 | |||
92 | BUG_ON(card->run_thread); | ||
93 | list_for_each_safe(cursor, next, &card->cmd_packet_list) { | ||
94 | packet = container_of(cursor, struct if_spi_packet, list); | ||
95 | list_del(&packet->list); | ||
96 | kfree(packet); | ||
97 | } | ||
98 | list_for_each_safe(cursor, next, &card->data_packet_list) { | ||
99 | packet = container_of(cursor, struct if_spi_packet, list); | ||
100 | list_del(&packet->list); | ||
101 | kfree(packet); | ||
102 | } | ||
103 | spi_set_drvdata(card->spi, NULL); | ||
104 | kfree(card); | ||
105 | } | ||
106 | |||
107 | static struct chip_ident chip_id_to_device_name[] = { | ||
108 | { .chip_id = 0x04, .name = 8385 }, | ||
109 | { .chip_id = 0x0b, .name = 8686 }, | ||
110 | }; | ||
111 | |||
112 | /* | ||
113 | * SPI Interface Unit Routines | ||
114 | * | ||
115 | * The SPU sits between the host and the WLAN module. | ||
116 | * All communication with the firmware is through SPU transactions. | ||
117 | * | ||
118 | * First we have to put a SPU register name on the bus. Then we can | ||
119 | * either read from or write to that register. | ||
120 | * | ||
121 | * For 16-bit transactions, byte order on the bus is big-endian. | ||
122 | * We don't have to worry about that here, though. | ||
123 | * The translation takes place in the SPI routines. | ||
124 | */ | ||
125 | |||
126 | static void spu_transaction_init(struct if_spi_card *card) | ||
127 | { | ||
128 | if (!time_after(jiffies, card->prev_xfer_time + 1)) { | ||
129 | /* Unfortunately, the SPU requires a delay between successive | ||
130 | * transactions. If our last transaction was more than a jiffy | ||
131 | * ago, we have obviously already delayed enough. | ||
132 | * If not, we have to busy-wait to be on the safe side. */ | ||
133 | ndelay(400); | ||
134 | } | ||
135 | gpio_set_value(card->gpio_cs, 0); /* assert CS */ | ||
136 | } | ||
137 | |||
138 | static void spu_transaction_finish(struct if_spi_card *card) | ||
139 | { | ||
140 | gpio_set_value(card->gpio_cs, 1); /* drop CS */ | ||
141 | card->prev_xfer_time = jiffies; | ||
142 | } | ||
143 | |||
144 | /* Write out a byte buffer to an SPI register, | ||
145 | * using a series of 16-bit transfers. */ | ||
146 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | ||
147 | { | ||
148 | int err = 0; | ||
149 | u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK; | ||
150 | |||
151 | /* You must give an even number of bytes to the SPU, even if it | ||
152 | * doesn't care about the last one. */ | ||
153 | BUG_ON(len & 0x1); | ||
154 | |||
155 | spu_transaction_init(card); | ||
156 | |||
157 | /* write SPU register index */ | ||
158 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | ||
159 | if (err) | ||
160 | goto out; | ||
161 | |||
162 | err = spi_write(card->spi, buf, len); | ||
163 | |||
164 | out: | ||
165 | spu_transaction_finish(card); | ||
166 | return err; | ||
167 | } | ||
168 | |||
169 | static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) | ||
170 | { | ||
171 | return spu_write(card, reg, (u8 *)&val, sizeof(u16)); | ||
172 | } | ||
173 | |||
174 | static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val) | ||
175 | { | ||
176 | /* The lower 16 bits are written first. */ | ||
177 | u16 out[2]; | ||
178 | out[0] = val & 0xffff; | ||
179 | out[1] = (val & 0xffff0000) >> 16; | ||
180 | return spu_write(card, reg, (u8 *)&out, sizeof(u32)); | ||
181 | } | ||
182 | |||
183 | static inline int spu_reg_is_port_reg(u16 reg) | ||
184 | { | ||
185 | switch (reg) { | ||
186 | case IF_SPI_IO_RDWRPORT_REG: | ||
187 | case IF_SPI_CMD_RDWRPORT_REG: | ||
188 | case IF_SPI_DATA_RDWRPORT_REG: | ||
189 | return 1; | ||
190 | default: | ||
191 | return 0; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | ||
196 | { | ||
197 | unsigned int i, delay; | ||
198 | int err = 0; | ||
199 | u16 zero = 0; | ||
200 | u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK; | ||
201 | |||
202 | /* You must take an even number of bytes from the SPU, even if you | ||
203 | * don't care about the last one. */ | ||
204 | BUG_ON(len & 0x1); | ||
205 | |||
206 | spu_transaction_init(card); | ||
207 | |||
208 | /* write SPU register index */ | ||
209 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | ||
210 | if (err) | ||
211 | goto out; | ||
212 | |||
213 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : | ||
214 | card->spu_reg_delay; | ||
215 | if (card->use_dummy_writes) { | ||
216 | /* Clock in dummy cycles while the SPU fills the FIFO */ | ||
217 | for (i = 0; i < delay / 16; ++i) { | ||
218 | err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); | ||
219 | if (err) | ||
220 | return err; | ||
221 | } | ||
222 | } else { | ||
223 | /* Busy-wait while the SPU fills the FIFO */ | ||
224 | ndelay(100 + (delay * 10)); | ||
225 | } | ||
226 | |||
227 | /* read in data */ | ||
228 | err = spi_read(card->spi, buf, len); | ||
229 | |||
230 | out: | ||
231 | spu_transaction_finish(card); | ||
232 | return err; | ||
233 | } | ||
234 | |||
235 | /* Read 16 bits from an SPI register */ | ||
236 | static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) | ||
237 | { | ||
238 | return spu_read(card, reg, (u8 *)val, sizeof(u16)); | ||
239 | } | ||
240 | |||
241 | /* Read 32 bits from an SPI register. | ||
242 | * The low 16 bits are read first. */ | ||
243 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | ||
244 | { | ||
245 | u16 buf[2]; | ||
246 | int err; | ||
247 | err = spu_read(card, reg, (u8 *)buf, sizeof(u32)); | ||
248 | if (!err) | ||
249 | *val = buf[0] | (buf[1] << 16); | ||
250 | return err; | ||
251 | } | ||
252 | |||
253 | /* Keep reading 16 bits from an SPI register until you get the correct result. | ||
254 | * | ||
255 | * If mask = 0, the correct result is any non-zero number. | ||
256 | * If mask != 0, the correct result is any number where | ||
257 | * number & target_mask == target | ||
258 | * | ||
259 | * Returns -ETIMEDOUT if a second passes without the correct result. */ | ||
260 | static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, | ||
261 | u16 target_mask, u16 target) | ||
262 | { | ||
263 | int err; | ||
264 | unsigned long timeout = jiffies + 5*HZ; | ||
265 | while (1) { | ||
266 | u16 val; | ||
267 | err = spu_read_u16(card, reg, &val); | ||
268 | if (err) | ||
269 | return err; | ||
270 | if (target_mask) { | ||
271 | if ((val & target_mask) == target) | ||
272 | return 0; | ||
273 | } else { | ||
274 | if (val) | ||
275 | return 0; | ||
276 | } | ||
277 | udelay(100); | ||
278 | if (time_after(jiffies, timeout)) { | ||
279 | lbs_pr_err("%s: timeout with val=%02x, " | ||
280 | "target_mask=%02x, target=%02x\n", | ||
281 | __func__, val, target_mask, target); | ||
282 | return -ETIMEDOUT; | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | |||
287 | /* Read 16 bits from an SPI register until you receive a specific value. | ||
288 | * Returns -ETIMEDOUT if a 4 tries pass without success. */ | ||
289 | static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target) | ||
290 | { | ||
291 | int err, try; | ||
292 | for (try = 0; try < 4; ++try) { | ||
293 | u32 val = 0; | ||
294 | err = spu_read_u32(card, reg, &val); | ||
295 | if (err) | ||
296 | return err; | ||
297 | if (val == target) | ||
298 | return 0; | ||
299 | mdelay(100); | ||
300 | } | ||
301 | return -ETIMEDOUT; | ||
302 | } | ||
303 | |||
304 | static int spu_set_interrupt_mode(struct if_spi_card *card, | ||
305 | int suppress_host_int, | ||
306 | int auto_int) | ||
307 | { | ||
308 | int err = 0; | ||
309 | |||
310 | /* We can suppress a host interrupt by clearing the appropriate | ||
311 | * bit in the "host interrupt status mask" register */ | ||
312 | if (suppress_host_int) { | ||
313 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0); | ||
314 | if (err) | ||
315 | return err; | ||
316 | } else { | ||
317 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, | ||
318 | IF_SPI_HISM_TX_DOWNLOAD_RDY | | ||
319 | IF_SPI_HISM_RX_UPLOAD_RDY | | ||
320 | IF_SPI_HISM_CMD_DOWNLOAD_RDY | | ||
321 | IF_SPI_HISM_CARDEVENT | | ||
322 | IF_SPI_HISM_CMD_UPLOAD_RDY); | ||
323 | if (err) | ||
324 | return err; | ||
325 | } | ||
326 | |||
327 | /* If auto-interrupts are on, the completion of certain transactions | ||
328 | * will trigger an interrupt automatically. If auto-interrupts | ||
329 | * are off, we need to set the "Card Interrupt Cause" register to | ||
330 | * trigger a card interrupt. */ | ||
331 | if (auto_int) { | ||
332 | err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG, | ||
333 | IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO | | ||
334 | IF_SPI_HICT_RX_UPLOAD_OVER_AUTO | | ||
335 | IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO | | ||
336 | IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO); | ||
337 | if (err) | ||
338 | return err; | ||
339 | } else { | ||
340 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0); | ||
341 | if (err) | ||
342 | return err; | ||
343 | } | ||
344 | return err; | ||
345 | } | ||
346 | |||
347 | static int spu_get_chip_revision(struct if_spi_card *card, | ||
348 | u16 *card_id, u8 *card_rev) | ||
349 | { | ||
350 | int err = 0; | ||
351 | u32 dev_ctrl; | ||
352 | err = spu_read_u32(card, IF_SPI_DEVICEID_CTRL_REG, &dev_ctrl); | ||
353 | if (err) | ||
354 | return err; | ||
355 | *card_id = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dev_ctrl); | ||
356 | *card_rev = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dev_ctrl); | ||
357 | return err; | ||
358 | } | ||
359 | |||
360 | static int spu_set_bus_mode(struct if_spi_card *card, u16 mode) | ||
361 | { | ||
362 | int err = 0; | ||
363 | u16 rval; | ||
364 | /* set bus mode */ | ||
365 | err = spu_write_u16(card, IF_SPI_SPU_BUS_MODE_REG, mode); | ||
366 | if (err) | ||
367 | return err; | ||
368 | /* Check that we were able to read back what we just wrote. */ | ||
369 | err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval); | ||
370 | if (err) | ||
371 | return err; | ||
372 | if (rval != mode) { | ||
373 | lbs_pr_err("Can't read bus mode register.\n"); | ||
374 | return -EIO; | ||
375 | } | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int spu_init(struct if_spi_card *card, int use_dummy_writes) | ||
380 | { | ||
381 | int err = 0; | ||
382 | u32 delay; | ||
383 | |||
384 | /* We have to start up in timed delay mode so that we can safely | ||
385 | * read the Delay Read Register. */ | ||
386 | card->use_dummy_writes = 0; | ||
387 | err = spu_set_bus_mode(card, | ||
388 | IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING | | ||
389 | IF_SPI_BUS_MODE_DELAY_METHOD_TIMED | | ||
390 | IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA); | ||
391 | if (err) | ||
392 | return err; | ||
393 | card->spu_port_delay = 1000; | ||
394 | card->spu_reg_delay = 1000; | ||
395 | err = spu_read_u32(card, IF_SPI_DELAY_READ_REG, &delay); | ||
396 | if (err) | ||
397 | return err; | ||
398 | card->spu_port_delay = delay & 0x0000ffff; | ||
399 | card->spu_reg_delay = (delay & 0xffff0000) >> 16; | ||
400 | |||
401 | /* If dummy clock delay mode has been requested, switch to it now */ | ||
402 | if (use_dummy_writes) { | ||
403 | card->use_dummy_writes = 1; | ||
404 | err = spu_set_bus_mode(card, | ||
405 | IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING | | ||
406 | IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK | | ||
407 | IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA); | ||
408 | if (err) | ||
409 | return err; | ||
410 | } | ||
411 | |||
412 | lbs_deb_spi("Initialized SPU unit. " | ||
413 | "spu_port_delay=0x%04lx, spu_reg_delay=0x%04lx\n", | ||
414 | card->spu_port_delay, card->spu_reg_delay); | ||
415 | return err; | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * Firmware Loading | ||
420 | */ | ||
421 | |||
422 | static int if_spi_prog_helper_firmware(struct if_spi_card *card) | ||
423 | { | ||
424 | int err = 0; | ||
425 | const struct firmware *firmware = NULL; | ||
426 | int bytes_remaining; | ||
427 | const u8 *fw; | ||
428 | u8 temp[HELPER_FW_LOAD_CHUNK_SZ]; | ||
429 | struct spi_device *spi = card->spi; | ||
430 | |||
431 | lbs_deb_enter(LBS_DEB_SPI); | ||
432 | |||
433 | err = spu_set_interrupt_mode(card, 1, 0); | ||
434 | if (err) | ||
435 | goto out; | ||
436 | /* Get helper firmware image */ | ||
437 | err = request_firmware(&firmware, card->helper_fw_name, &spi->dev); | ||
438 | if (err) { | ||
439 | lbs_pr_err("request_firmware failed with err = %d\n", err); | ||
440 | goto out; | ||
441 | } | ||
442 | bytes_remaining = firmware->size; | ||
443 | fw = firmware->data; | ||
444 | |||
445 | /* Load helper firmware image */ | ||
446 | while (bytes_remaining > 0) { | ||
447 | /* Scratch pad 1 should contain the number of bytes we | ||
448 | * want to download to the firmware */ | ||
449 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, | ||
450 | HELPER_FW_LOAD_CHUNK_SZ); | ||
451 | if (err) | ||
452 | goto release_firmware; | ||
453 | |||
454 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, | ||
455 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, | ||
456 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); | ||
457 | if (err) | ||
458 | goto release_firmware; | ||
459 | |||
460 | /* Feed the data into the command read/write port reg | ||
461 | * in chunks of 64 bytes */ | ||
462 | memset(temp, 0, sizeof(temp)); | ||
463 | memcpy(temp, fw, | ||
464 | min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ)); | ||
465 | mdelay(10); | ||
466 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, | ||
467 | temp, HELPER_FW_LOAD_CHUNK_SZ); | ||
468 | if (err) | ||
469 | goto release_firmware; | ||
470 | |||
471 | /* Interrupt the boot code */ | ||
472 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); | ||
473 | if (err) | ||
474 | goto release_firmware; | ||
475 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, | ||
476 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); | ||
477 | if (err) | ||
478 | goto release_firmware; | ||
479 | bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ; | ||
480 | fw += HELPER_FW_LOAD_CHUNK_SZ; | ||
481 | } | ||
482 | |||
483 | /* Once the helper / single stage firmware download is complete, | ||
484 | * write 0 to scratch pad 1 and interrupt the | ||
485 | * bootloader. This completes the helper download. */ | ||
486 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); | ||
487 | if (err) | ||
488 | goto release_firmware; | ||
489 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); | ||
490 | if (err) | ||
491 | goto release_firmware; | ||
492 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, | ||
493 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); | ||
494 | goto release_firmware; | ||
495 | |||
496 | lbs_deb_spi("waiting for helper to boot...\n"); | ||
497 | |||
498 | release_firmware: | ||
499 | release_firmware(firmware); | ||
500 | out: | ||
501 | if (err) | ||
502 | lbs_pr_err("failed to load helper firmware (err=%d)\n", err); | ||
503 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); | ||
504 | return err; | ||
505 | } | ||
506 | |||
507 | /* Returns the length of the next packet the firmware expects us to send | ||
508 | * Sets crc_err if the previous transfer had a CRC error. */ | ||
509 | static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, | ||
510 | int *crc_err) | ||
511 | { | ||
512 | u16 len; | ||
513 | int err = 0; | ||
514 | |||
515 | /* wait until the host interrupt status register indicates | ||
516 | * that we are ready to download */ | ||
517 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, | ||
518 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, | ||
519 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); | ||
520 | if (err) { | ||
521 | lbs_pr_err("timed out waiting for host_int_status\n"); | ||
522 | return err; | ||
523 | } | ||
524 | |||
525 | /* Ask the device how many bytes of firmware it wants. */ | ||
526 | err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len); | ||
527 | if (err) | ||
528 | return err; | ||
529 | |||
530 | if (len > IF_SPI_CMD_BUF_SIZE) { | ||
531 | lbs_pr_err("firmware load device requested a larger " | ||
532 | "tranfer than we are prepared to " | ||
533 | "handle. (len = %d)\n", len); | ||
534 | return -EIO; | ||
535 | } | ||
536 | if (len & 0x1) { | ||
537 | lbs_deb_spi("%s: crc error\n", __func__); | ||
538 | len &= ~0x1; | ||
539 | *crc_err = 1; | ||
540 | } else | ||
541 | *crc_err = 0; | ||
542 | |||
543 | return len; | ||
544 | } | ||
545 | |||
546 | static int if_spi_prog_main_firmware(struct if_spi_card *card) | ||
547 | { | ||
548 | int len, prev_len; | ||
549 | int bytes, crc_err = 0, err = 0; | ||
550 | const struct firmware *firmware = NULL; | ||
551 | const u8 *fw; | ||
552 | struct spi_device *spi = card->spi; | ||
553 | u16 num_crc_errs; | ||
554 | |||
555 | lbs_deb_enter(LBS_DEB_SPI); | ||
556 | |||
557 | err = spu_set_interrupt_mode(card, 1, 0); | ||
558 | if (err) | ||
559 | goto out; | ||
560 | |||
561 | /* Get firmware image */ | ||
562 | err = request_firmware(&firmware, card->main_fw_name, &spi->dev); | ||
563 | if (err) { | ||
564 | lbs_pr_err("%s: can't get firmware '%s' from kernel. " | ||
565 | "err = %d\n", __func__, card->main_fw_name, err); | ||
566 | goto out; | ||
567 | } | ||
568 | |||
569 | err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0); | ||
570 | if (err) { | ||
571 | lbs_pr_err("%s: timed out waiting for initial " | ||
572 | "scratch reg = 0\n", __func__); | ||
573 | goto release_firmware; | ||
574 | } | ||
575 | |||
576 | num_crc_errs = 0; | ||
577 | prev_len = 0; | ||
578 | bytes = firmware->size; | ||
579 | fw = firmware->data; | ||
580 | while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) { | ||
581 | if (len < 0) { | ||
582 | err = len; | ||
583 | goto release_firmware; | ||
584 | } | ||
585 | if (bytes < 0) { | ||
586 | /* If there are no more bytes left, we would normally | ||
587 | * expect to have terminated with len = 0 */ | ||
588 | lbs_pr_err("Firmware load wants more bytes " | ||
589 | "than we have to offer.\n"); | ||
590 | break; | ||
591 | } | ||
592 | if (crc_err) { | ||
593 | /* Previous transfer failed. */ | ||
594 | if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) { | ||
595 | lbs_pr_err("Too many CRC errors encountered " | ||
596 | "in firmware load.\n"); | ||
597 | err = -EIO; | ||
598 | goto release_firmware; | ||
599 | } | ||
600 | } else { | ||
601 | /* Previous transfer succeeded. Advance counters. */ | ||
602 | bytes -= prev_len; | ||
603 | fw += prev_len; | ||
604 | } | ||
605 | if (bytes < len) { | ||
606 | memset(card->cmd_buffer, 0, len); | ||
607 | memcpy(card->cmd_buffer, fw, bytes); | ||
608 | } else | ||
609 | memcpy(card->cmd_buffer, fw, len); | ||
610 | |||
611 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); | ||
612 | if (err) | ||
613 | goto release_firmware; | ||
614 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, | ||
615 | card->cmd_buffer, len); | ||
616 | if (err) | ||
617 | goto release_firmware; | ||
618 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG , | ||
619 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); | ||
620 | if (err) | ||
621 | goto release_firmware; | ||
622 | prev_len = len; | ||
623 | } | ||
624 | if (bytes > prev_len) { | ||
625 | lbs_pr_err("firmware load wants fewer bytes than " | ||
626 | "we have to offer.\n"); | ||
627 | } | ||
628 | |||
629 | /* Confirm firmware download */ | ||
630 | err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG, | ||
631 | SUCCESSFUL_FW_DOWNLOAD_MAGIC); | ||
632 | if (err) { | ||
633 | lbs_pr_err("failed to confirm the firmware download\n"); | ||
634 | goto release_firmware; | ||
635 | } | ||
636 | |||
637 | release_firmware: | ||
638 | release_firmware(firmware); | ||
639 | |||
640 | out: | ||
641 | if (err) | ||
642 | lbs_pr_err("failed to load firmware (err=%d)\n", err); | ||
643 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); | ||
644 | return err; | ||
645 | } | ||
646 | |||
647 | /* | ||
648 | * SPI Transfer Thread | ||
649 | * | ||
650 | * The SPI thread handles all SPI transfers, so there is no need for a lock. | ||
651 | */ | ||
652 | |||
653 | /* Move a command from the card to the host */ | ||
654 | static int if_spi_c2h_cmd(struct if_spi_card *card) | ||
655 | { | ||
656 | struct lbs_private *priv = card->priv; | ||
657 | unsigned long flags; | ||
658 | int err = 0; | ||
659 | u16 len; | ||
660 | u8 i; | ||
661 | |||
662 | /* We need a buffer big enough to handle whatever people send to | ||
663 | * hw_host_to_card */ | ||
664 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE); | ||
665 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE); | ||
666 | |||
667 | /* It's just annoying if the buffer size isn't a multiple of 4, because | ||
668 | * then we might have len < IF_SPI_CMD_BUF_SIZE but | ||
669 | * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */ | ||
670 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0); | ||
671 | |||
672 | lbs_deb_enter(LBS_DEB_SPI); | ||
673 | |||
674 | /* How many bytes are there to read? */ | ||
675 | err = spu_read_u16(card, IF_SPI_SCRATCH_2_REG, &len); | ||
676 | if (err) | ||
677 | goto out; | ||
678 | if (!len) { | ||
679 | lbs_pr_err("%s: error: card has no data for host\n", | ||
680 | __func__); | ||
681 | err = -EINVAL; | ||
682 | goto out; | ||
683 | } else if (len > IF_SPI_CMD_BUF_SIZE) { | ||
684 | lbs_pr_err("%s: error: response packet too large: " | ||
685 | "%d bytes, but maximum is %d\n", | ||
686 | __func__, len, IF_SPI_CMD_BUF_SIZE); | ||
687 | err = -EINVAL; | ||
688 | goto out; | ||
689 | } | ||
690 | |||
691 | /* Read the data from the WLAN module into our command buffer */ | ||
692 | err = spu_read(card, IF_SPI_CMD_RDWRPORT_REG, | ||
693 | card->cmd_buffer, ALIGN(len, 4)); | ||
694 | if (err) | ||
695 | goto out; | ||
696 | |||
697 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
698 | i = (priv->resp_idx == 0) ? 1 : 0; | ||
699 | BUG_ON(priv->resp_len[i]); | ||
700 | priv->resp_len[i] = len; | ||
701 | memcpy(priv->resp_buf[i], card->cmd_buffer, len); | ||
702 | lbs_notify_command_response(priv, i); | ||
703 | spin_unlock_irqrestore(&priv->driver_lock, flags); | ||
704 | |||
705 | out: | ||
706 | if (err) | ||
707 | lbs_pr_err("%s: err=%d\n", __func__, err); | ||
708 | lbs_deb_leave(LBS_DEB_SPI); | ||
709 | return err; | ||
710 | } | ||
711 | |||
712 | /* Move data from the card to the host */ | ||
713 | static int if_spi_c2h_data(struct if_spi_card *card) | ||
714 | { | ||
715 | struct sk_buff *skb; | ||
716 | char *data; | ||
717 | u16 len; | ||
718 | int err = 0; | ||
719 | |||
720 | lbs_deb_enter(LBS_DEB_SPI); | ||
721 | |||
722 | /* How many bytes are there to read? */ | ||
723 | err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len); | ||
724 | if (err) | ||
725 | goto out; | ||
726 | if (!len) { | ||
727 | lbs_pr_err("%s: error: card has no data for host\n", | ||
728 | __func__); | ||
729 | err = -EINVAL; | ||
730 | goto out; | ||
731 | } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { | ||
732 | lbs_pr_err("%s: error: card has %d bytes of data, but " | ||
733 | "our maximum skb size is %u\n", | ||
734 | __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); | ||
735 | err = -EINVAL; | ||
736 | goto out; | ||
737 | } | ||
738 | |||
739 | /* TODO: should we allocate a smaller skb if we have less data? */ | ||
740 | skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); | ||
741 | if (!skb) { | ||
742 | err = -ENOBUFS; | ||
743 | goto out; | ||
744 | } | ||
745 | skb_reserve(skb, IPFIELD_ALIGN_OFFSET); | ||
746 | data = skb_put(skb, len); | ||
747 | |||
748 | /* Read the data from the WLAN module into our skb... */ | ||
749 | err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4)); | ||
750 | if (err) | ||
751 | goto free_skb; | ||
752 | |||
753 | /* pass the SKB to libertas */ | ||
754 | err = lbs_process_rxed_packet(card->priv, skb); | ||
755 | if (err) | ||
756 | goto free_skb; | ||
757 | |||
758 | /* success */ | ||
759 | goto out; | ||
760 | |||
761 | free_skb: | ||
762 | dev_kfree_skb(skb); | ||
763 | out: | ||
764 | if (err) | ||
765 | lbs_pr_err("%s: err=%d\n", __func__, err); | ||
766 | lbs_deb_leave(LBS_DEB_SPI); | ||
767 | return err; | ||
768 | } | ||
769 | |||
770 | /* Move data or a command from the host to the card. */ | ||
771 | static void if_spi_h2c(struct if_spi_card *card, | ||
772 | struct if_spi_packet *packet, int type) | ||
773 | { | ||
774 | int err = 0; | ||
775 | u16 int_type, port_reg; | ||
776 | |||
777 | switch (type) { | ||
778 | case MVMS_DAT: | ||
779 | int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER; | ||
780 | port_reg = IF_SPI_DATA_RDWRPORT_REG; | ||
781 | break; | ||
782 | case MVMS_CMD: | ||
783 | int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER; | ||
784 | port_reg = IF_SPI_CMD_RDWRPORT_REG; | ||
785 | break; | ||
786 | default: | ||
787 | lbs_pr_err("can't transfer buffer of type %d\n", type); | ||
788 | err = -EINVAL; | ||
789 | goto out; | ||
790 | } | ||
791 | |||
792 | /* Write the data to the card */ | ||
793 | err = spu_write(card, port_reg, packet->buffer, packet->blen); | ||
794 | if (err) | ||
795 | goto out; | ||
796 | |||
797 | out: | ||
798 | kfree(packet); | ||
799 | |||
800 | if (err) | ||
801 | lbs_pr_err("%s: error %d\n", __func__, err); | ||
802 | } | ||
803 | |||
804 | /* Inform the host about a card event */ | ||
805 | static void if_spi_e2h(struct if_spi_card *card) | ||
806 | { | ||
807 | int err = 0; | ||
808 | unsigned long flags; | ||
809 | u32 cause; | ||
810 | struct lbs_private *priv = card->priv; | ||
811 | |||
812 | err = spu_read_u32(card, IF_SPI_SCRATCH_3_REG, &cause); | ||
813 | if (err) | ||
814 | goto out; | ||
815 | |||
816 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
817 | lbs_queue_event(priv, cause & 0xff); | ||
818 | spin_unlock_irqrestore(&priv->driver_lock, flags); | ||
819 | |||
820 | out: | ||
821 | if (err) | ||
822 | lbs_pr_err("%s: error %d\n", __func__, err); | ||
823 | } | ||
824 | |||
825 | static int lbs_spi_thread(void *data) | ||
826 | { | ||
827 | int err; | ||
828 | struct if_spi_card *card = data; | ||
829 | u16 hiStatus; | ||
830 | unsigned long flags; | ||
831 | struct if_spi_packet *packet; | ||
832 | |||
833 | while (1) { | ||
834 | /* Wait to be woken up by one of two things. First, our ISR | ||
835 | * could tell us that something happened on the WLAN. | ||
836 | * Secondly, libertas could call hw_host_to_card with more | ||
837 | * data, which we might be able to send. | ||
838 | */ | ||
839 | do { | ||
840 | err = down_interruptible(&card->spi_ready); | ||
841 | if (!card->run_thread) { | ||
842 | up(&card->spi_thread_terminated); | ||
843 | do_exit(0); | ||
844 | } | ||
845 | } while (err == EINTR); | ||
846 | |||
847 | /* Read the host interrupt status register to see what we | ||
848 | * can do. */ | ||
849 | err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, | ||
850 | &hiStatus); | ||
851 | if (err) { | ||
852 | lbs_pr_err("I/O error\n"); | ||
853 | goto err; | ||
854 | } | ||
855 | |||
856 | if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) | ||
857 | err = if_spi_c2h_cmd(card); | ||
858 | if (err) | ||
859 | goto err; | ||
860 | if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) | ||
861 | err = if_spi_c2h_data(card); | ||
862 | if (err) | ||
863 | goto err; | ||
864 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY) { | ||
865 | /* This means two things. First of all, | ||
866 | * if there was a previous command sent, the card has | ||
867 | * successfully received it. | ||
868 | * Secondly, it is now ready to download another | ||
869 | * command. | ||
870 | */ | ||
871 | lbs_host_to_card_done(card->priv); | ||
872 | |||
873 | /* Do we have any command packets from the host to | ||
874 | * send? */ | ||
875 | packet = NULL; | ||
876 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
877 | if (!list_empty(&card->cmd_packet_list)) { | ||
878 | packet = (struct if_spi_packet *)(card-> | ||
879 | cmd_packet_list.next); | ||
880 | list_del(&packet->list); | ||
881 | } | ||
882 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
883 | |||
884 | if (packet) | ||
885 | if_spi_h2c(card, packet, MVMS_CMD); | ||
886 | } | ||
887 | if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) { | ||
888 | /* Do we have any data packets from the host to | ||
889 | * send? */ | ||
890 | packet = NULL; | ||
891 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
892 | if (!list_empty(&card->data_packet_list)) { | ||
893 | packet = (struct if_spi_packet *)(card-> | ||
894 | data_packet_list.next); | ||
895 | list_del(&packet->list); | ||
896 | } | ||
897 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
898 | |||
899 | if (packet) | ||
900 | if_spi_h2c(card, packet, MVMS_DAT); | ||
901 | } | ||
902 | if (hiStatus & IF_SPI_HIST_CARD_EVENT) | ||
903 | if_spi_e2h(card); | ||
904 | |||
905 | err: | ||
906 | if (err) | ||
907 | lbs_pr_err("%s: got error %d\n", __func__, err); | ||
908 | } | ||
909 | } | ||
910 | |||
911 | /* Block until lbs_spi_thread thread has terminated */ | ||
912 | static void if_spi_terminate_spi_thread(struct if_spi_card *card) | ||
913 | { | ||
914 | /* It would be nice to use kthread_stop here, but that function | ||
915 | * can't wake threads waiting for a semaphore. */ | ||
916 | card->run_thread = 0; | ||
917 | up(&card->spi_ready); | ||
918 | down(&card->spi_thread_terminated); | ||
919 | } | ||
920 | |||
921 | /* | ||
922 | * Host to Card | ||
923 | * | ||
924 | * Called from Libertas to transfer some data to the WLAN device | ||
925 | * We can't sleep here. */ | ||
926 | static int if_spi_host_to_card(struct lbs_private *priv, | ||
927 | u8 type, u8 *buf, u16 nb) | ||
928 | { | ||
929 | int err = 0; | ||
930 | unsigned long flags; | ||
931 | struct if_spi_card *card = priv->card; | ||
932 | struct if_spi_packet *packet; | ||
933 | u16 blen; | ||
934 | |||
935 | lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb); | ||
936 | |||
937 | if (nb == 0) { | ||
938 | lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb); | ||
939 | err = -EINVAL; | ||
940 | goto out; | ||
941 | } | ||
942 | blen = ALIGN(nb, 4); | ||
943 | packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC); | ||
944 | if (!packet) { | ||
945 | err = -ENOMEM; | ||
946 | goto out; | ||
947 | } | ||
948 | packet->blen = blen; | ||
949 | memcpy(packet->buffer, buf, nb); | ||
950 | memset(packet->buffer + nb, 0, blen - nb); | ||
951 | |||
952 | switch (type) { | ||
953 | case MVMS_CMD: | ||
954 | priv->dnld_sent = DNLD_CMD_SENT; | ||
955 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
956 | list_add_tail(&packet->list, &card->cmd_packet_list); | ||
957 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
958 | break; | ||
959 | case MVMS_DAT: | ||
960 | priv->dnld_sent = DNLD_DATA_SENT; | ||
961 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
962 | list_add_tail(&packet->list, &card->data_packet_list); | ||
963 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
964 | break; | ||
965 | default: | ||
966 | lbs_pr_err("can't transfer buffer of type %d", type); | ||
967 | err = -EINVAL; | ||
968 | break; | ||
969 | } | ||
970 | |||
971 | /* Wake up the spi thread */ | ||
972 | up(&card->spi_ready); | ||
973 | out: | ||
974 | lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err); | ||
975 | return err; | ||
976 | } | ||
977 | |||
978 | /* | ||
979 | * Host Interrupts | ||
980 | * | ||
981 | * Service incoming interrupts from the WLAN device. We can't sleep here, so | ||
982 | * don't try to talk on the SPI bus, just wake up the SPI thread. | ||
983 | */ | ||
984 | static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) | ||
985 | { | ||
986 | struct if_spi_card *card = dev_id; | ||
987 | |||
988 | up(&card->spi_ready); | ||
989 | return IRQ_HANDLED; | ||
990 | } | ||
991 | |||
992 | /* | ||
993 | * SPI callbacks | ||
994 | */ | ||
995 | |||
996 | static int if_spi_calculate_fw_names(u16 card_id, | ||
997 | char *helper_fw, char *main_fw) | ||
998 | { | ||
999 | int i; | ||
1000 | for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) { | ||
1001 | if (card_id == chip_id_to_device_name[i].chip_id) | ||
1002 | break; | ||
1003 | } | ||
1004 | if (i == ARRAY_SIZE(chip_id_to_device_name)) { | ||
1005 | lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id); | ||
1006 | return -EAFNOSUPPORT; | ||
1007 | } | ||
1008 | snprintf(helper_fw, FIRMWARE_NAME_MAX, "libertas/gspi%d_hlp.bin", | ||
1009 | chip_id_to_device_name[i].name); | ||
1010 | snprintf(main_fw, FIRMWARE_NAME_MAX, "libertas/gspi%d.bin", | ||
1011 | chip_id_to_device_name[i].name); | ||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int __devinit if_spi_probe(struct spi_device *spi) | ||
1016 | { | ||
1017 | struct if_spi_card *card; | ||
1018 | struct lbs_private *priv = NULL; | ||
1019 | struct libertas_spi_platform_data *pdata = spi->dev.platform_data; | ||
1020 | int err = 0; | ||
1021 | u32 scratch; | ||
1022 | |||
1023 | lbs_deb_enter(LBS_DEB_SPI); | ||
1024 | |||
1025 | /* Allocate card structure to represent this specific device */ | ||
1026 | card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL); | ||
1027 | if (!card) { | ||
1028 | err = -ENOMEM; | ||
1029 | goto out; | ||
1030 | } | ||
1031 | spi_set_drvdata(spi, card); | ||
1032 | card->spi = spi; | ||
1033 | card->gpio_cs = pdata->gpio_cs; | ||
1034 | card->prev_xfer_time = jiffies; | ||
1035 | |||
1036 | sema_init(&card->spi_ready, 0); | ||
1037 | sema_init(&card->spi_thread_terminated, 0); | ||
1038 | INIT_LIST_HEAD(&card->cmd_packet_list); | ||
1039 | INIT_LIST_HEAD(&card->data_packet_list); | ||
1040 | spin_lock_init(&card->buffer_lock); | ||
1041 | |||
1042 | /* set up GPIO CS line. TODO: use regular CS line */ | ||
1043 | err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); | ||
1044 | if (err) | ||
1045 | goto free_card; | ||
1046 | err = gpio_direction_output(card->gpio_cs, 1); | ||
1047 | if (err) | ||
1048 | goto free_gpio; | ||
1049 | |||
1050 | /* Initialize the SPI Interface Unit */ | ||
1051 | err = spu_init(card, pdata->use_dummy_writes); | ||
1052 | if (err) | ||
1053 | goto free_gpio; | ||
1054 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); | ||
1055 | if (err) | ||
1056 | goto free_gpio; | ||
1057 | |||
1058 | /* Firmware load */ | ||
1059 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); | ||
1060 | if (err) | ||
1061 | goto free_gpio; | ||
1062 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) | ||
1063 | lbs_deb_spi("Firmware is already loaded for " | ||
1064 | "Marvell WLAN 802.11 adapter\n"); | ||
1065 | else { | ||
1066 | err = if_spi_calculate_fw_names(card->card_id, | ||
1067 | card->helper_fw_name, card->main_fw_name); | ||
1068 | if (err) | ||
1069 | goto free_gpio; | ||
1070 | |||
1071 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " | ||
1072 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " | ||
1073 | "attached to SPI bus_num %d, chip_select %d. " | ||
1074 | "spi->max_speed_hz=%d\n", | ||
1075 | card->card_id, card->card_rev, | ||
1076 | spi->master->bus_num, spi->chip_select, | ||
1077 | spi->max_speed_hz); | ||
1078 | err = if_spi_prog_helper_firmware(card); | ||
1079 | if (err) | ||
1080 | goto free_gpio; | ||
1081 | err = if_spi_prog_main_firmware(card); | ||
1082 | if (err) | ||
1083 | goto free_gpio; | ||
1084 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); | ||
1085 | } | ||
1086 | |||
1087 | err = spu_set_interrupt_mode(card, 0, 1); | ||
1088 | if (err) | ||
1089 | goto free_gpio; | ||
1090 | |||
1091 | /* Register our card with libertas. | ||
1092 | * This will call alloc_etherdev */ | ||
1093 | priv = lbs_add_card(card, &spi->dev); | ||
1094 | if (!priv) { | ||
1095 | err = -ENOMEM; | ||
1096 | goto free_gpio; | ||
1097 | } | ||
1098 | card->priv = priv; | ||
1099 | priv->card = card; | ||
1100 | priv->hw_host_to_card = if_spi_host_to_card; | ||
1101 | priv->fw_ready = 1; | ||
1102 | priv->ps_supported = 1; | ||
1103 | |||
1104 | /* Initialize interrupt handling stuff. */ | ||
1105 | card->run_thread = 1; | ||
1106 | card->spi_thread = kthread_run(lbs_spi_thread, card, "lbs_spi_thread"); | ||
1107 | if (IS_ERR(card->spi_thread)) { | ||
1108 | card->run_thread = 0; | ||
1109 | err = PTR_ERR(card->spi_thread); | ||
1110 | lbs_pr_err("error creating SPI thread: err=%d\n", err); | ||
1111 | goto remove_card; | ||
1112 | } | ||
1113 | err = request_irq(spi->irq, if_spi_host_interrupt, | ||
1114 | IRQF_TRIGGER_FALLING, "libertas_spi", card); | ||
1115 | if (err) { | ||
1116 | lbs_pr_err("can't get host irq line-- request_irq failed\n"); | ||
1117 | goto terminate_thread; | ||
1118 | } | ||
1119 | |||
1120 | /* Start the card. | ||
1121 | * This will call register_netdev, and we'll start | ||
1122 | * getting interrupts... */ | ||
1123 | err = lbs_start_card(priv); | ||
1124 | if (err) | ||
1125 | goto release_irq; | ||
1126 | |||
1127 | lbs_deb_spi("Finished initializing WLAN module.\n"); | ||
1128 | |||
1129 | /* successful exit */ | ||
1130 | goto out; | ||
1131 | |||
1132 | release_irq: | ||
1133 | free_irq(spi->irq, card); | ||
1134 | terminate_thread: | ||
1135 | if_spi_terminate_spi_thread(card); | ||
1136 | remove_card: | ||
1137 | lbs_remove_card(priv); /* will call free_netdev */ | ||
1138 | free_gpio: | ||
1139 | gpio_free(card->gpio_cs); | ||
1140 | free_card: | ||
1141 | free_if_spi_card(card); | ||
1142 | out: | ||
1143 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); | ||
1144 | return err; | ||
1145 | } | ||
1146 | |||
1147 | static int __devexit libertas_spi_remove(struct spi_device *spi) | ||
1148 | { | ||
1149 | struct if_spi_card *card = spi_get_drvdata(spi); | ||
1150 | struct lbs_private *priv = card->priv; | ||
1151 | |||
1152 | lbs_deb_spi("libertas_spi_remove\n"); | ||
1153 | lbs_deb_enter(LBS_DEB_SPI); | ||
1154 | priv->surpriseremoved = 1; | ||
1155 | |||
1156 | lbs_stop_card(priv); | ||
1157 | free_irq(spi->irq, card); | ||
1158 | if_spi_terminate_spi_thread(card); | ||
1159 | lbs_remove_card(priv); /* will call free_netdev */ | ||
1160 | gpio_free(card->gpio_cs); | ||
1161 | free_if_spi_card(card); | ||
1162 | lbs_deb_leave(LBS_DEB_SPI); | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | static struct spi_driver libertas_spi_driver = { | ||
1167 | .probe = if_spi_probe, | ||
1168 | .remove = __devexit_p(libertas_spi_remove), | ||
1169 | .driver = { | ||
1170 | .name = "libertas_spi", | ||
1171 | .bus = &spi_bus_type, | ||
1172 | .owner = THIS_MODULE, | ||
1173 | }, | ||
1174 | }; | ||
1175 | |||
1176 | /* | ||
1177 | * Module functions | ||
1178 | */ | ||
1179 | |||
1180 | static int __init if_spi_init_module(void) | ||
1181 | { | ||
1182 | int ret = 0; | ||
1183 | lbs_deb_enter(LBS_DEB_SPI); | ||
1184 | printk(KERN_INFO "libertas_spi: Libertas SPI driver\n"); | ||
1185 | ret = spi_register_driver(&libertas_spi_driver); | ||
1186 | lbs_deb_leave(LBS_DEB_SPI); | ||
1187 | return ret; | ||
1188 | } | ||
1189 | |||
1190 | static void __exit if_spi_exit_module(void) | ||
1191 | { | ||
1192 | lbs_deb_enter(LBS_DEB_SPI); | ||
1193 | spi_unregister_driver(&libertas_spi_driver); | ||
1194 | lbs_deb_leave(LBS_DEB_SPI); | ||
1195 | } | ||
1196 | |||
1197 | module_init(if_spi_init_module); | ||
1198 | module_exit(if_spi_exit_module); | ||
1199 | |||
1200 | MODULE_DESCRIPTION("Libertas SPI WLAN Driver"); | ||
1201 | MODULE_AUTHOR("Andrey Yurovsky <andrey@cozybit.com>, " | ||
1202 | "Colin McCabe <colin@cozybit.com>"); | ||
1203 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h new file mode 100644 index 000000000000..2103869cc5b0 --- /dev/null +++ b/drivers/net/wireless/libertas/if_spi.h | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * linux/drivers/net/wireless/libertas/if_spi.c | ||
3 | * | ||
4 | * Driver for Marvell SPI WLAN cards. | ||
5 | * | ||
6 | * Copyright 2008 Analog Devices Inc. | ||
7 | * | ||
8 | * Authors: | ||
9 | * Andrey Yurovsky <andrey@cozybit.com> | ||
10 | * Colin McCabe <colin@cozybit.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or (at | ||
15 | * your option) any later version. | ||
16 | */ | ||
17 | |||
18 | #ifndef _LBS_IF_SPI_H_ | ||
19 | #define _LBS_IF_SPI_H_ | ||
20 | |||
21 | #define IPFIELD_ALIGN_OFFSET 2 | ||
22 | #define IF_SPI_CMD_BUF_SIZE 2400 | ||
23 | |||
24 | /***************** Firmware *****************/ | ||
25 | struct chip_ident { | ||
26 | u16 chip_id; | ||
27 | u16 name; | ||
28 | }; | ||
29 | |||
30 | #define MAX_MAIN_FW_LOAD_CRC_ERR 10 | ||
31 | |||
32 | /* Chunk size when loading the helper firmware */ | ||
33 | #define HELPER_FW_LOAD_CHUNK_SZ 64 | ||
34 | |||
35 | /* Value to write to indicate end of helper firmware dnld */ | ||
36 | #define FIRMWARE_DNLD_OK 0x0000 | ||
37 | |||
38 | /* Value to check once the main firmware is downloaded */ | ||
39 | #define SUCCESSFUL_FW_DOWNLOAD_MAGIC 0x88888888 | ||
40 | |||
41 | /***************** SPI Interface Unit *****************/ | ||
42 | /* Masks used in SPI register read/write operations */ | ||
43 | #define IF_SPI_READ_OPERATION_MASK 0x0 | ||
44 | #define IF_SPI_WRITE_OPERATION_MASK 0x8000 | ||
45 | |||
46 | /* SPI register offsets. 4-byte aligned. */ | ||
47 | #define IF_SPI_DEVICEID_CTRL_REG 0x00 /* DeviceID controller reg */ | ||
48 | #define IF_SPI_IO_READBASE_REG 0x04 /* Read I/O base reg */ | ||
49 | #define IF_SPI_IO_WRITEBASE_REG 0x08 /* Write I/O base reg */ | ||
50 | #define IF_SPI_IO_RDWRPORT_REG 0x0C /* Read/Write I/O port reg */ | ||
51 | |||
52 | #define IF_SPI_CMD_READBASE_REG 0x10 /* Read command base reg */ | ||
53 | #define IF_SPI_CMD_WRITEBASE_REG 0x14 /* Write command base reg */ | ||
54 | #define IF_SPI_CMD_RDWRPORT_REG 0x18 /* Read/Write command port reg */ | ||
55 | |||
56 | #define IF_SPI_DATA_READBASE_REG 0x1C /* Read data base reg */ | ||
57 | #define IF_SPI_DATA_WRITEBASE_REG 0x20 /* Write data base reg */ | ||
58 | #define IF_SPI_DATA_RDWRPORT_REG 0x24 /* Read/Write data port reg */ | ||
59 | |||
60 | #define IF_SPI_SCRATCH_1_REG 0x28 /* Scratch reg 1 */ | ||
61 | #define IF_SPI_SCRATCH_2_REG 0x2C /* Scratch reg 2 */ | ||
62 | #define IF_SPI_SCRATCH_3_REG 0x30 /* Scratch reg 3 */ | ||
63 | #define IF_SPI_SCRATCH_4_REG 0x34 /* Scratch reg 4 */ | ||
64 | |||
65 | #define IF_SPI_TX_FRAME_SEQ_NUM_REG 0x38 /* Tx frame sequence number reg */ | ||
66 | #define IF_SPI_TX_FRAME_STATUS_REG 0x3C /* Tx frame status reg */ | ||
67 | |||
68 | #define IF_SPI_HOST_INT_CTRL_REG 0x40 /* Host interrupt controller reg */ | ||
69 | |||
70 | #define IF_SPI_CARD_INT_CAUSE_REG 0x44 /* Card interrupt cause reg */ | ||
71 | #define IF_SPI_CARD_INT_STATUS_REG 0x48 /* Card interupt status reg */ | ||
72 | #define IF_SPI_CARD_INT_EVENT_MASK_REG 0x4C /* Card interrupt event mask */ | ||
73 | #define IF_SPI_CARD_INT_STATUS_MASK_REG 0x50 /* Card interrupt status mask */ | ||
74 | |||
75 | #define IF_SPI_CARD_INT_RESET_SELECT_REG 0x54 /* Card interrupt reset select */ | ||
76 | |||
77 | #define IF_SPI_HOST_INT_CAUSE_REG 0x58 /* Host interrupt cause reg */ | ||
78 | #define IF_SPI_HOST_INT_STATUS_REG 0x5C /* Host interrupt status reg */ | ||
79 | #define IF_SPI_HOST_INT_EVENT_MASK_REG 0x60 /* Host interrupt event mask */ | ||
80 | #define IF_SPI_HOST_INT_STATUS_MASK_REG 0x64 /* Host interrupt status mask */ | ||
81 | #define IF_SPI_HOST_INT_RESET_SELECT_REG 0x68 /* Host interrupt reset select */ | ||
82 | |||
83 | #define IF_SPI_DELAY_READ_REG 0x6C /* Delay read reg */ | ||
84 | #define IF_SPI_SPU_BUS_MODE_REG 0x70 /* SPU BUS mode reg */ | ||
85 | |||
86 | /***************** IF_SPI_DEVICEID_CTRL_REG *****************/ | ||
87 | #define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dc) ((dc & 0xffff0000)>>16) | ||
88 | #define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff) | ||
89 | |||
90 | /***************** IF_SPI_HOST_INT_CTRL_REG *****************/ | ||
91 | /** Host Interrupt Control bit : Wake up */ | ||
92 | #define IF_SPI_HICT_WAKE_UP (1<<0) | ||
93 | /** Host Interrupt Control bit : WLAN ready */ | ||
94 | #define IF_SPI_HICT_WLAN_READY (1<<1) | ||
95 | /*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */ | ||
96 | /*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */ | ||
97 | /*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */ | ||
98 | /** Host Interrupt Control bit : Tx auto download */ | ||
99 | #define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5) | ||
100 | /** Host Interrupt Control bit : Rx auto upload */ | ||
101 | #define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6) | ||
102 | /** Host Interrupt Control bit : Command auto download */ | ||
103 | #define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7) | ||
104 | /** Host Interrupt Control bit : Command auto upload */ | ||
105 | #define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8) | ||
106 | |||
107 | /***************** IF_SPI_CARD_INT_CAUSE_REG *****************/ | ||
108 | /** Card Interrupt Case bit : Tx download over */ | ||
109 | #define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0) | ||
110 | /** Card Interrupt Case bit : Rx upload over */ | ||
111 | #define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1) | ||
112 | /** Card Interrupt Case bit : Command download over */ | ||
113 | #define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2) | ||
114 | /** Card Interrupt Case bit : Host event */ | ||
115 | #define IF_SPI_CIC_HOST_EVENT (1<<3) | ||
116 | /** Card Interrupt Case bit : Command upload over */ | ||
117 | #define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4) | ||
118 | /** Card Interrupt Case bit : Power down */ | ||
119 | #define IF_SPI_CIC_POWER_DOWN (1<<5) | ||
120 | |||
121 | /***************** IF_SPI_CARD_INT_STATUS_REG *****************/ | ||
122 | #define IF_SPI_CIS_TX_DOWNLOAD_OVER (1<<0) | ||
123 | #define IF_SPI_CIS_RX_UPLOAD_OVER (1<<1) | ||
124 | #define IF_SPI_CIS_CMD_DOWNLOAD_OVER (1<<2) | ||
125 | #define IF_SPI_CIS_HOST_EVENT (1<<3) | ||
126 | #define IF_SPI_CIS_CMD_UPLOAD_OVER (1<<4) | ||
127 | #define IF_SPI_CIS_POWER_DOWN (1<<5) | ||
128 | |||
129 | /***************** IF_SPI_HOST_INT_CAUSE_REG *****************/ | ||
130 | #define IF_SPI_HICU_TX_DOWNLOAD_RDY (1<<0) | ||
131 | #define IF_SPI_HICU_RX_UPLOAD_RDY (1<<1) | ||
132 | #define IF_SPI_HICU_CMD_DOWNLOAD_RDY (1<<2) | ||
133 | #define IF_SPI_HICU_CARD_EVENT (1<<3) | ||
134 | #define IF_SPI_HICU_CMD_UPLOAD_RDY (1<<4) | ||
135 | #define IF_SPI_HICU_IO_WR_FIFO_OVERFLOW (1<<5) | ||
136 | #define IF_SPI_HICU_IO_RD_FIFO_UNDERFLOW (1<<6) | ||
137 | #define IF_SPI_HICU_DATA_WR_FIFO_OVERFLOW (1<<7) | ||
138 | #define IF_SPI_HICU_DATA_RD_FIFO_UNDERFLOW (1<<8) | ||
139 | #define IF_SPI_HICU_CMD_WR_FIFO_OVERFLOW (1<<9) | ||
140 | #define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10) | ||
141 | |||
142 | /***************** IF_SPI_HOST_INT_STATUS_REG *****************/ | ||
143 | /** Host Interrupt Status bit : Tx download ready */ | ||
144 | #define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0) | ||
145 | /** Host Interrupt Status bit : Rx upload ready */ | ||
146 | #define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1) | ||
147 | /** Host Interrupt Status bit : Command download ready */ | ||
148 | #define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2) | ||
149 | /** Host Interrupt Status bit : Card event */ | ||
150 | #define IF_SPI_HIST_CARD_EVENT (1<<3) | ||
151 | /** Host Interrupt Status bit : Command upload ready */ | ||
152 | #define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4) | ||
153 | /** Host Interrupt Status bit : I/O write FIFO overflow */ | ||
154 | #define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5) | ||
155 | /** Host Interrupt Status bit : I/O read FIFO underflow */ | ||
156 | #define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6) | ||
157 | /** Host Interrupt Status bit : Data write FIFO overflow */ | ||
158 | #define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7) | ||
159 | /** Host Interrupt Status bit : Data read FIFO underflow */ | ||
160 | #define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8) | ||
161 | /** Host Interrupt Status bit : Command write FIFO overflow */ | ||
162 | #define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9) | ||
163 | /** Host Interrupt Status bit : Command read FIFO underflow */ | ||
164 | #define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10) | ||
165 | |||
166 | /***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/ | ||
167 | /** Host Interrupt Status Mask bit : Tx download ready */ | ||
168 | #define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0) | ||
169 | /** Host Interrupt Status Mask bit : Rx upload ready */ | ||
170 | #define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1) | ||
171 | /** Host Interrupt Status Mask bit : Command download ready */ | ||
172 | #define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2) | ||
173 | /** Host Interrupt Status Mask bit : Card event */ | ||
174 | #define IF_SPI_HISM_CARDEVENT (1<<3) | ||
175 | /** Host Interrupt Status Mask bit : Command upload ready */ | ||
176 | #define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4) | ||
177 | /** Host Interrupt Status Mask bit : I/O write FIFO overflow */ | ||
178 | #define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5) | ||
179 | /** Host Interrupt Status Mask bit : I/O read FIFO underflow */ | ||
180 | #define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6) | ||
181 | /** Host Interrupt Status Mask bit : Data write FIFO overflow */ | ||
182 | #define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7) | ||
183 | /** Host Interrupt Status Mask bit : Data write FIFO underflow */ | ||
184 | #define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8) | ||
185 | /** Host Interrupt Status Mask bit : Command write FIFO overflow */ | ||
186 | #define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9) | ||
187 | /** Host Interrupt Status Mask bit : Command write FIFO underflow */ | ||
188 | #define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10) | ||
189 | |||
190 | /***************** IF_SPI_SPU_BUS_MODE_REG *****************/ | ||
191 | /* SCK edge on which the WLAN module outputs data on MISO */ | ||
192 | #define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_FALLING 0x8 | ||
193 | #define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING 0x0 | ||
194 | |||
195 | /* In a SPU read operation, there is a delay between writing the SPU | ||
196 | * register name and getting back data from the WLAN module. | ||
197 | * This can be specified in terms of nanoseconds or in terms of dummy | ||
198 | * clock cycles which the master must output before receiving a response. */ | ||
199 | #define IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK 0x4 | ||
200 | #define IF_SPI_BUS_MODE_DELAY_METHOD_TIMED 0x0 | ||
201 | |||
202 | /* Some different modes of SPI operation */ | ||
203 | #define IF_SPI_BUS_MODE_8_BIT_ADDRESS_16_BIT_DATA 0x00 | ||
204 | #define IF_SPI_BUS_MODE_8_BIT_ADDRESS_32_BIT_DATA 0x01 | ||
205 | #define IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA 0x02 | ||
206 | #define IF_SPI_BUS_MODE_16_BIT_ADDRESS_32_BIT_DATA 0x03 | ||
207 | |||
208 | #endif | ||
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 4e0007d20030..8a7eb2778eb6 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -1006,9 +1006,8 @@ void lbs_resume(struct lbs_private *priv) | |||
1006 | EXPORT_SYMBOL_GPL(lbs_resume); | 1006 | EXPORT_SYMBOL_GPL(lbs_resume); |
1007 | 1007 | ||
1008 | /** | 1008 | /** |
1009 | * @brief This function downloads firmware image, gets | 1009 | * @brief This function gets the HW spec from the firmware and sets |
1010 | * HW spec from firmware and set basic parameters to | 1010 | * some basic parameters. |
1011 | * firmware. | ||
1012 | * | 1011 | * |
1013 | * @param priv A pointer to struct lbs_private structure | 1012 | * @param priv A pointer to struct lbs_private structure |
1014 | * @return 0 or -1 | 1013 | * @return 0 or -1 |
diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c index 3d3914c83b14..28790e03dc43 100644 --- a/drivers/net/wireless/libertas_tf/cmd.c +++ b/drivers/net/wireless/libertas_tf/cmd.c | |||
@@ -286,7 +286,7 @@ void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode) | |||
286 | lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd)); | 286 | lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd)); |
287 | } | 287 | } |
288 | 288 | ||
289 | void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid) | 289 | void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid) |
290 | { | 290 | { |
291 | struct cmd_ds_set_bssid cmd; | 291 | struct cmd_ds_set_bssid cmd; |
292 | 292 | ||
diff --git a/drivers/net/wireless/libertas_tf/libertas_tf.h b/drivers/net/wireless/libertas_tf/libertas_tf.h index 8995cd7c29bf..4cc42dd5a005 100644 --- a/drivers/net/wireless/libertas_tf/libertas_tf.h +++ b/drivers/net/wireless/libertas_tf/libertas_tf.h | |||
@@ -463,7 +463,7 @@ int lbtf_set_radio_control(struct lbtf_private *priv); | |||
463 | int lbtf_update_hw_spec(struct lbtf_private *priv); | 463 | int lbtf_update_hw_spec(struct lbtf_private *priv); |
464 | int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv); | 464 | int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv); |
465 | void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode); | 465 | void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode); |
466 | void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid); | 466 | void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid); |
467 | int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr); | 467 | int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr); |
468 | 468 | ||
469 | int lbtf_set_channel(struct lbtf_private *priv, u8 channel); | 469 | int lbtf_set_channel(struct lbtf_private *priv, u8 channel); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index f83d69e813d3..fce49ba061d5 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -779,6 +779,8 @@ static int __init init_mac80211_hwsim(void) | |||
779 | BIT(NL80211_IFTYPE_MESH_POINT); | 779 | BIT(NL80211_IFTYPE_MESH_POINT); |
780 | hw->ampdu_queues = 1; | 780 | hw->ampdu_queues = 1; |
781 | 781 | ||
782 | hw->flags = IEEE80211_HW_MFP_CAPABLE; | ||
783 | |||
782 | /* ask mac80211 to reserve space for magic */ | 784 | /* ask mac80211 to reserve space for magic */ |
783 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); | 785 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); |
784 | hw->sta_data_size = sizeof(struct hwsim_sta_priv); | 786 | hw->sta_data_size = sizeof(struct hwsim_sta_priv); |
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig new file mode 100644 index 000000000000..44411eb4e91b --- /dev/null +++ b/drivers/net/wireless/orinoco/Kconfig | |||
@@ -0,0 +1,120 @@ | |||
1 | config HERMES | ||
2 | tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)" | ||
3 | depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211 | ||
4 | select WIRELESS_EXT | ||
5 | select FW_LOADER | ||
6 | select CRYPTO | ||
7 | select CRYPTO_MICHAEL_MIC | ||
8 | ---help--- | ||
9 | A driver for 802.11b wireless cards based on the "Hermes" or | ||
10 | Intersil HFA384x (Prism 2) MAC controller. This includes the vast | ||
11 | majority of the PCMCIA 802.11b cards (which are nearly all rebadges) | ||
12 | - except for the Cisco/Aironet cards. Cards supported include the | ||
13 | Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco, | ||
14 | Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya, | ||
15 | IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear | ||
16 | MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel | ||
17 | IPW2011, and Symbol Spectrum24 High Rate amongst others. | ||
18 | |||
19 | This option includes the guts of the driver, but in order to | ||
20 | actually use a card you will also need to enable support for PCMCIA | ||
21 | Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below. | ||
22 | |||
23 | You will also very likely also need the Wireless Tools in order to | ||
24 | configure your card and that /etc/pcmcia/wireless.opts works : | ||
25 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> | ||
26 | |||
27 | config HERMES_CACHE_FW_ON_INIT | ||
28 | bool "Cache Hermes firmware on driver initialisation" | ||
29 | depends on HERMES | ||
30 | default y | ||
31 | ---help--- | ||
32 | Say Y to cache any firmware required by the Hermes drivers | ||
33 | on startup. The firmware will remain cached until the | ||
34 | driver is unloaded. The cache uses 64K of RAM. | ||
35 | |||
36 | Otherwise load the firmware from userspace as required. In | ||
37 | this case the driver should be unloaded and restarted | ||
38 | whenever the firmware is changed. | ||
39 | |||
40 | If you are not sure, say Y. | ||
41 | |||
42 | config APPLE_AIRPORT | ||
43 | tristate "Apple Airport support (built-in)" | ||
44 | depends on PPC_PMAC && HERMES | ||
45 | help | ||
46 | Say Y here to support the Airport 802.11b wireless Ethernet hardware | ||
47 | built into the Macintosh iBook and other recent PowerPC-based | ||
48 | Macintosh machines. This is essentially a Lucent Orinoco card with | ||
49 | a non-standard interface. | ||
50 | |||
51 | This driver does not support the Airport Extreme (802.11b/g). Use | ||
52 | the BCM43xx driver for Airport Extreme cards. | ||
53 | |||
54 | config PLX_HERMES | ||
55 | tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)" | ||
56 | depends on PCI && HERMES | ||
57 | help | ||
58 | Enable support for PCMCIA cards supported by the "Hermes" (aka | ||
59 | orinoco) driver when used in PLX9052 based PCI adaptors. These | ||
60 | adaptors are not a full PCMCIA controller but act as a more limited | ||
61 | PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that | ||
62 | 802.11b PCMCIA cards can be used in desktop machines. The Netgear | ||
63 | MA301 is such an adaptor. | ||
64 | |||
65 | config TMD_HERMES | ||
66 | tristate "Hermes in TMD7160 based PCI adaptor support" | ||
67 | depends on PCI && HERMES | ||
68 | help | ||
69 | Enable support for PCMCIA cards supported by the "Hermes" (aka | ||
70 | orinoco) driver when used in TMD7160 based PCI adaptors. These | ||
71 | adaptors are not a full PCMCIA controller but act as a more limited | ||
72 | PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that | ||
73 | 802.11b PCMCIA cards can be used in desktop machines. | ||
74 | |||
75 | config NORTEL_HERMES | ||
76 | tristate "Nortel emobility PCI adaptor support" | ||
77 | depends on PCI && HERMES | ||
78 | help | ||
79 | Enable support for PCMCIA cards supported by the "Hermes" (aka | ||
80 | orinoco) driver when used in Nortel emobility PCI adaptors. These | ||
81 | adaptors are not full PCMCIA controllers, but act as a more limited | ||
82 | PCI <-> PCMCIA bridge. | ||
83 | |||
84 | config PCI_HERMES | ||
85 | tristate "Prism 2.5 PCI 802.11b adaptor support" | ||
86 | depends on PCI && HERMES | ||
87 | help | ||
88 | Enable support for PCI and mini-PCI 802.11b wireless NICs based on | ||
89 | the Prism 2.5 chipset. These are true PCI cards, not the 802.11b | ||
90 | PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also | ||
91 | common. Some of the built-in wireless adaptors in laptops are of | ||
92 | this variety. | ||
93 | |||
94 | config PCMCIA_HERMES | ||
95 | tristate "Hermes PCMCIA card support" | ||
96 | depends on PCMCIA && HERMES | ||
97 | ---help--- | ||
98 | A driver for "Hermes" chipset based PCMCIA wireless adaptors, such | ||
99 | as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/ | ||
100 | EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and | ||
101 | others). It should also be usable on various Prism II based cards | ||
102 | such as the Linksys, D-Link and Farallon Skyline. It should also | ||
103 | work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN. | ||
104 | |||
105 | You will very likely need the Wireless Tools in order to | ||
106 | configure your card and that /etc/pcmcia/wireless.opts works: | ||
107 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. | ||
108 | |||
109 | config PCMCIA_SPECTRUM | ||
110 | tristate "Symbol Spectrum24 Trilogy PCMCIA card support" | ||
111 | depends on PCMCIA && HERMES | ||
112 | ---help--- | ||
113 | |||
114 | This is a driver for 802.11b cards using RAM-loadable Symbol | ||
115 | firmware, such as Symbol Wireless Networker LA4100, CompactFlash | ||
116 | cards by Socket Communications and Intel PRO/Wireless 2011B. | ||
117 | |||
118 | This driver requires firmware download on startup. Utilities | ||
119 | for downloading Symbol firmware are available at | ||
120 | <http://sourceforge.net/projects/orinoco/> | ||
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c index 45a04faa7818..6514e4611b96 100644 --- a/drivers/net/wireless/orinoco/orinoco.c +++ b/drivers/net/wireless/orinoco/orinoco.c | |||
@@ -178,12 +178,7 @@ static const struct ethtool_ops orinoco_ethtool_ops; | |||
178 | /* Data tables */ | 178 | /* Data tables */ |
179 | /********************************************************************/ | 179 | /********************************************************************/ |
180 | 180 | ||
181 | /* The frequency of each channel in MHz */ | 181 | #define NUM_CHANNELS 14 |
182 | static const long channel_frequency[] = { | ||
183 | 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
184 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 | ||
185 | }; | ||
186 | #define NUM_CHANNELS ARRAY_SIZE(channel_frequency) | ||
187 | 182 | ||
188 | /* This tables gives the actual meanings of the bitrate IDs returned | 183 | /* This tables gives the actual meanings of the bitrate IDs returned |
189 | * by the firmware. */ | 184 | * by the firmware. */ |
@@ -240,6 +235,12 @@ struct hermes_rx_descriptor { | |||
240 | __le16 data_len; | 235 | __le16 data_len; |
241 | } __attribute__ ((packed)); | 236 | } __attribute__ ((packed)); |
242 | 237 | ||
238 | struct orinoco_rx_data { | ||
239 | struct hermes_rx_descriptor *desc; | ||
240 | struct sk_buff *skb; | ||
241 | struct list_head list; | ||
242 | }; | ||
243 | |||
243 | /********************************************************************/ | 244 | /********************************************************************/ |
244 | /* Function prototypes */ | 245 | /* Function prototypes */ |
245 | /********************************************************************/ | 246 | /********************************************************************/ |
@@ -3582,6 +3583,17 @@ static int orinoco_init(struct net_device *dev) | |||
3582 | return err; | 3583 | return err; |
3583 | } | 3584 | } |
3584 | 3585 | ||
3586 | static const struct net_device_ops orinoco_netdev_ops = { | ||
3587 | .ndo_init = orinoco_init, | ||
3588 | .ndo_open = orinoco_open, | ||
3589 | .ndo_stop = orinoco_stop, | ||
3590 | .ndo_start_xmit = orinoco_xmit, | ||
3591 | .ndo_set_multicast_list = orinoco_set_multicast_list, | ||
3592 | .ndo_change_mtu = orinoco_change_mtu, | ||
3593 | .ndo_tx_timeout = orinoco_tx_timeout, | ||
3594 | .ndo_get_stats = orinoco_get_stats, | ||
3595 | }; | ||
3596 | |||
3585 | struct net_device | 3597 | struct net_device |
3586 | *alloc_orinocodev(int sizeof_card, | 3598 | *alloc_orinocodev(int sizeof_card, |
3587 | struct device *device, | 3599 | struct device *device, |
@@ -3592,7 +3604,7 @@ struct net_device | |||
3592 | struct orinoco_private *priv; | 3604 | struct orinoco_private *priv; |
3593 | 3605 | ||
3594 | dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card); | 3606 | dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card); |
3595 | if (! dev) | 3607 | if (!dev) |
3596 | return NULL; | 3608 | return NULL; |
3597 | priv = netdev_priv(dev); | 3609 | priv = netdev_priv(dev); |
3598 | priv->ndev = dev; | 3610 | priv->ndev = dev; |
@@ -3604,27 +3616,20 @@ struct net_device | |||
3604 | priv->dev = device; | 3616 | priv->dev = device; |
3605 | 3617 | ||
3606 | /* Setup / override net_device fields */ | 3618 | /* Setup / override net_device fields */ |
3607 | dev->init = orinoco_init; | 3619 | dev->netdev_ops = &orinoco_netdev_ops; |
3608 | dev->hard_start_xmit = orinoco_xmit; | ||
3609 | dev->tx_timeout = orinoco_tx_timeout; | ||
3610 | dev->watchdog_timeo = HZ; /* 1 second timeout */ | 3620 | dev->watchdog_timeo = HZ; /* 1 second timeout */ |
3611 | dev->get_stats = orinoco_get_stats; | ||
3612 | dev->ethtool_ops = &orinoco_ethtool_ops; | 3621 | dev->ethtool_ops = &orinoco_ethtool_ops; |
3613 | dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def; | 3622 | dev->wireless_handlers = &orinoco_handler_def; |
3614 | #ifdef WIRELESS_SPY | 3623 | #ifdef WIRELESS_SPY |
3615 | priv->wireless_data.spy_data = &priv->spy_data; | 3624 | priv->wireless_data.spy_data = &priv->spy_data; |
3616 | dev->wireless_data = &priv->wireless_data; | 3625 | dev->wireless_data = &priv->wireless_data; |
3617 | #endif | 3626 | #endif |
3618 | dev->change_mtu = orinoco_change_mtu; | ||
3619 | dev->set_multicast_list = orinoco_set_multicast_list; | ||
3620 | /* we use the default eth_mac_addr for setting the MAC addr */ | 3627 | /* we use the default eth_mac_addr for setting the MAC addr */ |
3621 | 3628 | ||
3622 | /* Reserve space in skb for the SNAP header */ | 3629 | /* Reserve space in skb for the SNAP header */ |
3623 | dev->hard_header_len += ENCAPS_OVERHEAD; | 3630 | dev->hard_header_len += ENCAPS_OVERHEAD; |
3624 | 3631 | ||
3625 | /* Set up default callbacks */ | 3632 | /* Set up default callbacks */ |
3626 | dev->open = orinoco_open; | ||
3627 | dev->stop = orinoco_stop; | ||
3628 | priv->hard_reset = hard_reset; | 3633 | priv->hard_reset = hard_reset; |
3629 | priv->stop_fw = stop_fw; | 3634 | priv->stop_fw = stop_fw; |
3630 | 3635 | ||
@@ -3742,13 +3747,13 @@ static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, | |||
3742 | return err; | 3747 | return err; |
3743 | } | 3748 | } |
3744 | 3749 | ||
3745 | static long orinoco_hw_get_freq(struct orinoco_private *priv) | 3750 | static int orinoco_hw_get_freq(struct orinoco_private *priv) |
3746 | { | 3751 | { |
3747 | 3752 | ||
3748 | hermes_t *hw = &priv->hw; | 3753 | hermes_t *hw = &priv->hw; |
3749 | int err = 0; | 3754 | int err = 0; |
3750 | u16 channel; | 3755 | u16 channel; |
3751 | long freq = 0; | 3756 | int freq = 0; |
3752 | unsigned long flags; | 3757 | unsigned long flags; |
3753 | 3758 | ||
3754 | if (orinoco_lock(priv, &flags) != 0) | 3759 | if (orinoco_lock(priv, &flags) != 0) |
@@ -3771,7 +3776,7 @@ static long orinoco_hw_get_freq(struct orinoco_private *priv) | |||
3771 | goto out; | 3776 | goto out; |
3772 | 3777 | ||
3773 | } | 3778 | } |
3774 | freq = channel_frequency[channel-1] * 100000; | 3779 | freq = ieee80211_dsss_chan_to_freq(channel); |
3775 | 3780 | ||
3776 | out: | 3781 | out: |
3777 | orinoco_unlock(priv, &flags); | 3782 | orinoco_unlock(priv, &flags); |
@@ -3998,7 +4003,8 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev, | |||
3998 | for (i = 0; i < NUM_CHANNELS; i++) { | 4003 | for (i = 0; i < NUM_CHANNELS; i++) { |
3999 | if (priv->channel_mask & (1 << i)) { | 4004 | if (priv->channel_mask & (1 << i)) { |
4000 | range->freq[k].i = i + 1; | 4005 | range->freq[k].i = i + 1; |
4001 | range->freq[k].m = channel_frequency[i] * 100000; | 4006 | range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) * |
4007 | 100000); | ||
4002 | range->freq[k].e = 1; | 4008 | range->freq[k].e = 1; |
4003 | k++; | 4009 | k++; |
4004 | } | 4010 | } |
@@ -4346,16 +4352,15 @@ static int orinoco_ioctl_setfreq(struct net_device *dev, | |||
4346 | /* Setting by channel number */ | 4352 | /* Setting by channel number */ |
4347 | chan = frq->m; | 4353 | chan = frq->m; |
4348 | } else { | 4354 | } else { |
4349 | /* Setting by frequency - search the table */ | 4355 | /* Setting by frequency */ |
4350 | int mult = 1; | 4356 | int denom = 1; |
4351 | int i; | 4357 | int i; |
4352 | 4358 | ||
4359 | /* Calculate denominator to rescale to MHz */ | ||
4353 | for (i = 0; i < (6 - frq->e); i++) | 4360 | for (i = 0; i < (6 - frq->e); i++) |
4354 | mult *= 10; | 4361 | denom *= 10; |
4355 | 4362 | ||
4356 | for (i = 0; i < NUM_CHANNELS; i++) | 4363 | chan = ieee80211_freq_to_dsss_chan(frq->m / denom); |
4357 | if (frq->m == (channel_frequency[i] * mult)) | ||
4358 | chan = i+1; | ||
4359 | } | 4364 | } |
4360 | 4365 | ||
4361 | if ( (chan < 1) || (chan > NUM_CHANNELS) || | 4366 | if ( (chan < 1) || (chan > NUM_CHANNELS) || |
@@ -4392,7 +4397,7 @@ static int orinoco_ioctl_getfreq(struct net_device *dev, | |||
4392 | return tmp; | 4397 | return tmp; |
4393 | } | 4398 | } |
4394 | 4399 | ||
4395 | frq->m = tmp; | 4400 | frq->m = tmp * 100000; |
4396 | frq->e = 1; | 4401 | frq->e = 1; |
4397 | 4402 | ||
4398 | return 0; | 4403 | return 0; |
@@ -5609,7 +5614,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
5609 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, | 5614 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
5610 | &iwe, IW_EV_FREQ_LEN); | 5615 | &iwe, IW_EV_FREQ_LEN); |
5611 | 5616 | ||
5612 | iwe.u.freq.m = channel_frequency[channel-1] * 100000; | 5617 | iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000; |
5613 | iwe.u.freq.e = 1; | 5618 | iwe.u.freq.e = 1; |
5614 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, | 5619 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
5615 | &iwe, IW_EV_FREQ_LEN); | 5620 | &iwe, IW_EV_FREQ_LEN); |
@@ -5760,7 +5765,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev, | |||
5760 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, | 5765 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
5761 | &iwe, IW_EV_FREQ_LEN); | 5766 | &iwe, IW_EV_FREQ_LEN); |
5762 | 5767 | ||
5763 | iwe.u.freq.m = channel_frequency[channel-1] * 100000; | 5768 | iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000; |
5764 | iwe.u.freq.e = 1; | 5769 | iwe.u.freq.e = 1; |
5765 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, | 5770 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
5766 | &iwe, IW_EV_FREQ_LEN); | 5771 | &iwe, IW_EV_FREQ_LEN); |
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h index 00750c8ba7db..c653816ef5fe 100644 --- a/drivers/net/wireless/orinoco/orinoco.h +++ b/drivers/net/wireless/orinoco/orinoco.h | |||
@@ -59,14 +59,6 @@ struct xbss_element { | |||
59 | struct list_head list; | 59 | struct list_head list; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct hermes_rx_descriptor; | ||
63 | |||
64 | struct orinoco_rx_data { | ||
65 | struct hermes_rx_descriptor *desc; | ||
66 | struct sk_buff *skb; | ||
67 | struct list_head list; | ||
68 | }; | ||
69 | |||
70 | struct firmware; | 62 | struct firmware; |
71 | 63 | ||
72 | struct orinoco_private { | 64 | struct orinoco_private { |
@@ -83,7 +75,6 @@ struct orinoco_private { | |||
83 | /* Interrupt tasklets */ | 75 | /* Interrupt tasklets */ |
84 | struct tasklet_struct rx_tasklet; | 76 | struct tasklet_struct rx_tasklet; |
85 | struct list_head rx_list; | 77 | struct list_head rx_list; |
86 | struct orinoco_rx_data *rx_data; | ||
87 | 78 | ||
88 | /* driver state */ | 79 | /* driver state */ |
89 | int open; | 80 | int open; |
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig index d3469d08f966..cfc5f41aa136 100644 --- a/drivers/net/wireless/p54/Kconfig +++ b/drivers/net/wireless/p54/Kconfig | |||
@@ -61,3 +61,13 @@ config P54_PCI | |||
61 | http://prism54.org/ | 61 | http://prism54.org/ |
62 | 62 | ||
63 | If you choose to build a module, it'll be called p54pci. | 63 | If you choose to build a module, it'll be called p54pci. |
64 | |||
65 | config P54_SPI | ||
66 | tristate "Prism54 SPI (stlc45xx) support" | ||
67 | depends on P54_COMMON && SPI_MASTER | ||
68 | ---help--- | ||
69 | This driver is for stlc4550 or stlc4560 based wireless chips. | ||
70 | This driver is experimental, untested and will probably only work on | ||
71 | Nokia's N800/N810 Portable Internet Tablet. | ||
72 | |||
73 | If you choose to build a module, it'll be called p54spi. | ||
diff --git a/drivers/net/wireless/p54/Makefile b/drivers/net/wireless/p54/Makefile index 4fa9ce717360..c2050dee6293 100644 --- a/drivers/net/wireless/p54/Makefile +++ b/drivers/net/wireless/p54/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-$(CONFIG_P54_COMMON) += p54common.o | 1 | obj-$(CONFIG_P54_COMMON) += p54common.o |
2 | obj-$(CONFIG_P54_USB) += p54usb.o | 2 | obj-$(CONFIG_P54_USB) += p54usb.o |
3 | obj-$(CONFIG_P54_PCI) += p54pci.o | 3 | obj-$(CONFIG_P54_PCI) += p54pci.o |
4 | obj-$(CONFIG_P54_SPI) += p54spi.o | ||
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index ab79e32f0b27..94c3acd1fcaf 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -44,6 +44,18 @@ enum p54_control_frame_types { | |||
44 | P54_CONTROL_TYPE_BT_OPTIONS = 35 | 44 | P54_CONTROL_TYPE_BT_OPTIONS = 35 |
45 | }; | 45 | }; |
46 | 46 | ||
47 | /* provide 16 bytes for the transport back-end */ | ||
48 | #define P54_TX_INFO_DATA_SIZE 16 | ||
49 | |||
50 | /* stored in ieee80211_tx_info's rate_driver_data */ | ||
51 | struct p54_tx_info { | ||
52 | u32 start_addr; | ||
53 | u32 end_addr; | ||
54 | void *data[P54_TX_INFO_DATA_SIZE / sizeof(void *)]; | ||
55 | }; | ||
56 | |||
57 | #define P54_MAX_CTRL_FRAME_LEN 0x1000 | ||
58 | |||
47 | #define P54_HDR_FLAG_CONTROL BIT(15) | 59 | #define P54_HDR_FLAG_CONTROL BIT(15) |
48 | #define P54_HDR_FLAG_CONTROL_OPSET (BIT(15) + BIT(0)) | 60 | #define P54_HDR_FLAG_CONTROL_OPSET (BIT(15) + BIT(0)) |
49 | 61 | ||
@@ -75,6 +87,14 @@ struct p54_rssi_linear_approximation { | |||
75 | s16 longbow_unk2; | 87 | s16 longbow_unk2; |
76 | }; | 88 | }; |
77 | 89 | ||
90 | struct p54_cal_database { | ||
91 | size_t entries; | ||
92 | size_t entry_size; | ||
93 | size_t offset; | ||
94 | size_t len; | ||
95 | u8 data[0]; | ||
96 | }; | ||
97 | |||
78 | #define EEPROM_READBACK_LEN 0x3fc | 98 | #define EEPROM_READBACK_LEN 0x3fc |
79 | 99 | ||
80 | #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 | 100 | #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 |
@@ -84,6 +104,14 @@ struct p54_rssi_linear_approximation { | |||
84 | #define FW_LM87 0x4c4d3837 | 104 | #define FW_LM87 0x4c4d3837 |
85 | #define FW_LM20 0x4c4d3230 | 105 | #define FW_LM20 0x4c4d3230 |
86 | 106 | ||
107 | enum fw_state { | ||
108 | FW_STATE_OFF, | ||
109 | FW_STATE_BOOTING, | ||
110 | FW_STATE_READY, | ||
111 | FW_STATE_RESET, | ||
112 | FW_STATE_RESETTING, | ||
113 | }; | ||
114 | |||
87 | struct p54_common { | 115 | struct p54_common { |
88 | struct ieee80211_hw *hw; | 116 | struct ieee80211_hw *hw; |
89 | u32 rx_start; | 117 | u32 rx_start; |
@@ -99,11 +127,12 @@ struct p54_common { | |||
99 | struct mutex conf_mutex; | 127 | struct mutex conf_mutex; |
100 | u8 mac_addr[ETH_ALEN]; | 128 | u8 mac_addr[ETH_ALEN]; |
101 | u8 bssid[ETH_ALEN]; | 129 | u8 bssid[ETH_ALEN]; |
130 | u8 rx_diversity_mask; | ||
131 | u8 tx_diversity_mask; | ||
102 | struct pda_iq_autocal_entry *iq_autocal; | 132 | struct pda_iq_autocal_entry *iq_autocal; |
103 | unsigned int iq_autocal_len; | 133 | unsigned int iq_autocal_len; |
104 | struct pda_channel_output_limit *output_limit; | 134 | struct p54_cal_database *output_limit; |
105 | unsigned int output_limit_len; | 135 | struct p54_cal_database *curve_data; |
106 | struct pda_pa_curve_data *curve_data; | ||
107 | struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; | 136 | struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; |
108 | unsigned int filter_flags; | 137 | unsigned int filter_flags; |
109 | bool use_short_slot; | 138 | bool use_short_slot; |
@@ -115,7 +144,7 @@ struct p54_common { | |||
115 | unsigned int output_power; | 144 | unsigned int output_power; |
116 | u32 tsf_low32; | 145 | u32 tsf_low32; |
117 | u32 tsf_high32; | 146 | u32 tsf_high32; |
118 | u64 basic_rate_mask; | 147 | u32 basic_rate_mask; |
119 | u16 wakeup_timer; | 148 | u16 wakeup_timer; |
120 | u16 aid; | 149 | u16 aid; |
121 | struct ieee80211_tx_queue_stats tx_stats[8]; | 150 | struct ieee80211_tx_queue_stats tx_stats[8]; |
@@ -133,6 +162,7 @@ struct p54_common { | |||
133 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); | 162 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); |
134 | void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb); | 163 | void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb); |
135 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); | 164 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); |
165 | int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len); | ||
136 | int p54_read_eeprom(struct ieee80211_hw *dev); | 166 | int p54_read_eeprom(struct ieee80211_hw *dev); |
137 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); | 167 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); |
138 | void p54_free_common(struct ieee80211_hw *dev); | 168 | void p54_free_common(struct ieee80211_hw *dev); |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 34561e6e816b..45c2e7ad3acd 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -239,11 +239,11 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
239 | 239 | ||
240 | if (priv->fw_var >= 0x300) { | 240 | if (priv->fw_var >= 0x300) { |
241 | /* Firmware supports QoS, use it! */ | 241 | /* Firmware supports QoS, use it! */ |
242 | priv->tx_stats[4].limit = 3; /* AC_VO */ | 242 | priv->tx_stats[P54_QUEUE_AC_VO].limit = 3; |
243 | priv->tx_stats[5].limit = 4; /* AC_VI */ | 243 | priv->tx_stats[P54_QUEUE_AC_VI].limit = 4; |
244 | priv->tx_stats[6].limit = 3; /* AC_BE */ | 244 | priv->tx_stats[P54_QUEUE_AC_BE].limit = 3; |
245 | priv->tx_stats[7].limit = 2; /* AC_BK */ | 245 | priv->tx_stats[P54_QUEUE_AC_BK].limit = 2; |
246 | dev->queues = 4; | 246 | dev->queues = P54_QUEUE_AC_NUM; |
247 | } | 247 | } |
248 | 248 | ||
249 | if (!modparam_nohwcrypt) | 249 | if (!modparam_nohwcrypt) |
@@ -272,13 +272,19 @@ static int p54_convert_rev0(struct ieee80211_hw *dev, | |||
272 | unsigned int i, j; | 272 | unsigned int i, j; |
273 | void *source, *target; | 273 | void *source, *target; |
274 | 274 | ||
275 | priv->curve_data = kmalloc(cd_len, GFP_KERNEL); | 275 | priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len, |
276 | GFP_KERNEL); | ||
276 | if (!priv->curve_data) | 277 | if (!priv->curve_data) |
277 | return -ENOMEM; | 278 | return -ENOMEM; |
278 | 279 | ||
279 | memcpy(priv->curve_data, curve_data, sizeof(*curve_data)); | 280 | priv->curve_data->entries = curve_data->channels; |
281 | priv->curve_data->entry_size = sizeof(__le16) + | ||
282 | sizeof(*dst) * curve_data->points_per_channel; | ||
283 | priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data); | ||
284 | priv->curve_data->len = cd_len; | ||
285 | memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data)); | ||
280 | source = curve_data->data; | 286 | source = curve_data->data; |
281 | target = priv->curve_data->data; | 287 | target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data; |
282 | for (i = 0; i < curve_data->channels; i++) { | 288 | for (i = 0; i < curve_data->channels; i++) { |
283 | __le16 *freq = source; | 289 | __le16 *freq = source; |
284 | source += sizeof(__le16); | 290 | source += sizeof(__le16); |
@@ -318,13 +324,19 @@ static int p54_convert_rev1(struct ieee80211_hw *dev, | |||
318 | unsigned int i, j; | 324 | unsigned int i, j; |
319 | void *source, *target; | 325 | void *source, *target; |
320 | 326 | ||
321 | priv->curve_data = kmalloc(cd_len, GFP_KERNEL); | 327 | priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data), |
328 | GFP_KERNEL); | ||
322 | if (!priv->curve_data) | 329 | if (!priv->curve_data) |
323 | return -ENOMEM; | 330 | return -ENOMEM; |
324 | 331 | ||
325 | memcpy(priv->curve_data, curve_data, sizeof(*curve_data)); | 332 | priv->curve_data->entries = curve_data->channels; |
333 | priv->curve_data->entry_size = sizeof(__le16) + | ||
334 | sizeof(*dst) * curve_data->points_per_channel; | ||
335 | priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data); | ||
336 | priv->curve_data->len = cd_len; | ||
337 | memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data)); | ||
326 | source = curve_data->data; | 338 | source = curve_data->data; |
327 | target = priv->curve_data->data; | 339 | target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data; |
328 | for (i = 0; i < curve_data->channels; i++) { | 340 | for (i = 0; i < curve_data->channels; i++) { |
329 | __le16 *freq = source; | 341 | __le16 *freq = source; |
330 | source += sizeof(__le16); | 342 | source += sizeof(__le16); |
@@ -376,7 +388,102 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, | |||
376 | } | 388 | } |
377 | } | 389 | } |
378 | 390 | ||
379 | static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | 391 | static void p54_parse_default_country(struct ieee80211_hw *dev, |
392 | void *data, int len) | ||
393 | { | ||
394 | struct pda_country *country; | ||
395 | |||
396 | if (len != sizeof(*country)) { | ||
397 | printk(KERN_ERR "%s: found possible invalid default country " | ||
398 | "eeprom entry. (entry size: %d)\n", | ||
399 | wiphy_name(dev->wiphy), len); | ||
400 | |||
401 | print_hex_dump_bytes("country:", DUMP_PREFIX_NONE, | ||
402 | data, len); | ||
403 | |||
404 | printk(KERN_ERR "%s: please report this issue.\n", | ||
405 | wiphy_name(dev->wiphy)); | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | country = (struct pda_country *) data; | ||
410 | if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO) | ||
411 | regulatory_hint(dev->wiphy, country->alpha2); | ||
412 | else { | ||
413 | /* TODO: | ||
414 | * write a shared/common function that converts | ||
415 | * "Regulatory domain codes" (802.11-2007 14.8.2.2) | ||
416 | * into ISO/IEC 3166-1 alpha2 for regulatory_hint. | ||
417 | */ | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static int p54_convert_output_limits(struct ieee80211_hw *dev, | ||
422 | u8 *data, size_t len) | ||
423 | { | ||
424 | struct p54_common *priv = dev->priv; | ||
425 | |||
426 | if (len < 2) | ||
427 | return -EINVAL; | ||
428 | |||
429 | if (data[0] != 0) { | ||
430 | printk(KERN_ERR "%s: unknown output power db revision:%x\n", | ||
431 | wiphy_name(dev->wiphy), data[0]); | ||
432 | return -EINVAL; | ||
433 | } | ||
434 | |||
435 | if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len) | ||
436 | return -EINVAL; | ||
437 | |||
438 | priv->output_limit = kmalloc(data[1] * | ||
439 | sizeof(struct pda_channel_output_limit) + | ||
440 | sizeof(*priv->output_limit), GFP_KERNEL); | ||
441 | |||
442 | if (!priv->output_limit) | ||
443 | return -ENOMEM; | ||
444 | |||
445 | priv->output_limit->offset = 0; | ||
446 | priv->output_limit->entries = data[1]; | ||
447 | priv->output_limit->entry_size = | ||
448 | sizeof(struct pda_channel_output_limit); | ||
449 | priv->output_limit->len = priv->output_limit->entry_size * | ||
450 | priv->output_limit->entries + | ||
451 | priv->output_limit->offset; | ||
452 | |||
453 | memcpy(priv->output_limit->data, &data[2], | ||
454 | data[1] * sizeof(struct pda_channel_output_limit)); | ||
455 | |||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src, | ||
460 | size_t total_len) | ||
461 | { | ||
462 | struct p54_cal_database *dst; | ||
463 | size_t payload_len, entries, entry_size, offset; | ||
464 | |||
465 | payload_len = le16_to_cpu(src->len); | ||
466 | entries = le16_to_cpu(src->entries); | ||
467 | entry_size = le16_to_cpu(src->entry_size); | ||
468 | offset = le16_to_cpu(src->offset); | ||
469 | if (((entries * entry_size + offset) != payload_len) || | ||
470 | (payload_len + sizeof(*src) != total_len)) | ||
471 | return NULL; | ||
472 | |||
473 | dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL); | ||
474 | if (!dst) | ||
475 | return NULL; | ||
476 | |||
477 | dst->entries = entries; | ||
478 | dst->entry_size = entry_size; | ||
479 | dst->offset = offset; | ||
480 | dst->len = payload_len; | ||
481 | |||
482 | memcpy(dst->data, src->data, payload_len); | ||
483 | return dst; | ||
484 | } | ||
485 | |||
486 | int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | ||
380 | { | 487 | { |
381 | struct p54_common *priv = dev->priv; | 488 | struct p54_common *priv = dev->priv; |
382 | struct eeprom_pda_wrap *wrap = NULL; | 489 | struct eeprom_pda_wrap *wrap = NULL; |
@@ -401,30 +508,17 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
401 | 508 | ||
402 | switch (le16_to_cpu(entry->code)) { | 509 | switch (le16_to_cpu(entry->code)) { |
403 | case PDR_MAC_ADDRESS: | 510 | case PDR_MAC_ADDRESS: |
511 | if (data_len != ETH_ALEN) | ||
512 | break; | ||
404 | SET_IEEE80211_PERM_ADDR(dev, entry->data); | 513 | SET_IEEE80211_PERM_ADDR(dev, entry->data); |
405 | break; | 514 | break; |
406 | case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS: | 515 | case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS: |
407 | if (data_len < 2) { | 516 | if (priv->output_limit) |
408 | err = -EINVAL; | 517 | break; |
409 | goto err; | 518 | err = p54_convert_output_limits(dev, entry->data, |
410 | } | 519 | data_len); |
411 | 520 | if (err) | |
412 | if (2 + entry->data[1]*sizeof(*priv->output_limit) > data_len) { | ||
413 | err = -EINVAL; | ||
414 | goto err; | ||
415 | } | ||
416 | |||
417 | priv->output_limit = kmalloc(entry->data[1] * | ||
418 | sizeof(*priv->output_limit), GFP_KERNEL); | ||
419 | |||
420 | if (!priv->output_limit) { | ||
421 | err = -ENOMEM; | ||
422 | goto err; | 521 | goto err; |
423 | } | ||
424 | |||
425 | memcpy(priv->output_limit, &entry->data[2], | ||
426 | entry->data[1]*sizeof(*priv->output_limit)); | ||
427 | priv->output_limit_len = entry->data[1]; | ||
428 | break; | 522 | break; |
429 | case PDR_PRISM_PA_CAL_CURVE_DATA: { | 523 | case PDR_PRISM_PA_CAL_CURVE_DATA: { |
430 | struct pda_pa_curve_data *curve_data = | 524 | struct pda_pa_curve_data *curve_data = |
@@ -463,6 +557,9 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
463 | memcpy(priv->iq_autocal, entry->data, data_len); | 557 | memcpy(priv->iq_autocal, entry->data, data_len); |
464 | priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry); | 558 | priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry); |
465 | break; | 559 | break; |
560 | case PDR_DEFAULT_COUNTRY: | ||
561 | p54_parse_default_country(dev, entry->data, data_len); | ||
562 | break; | ||
466 | case PDR_INTERFACE_LIST: | 563 | case PDR_INTERFACE_LIST: |
467 | tmp = entry->data; | 564 | tmp = entry->data; |
468 | while ((u8 *)tmp < entry->data + data_len) { | 565 | while ((u8 *)tmp < entry->data + data_len) { |
@@ -473,6 +570,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
473 | } | 570 | } |
474 | break; | 571 | break; |
475 | case PDR_HARDWARE_PLATFORM_COMPONENT_ID: | 572 | case PDR_HARDWARE_PLATFORM_COMPONENT_ID: |
573 | if (data_len < 2) | ||
574 | break; | ||
476 | priv->version = *(u8 *)(entry->data + 1); | 575 | priv->version = *(u8 *)(entry->data + 1); |
477 | break; | 576 | break; |
478 | case PDR_RSSI_LINEAR_APPROXIMATION: | 577 | case PDR_RSSI_LINEAR_APPROXIMATION: |
@@ -481,6 +580,34 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
481 | p54_parse_rssical(dev, entry->data, data_len, | 580 | p54_parse_rssical(dev, entry->data, data_len, |
482 | le16_to_cpu(entry->code)); | 581 | le16_to_cpu(entry->code)); |
483 | break; | 582 | break; |
583 | case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: { | ||
584 | __le16 *src = (void *) entry->data; | ||
585 | s16 *dst = (void *) &priv->rssical_db; | ||
586 | int i; | ||
587 | |||
588 | if (data_len != sizeof(priv->rssical_db)) { | ||
589 | err = -EINVAL; | ||
590 | goto err; | ||
591 | } | ||
592 | for (i = 0; i < sizeof(priv->rssical_db) / | ||
593 | sizeof(*src); i++) | ||
594 | *(dst++) = (s16) le16_to_cpu(*(src++)); | ||
595 | } | ||
596 | break; | ||
597 | case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { | ||
598 | struct pda_custom_wrapper *pda = (void *) entry->data; | ||
599 | if (priv->output_limit || data_len < sizeof(*pda)) | ||
600 | break; | ||
601 | priv->output_limit = p54_convert_db(pda, data_len); | ||
602 | } | ||
603 | break; | ||
604 | case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: { | ||
605 | struct pda_custom_wrapper *pda = (void *) entry->data; | ||
606 | if (priv->curve_data || data_len < sizeof(*pda)) | ||
607 | break; | ||
608 | priv->curve_data = p54_convert_db(pda, data_len); | ||
609 | } | ||
610 | break; | ||
484 | case PDR_END: | 611 | case PDR_END: |
485 | /* make it overrun */ | 612 | /* make it overrun */ |
486 | entry_len = len; | 613 | entry_len = len; |
@@ -497,7 +624,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
497 | case PDR_UTF8_OEM_NAME: | 624 | case PDR_UTF8_OEM_NAME: |
498 | case PDR_UTF8_PRODUCT_NAME: | 625 | case PDR_UTF8_PRODUCT_NAME: |
499 | case PDR_COUNTRY_LIST: | 626 | case PDR_COUNTRY_LIST: |
500 | case PDR_DEFAULT_COUNTRY: | ||
501 | case PDR_ANTENNA_GAIN: | 627 | case PDR_ANTENNA_GAIN: |
502 | case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA: | 628 | case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA: |
503 | case PDR_REGULATORY_POWER_LIMITS: | 629 | case PDR_REGULATORY_POWER_LIMITS: |
@@ -525,12 +651,16 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
525 | } | 651 | } |
526 | 652 | ||
527 | priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK; | 653 | priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK; |
528 | if (priv->rxhw == 4) | 654 | if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW) |
529 | p54_init_xbow_synth(dev); | 655 | p54_init_xbow_synth(dev); |
530 | if (!(synth & PDR_SYNTH_24_GHZ_DISABLED)) | 656 | if (!(synth & PDR_SYNTH_24_GHZ_DISABLED)) |
531 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; | 657 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; |
532 | if (!(synth & PDR_SYNTH_5_GHZ_DISABLED)) | 658 | if (!(synth & PDR_SYNTH_5_GHZ_DISABLED)) |
533 | dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz; | 659 | dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz; |
660 | if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED) | ||
661 | priv->rx_diversity_mask = 3; | ||
662 | if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED) | ||
663 | priv->tx_diversity_mask = 3; | ||
534 | 664 | ||
535 | if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { | 665 | if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { |
536 | u8 perm_addr[ETH_ALEN]; | 666 | u8 perm_addr[ETH_ALEN]; |
@@ -568,13 +698,21 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
568 | wiphy_name(dev->wiphy)); | 698 | wiphy_name(dev->wiphy)); |
569 | return err; | 699 | return err; |
570 | } | 700 | } |
701 | EXPORT_SYMBOL_GPL(p54_parse_eeprom); | ||
571 | 702 | ||
572 | static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi) | 703 | static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi) |
573 | { | 704 | { |
574 | struct p54_common *priv = dev->priv; | 705 | struct p54_common *priv = dev->priv; |
575 | int band = dev->conf.channel->band; | 706 | int band = dev->conf.channel->band; |
576 | 707 | ||
577 | return ((rssi * priv->rssical_db[band].mul) / 64 + | 708 | if (priv->rxhw != PDR_SYNTH_FRONTEND_LONGBOW) |
709 | return ((rssi * priv->rssical_db[band].mul) / 64 + | ||
710 | priv->rssical_db[band].add) / 4; | ||
711 | else | ||
712 | /* | ||
713 | * TODO: find the correct formula | ||
714 | */ | ||
715 | return ((rssi * priv->rssical_db[band].mul) / 64 + | ||
578 | priv->rssical_db[band].add) / 4; | 716 | priv->rssical_db[band].add) / 4; |
579 | } | 717 | } |
580 | 718 | ||
@@ -655,7 +793,8 @@ static void inline p54_wake_free_queues(struct ieee80211_hw *dev) | |||
655 | return ; | 793 | return ; |
656 | 794 | ||
657 | for (i = 0; i < dev->queues; i++) | 795 | for (i = 0; i < dev->queues; i++) |
658 | if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit) | 796 | if (priv->tx_stats[i + P54_QUEUE_DATA].len < |
797 | priv->tx_stats[i + P54_QUEUE_DATA].limit) | ||
659 | ieee80211_wake_queue(dev, i); | 798 | ieee80211_wake_queue(dev, i); |
660 | } | 799 | } |
661 | 800 | ||
@@ -663,7 +802,7 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
663 | { | 802 | { |
664 | struct p54_common *priv = dev->priv; | 803 | struct p54_common *priv = dev->priv; |
665 | struct ieee80211_tx_info *info; | 804 | struct ieee80211_tx_info *info; |
666 | struct memrecord *range; | 805 | struct p54_tx_info *range; |
667 | unsigned long flags; | 806 | unsigned long flags; |
668 | u32 freed = 0, last_addr = priv->rx_start; | 807 | u32 freed = 0, last_addr = priv->rx_start; |
669 | 808 | ||
@@ -681,18 +820,18 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
681 | range = (void *)info->rate_driver_data; | 820 | range = (void *)info->rate_driver_data; |
682 | if (skb->prev != (struct sk_buff *)&priv->tx_queue) { | 821 | if (skb->prev != (struct sk_buff *)&priv->tx_queue) { |
683 | struct ieee80211_tx_info *ni; | 822 | struct ieee80211_tx_info *ni; |
684 | struct memrecord *mr; | 823 | struct p54_tx_info *mr; |
685 | 824 | ||
686 | ni = IEEE80211_SKB_CB(skb->prev); | 825 | ni = IEEE80211_SKB_CB(skb->prev); |
687 | mr = (struct memrecord *)ni->rate_driver_data; | 826 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
688 | last_addr = mr->end_addr; | 827 | last_addr = mr->end_addr; |
689 | } | 828 | } |
690 | if (skb->next != (struct sk_buff *)&priv->tx_queue) { | 829 | if (skb->next != (struct sk_buff *)&priv->tx_queue) { |
691 | struct ieee80211_tx_info *ni; | 830 | struct ieee80211_tx_info *ni; |
692 | struct memrecord *mr; | 831 | struct p54_tx_info *mr; |
693 | 832 | ||
694 | ni = IEEE80211_SKB_CB(skb->next); | 833 | ni = IEEE80211_SKB_CB(skb->next); |
695 | mr = (struct memrecord *)ni->rate_driver_data; | 834 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
696 | freed = mr->start_addr - last_addr; | 835 | freed = mr->start_addr - last_addr; |
697 | } else | 836 | } else |
698 | freed = priv->rx_end - last_addr; | 837 | freed = priv->rx_end - last_addr; |
@@ -734,7 +873,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
734 | struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data; | 873 | struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data; |
735 | struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next; | 874 | struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next; |
736 | u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom; | 875 | u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom; |
737 | struct memrecord *range = NULL; | 876 | struct p54_tx_info *range = NULL; |
738 | u32 freed = 0; | 877 | u32 freed = 0; |
739 | u32 last_addr = priv->rx_start; | 878 | u32 last_addr = priv->rx_start; |
740 | unsigned long flags; | 879 | unsigned long flags; |
@@ -756,10 +895,10 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
756 | 895 | ||
757 | if (entry->next != (struct sk_buff *)&priv->tx_queue) { | 896 | if (entry->next != (struct sk_buff *)&priv->tx_queue) { |
758 | struct ieee80211_tx_info *ni; | 897 | struct ieee80211_tx_info *ni; |
759 | struct memrecord *mr; | 898 | struct p54_tx_info *mr; |
760 | 899 | ||
761 | ni = IEEE80211_SKB_CB(entry->next); | 900 | ni = IEEE80211_SKB_CB(entry->next); |
762 | mr = (struct memrecord *)ni->rate_driver_data; | 901 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
763 | freed = mr->start_addr - last_addr; | 902 | freed = mr->start_addr - last_addr; |
764 | } else | 903 | } else |
765 | freed = priv->rx_end - last_addr; | 904 | freed = priv->rx_end - last_addr; |
@@ -774,9 +913,16 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
774 | priv->tx_stats[entry_data->hw_queue].len--; | 913 | priv->tx_stats[entry_data->hw_queue].len--; |
775 | priv->stats.dot11ACKFailureCount += payload->tries - 1; | 914 | priv->stats.dot11ACKFailureCount += payload->tries - 1; |
776 | 915 | ||
777 | if (unlikely(entry == priv->cached_beacon)) { | 916 | /* |
917 | * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are | ||
918 | * generated by the driver. Therefore tx_status is bogus | ||
919 | * and we don't want to confuse the mac80211 stack. | ||
920 | */ | ||
921 | if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) { | ||
922 | if (entry_data->hw_queue == P54_QUEUE_BEACON) | ||
923 | priv->cached_beacon = NULL; | ||
924 | |||
778 | kfree_skb(entry); | 925 | kfree_skb(entry); |
779 | priv->cached_beacon = NULL; | ||
780 | goto out; | 926 | goto out; |
781 | } | 927 | } |
782 | 928 | ||
@@ -969,8 +1115,8 @@ EXPORT_SYMBOL_GPL(p54_rx); | |||
969 | * can find some unused memory to upload our packets to. However, data that we | 1115 | * can find some unused memory to upload our packets to. However, data that we |
970 | * want the card to TX needs to stay intact until the card has told us that | 1116 | * want the card to TX needs to stay intact until the card has told us that |
971 | * it is done with it. This function finds empty places we can upload to and | 1117 | * it is done with it. This function finds empty places we can upload to and |
972 | * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees | 1118 | * marks allocated areas as reserved if necessary. p54_rx_frame_sent or |
973 | * allocated areas. | 1119 | * p54_free_skb frees allocated areas. |
974 | */ | 1120 | */ |
975 | static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | 1121 | static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, |
976 | struct p54_hdr *data, u32 len) | 1122 | struct p54_hdr *data, u32 len) |
@@ -979,7 +1125,7 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
979 | struct sk_buff *entry = priv->tx_queue.next; | 1125 | struct sk_buff *entry = priv->tx_queue.next; |
980 | struct sk_buff *target_skb = NULL; | 1126 | struct sk_buff *target_skb = NULL; |
981 | struct ieee80211_tx_info *info; | 1127 | struct ieee80211_tx_info *info; |
982 | struct memrecord *range; | 1128 | struct p54_tx_info *range; |
983 | u32 last_addr = priv->rx_start; | 1129 | u32 last_addr = priv->rx_start; |
984 | u32 largest_hole = 0; | 1130 | u32 largest_hole = 0; |
985 | u32 target_addr = priv->rx_start; | 1131 | u32 target_addr = priv->rx_start; |
@@ -1060,25 +1206,29 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1060 | return 0; | 1206 | return 0; |
1061 | } | 1207 | } |
1062 | 1208 | ||
1063 | static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, | 1209 | static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, u16 hdr_flags, |
1064 | u16 hdr_flags, u16 len, u16 type, gfp_t memflags) | 1210 | u16 payload_len, u16 type, gfp_t memflags) |
1065 | { | 1211 | { |
1066 | struct p54_common *priv = dev->priv; | 1212 | struct p54_common *priv = dev->priv; |
1067 | struct p54_hdr *hdr; | 1213 | struct p54_hdr *hdr; |
1068 | struct sk_buff *skb; | 1214 | struct sk_buff *skb; |
1215 | size_t frame_len = sizeof(*hdr) + payload_len; | ||
1216 | |||
1217 | if (frame_len > P54_MAX_CTRL_FRAME_LEN) | ||
1218 | return NULL; | ||
1069 | 1219 | ||
1070 | skb = __dev_alloc_skb(len + priv->tx_hdr_len, memflags); | 1220 | skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags); |
1071 | if (!skb) | 1221 | if (!skb) |
1072 | return NULL; | 1222 | return NULL; |
1073 | skb_reserve(skb, priv->tx_hdr_len); | 1223 | skb_reserve(skb, priv->tx_hdr_len); |
1074 | 1224 | ||
1075 | hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr)); | 1225 | hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr)); |
1076 | hdr->flags = cpu_to_le16(hdr_flags); | 1226 | hdr->flags = cpu_to_le16(hdr_flags); |
1077 | hdr->len = cpu_to_le16(len - sizeof(*hdr)); | 1227 | hdr->len = cpu_to_le16(payload_len); |
1078 | hdr->type = cpu_to_le16(type); | 1228 | hdr->type = cpu_to_le16(type); |
1079 | hdr->tries = hdr->rts_tries = 0; | 1229 | hdr->tries = hdr->rts_tries = 0; |
1080 | 1230 | ||
1081 | if (unlikely(p54_assign_address(dev, skb, hdr, len))) { | 1231 | if (p54_assign_address(dev, skb, hdr, frame_len)) { |
1082 | kfree_skb(skb); | 1232 | kfree_skb(skb); |
1083 | return NULL; | 1233 | return NULL; |
1084 | } | 1234 | } |
@@ -1088,7 +1238,6 @@ static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, | |||
1088 | int p54_read_eeprom(struct ieee80211_hw *dev) | 1238 | int p54_read_eeprom(struct ieee80211_hw *dev) |
1089 | { | 1239 | { |
1090 | struct p54_common *priv = dev->priv; | 1240 | struct p54_common *priv = dev->priv; |
1091 | struct p54_hdr *hdr = NULL; | ||
1092 | struct p54_eeprom_lm86 *eeprom_hdr; | 1241 | struct p54_eeprom_lm86 *eeprom_hdr; |
1093 | struct sk_buff *skb; | 1242 | struct sk_buff *skb; |
1094 | size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize; | 1243 | size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize; |
@@ -1101,9 +1250,9 @@ int p54_read_eeprom(struct ieee80211_hw *dev) | |||
1101 | else | 1250 | else |
1102 | maxblocksize -= 0x4; | 1251 | maxblocksize -= 0x4; |
1103 | 1252 | ||
1104 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) + | 1253 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*eeprom_hdr) + |
1105 | sizeof(*eeprom_hdr) + maxblocksize, | 1254 | maxblocksize, P54_CONTROL_TYPE_EEPROM_READBACK, |
1106 | P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL); | 1255 | GFP_KERNEL); |
1107 | if (!skb) | 1256 | if (!skb) |
1108 | goto free; | 1257 | goto free; |
1109 | priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL); | 1258 | priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL); |
@@ -1159,9 +1308,8 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta, | |||
1159 | struct sk_buff *skb; | 1308 | struct sk_buff *skb; |
1160 | struct p54_tim *tim; | 1309 | struct p54_tim *tim; |
1161 | 1310 | ||
1162 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, | 1311 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim), |
1163 | sizeof(struct p54_hdr) + sizeof(*tim), | 1312 | P54_CONTROL_TYPE_TIM, GFP_ATOMIC); |
1164 | P54_CONTROL_TYPE_TIM, GFP_ATOMIC); | ||
1165 | if (!skb) | 1313 | if (!skb) |
1166 | return -ENOMEM; | 1314 | return -ENOMEM; |
1167 | 1315 | ||
@@ -1178,9 +1326,8 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr) | |||
1178 | struct sk_buff *skb; | 1326 | struct sk_buff *skb; |
1179 | struct p54_sta_unlock *sta; | 1327 | struct p54_sta_unlock *sta; |
1180 | 1328 | ||
1181 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, | 1329 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta), |
1182 | sizeof(struct p54_hdr) + sizeof(*sta), | 1330 | P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC); |
1183 | P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC); | ||
1184 | if (!skb) | 1331 | if (!skb) |
1185 | return -ENOMEM; | 1332 | return -ENOMEM; |
1186 | 1333 | ||
@@ -1220,9 +1367,8 @@ static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry) | |||
1220 | struct p54_hdr *hdr; | 1367 | struct p54_hdr *hdr; |
1221 | struct p54_txcancel *cancel; | 1368 | struct p54_txcancel *cancel; |
1222 | 1369 | ||
1223 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, | 1370 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel), |
1224 | sizeof(struct p54_hdr) + sizeof(*cancel), | 1371 | P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC); |
1225 | P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC); | ||
1226 | if (!skb) | 1372 | if (!skb) |
1227 | return -ENOMEM; | 1373 | return -ENOMEM; |
1228 | 1374 | ||
@@ -1239,46 +1385,73 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1239 | { | 1385 | { |
1240 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1386 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1241 | struct p54_common *priv = dev->priv; | 1387 | struct p54_common *priv = dev->priv; |
1242 | int ret = 0; | 1388 | int ret = 1; |
1243 | |||
1244 | if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) { | ||
1245 | if (ieee80211_is_beacon(hdr->frame_control)) { | ||
1246 | *aid = 0; | ||
1247 | *queue = 0; | ||
1248 | *extra_len = IEEE80211_MAX_TIM_LEN; | ||
1249 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP; | ||
1250 | return 0; | ||
1251 | } else if (ieee80211_is_probe_resp(hdr->frame_control)) { | ||
1252 | *aid = 0; | ||
1253 | *queue = 2; | ||
1254 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP | | ||
1255 | P54_HDR_FLAG_DATA_OUT_NOCANCEL; | ||
1256 | return 0; | ||
1257 | } else { | ||
1258 | *queue = 2; | ||
1259 | ret = 0; | ||
1260 | } | ||
1261 | } else { | ||
1262 | *queue += 4; | ||
1263 | ret = 1; | ||
1264 | } | ||
1265 | 1389 | ||
1266 | switch (priv->mode) { | 1390 | switch (priv->mode) { |
1391 | case NL80211_IFTYPE_MONITOR: | ||
1392 | /* | ||
1393 | * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for | ||
1394 | * every frame in promiscuous/monitor mode. | ||
1395 | * see STSW45x0C LMAC API - page 12. | ||
1396 | */ | ||
1397 | *aid = 0; | ||
1398 | *flags = P54_HDR_FLAG_DATA_OUT_PROMISC; | ||
1399 | *queue += P54_QUEUE_DATA; | ||
1400 | break; | ||
1267 | case NL80211_IFTYPE_STATION: | 1401 | case NL80211_IFTYPE_STATION: |
1268 | *aid = 1; | 1402 | *aid = 1; |
1403 | if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) { | ||
1404 | *queue = P54_QUEUE_MGMT; | ||
1405 | ret = 0; | ||
1406 | } else | ||
1407 | *queue += P54_QUEUE_DATA; | ||
1269 | break; | 1408 | break; |
1270 | case NL80211_IFTYPE_AP: | 1409 | case NL80211_IFTYPE_AP: |
1271 | case NL80211_IFTYPE_ADHOC: | 1410 | case NL80211_IFTYPE_ADHOC: |
1272 | case NL80211_IFTYPE_MESH_POINT: | 1411 | case NL80211_IFTYPE_MESH_POINT: |
1273 | if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { | 1412 | if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { |
1274 | *aid = 0; | 1413 | *aid = 0; |
1275 | *queue = 3; | 1414 | *queue = P54_QUEUE_CAB; |
1276 | return 0; | 1415 | return 0; |
1277 | } | 1416 | } |
1417 | |||
1418 | if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) { | ||
1419 | if (ieee80211_is_probe_resp(hdr->frame_control)) { | ||
1420 | *aid = 0; | ||
1421 | *queue = P54_QUEUE_MGMT; | ||
1422 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP | | ||
1423 | P54_HDR_FLAG_DATA_OUT_NOCANCEL; | ||
1424 | return 0; | ||
1425 | } else if (ieee80211_is_beacon(hdr->frame_control)) { | ||
1426 | *aid = 0; | ||
1427 | |||
1428 | if (info->flags & IEEE80211_TX_CTL_INJECTED) { | ||
1429 | /* | ||
1430 | * Injecting beacons on top of a AP is | ||
1431 | * not a good idea... nevertheless, | ||
1432 | * it should be doable. | ||
1433 | */ | ||
1434 | |||
1435 | *queue += P54_QUEUE_DATA; | ||
1436 | return 1; | ||
1437 | } | ||
1438 | |||
1439 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP; | ||
1440 | *queue = P54_QUEUE_BEACON; | ||
1441 | *extra_len = IEEE80211_MAX_TIM_LEN; | ||
1442 | return 0; | ||
1443 | } else { | ||
1444 | *queue = P54_QUEUE_MGMT; | ||
1445 | ret = 0; | ||
1446 | } | ||
1447 | } else | ||
1448 | *queue += P54_QUEUE_DATA; | ||
1449 | |||
1278 | if (info->control.sta) | 1450 | if (info->control.sta) |
1279 | *aid = info->control.sta->aid; | 1451 | *aid = info->control.sta->aid; |
1280 | else | 1452 | else |
1281 | *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; | 1453 | *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; |
1454 | break; | ||
1282 | } | 1455 | } |
1283 | return ret; | 1456 | return ret; |
1284 | } | 1457 | } |
@@ -1300,7 +1473,7 @@ static u8 p54_convert_algo(enum ieee80211_key_alg alg) | |||
1300 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | 1473 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
1301 | { | 1474 | { |
1302 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1475 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1303 | struct ieee80211_tx_queue_stats *current_queue = NULL; | 1476 | struct ieee80211_tx_queue_stats *current_queue; |
1304 | struct p54_common *priv = dev->priv; | 1477 | struct p54_common *priv = dev->priv; |
1305 | struct p54_hdr *hdr; | 1478 | struct p54_hdr *hdr; |
1306 | struct p54_tx_data *txhdr; | 1479 | struct p54_tx_data *txhdr; |
@@ -1443,15 +1616,17 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1443 | } | 1616 | } |
1444 | txhdr->crypt_offset = crypt_offset; | 1617 | txhdr->crypt_offset = crypt_offset; |
1445 | txhdr->hw_queue = queue; | 1618 | txhdr->hw_queue = queue; |
1446 | if (current_queue) | 1619 | txhdr->backlog = current_queue->len; |
1447 | txhdr->backlog = current_queue->len; | ||
1448 | else | ||
1449 | txhdr->backlog = 0; | ||
1450 | memset(txhdr->durations, 0, sizeof(txhdr->durations)); | 1620 | memset(txhdr->durations, 0, sizeof(txhdr->durations)); |
1451 | txhdr->tx_antenna = (info->antenna_sel_tx == 0) ? | 1621 | txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ? |
1452 | 2 : info->antenna_sel_tx - 1; | 1622 | 2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask; |
1453 | txhdr->output_power = priv->output_power; | 1623 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { |
1454 | txhdr->cts_rate = cts_rate; | 1624 | txhdr->longbow.cts_rate = cts_rate; |
1625 | txhdr->longbow.output_power = cpu_to_le16(priv->output_power); | ||
1626 | } else { | ||
1627 | txhdr->normal.output_power = priv->output_power; | ||
1628 | txhdr->normal.cts_rate = cts_rate; | ||
1629 | } | ||
1455 | if (padding) | 1630 | if (padding) |
1456 | txhdr->align[0] = padding; | 1631 | txhdr->align[0] = padding; |
1457 | 1632 | ||
@@ -1464,14 +1639,12 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1464 | queue_delayed_work(dev->workqueue, &priv->work, | 1639 | queue_delayed_work(dev->workqueue, &priv->work, |
1465 | msecs_to_jiffies(P54_TX_FRAME_LIFETIME)); | 1640 | msecs_to_jiffies(P54_TX_FRAME_LIFETIME)); |
1466 | 1641 | ||
1467 | return 0; | 1642 | return NETDEV_TX_OK; |
1468 | 1643 | ||
1469 | err: | 1644 | err: |
1470 | skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding); | 1645 | skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding); |
1471 | if (current_queue) { | 1646 | current_queue->len--; |
1472 | current_queue->len--; | 1647 | current_queue->count--; |
1473 | current_queue->count--; | ||
1474 | } | ||
1475 | return NETDEV_TX_BUSY; | 1648 | return NETDEV_TX_BUSY; |
1476 | } | 1649 | } |
1477 | 1650 | ||
@@ -1482,9 +1655,8 @@ static int p54_setup_mac(struct ieee80211_hw *dev) | |||
1482 | struct p54_setup_mac *setup; | 1655 | struct p54_setup_mac *setup; |
1483 | u16 mode; | 1656 | u16 mode; |
1484 | 1657 | ||
1485 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) + | 1658 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup), |
1486 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP, | 1659 | P54_CONTROL_TYPE_SETUP, GFP_ATOMIC); |
1487 | GFP_ATOMIC); | ||
1488 | if (!skb) | 1660 | if (!skb) |
1489 | return -ENOMEM; | 1661 | return -ENOMEM; |
1490 | 1662 | ||
@@ -1501,11 +1673,21 @@ static int p54_setup_mac(struct ieee80211_hw *dev) | |||
1501 | case NL80211_IFTYPE_MESH_POINT: | 1673 | case NL80211_IFTYPE_MESH_POINT: |
1502 | mode = P54_FILTER_TYPE_IBSS; | 1674 | mode = P54_FILTER_TYPE_IBSS; |
1503 | break; | 1675 | break; |
1676 | case NL80211_IFTYPE_MONITOR: | ||
1677 | mode = P54_FILTER_TYPE_PROMISCUOUS; | ||
1678 | break; | ||
1504 | default: | 1679 | default: |
1505 | mode = P54_FILTER_TYPE_NONE; | 1680 | mode = P54_FILTER_TYPE_NONE; |
1506 | break; | 1681 | break; |
1507 | } | 1682 | } |
1508 | if (priv->filter_flags & FIF_PROMISC_IN_BSS) | 1683 | |
1684 | /* | ||
1685 | * "TRANSPARENT and PROMISCUOUS are mutually exclusive" | ||
1686 | * STSW45X0C LMAC API - page 12 | ||
1687 | */ | ||
1688 | if (((priv->filter_flags & FIF_PROMISC_IN_BSS) || | ||
1689 | (priv->filter_flags & FIF_OTHER_BSS)) && | ||
1690 | (mode != P54_FILTER_TYPE_PROMISCUOUS)) | ||
1509 | mode |= P54_FILTER_TYPE_TRANSPARENT; | 1691 | mode |= P54_FILTER_TYPE_TRANSPARENT; |
1510 | } else | 1692 | } else |
1511 | mode = P54_FILTER_TYPE_RX_DISABLED; | 1693 | mode = P54_FILTER_TYPE_RX_DISABLED; |
@@ -1513,7 +1695,7 @@ static int p54_setup_mac(struct ieee80211_hw *dev) | |||
1513 | setup->mac_mode = cpu_to_le16(mode); | 1695 | setup->mac_mode = cpu_to_le16(mode); |
1514 | memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN); | 1696 | memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN); |
1515 | memcpy(setup->bssid, priv->bssid, ETH_ALEN); | 1697 | memcpy(setup->bssid, priv->bssid, ETH_ALEN); |
1516 | setup->rx_antenna = 2; /* automatic */ | 1698 | setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */ |
1517 | setup->rx_align = 0; | 1699 | setup->rx_align = 0; |
1518 | if (priv->fw_var < 0x500) { | 1700 | if (priv->fw_var < 0x500) { |
1519 | setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); | 1701 | setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); |
@@ -1546,79 +1728,137 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell) | |||
1546 | { | 1728 | { |
1547 | struct p54_common *priv = dev->priv; | 1729 | struct p54_common *priv = dev->priv; |
1548 | struct sk_buff *skb; | 1730 | struct sk_buff *skb; |
1549 | struct p54_scan *chan; | 1731 | struct p54_hdr *hdr; |
1732 | struct p54_scan_head *head; | ||
1733 | struct p54_iq_autocal_entry *iq_autocal; | ||
1734 | union p54_scan_body_union *body; | ||
1735 | struct p54_scan_tail_rate *rate; | ||
1736 | struct pda_rssi_cal_entry *rssi; | ||
1550 | unsigned int i; | 1737 | unsigned int i; |
1551 | void *entry; | 1738 | void *entry; |
1552 | __le16 freq = cpu_to_le16(dev->conf.channel->center_freq); | ||
1553 | int band = dev->conf.channel->band; | 1739 | int band = dev->conf.channel->band; |
1740 | __le16 freq = cpu_to_le16(dev->conf.channel->center_freq); | ||
1554 | 1741 | ||
1555 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) + | 1742 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + |
1556 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN, | 1743 | 2 + sizeof(*iq_autocal) + sizeof(*body) + |
1557 | GFP_ATOMIC); | 1744 | sizeof(*rate) + 2 * sizeof(*rssi), |
1745 | P54_CONTROL_TYPE_SCAN, GFP_ATOMIC); | ||
1558 | if (!skb) | 1746 | if (!skb) |
1559 | return -ENOMEM; | 1747 | return -ENOMEM; |
1560 | 1748 | ||
1561 | chan = (struct p54_scan *) skb_put(skb, sizeof(*chan)); | 1749 | head = (struct p54_scan_head *) skb_put(skb, sizeof(*head)); |
1562 | memset(chan->padding1, 0, sizeof(chan->padding1)); | 1750 | memset(head->scan_params, 0, sizeof(head->scan_params)); |
1563 | chan->mode = cpu_to_le16(mode); | 1751 | head->mode = cpu_to_le16(mode); |
1564 | chan->dwell = cpu_to_le16(dwell); | 1752 | head->dwell = cpu_to_le16(dwell); |
1753 | head->freq = freq; | ||
1754 | |||
1755 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { | ||
1756 | __le16 *pa_power_points = (__le16 *) skb_put(skb, 2); | ||
1757 | *pa_power_points = cpu_to_le16(0x0c); | ||
1758 | } | ||
1565 | 1759 | ||
1760 | iq_autocal = (void *) skb_put(skb, sizeof(*iq_autocal)); | ||
1566 | for (i = 0; i < priv->iq_autocal_len; i++) { | 1761 | for (i = 0; i < priv->iq_autocal_len; i++) { |
1567 | if (priv->iq_autocal[i].freq != freq) | 1762 | if (priv->iq_autocal[i].freq != freq) |
1568 | continue; | 1763 | continue; |
1569 | 1764 | ||
1570 | memcpy(&chan->iq_autocal, &priv->iq_autocal[i], | 1765 | memcpy(iq_autocal, &priv->iq_autocal[i].params, |
1571 | sizeof(*priv->iq_autocal)); | 1766 | sizeof(struct p54_iq_autocal_entry)); |
1572 | break; | 1767 | break; |
1573 | } | 1768 | } |
1574 | if (i == priv->iq_autocal_len) | 1769 | if (i == priv->iq_autocal_len) |
1575 | goto err; | 1770 | goto err; |
1576 | 1771 | ||
1577 | for (i = 0; i < priv->output_limit_len; i++) { | 1772 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) |
1578 | if (priv->output_limit[i].freq != freq) | 1773 | body = (void *) skb_put(skb, sizeof(body->longbow)); |
1774 | else | ||
1775 | body = (void *) skb_put(skb, sizeof(body->normal)); | ||
1776 | |||
1777 | for (i = 0; i < priv->output_limit->entries; i++) { | ||
1778 | __le16 *entry_freq = (void *) (priv->output_limit->data + | ||
1779 | priv->output_limit->entry_size * i); | ||
1780 | |||
1781 | if (*entry_freq != freq) | ||
1579 | continue; | 1782 | continue; |
1580 | 1783 | ||
1581 | chan->val_barker = 0x38; | 1784 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { |
1582 | chan->val_bpsk = chan->dup_bpsk = | 1785 | memcpy(&body->longbow.power_limits, |
1583 | priv->output_limit[i].val_bpsk; | 1786 | (void *) entry_freq + sizeof(__le16), |
1584 | chan->val_qpsk = chan->dup_qpsk = | 1787 | priv->output_limit->entry_size); |
1585 | priv->output_limit[i].val_qpsk; | 1788 | } else { |
1586 | chan->val_16qam = chan->dup_16qam = | 1789 | struct pda_channel_output_limit *limits = |
1587 | priv->output_limit[i].val_16qam; | 1790 | (void *) entry_freq; |
1588 | chan->val_64qam = chan->dup_64qam = | 1791 | |
1589 | priv->output_limit[i].val_64qam; | 1792 | body->normal.val_barker = 0x38; |
1793 | body->normal.val_bpsk = body->normal.dup_bpsk = | ||
1794 | limits->val_bpsk; | ||
1795 | body->normal.val_qpsk = body->normal.dup_qpsk = | ||
1796 | limits->val_qpsk; | ||
1797 | body->normal.val_16qam = body->normal.dup_16qam = | ||
1798 | limits->val_16qam; | ||
1799 | body->normal.val_64qam = body->normal.dup_64qam = | ||
1800 | limits->val_64qam; | ||
1801 | } | ||
1590 | break; | 1802 | break; |
1591 | } | 1803 | } |
1592 | if (i == priv->output_limit_len) | 1804 | if (i == priv->output_limit->entries) |
1593 | goto err; | 1805 | goto err; |
1594 | 1806 | ||
1595 | entry = priv->curve_data->data; | 1807 | entry = (void *)(priv->curve_data->data + priv->curve_data->offset); |
1596 | for (i = 0; i < priv->curve_data->channels; i++) { | 1808 | for (i = 0; i < priv->curve_data->entries; i++) { |
1597 | if (*((__le16 *)entry) != freq) { | 1809 | if (*((__le16 *)entry) != freq) { |
1598 | entry += sizeof(__le16); | 1810 | entry += priv->curve_data->entry_size; |
1599 | entry += sizeof(struct p54_pa_curve_data_sample) * | ||
1600 | priv->curve_data->points_per_channel; | ||
1601 | continue; | 1811 | continue; |
1602 | } | 1812 | } |
1603 | 1813 | ||
1604 | entry += sizeof(__le16); | 1814 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { |
1605 | chan->pa_points_per_curve = 8; | 1815 | memcpy(&body->longbow.curve_data, |
1606 | memset(chan->curve_data, 0, sizeof(*chan->curve_data)); | 1816 | (void *) entry + sizeof(__le16), |
1607 | memcpy(chan->curve_data, entry, | 1817 | priv->curve_data->entry_size); |
1608 | sizeof(struct p54_pa_curve_data_sample) * | 1818 | } else { |
1609 | min((u8)8, priv->curve_data->points_per_channel)); | 1819 | struct p54_scan_body *chan = &body->normal; |
1820 | struct pda_pa_curve_data *curve_data = | ||
1821 | (void *) priv->curve_data->data; | ||
1822 | |||
1823 | entry += sizeof(__le16); | ||
1824 | chan->pa_points_per_curve = 8; | ||
1825 | memset(chan->curve_data, 0, sizeof(*chan->curve_data)); | ||
1826 | memcpy(chan->curve_data, entry, | ||
1827 | sizeof(struct p54_pa_curve_data_sample) * | ||
1828 | min((u8)8, curve_data->points_per_channel)); | ||
1829 | } | ||
1610 | break; | 1830 | break; |
1611 | } | 1831 | } |
1832 | if (i == priv->curve_data->entries) | ||
1833 | goto err; | ||
1612 | 1834 | ||
1613 | if (priv->fw_var < 0x500) { | 1835 | if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) { |
1614 | chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul); | 1836 | rate = (void *) skb_put(skb, sizeof(*rate)); |
1615 | chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add); | 1837 | rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); |
1616 | } else { | 1838 | for (i = 0; i < sizeof(rate->rts_rates); i++) |
1617 | chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul); | 1839 | rate->rts_rates[i] = i; |
1618 | chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add); | ||
1619 | chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); | ||
1620 | memset(chan->v2.rts_rates, 0, 8); | ||
1621 | } | 1840 | } |
1841 | |||
1842 | rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi)); | ||
1843 | rssi->mul = cpu_to_le16(priv->rssical_db[band].mul); | ||
1844 | rssi->add = cpu_to_le16(priv->rssical_db[band].add); | ||
1845 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { | ||
1846 | /* Longbow frontend needs ever more */ | ||
1847 | rssi = (void *) skb_put(skb, sizeof(*rssi)); | ||
1848 | rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn); | ||
1849 | rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2); | ||
1850 | } | ||
1851 | |||
1852 | if (priv->fw_var >= 0x509) { | ||
1853 | rate = (void *) skb_put(skb, sizeof(*rate)); | ||
1854 | rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); | ||
1855 | for (i = 0; i < sizeof(rate->rts_rates); i++) | ||
1856 | rate->rts_rates[i] = i; | ||
1857 | } | ||
1858 | |||
1859 | hdr = (struct p54_hdr *) skb->data; | ||
1860 | hdr->len = cpu_to_le16(skb->len - sizeof(*hdr)); | ||
1861 | |||
1622 | priv->tx(dev, skb); | 1862 | priv->tx(dev, skb); |
1623 | return 0; | 1863 | return 0; |
1624 | 1864 | ||
@@ -1634,9 +1874,8 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act) | |||
1634 | struct sk_buff *skb; | 1874 | struct sk_buff *skb; |
1635 | struct p54_led *led; | 1875 | struct p54_led *led; |
1636 | 1876 | ||
1637 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led) + | 1877 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led), |
1638 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_LED, | 1878 | P54_CONTROL_TYPE_LED, GFP_ATOMIC); |
1639 | GFP_ATOMIC); | ||
1640 | if (!skb) | 1879 | if (!skb) |
1641 | return -ENOMEM; | 1880 | return -ENOMEM; |
1642 | 1881 | ||
@@ -1663,9 +1902,8 @@ static int p54_set_edcf(struct ieee80211_hw *dev) | |||
1663 | struct sk_buff *skb; | 1902 | struct sk_buff *skb; |
1664 | struct p54_edcf *edcf; | 1903 | struct p54_edcf *edcf; |
1665 | 1904 | ||
1666 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf) + | 1905 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf), |
1667 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_DCFINIT, | 1906 | P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC); |
1668 | GFP_ATOMIC); | ||
1669 | if (!skb) | 1907 | if (!skb) |
1670 | return -ENOMEM; | 1908 | return -ENOMEM; |
1671 | 1909 | ||
@@ -1689,6 +1927,42 @@ static int p54_set_edcf(struct ieee80211_hw *dev) | |||
1689 | return 0; | 1927 | return 0; |
1690 | } | 1928 | } |
1691 | 1929 | ||
1930 | static int p54_set_ps(struct ieee80211_hw *dev) | ||
1931 | { | ||
1932 | struct p54_common *priv = dev->priv; | ||
1933 | struct sk_buff *skb; | ||
1934 | struct p54_psm *psm; | ||
1935 | u16 mode; | ||
1936 | int i; | ||
1937 | |||
1938 | if (dev->conf.flags & IEEE80211_CONF_PS) | ||
1939 | mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC; | ||
1940 | else | ||
1941 | mode = P54_PSM_CAM; | ||
1942 | |||
1943 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm), | ||
1944 | P54_CONTROL_TYPE_PSM, GFP_ATOMIC); | ||
1945 | if (!skb) | ||
1946 | return -ENOMEM; | ||
1947 | |||
1948 | psm = (struct p54_psm *)skb_put(skb, sizeof(*psm)); | ||
1949 | psm->mode = cpu_to_le16(mode); | ||
1950 | psm->aid = cpu_to_le16(priv->aid); | ||
1951 | for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) { | ||
1952 | psm->intervals[i].interval = | ||
1953 | cpu_to_le16(dev->conf.listen_interval); | ||
1954 | psm->intervals[i].periods = cpu_to_le16(1); | ||
1955 | } | ||
1956 | |||
1957 | psm->beacon_rssi_skip_max = 60; | ||
1958 | psm->rssi_delta_threshold = 0; | ||
1959 | psm->nr = 0; | ||
1960 | |||
1961 | priv->tx(dev, skb); | ||
1962 | |||
1963 | return 0; | ||
1964 | } | ||
1965 | |||
1692 | static int p54_beacon_tim(struct sk_buff *skb) | 1966 | static int p54_beacon_tim(struct sk_buff *skb) |
1693 | { | 1967 | { |
1694 | /* | 1968 | /* |
@@ -1881,6 +2155,11 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed) | |||
1881 | if (ret) | 2155 | if (ret) |
1882 | goto out; | 2156 | goto out; |
1883 | } | 2157 | } |
2158 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
2159 | ret = p54_set_ps(dev); | ||
2160 | if (ret) | ||
2161 | goto out; | ||
2162 | } | ||
1884 | 2163 | ||
1885 | out: | 2164 | out: |
1886 | mutex_unlock(&priv->conf_mutex); | 2165 | mutex_unlock(&priv->conf_mutex); |
@@ -1932,12 +2211,13 @@ static void p54_configure_filter(struct ieee80211_hw *dev, | |||
1932 | struct p54_common *priv = dev->priv; | 2211 | struct p54_common *priv = dev->priv; |
1933 | 2212 | ||
1934 | *total_flags &= FIF_PROMISC_IN_BSS | | 2213 | *total_flags &= FIF_PROMISC_IN_BSS | |
2214 | FIF_OTHER_BSS | | ||
1935 | (*total_flags & FIF_PROMISC_IN_BSS) ? | 2215 | (*total_flags & FIF_PROMISC_IN_BSS) ? |
1936 | FIF_FCSFAIL : 0; | 2216 | FIF_FCSFAIL : 0; |
1937 | 2217 | ||
1938 | priv->filter_flags = *total_flags; | 2218 | priv->filter_flags = *total_flags; |
1939 | 2219 | ||
1940 | if (changed_flags & FIF_PROMISC_IN_BSS) | 2220 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) |
1941 | p54_setup_mac(dev); | 2221 | p54_setup_mac(dev); |
1942 | } | 2222 | } |
1943 | 2223 | ||
@@ -1964,10 +2244,8 @@ static int p54_init_xbow_synth(struct ieee80211_hw *dev) | |||
1964 | struct sk_buff *skb; | 2244 | struct sk_buff *skb; |
1965 | struct p54_xbow_synth *xbow; | 2245 | struct p54_xbow_synth *xbow; |
1966 | 2246 | ||
1967 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow) + | 2247 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow), |
1968 | sizeof(struct p54_hdr), | 2248 | P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL); |
1969 | P54_CONTROL_TYPE_XBOW_SYNTH_CFG, | ||
1970 | GFP_KERNEL); | ||
1971 | if (!skb) | 2249 | if (!skb) |
1972 | return -ENOMEM; | 2250 | return -ENOMEM; |
1973 | 2251 | ||
@@ -1996,7 +2274,7 @@ static void p54_work(struct work_struct *work) | |||
1996 | * 2. cancel stuck frames / reset the device if necessary. | 2274 | * 2. cancel stuck frames / reset the device if necessary. |
1997 | */ | 2275 | */ |
1998 | 2276 | ||
1999 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(struct p54_hdr) + | 2277 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, |
2000 | sizeof(struct p54_statistics), | 2278 | sizeof(struct p54_statistics), |
2001 | P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL); | 2279 | P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL); |
2002 | if (!skb) | 2280 | if (!skb) |
@@ -2019,8 +2297,8 @@ static int p54_get_tx_stats(struct ieee80211_hw *dev, | |||
2019 | { | 2297 | { |
2020 | struct p54_common *priv = dev->priv; | 2298 | struct p54_common *priv = dev->priv; |
2021 | 2299 | ||
2022 | memcpy(stats, &priv->tx_stats[4], sizeof(stats[0]) * dev->queues); | 2300 | memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA], |
2023 | 2301 | sizeof(stats[0]) * dev->queues); | |
2024 | return 0; | 2302 | return 0; |
2025 | } | 2303 | } |
2026 | 2304 | ||
@@ -2056,7 +2334,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev, | |||
2056 | } | 2334 | } |
2057 | 2335 | ||
2058 | static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | 2336 | static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, |
2059 | const u8 *local_address, const u8 *address, | 2337 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
2060 | struct ieee80211_key_conf *key) | 2338 | struct ieee80211_key_conf *key) |
2061 | { | 2339 | { |
2062 | struct p54_common *priv = dev->priv; | 2340 | struct p54_common *priv = dev->priv; |
@@ -2107,9 +2385,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | |||
2107 | } | 2385 | } |
2108 | 2386 | ||
2109 | mutex_lock(&priv->conf_mutex); | 2387 | mutex_lock(&priv->conf_mutex); |
2110 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey) + | 2388 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey), |
2111 | sizeof(struct p54_hdr), P54_CONTROL_TYPE_RX_KEYCACHE, | 2389 | P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC); |
2112 | GFP_ATOMIC); | ||
2113 | if (!skb) { | 2390 | if (!skb) { |
2114 | mutex_unlock(&priv->conf_mutex); | 2391 | mutex_unlock(&priv->conf_mutex); |
2115 | return -ENOMEM; | 2392 | return -ENOMEM; |
@@ -2120,8 +2397,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | |||
2120 | rxkey->entry = key->keyidx; | 2397 | rxkey->entry = key->keyidx; |
2121 | rxkey->key_id = key->keyidx; | 2398 | rxkey->key_id = key->keyidx; |
2122 | rxkey->key_type = algo; | 2399 | rxkey->key_type = algo; |
2123 | if (address) | 2400 | if (sta) |
2124 | memcpy(rxkey->mac, address, ETH_ALEN); | 2401 | memcpy(rxkey->mac, sta->addr, ETH_ALEN); |
2125 | else | 2402 | else |
2126 | memset(rxkey->mac, ~0, ETH_ALEN); | 2403 | memset(rxkey->mac, ~0, ETH_ALEN); |
2127 | if (key->alg != ALG_TKIP) { | 2404 | if (key->alg != ALG_TKIP) { |
@@ -2181,11 +2458,11 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
2181 | BIT(NL80211_IFTYPE_MESH_POINT); | 2458 | BIT(NL80211_IFTYPE_MESH_POINT); |
2182 | 2459 | ||
2183 | dev->channel_change_time = 1000; /* TODO: find actual value */ | 2460 | dev->channel_change_time = 1000; /* TODO: find actual value */ |
2184 | priv->tx_stats[0].limit = 1; /* Beacon queue */ | 2461 | priv->tx_stats[P54_QUEUE_BEACON].limit = 1; |
2185 | priv->tx_stats[1].limit = 1; /* Probe queue for HW scan */ | 2462 | priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1; |
2186 | priv->tx_stats[2].limit = 3; /* queue for MLMEs */ | 2463 | priv->tx_stats[P54_QUEUE_MGMT].limit = 3; |
2187 | priv->tx_stats[3].limit = 3; /* Broadcast / MC queue */ | 2464 | priv->tx_stats[P54_QUEUE_CAB].limit = 3; |
2188 | priv->tx_stats[4].limit = 5; /* Data */ | 2465 | priv->tx_stats[P54_QUEUE_DATA].limit = 5; |
2189 | dev->queues = 1; | 2466 | dev->queues = 1; |
2190 | priv->noise = -94; | 2467 | priv->noise = -94; |
2191 | /* | 2468 | /* |
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h index f5729de83fe1..def23b1f49ec 100644 --- a/drivers/net/wireless/p54/p54common.h +++ b/drivers/net/wireless/p54/p54common.h | |||
@@ -26,12 +26,17 @@ struct bootrec { | |||
26 | } __attribute__((packed)); | 26 | } __attribute__((packed)); |
27 | 27 | ||
28 | #define PDR_SYNTH_FRONTEND_MASK 0x0007 | 28 | #define PDR_SYNTH_FRONTEND_MASK 0x0007 |
29 | #define PDR_SYNTH_FRONTEND_DUETTE3 0x0001 | ||
30 | #define PDR_SYNTH_FRONTEND_DUETTE2 0x0002 | ||
31 | #define PDR_SYNTH_FRONTEND_FRISBEE 0x0003 | ||
32 | #define PDR_SYNTH_FRONTEND_XBOW 0x0004 | ||
33 | #define PDR_SYNTH_FRONTEND_LONGBOW 0x0005 | ||
29 | #define PDR_SYNTH_IQ_CAL_MASK 0x0018 | 34 | #define PDR_SYNTH_IQ_CAL_MASK 0x0018 |
30 | #define PDR_SYNTH_IQ_CAL_PA_DETECTOR 0x0000 | 35 | #define PDR_SYNTH_IQ_CAL_PA_DETECTOR 0x0000 |
31 | #define PDR_SYNTH_IQ_CAL_DISABLED 0x0008 | 36 | #define PDR_SYNTH_IQ_CAL_DISABLED 0x0008 |
32 | #define PDR_SYNTH_IQ_CAL_ZIF 0x0010 | 37 | #define PDR_SYNTH_IQ_CAL_ZIF 0x0010 |
33 | #define PDR_SYNTH_FAA_SWITCH_MASK 0x0020 | 38 | #define PDR_SYNTH_FAA_SWITCH_MASK 0x0020 |
34 | #define PDR_SYNTH_FAA_SWITCH_ENABLED 0x0001 | 39 | #define PDR_SYNTH_FAA_SWITCH_ENABLED 0x0020 |
35 | #define PDR_SYNTH_24_GHZ_MASK 0x0040 | 40 | #define PDR_SYNTH_24_GHZ_MASK 0x0040 |
36 | #define PDR_SYNTH_24_GHZ_DISABLED 0x0040 | 41 | #define PDR_SYNTH_24_GHZ_DISABLED 0x0040 |
37 | #define PDR_SYNTH_5_GHZ_MASK 0x0080 | 42 | #define PDR_SYNTH_5_GHZ_MASK 0x0080 |
@@ -125,9 +130,13 @@ struct eeprom_pda_wrap { | |||
125 | u8 data[0]; | 130 | u8 data[0]; |
126 | } __attribute__ ((packed)); | 131 | } __attribute__ ((packed)); |
127 | 132 | ||
133 | struct p54_iq_autocal_entry { | ||
134 | __le16 iq_param[4]; | ||
135 | } __attribute__ ((packed)); | ||
136 | |||
128 | struct pda_iq_autocal_entry { | 137 | struct pda_iq_autocal_entry { |
129 | __le16 freq; | 138 | __le16 freq; |
130 | __le16 iq_param[4]; | 139 | struct p54_iq_autocal_entry params; |
131 | } __attribute__ ((packed)); | 140 | } __attribute__ ((packed)); |
132 | 141 | ||
133 | struct pda_channel_output_limit { | 142 | struct pda_channel_output_limit { |
@@ -180,6 +189,35 @@ struct pda_rssi_cal_entry { | |||
180 | __le16 add; | 189 | __le16 add; |
181 | } __attribute__ ((packed)); | 190 | } __attribute__ ((packed)); |
182 | 191 | ||
192 | struct pda_country { | ||
193 | u8 regdomain; | ||
194 | u8 alpha2[2]; | ||
195 | u8 flags; | ||
196 | } __attribute__ ((packed)); | ||
197 | |||
198 | /* | ||
199 | * Warning: Longbow's structures are bogus. | ||
200 | */ | ||
201 | struct p54_channel_output_limit_longbow { | ||
202 | __le16 rf_power_points[12]; | ||
203 | } __attribute__ ((packed)); | ||
204 | |||
205 | struct p54_pa_curve_data_sample_longbow { | ||
206 | __le16 rf_power; | ||
207 | __le16 pa_detector; | ||
208 | struct { | ||
209 | __le16 data[4]; | ||
210 | } points[3] __attribute__ ((packed)); | ||
211 | } __attribute__ ((packed)); | ||
212 | |||
213 | struct pda_custom_wrapper { | ||
214 | __le16 entries; | ||
215 | __le16 entry_size; | ||
216 | __le16 offset; | ||
217 | __le16 len; | ||
218 | u8 data[0]; | ||
219 | } __attribute__ ((packed)); | ||
220 | |||
183 | /* | 221 | /* |
184 | * this defines the PDR codes used to build PDAs as defined in document | 222 | * this defines the PDR codes used to build PDAs as defined in document |
185 | * number 553155. The current implementation mirrors version 1.1 of the | 223 | * number 553155. The current implementation mirrors version 1.1 of the |
@@ -225,8 +263,13 @@ struct pda_rssi_cal_entry { | |||
225 | /* reserved range (0x2000 - 0x7fff) */ | 263 | /* reserved range (0x2000 - 0x7fff) */ |
226 | 264 | ||
227 | /* customer range (0x8000 - 0xffff) */ | 265 | /* customer range (0x8000 - 0xffff) */ |
228 | #define PDR_BASEBAND_REGISTERS 0x8000 | 266 | #define PDR_BASEBAND_REGISTERS 0x8000 |
229 | #define PDR_PER_CHANNEL_BASEBAND_REGISTERS 0x8001 | 267 | #define PDR_PER_CHANNEL_BASEBAND_REGISTERS 0x8001 |
268 | |||
269 | /* used by our modificated eeprom image */ | ||
270 | #define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD | ||
271 | #define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF | ||
272 | #define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D | ||
230 | 273 | ||
231 | /* PDR definitions for default country & country list */ | 274 | /* PDR definitions for default country & country list */ |
232 | #define PDR_COUNTRY_CERT_CODE 0x80 | 275 | #define PDR_COUNTRY_CERT_CODE 0x80 |
@@ -241,12 +284,6 @@ struct pda_rssi_cal_entry { | |||
241 | #define PDR_COUNTRY_CERT_IODOOR_OUTDOOR 0x30 | 284 | #define PDR_COUNTRY_CERT_IODOOR_OUTDOOR 0x30 |
242 | #define PDR_COUNTRY_CERT_INDEX 0x0F | 285 | #define PDR_COUNTRY_CERT_INDEX 0x0F |
243 | 286 | ||
244 | /* stored in skb->cb */ | ||
245 | struct memrecord { | ||
246 | u32 start_addr; | ||
247 | u32 end_addr; | ||
248 | }; | ||
249 | |||
250 | struct p54_eeprom_lm86 { | 287 | struct p54_eeprom_lm86 { |
251 | union { | 288 | union { |
252 | struct { | 289 | struct { |
@@ -329,7 +366,7 @@ struct p54_frame_sent { | |||
329 | u8 padding; | 366 | u8 padding; |
330 | } __attribute__ ((packed)); | 367 | } __attribute__ ((packed)); |
331 | 368 | ||
332 | enum p54_tx_data_crypt { | 369 | enum p54_tx_data_crypt { |
333 | P54_CRYPTO_NONE = 0, | 370 | P54_CRYPTO_NONE = 0, |
334 | P54_CRYPTO_WEP, | 371 | P54_CRYPTO_WEP, |
335 | P54_CRYPTO_TKIP, | 372 | P54_CRYPTO_TKIP, |
@@ -340,6 +377,23 @@ enum p54_tx_data_crypt { | |||
340 | P54_CRYPTO_AESCCMP | 377 | P54_CRYPTO_AESCCMP |
341 | }; | 378 | }; |
342 | 379 | ||
380 | enum p54_tx_data_queue { | ||
381 | P54_QUEUE_BEACON = 0, | ||
382 | P54_QUEUE_FWSCAN = 1, | ||
383 | P54_QUEUE_MGMT = 2, | ||
384 | P54_QUEUE_CAB = 3, | ||
385 | P54_QUEUE_DATA = 4, | ||
386 | |||
387 | P54_QUEUE_AC_NUM = 4, | ||
388 | P54_QUEUE_AC_VO = 4, | ||
389 | P54_QUEUE_AC_VI = 5, | ||
390 | P54_QUEUE_AC_BE = 6, | ||
391 | P54_QUEUE_AC_BK = 7, | ||
392 | |||
393 | /* keep last */ | ||
394 | P54_QUEUE_NUM = 8, | ||
395 | }; | ||
396 | |||
343 | struct p54_tx_data { | 397 | struct p54_tx_data { |
344 | u8 rateset[8]; | 398 | u8 rateset[8]; |
345 | u8 rts_rate_idx; | 399 | u8 rts_rate_idx; |
@@ -351,9 +405,18 @@ struct p54_tx_data { | |||
351 | u8 backlog; | 405 | u8 backlog; |
352 | __le16 durations[4]; | 406 | __le16 durations[4]; |
353 | u8 tx_antenna; | 407 | u8 tx_antenna; |
354 | u8 output_power; | 408 | union { |
355 | u8 cts_rate; | 409 | struct { |
356 | u8 unalloc2[3]; | 410 | u8 cts_rate; |
411 | __le16 output_power; | ||
412 | } __attribute__((packed)) longbow; | ||
413 | struct { | ||
414 | u8 output_power; | ||
415 | u8 cts_rate; | ||
416 | u8 unalloc; | ||
417 | } __attribute__ ((packed)) normal; | ||
418 | } __attribute__ ((packed)); | ||
419 | u8 unalloc2[2]; | ||
357 | u8 align[0]; | 420 | u8 align[0]; |
358 | } __attribute__ ((packed)); | 421 | } __attribute__ ((packed)); |
359 | 422 | ||
@@ -414,11 +477,14 @@ struct p54_setup_mac { | |||
414 | #define P54_SCAN_ACTIVE BIT(2) | 477 | #define P54_SCAN_ACTIVE BIT(2) |
415 | #define P54_SCAN_FILTER BIT(3) | 478 | #define P54_SCAN_FILTER BIT(3) |
416 | 479 | ||
417 | struct p54_scan { | 480 | struct p54_scan_head { |
418 | __le16 mode; | 481 | __le16 mode; |
419 | __le16 dwell; | 482 | __le16 dwell; |
420 | u8 padding1[20]; | 483 | u8 scan_params[20]; |
421 | struct pda_iq_autocal_entry iq_autocal; | 484 | __le16 freq; |
485 | } __attribute__ ((packed)); | ||
486 | |||
487 | struct p54_scan_body { | ||
422 | u8 pa_points_per_curve; | 488 | u8 pa_points_per_curve; |
423 | u8 val_barker; | 489 | u8 val_barker; |
424 | u8 val_bpsk; | 490 | u8 val_bpsk; |
@@ -430,19 +496,23 @@ struct p54_scan { | |||
430 | u8 dup_qpsk; | 496 | u8 dup_qpsk; |
431 | u8 dup_16qam; | 497 | u8 dup_16qam; |
432 | u8 dup_64qam; | 498 | u8 dup_64qam; |
433 | union { | 499 | } __attribute__ ((packed)); |
434 | struct pda_rssi_cal_entry v1_rssi; | ||
435 | 500 | ||
436 | struct { | 501 | struct p54_scan_body_longbow { |
437 | __le32 basic_rate_mask; | 502 | struct p54_channel_output_limit_longbow power_limits; |
438 | u8 rts_rates[8]; | 503 | struct p54_pa_curve_data_sample_longbow curve_data[8]; |
439 | struct pda_rssi_cal_entry rssi; | 504 | __le16 unkn[6]; /* maybe more power_limits or rate_mask */ |
440 | } v2 __attribute__ ((packed)); | 505 | } __attribute__ ((packed)); |
441 | } __attribute__ ((packed)); | 506 | |
507 | union p54_scan_body_union { | ||
508 | struct p54_scan_body normal; | ||
509 | struct p54_scan_body_longbow longbow; | ||
442 | } __attribute__ ((packed)); | 510 | } __attribute__ ((packed)); |
443 | 511 | ||
444 | #define P54_SCAN_V1_LEN 0x70 | 512 | struct p54_scan_tail_rate { |
445 | #define P54_SCAN_V2_LEN 0x7c | 513 | __le32 basic_rate_mask; |
514 | u8 rts_rates[8]; | ||
515 | } __attribute__ ((packed)); | ||
446 | 516 | ||
447 | struct p54_led { | 517 | struct p54_led { |
448 | __le16 mode; | 518 | __le16 mode; |
@@ -511,6 +581,7 @@ struct p54_psm_interval { | |||
511 | __le16 periods; | 581 | __le16 periods; |
512 | } __attribute__ ((packed)); | 582 | } __attribute__ ((packed)); |
513 | 583 | ||
584 | #define P54_PSM_CAM 0 | ||
514 | #define P54_PSM BIT(0) | 585 | #define P54_PSM BIT(0) |
515 | #define P54_PSM_DTIM BIT(1) | 586 | #define P54_PSM_DTIM BIT(1) |
516 | #define P54_PSM_MCBC BIT(2) | 587 | #define P54_PSM_MCBC BIT(2) |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index aa367a0ddc49..3f9a6b04ea95 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -79,6 +79,12 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) | |||
79 | if (err) | 79 | if (err) |
80 | return err; | 80 | return err; |
81 | 81 | ||
82 | if (priv->common.fw_interface != FW_LM86) { | ||
83 | dev_err(&priv->pdev->dev, "wrong firmware, " | ||
84 | "please get a LM86(PCI) firmware a try again.\n"); | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | |||
82 | data = (__le32 *) priv->firmware->data; | 88 | data = (__le32 *) priv->firmware->data; |
83 | remains = priv->firmware->size; | 89 | remains = priv->firmware->size; |
84 | device_addr = ISL38XX_DEV_FIRMWARE_ADDR; | 90 | device_addr = ISL38XX_DEV_FIRMWARE_ADDR; |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c new file mode 100644 index 000000000000..7fde243b3d5d --- /dev/null +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -0,0 +1,770 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de> | ||
3 | * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> | ||
4 | * | ||
5 | * This driver is a port from stlc45xx: | ||
6 | * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/firmware.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/spi/spi.h> | ||
30 | #include <linux/etherdevice.h> | ||
31 | #include <linux/gpio.h> | ||
32 | |||
33 | #include "p54spi.h" | ||
34 | #include "p54spi_eeprom.h" | ||
35 | #include "p54.h" | ||
36 | |||
37 | #include "p54common.h" | ||
38 | |||
39 | MODULE_FIRMWARE("3826.arm"); | ||
40 | MODULE_ALIAS("stlc45xx"); | ||
41 | |||
42 | /* | ||
43 | * gpios should be handled in board files and provided via platform data, | ||
44 | * but because it's currently impossible for p54spi to have a header file | ||
45 | * in include/linux, let's use module paramaters for now | ||
46 | */ | ||
47 | |||
48 | static int p54spi_gpio_power = 97; | ||
49 | module_param(p54spi_gpio_power, int, 0444); | ||
50 | MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line"); | ||
51 | |||
52 | static int p54spi_gpio_irq = 87; | ||
53 | module_param(p54spi_gpio_irq, int, 0444); | ||
54 | MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line"); | ||
55 | |||
56 | static void p54spi_spi_read(struct p54s_priv *priv, u8 address, | ||
57 | void *buf, size_t len) | ||
58 | { | ||
59 | struct spi_transfer t[2]; | ||
60 | struct spi_message m; | ||
61 | __le16 addr; | ||
62 | |||
63 | /* We first push the address */ | ||
64 | addr = cpu_to_le16(address << 8 | SPI_ADRS_READ_BIT_15); | ||
65 | |||
66 | spi_message_init(&m); | ||
67 | memset(t, 0, sizeof(t)); | ||
68 | |||
69 | t[0].tx_buf = &addr; | ||
70 | t[0].len = sizeof(addr); | ||
71 | spi_message_add_tail(&t[0], &m); | ||
72 | |||
73 | t[1].rx_buf = buf; | ||
74 | t[1].len = len; | ||
75 | spi_message_add_tail(&t[1], &m); | ||
76 | |||
77 | spi_sync(priv->spi, &m); | ||
78 | } | ||
79 | |||
80 | |||
81 | static void p54spi_spi_write(struct p54s_priv *priv, u8 address, | ||
82 | const void *buf, size_t len) | ||
83 | { | ||
84 | struct spi_transfer t[3]; | ||
85 | struct spi_message m; | ||
86 | __le16 addr; | ||
87 | |||
88 | /* We first push the address */ | ||
89 | addr = cpu_to_le16(address << 8); | ||
90 | |||
91 | spi_message_init(&m); | ||
92 | memset(t, 0, sizeof(t)); | ||
93 | |||
94 | t[0].tx_buf = &addr; | ||
95 | t[0].len = sizeof(addr); | ||
96 | spi_message_add_tail(&t[0], &m); | ||
97 | |||
98 | t[1].tx_buf = buf; | ||
99 | t[1].len = len; | ||
100 | spi_message_add_tail(&t[1], &m); | ||
101 | |||
102 | if (len % 2) { | ||
103 | __le16 last_word; | ||
104 | last_word = cpu_to_le16(((u8 *)buf)[len - 1]); | ||
105 | |||
106 | t[2].tx_buf = &last_word; | ||
107 | t[2].len = sizeof(last_word); | ||
108 | spi_message_add_tail(&t[2], &m); | ||
109 | } | ||
110 | |||
111 | spi_sync(priv->spi, &m); | ||
112 | } | ||
113 | |||
114 | static u16 p54spi_read16(struct p54s_priv *priv, u8 addr) | ||
115 | { | ||
116 | __le16 val; | ||
117 | |||
118 | p54spi_spi_read(priv, addr, &val, sizeof(val)); | ||
119 | |||
120 | return le16_to_cpu(val); | ||
121 | } | ||
122 | |||
123 | static u32 p54spi_read32(struct p54s_priv *priv, u8 addr) | ||
124 | { | ||
125 | __le32 val; | ||
126 | |||
127 | p54spi_spi_read(priv, addr, &val, sizeof(val)); | ||
128 | |||
129 | return le32_to_cpu(val); | ||
130 | } | ||
131 | |||
132 | static inline void p54spi_write16(struct p54s_priv *priv, u8 addr, __le16 val) | ||
133 | { | ||
134 | p54spi_spi_write(priv, addr, &val, sizeof(val)); | ||
135 | } | ||
136 | |||
137 | static inline void p54spi_write32(struct p54s_priv *priv, u8 addr, __le32 val) | ||
138 | { | ||
139 | p54spi_spi_write(priv, addr, &val, sizeof(val)); | ||
140 | } | ||
141 | |||
142 | struct p54spi_spi_reg { | ||
143 | u16 address; /* __le16 ? */ | ||
144 | u16 length; | ||
145 | char *name; | ||
146 | }; | ||
147 | |||
148 | static const struct p54spi_spi_reg p54spi_registers_array[] = | ||
149 | { | ||
150 | { SPI_ADRS_ARM_INTERRUPTS, 32, "ARM_INT " }, | ||
151 | { SPI_ADRS_ARM_INT_EN, 32, "ARM_INT_ENA " }, | ||
152 | { SPI_ADRS_HOST_INTERRUPTS, 32, "HOST_INT " }, | ||
153 | { SPI_ADRS_HOST_INT_EN, 32, "HOST_INT_ENA" }, | ||
154 | { SPI_ADRS_HOST_INT_ACK, 32, "HOST_INT_ACK" }, | ||
155 | { SPI_ADRS_GEN_PURP_1, 32, "GP1_COMM " }, | ||
156 | { SPI_ADRS_GEN_PURP_2, 32, "GP2_COMM " }, | ||
157 | { SPI_ADRS_DEV_CTRL_STAT, 32, "DEV_CTRL_STA" }, | ||
158 | { SPI_ADRS_DMA_DATA, 16, "DMA_DATA " }, | ||
159 | { SPI_ADRS_DMA_WRITE_CTRL, 16, "DMA_WR_CTRL " }, | ||
160 | { SPI_ADRS_DMA_WRITE_LEN, 16, "DMA_WR_LEN " }, | ||
161 | { SPI_ADRS_DMA_WRITE_BASE, 32, "DMA_WR_BASE " }, | ||
162 | { SPI_ADRS_DMA_READ_CTRL, 16, "DMA_RD_CTRL " }, | ||
163 | { SPI_ADRS_DMA_READ_LEN, 16, "DMA_RD_LEN " }, | ||
164 | { SPI_ADRS_DMA_WRITE_BASE, 32, "DMA_RD_BASE " } | ||
165 | }; | ||
166 | |||
167 | static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits) | ||
168 | { | ||
169 | int i; | ||
170 | __le32 buffer; | ||
171 | |||
172 | for (i = 0; i < 2000; i++) { | ||
173 | p54spi_spi_read(priv, reg, &buffer, sizeof(buffer)); | ||
174 | if (buffer == bits) | ||
175 | return 1; | ||
176 | |||
177 | msleep(1); | ||
178 | } | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int p54spi_request_firmware(struct ieee80211_hw *dev) | ||
183 | { | ||
184 | struct p54s_priv *priv = dev->priv; | ||
185 | int ret; | ||
186 | |||
187 | /* FIXME: should driver use it's own struct device? */ | ||
188 | ret = request_firmware(&priv->firmware, "3826.arm", &priv->spi->dev); | ||
189 | |||
190 | if (ret < 0) { | ||
191 | dev_err(&priv->spi->dev, "request_firmware() failed: %d", ret); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | ret = p54_parse_firmware(dev, priv->firmware); | ||
196 | if (ret) { | ||
197 | release_firmware(priv->firmware); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int p54spi_request_eeprom(struct ieee80211_hw *dev) | ||
205 | { | ||
206 | struct p54s_priv *priv = dev->priv; | ||
207 | const struct firmware *eeprom; | ||
208 | int ret; | ||
209 | |||
210 | /* | ||
211 | * allow users to customize their eeprom. | ||
212 | */ | ||
213 | |||
214 | ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev); | ||
215 | if (ret < 0) { | ||
216 | dev_info(&priv->spi->dev, "loading default eeprom...\n"); | ||
217 | ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom, | ||
218 | sizeof(p54spi_eeprom)); | ||
219 | } else { | ||
220 | dev_info(&priv->spi->dev, "loading user eeprom...\n"); | ||
221 | ret = p54_parse_eeprom(dev, (void *) eeprom->data, | ||
222 | (int)eeprom->size); | ||
223 | release_firmware(eeprom); | ||
224 | } | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | static int p54spi_upload_firmware(struct ieee80211_hw *dev) | ||
229 | { | ||
230 | struct p54s_priv *priv = dev->priv; | ||
231 | unsigned long fw_len, fw_addr; | ||
232 | long _fw_len; | ||
233 | |||
234 | /* stop the device */ | ||
235 | p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16( | ||
236 | SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET | | ||
237 | SPI_CTRL_STAT_START_HALTED)); | ||
238 | |||
239 | msleep(TARGET_BOOT_SLEEP); | ||
240 | |||
241 | p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16( | ||
242 | SPI_CTRL_STAT_HOST_OVERRIDE | | ||
243 | SPI_CTRL_STAT_START_HALTED)); | ||
244 | |||
245 | msleep(TARGET_BOOT_SLEEP); | ||
246 | |||
247 | fw_addr = ISL38XX_DEV_FIRMWARE_ADDR; | ||
248 | fw_len = priv->firmware->size; | ||
249 | |||
250 | while (fw_len > 0) { | ||
251 | _fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE); | ||
252 | |||
253 | p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL, | ||
254 | cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE)); | ||
255 | |||
256 | if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL, | ||
257 | cpu_to_le32(HOST_ALLOWED)) == 0) { | ||
258 | dev_err(&priv->spi->dev, "fw_upload not allowed " | ||
259 | "to DMA write."); | ||
260 | return -EAGAIN; | ||
261 | } | ||
262 | |||
263 | p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN, | ||
264 | cpu_to_le16(_fw_len)); | ||
265 | p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, | ||
266 | cpu_to_le32(fw_addr)); | ||
267 | |||
268 | p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, | ||
269 | &priv->firmware->data, _fw_len); | ||
270 | |||
271 | fw_len -= _fw_len; | ||
272 | fw_addr += _fw_len; | ||
273 | |||
274 | /* FIXME: I think this doesn't work if firmware is large, | ||
275 | * this loop goes to second round. fw->data is not | ||
276 | * increased at all! */ | ||
277 | } | ||
278 | |||
279 | BUG_ON(fw_len != 0); | ||
280 | |||
281 | /* enable host interrupts */ | ||
282 | p54spi_write32(priv, SPI_ADRS_HOST_INT_EN, | ||
283 | cpu_to_le32(SPI_HOST_INTS_DEFAULT)); | ||
284 | |||
285 | /* boot the device */ | ||
286 | p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16( | ||
287 | SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET | | ||
288 | SPI_CTRL_STAT_RAM_BOOT)); | ||
289 | |||
290 | msleep(TARGET_BOOT_SLEEP); | ||
291 | |||
292 | p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16( | ||
293 | SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT)); | ||
294 | msleep(TARGET_BOOT_SLEEP); | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static void p54spi_power_off(struct p54s_priv *priv) | ||
299 | { | ||
300 | disable_irq(gpio_to_irq(p54spi_gpio_irq)); | ||
301 | gpio_set_value(p54spi_gpio_power, 0); | ||
302 | } | ||
303 | |||
304 | static void p54spi_power_on(struct p54s_priv *priv) | ||
305 | { | ||
306 | gpio_set_value(p54spi_gpio_power, 1); | ||
307 | enable_irq(gpio_to_irq(p54spi_gpio_irq)); | ||
308 | |||
309 | /* | ||
310 | * need to wait a while before device can be accessed, the lenght | ||
311 | * is just a guess | ||
312 | */ | ||
313 | msleep(10); | ||
314 | } | ||
315 | |||
316 | static inline void p54spi_int_ack(struct p54s_priv *priv, u32 val) | ||
317 | { | ||
318 | p54spi_write32(priv, SPI_ADRS_HOST_INT_ACK, cpu_to_le32(val)); | ||
319 | } | ||
320 | |||
321 | static void p54spi_wakeup(struct p54s_priv *priv) | ||
322 | { | ||
323 | unsigned long timeout; | ||
324 | u32 ints; | ||
325 | |||
326 | /* wake the chip */ | ||
327 | p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS, | ||
328 | cpu_to_le32(SPI_TARGET_INT_WAKEUP)); | ||
329 | |||
330 | /* And wait for the READY interrupt */ | ||
331 | timeout = jiffies + HZ; | ||
332 | |||
333 | ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); | ||
334 | while (!(ints & SPI_HOST_INT_READY)) { | ||
335 | if (time_after(jiffies, timeout)) | ||
336 | goto out; | ||
337 | ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); | ||
338 | } | ||
339 | |||
340 | p54spi_int_ack(priv, SPI_HOST_INT_READY); | ||
341 | |||
342 | out: | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | static inline void p54spi_sleep(struct p54s_priv *priv) | ||
347 | { | ||
348 | p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS, | ||
349 | cpu_to_le32(SPI_TARGET_INT_SLEEP)); | ||
350 | } | ||
351 | |||
352 | static void p54spi_int_ready(struct p54s_priv *priv) | ||
353 | { | ||
354 | p54spi_write32(priv, SPI_ADRS_HOST_INT_EN, cpu_to_le32( | ||
355 | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)); | ||
356 | |||
357 | switch (priv->fw_state) { | ||
358 | case FW_STATE_BOOTING: | ||
359 | priv->fw_state = FW_STATE_READY; | ||
360 | complete(&priv->fw_comp); | ||
361 | break; | ||
362 | case FW_STATE_RESETTING: | ||
363 | priv->fw_state = FW_STATE_READY; | ||
364 | /* TODO: reinitialize state */ | ||
365 | break; | ||
366 | default: | ||
367 | break; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | static int p54spi_rx(struct p54s_priv *priv) | ||
372 | { | ||
373 | struct sk_buff *skb; | ||
374 | u16 len; | ||
375 | |||
376 | p54spi_wakeup(priv); | ||
377 | |||
378 | /* dummy read to flush SPI DMA controller bug */ | ||
379 | p54spi_read16(priv, SPI_ADRS_GEN_PURP_1); | ||
380 | |||
381 | len = p54spi_read16(priv, SPI_ADRS_DMA_DATA); | ||
382 | |||
383 | if (len == 0) { | ||
384 | dev_err(&priv->spi->dev, "rx request of zero bytes"); | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | skb = dev_alloc_skb(len); | ||
389 | if (!skb) { | ||
390 | dev_err(&priv->spi->dev, "could not alloc skb"); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len); | ||
395 | p54spi_sleep(priv); | ||
396 | |||
397 | if (p54_rx(priv->hw, skb) == 0) | ||
398 | dev_kfree_skb(skb); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | |||
404 | static irqreturn_t p54spi_interrupt(int irq, void *config) | ||
405 | { | ||
406 | struct spi_device *spi = config; | ||
407 | struct p54s_priv *priv = dev_get_drvdata(&spi->dev); | ||
408 | |||
409 | queue_work(priv->hw->workqueue, &priv->work); | ||
410 | |||
411 | return IRQ_HANDLED; | ||
412 | } | ||
413 | |||
414 | static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb) | ||
415 | { | ||
416 | struct p54_hdr *hdr = (struct p54_hdr *) skb->data; | ||
417 | struct p54s_dma_regs dma_regs; | ||
418 | unsigned long timeout; | ||
419 | int ret = 0; | ||
420 | u32 ints; | ||
421 | |||
422 | p54spi_wakeup(priv); | ||
423 | |||
424 | dma_regs.cmd = cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE); | ||
425 | dma_regs.len = cpu_to_le16(skb->len); | ||
426 | dma_regs.addr = hdr->req_id; | ||
427 | |||
428 | p54spi_spi_write(priv, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs, | ||
429 | sizeof(dma_regs)); | ||
430 | |||
431 | p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, skb->data, skb->len); | ||
432 | |||
433 | timeout = jiffies + 2 * HZ; | ||
434 | ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); | ||
435 | while (!(ints & SPI_HOST_INT_WR_READY)) { | ||
436 | if (time_after(jiffies, timeout)) { | ||
437 | dev_err(&priv->spi->dev, "WR_READY timeout"); | ||
438 | ret = -1; | ||
439 | goto out; | ||
440 | } | ||
441 | ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); | ||
442 | } | ||
443 | |||
444 | p54spi_int_ack(priv, SPI_HOST_INT_WR_READY); | ||
445 | p54spi_sleep(priv); | ||
446 | |||
447 | out: | ||
448 | if (FREE_AFTER_TX(skb)) | ||
449 | p54_free_skb(priv->hw, skb); | ||
450 | return ret; | ||
451 | } | ||
452 | |||
453 | static int p54spi_wq_tx(struct p54s_priv *priv) | ||
454 | { | ||
455 | struct p54s_tx_info *entry; | ||
456 | struct sk_buff *skb; | ||
457 | struct ieee80211_tx_info *info; | ||
458 | struct p54_tx_info *minfo; | ||
459 | struct p54s_tx_info *dinfo; | ||
460 | int ret = 0; | ||
461 | |||
462 | spin_lock_bh(&priv->tx_lock); | ||
463 | |||
464 | while (!list_empty(&priv->tx_pending)) { | ||
465 | entry = list_entry(priv->tx_pending.next, | ||
466 | struct p54s_tx_info, tx_list); | ||
467 | |||
468 | list_del_init(&entry->tx_list); | ||
469 | |||
470 | spin_unlock_bh(&priv->tx_lock); | ||
471 | |||
472 | dinfo = container_of((void *) entry, struct p54s_tx_info, | ||
473 | tx_list); | ||
474 | minfo = container_of((void *) dinfo, struct p54_tx_info, | ||
475 | data); | ||
476 | info = container_of((void *) minfo, struct ieee80211_tx_info, | ||
477 | rate_driver_data); | ||
478 | skb = container_of((void *) info, struct sk_buff, cb); | ||
479 | |||
480 | ret = p54spi_tx_frame(priv, skb); | ||
481 | |||
482 | spin_lock_bh(&priv->tx_lock); | ||
483 | |||
484 | if (ret < 0) { | ||
485 | p54_free_skb(priv->hw, skb); | ||
486 | goto out; | ||
487 | } | ||
488 | } | ||
489 | |||
490 | out: | ||
491 | spin_unlock_bh(&priv->tx_lock); | ||
492 | return ret; | ||
493 | } | ||
494 | |||
495 | static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | ||
496 | { | ||
497 | struct p54s_priv *priv = dev->priv; | ||
498 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
499 | struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data; | ||
500 | struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data; | ||
501 | |||
502 | BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data))); | ||
503 | |||
504 | spin_lock_bh(&priv->tx_lock); | ||
505 | list_add_tail(&di->tx_list, &priv->tx_pending); | ||
506 | spin_unlock_bh(&priv->tx_lock); | ||
507 | |||
508 | queue_work(priv->hw->workqueue, &priv->work); | ||
509 | } | ||
510 | |||
511 | static void p54spi_work(struct work_struct *work) | ||
512 | { | ||
513 | struct p54s_priv *priv = container_of(work, struct p54s_priv, work); | ||
514 | u32 ints; | ||
515 | int ret; | ||
516 | |||
517 | mutex_lock(&priv->mutex); | ||
518 | |||
519 | if (priv->fw_state == FW_STATE_OFF && | ||
520 | priv->fw_state == FW_STATE_RESET) | ||
521 | goto out; | ||
522 | |||
523 | ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); | ||
524 | |||
525 | if (ints & SPI_HOST_INT_READY) { | ||
526 | p54spi_int_ready(priv); | ||
527 | p54spi_int_ack(priv, SPI_HOST_INT_READY); | ||
528 | } | ||
529 | |||
530 | if (priv->fw_state != FW_STATE_READY) | ||
531 | goto out; | ||
532 | |||
533 | if (ints & SPI_HOST_INT_UPDATE) { | ||
534 | p54spi_int_ack(priv, SPI_HOST_INT_UPDATE); | ||
535 | ret = p54spi_rx(priv); | ||
536 | if (ret < 0) | ||
537 | goto out; | ||
538 | } | ||
539 | if (ints & SPI_HOST_INT_SW_UPDATE) { | ||
540 | p54spi_int_ack(priv, SPI_HOST_INT_SW_UPDATE); | ||
541 | ret = p54spi_rx(priv); | ||
542 | if (ret < 0) | ||
543 | goto out; | ||
544 | } | ||
545 | |||
546 | ret = p54spi_wq_tx(priv); | ||
547 | if (ret < 0) | ||
548 | goto out; | ||
549 | |||
550 | ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); | ||
551 | |||
552 | out: | ||
553 | mutex_unlock(&priv->mutex); | ||
554 | } | ||
555 | |||
556 | static int p54spi_op_start(struct ieee80211_hw *dev) | ||
557 | { | ||
558 | struct p54s_priv *priv = dev->priv; | ||
559 | unsigned long timeout; | ||
560 | int ret = 0; | ||
561 | |||
562 | if (mutex_lock_interruptible(&priv->mutex)) { | ||
563 | ret = -EINTR; | ||
564 | goto out; | ||
565 | } | ||
566 | |||
567 | priv->fw_state = FW_STATE_BOOTING; | ||
568 | |||
569 | p54spi_power_on(priv); | ||
570 | |||
571 | ret = p54spi_upload_firmware(dev); | ||
572 | if (ret < 0) { | ||
573 | p54spi_power_off(priv); | ||
574 | goto out_unlock; | ||
575 | } | ||
576 | |||
577 | mutex_unlock(&priv->mutex); | ||
578 | |||
579 | timeout = msecs_to_jiffies(2000); | ||
580 | timeout = wait_for_completion_interruptible_timeout(&priv->fw_comp, | ||
581 | timeout); | ||
582 | if (!timeout) { | ||
583 | dev_err(&priv->spi->dev, "firmware boot failed"); | ||
584 | p54spi_power_off(priv); | ||
585 | ret = -1; | ||
586 | goto out; | ||
587 | } | ||
588 | |||
589 | if (mutex_lock_interruptible(&priv->mutex)) { | ||
590 | ret = -EINTR; | ||
591 | p54spi_power_off(priv); | ||
592 | goto out; | ||
593 | } | ||
594 | |||
595 | WARN_ON(priv->fw_state != FW_STATE_READY); | ||
596 | |||
597 | out_unlock: | ||
598 | mutex_unlock(&priv->mutex); | ||
599 | |||
600 | out: | ||
601 | return ret; | ||
602 | } | ||
603 | |||
604 | static void p54spi_op_stop(struct ieee80211_hw *dev) | ||
605 | { | ||
606 | struct p54s_priv *priv = dev->priv; | ||
607 | |||
608 | if (mutex_lock_interruptible(&priv->mutex)) { | ||
609 | /* FIXME: how to handle this error? */ | ||
610 | return; | ||
611 | } | ||
612 | |||
613 | WARN_ON(priv->fw_state != FW_STATE_READY); | ||
614 | |||
615 | cancel_work_sync(&priv->work); | ||
616 | |||
617 | p54spi_power_off(priv); | ||
618 | spin_lock_bh(&priv->tx_lock); | ||
619 | INIT_LIST_HEAD(&priv->tx_pending); | ||
620 | spin_unlock_bh(&priv->tx_lock); | ||
621 | |||
622 | priv->fw_state = FW_STATE_OFF; | ||
623 | mutex_unlock(&priv->mutex); | ||
624 | } | ||
625 | |||
626 | static int __devinit p54spi_probe(struct spi_device *spi) | ||
627 | { | ||
628 | struct p54s_priv *priv = NULL; | ||
629 | struct ieee80211_hw *hw; | ||
630 | int ret = -EINVAL; | ||
631 | |||
632 | hw = p54_init_common(sizeof(*priv)); | ||
633 | if (!hw) { | ||
634 | dev_err(&priv->spi->dev, "could not alloc ieee80211_hw"); | ||
635 | return -ENOMEM; | ||
636 | } | ||
637 | |||
638 | priv = hw->priv; | ||
639 | priv->hw = hw; | ||
640 | dev_set_drvdata(&spi->dev, priv); | ||
641 | priv->spi = spi; | ||
642 | |||
643 | spi->bits_per_word = 16; | ||
644 | spi->max_speed_hz = 24000000; | ||
645 | |||
646 | ret = spi_setup(spi); | ||
647 | if (ret < 0) { | ||
648 | dev_err(&priv->spi->dev, "spi_setup failed"); | ||
649 | goto err_free_common; | ||
650 | } | ||
651 | |||
652 | ret = gpio_request(p54spi_gpio_power, "p54spi power"); | ||
653 | if (ret < 0) { | ||
654 | dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); | ||
655 | goto err_free_common; | ||
656 | } | ||
657 | |||
658 | ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); | ||
659 | if (ret < 0) { | ||
660 | dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); | ||
661 | goto err_free_common; | ||
662 | } | ||
663 | |||
664 | gpio_direction_output(p54spi_gpio_power, 0); | ||
665 | gpio_direction_input(p54spi_gpio_irq); | ||
666 | |||
667 | ret = request_irq(gpio_to_irq(p54spi_gpio_irq), | ||
668 | p54spi_interrupt, IRQF_DISABLED, "p54spi", | ||
669 | priv->spi); | ||
670 | if (ret < 0) { | ||
671 | dev_err(&priv->spi->dev, "request_irq() failed"); | ||
672 | goto err_free_common; | ||
673 | } | ||
674 | |||
675 | set_irq_type(gpio_to_irq(p54spi_gpio_irq), | ||
676 | IRQ_TYPE_EDGE_RISING); | ||
677 | |||
678 | disable_irq(gpio_to_irq(p54spi_gpio_irq)); | ||
679 | |||
680 | INIT_WORK(&priv->work, p54spi_work); | ||
681 | init_completion(&priv->fw_comp); | ||
682 | INIT_LIST_HEAD(&priv->tx_pending); | ||
683 | mutex_init(&priv->mutex); | ||
684 | SET_IEEE80211_DEV(hw, &spi->dev); | ||
685 | priv->common.open = p54spi_op_start; | ||
686 | priv->common.stop = p54spi_op_stop; | ||
687 | priv->common.tx = p54spi_op_tx; | ||
688 | |||
689 | ret = p54spi_request_firmware(hw); | ||
690 | if (ret < 0) | ||
691 | goto err_free_common; | ||
692 | |||
693 | ret = p54spi_request_eeprom(hw); | ||
694 | if (ret) | ||
695 | goto err_free_common; | ||
696 | |||
697 | ret = ieee80211_register_hw(hw); | ||
698 | if (ret) { | ||
699 | dev_err(&priv->spi->dev, "unable to register " | ||
700 | "mac80211 hw: %d", ret); | ||
701 | goto err_free_common; | ||
702 | } | ||
703 | |||
704 | dev_info(&priv->spi->dev, "device is bound to %s\n", | ||
705 | wiphy_name(hw->wiphy)); | ||
706 | return 0; | ||
707 | |||
708 | err_free_common: | ||
709 | p54_free_common(priv->hw); | ||
710 | return ret; | ||
711 | } | ||
712 | |||
713 | static int __devexit p54spi_remove(struct spi_device *spi) | ||
714 | { | ||
715 | struct p54s_priv *priv = dev_get_drvdata(&spi->dev); | ||
716 | |||
717 | ieee80211_unregister_hw(priv->hw); | ||
718 | |||
719 | free_irq(gpio_to_irq(p54spi_gpio_irq), spi); | ||
720 | |||
721 | gpio_free(p54spi_gpio_power); | ||
722 | gpio_free(p54spi_gpio_irq); | ||
723 | release_firmware(priv->firmware); | ||
724 | |||
725 | mutex_destroy(&priv->mutex); | ||
726 | |||
727 | p54_free_common(priv->hw); | ||
728 | ieee80211_free_hw(priv->hw); | ||
729 | |||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | |||
734 | static struct spi_driver p54spi_driver = { | ||
735 | .driver = { | ||
736 | /* use cx3110x name because board-n800.c uses that for the | ||
737 | * SPI port */ | ||
738 | .name = "cx3110x", | ||
739 | .bus = &spi_bus_type, | ||
740 | .owner = THIS_MODULE, | ||
741 | }, | ||
742 | |||
743 | .probe = p54spi_probe, | ||
744 | .remove = __devexit_p(p54spi_remove), | ||
745 | }; | ||
746 | |||
747 | static int __init p54spi_init(void) | ||
748 | { | ||
749 | int ret; | ||
750 | |||
751 | ret = spi_register_driver(&p54spi_driver); | ||
752 | if (ret < 0) { | ||
753 | printk(KERN_ERR "failed to register SPI driver: %d", ret); | ||
754 | goto out; | ||
755 | } | ||
756 | |||
757 | out: | ||
758 | return ret; | ||
759 | } | ||
760 | |||
761 | static void __exit p54spi_exit(void) | ||
762 | { | ||
763 | spi_unregister_driver(&p54spi_driver); | ||
764 | } | ||
765 | |||
766 | module_init(p54spi_init); | ||
767 | module_exit(p54spi_exit); | ||
768 | |||
769 | MODULE_LICENSE("GPL"); | ||
770 | MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); | ||
diff --git a/drivers/net/wireless/p54/p54spi.h b/drivers/net/wireless/p54/p54spi.h new file mode 100644 index 000000000000..7fbe8d8fc67c --- /dev/null +++ b/drivers/net/wireless/p54/p54spi.h | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de> | ||
3 | * | ||
4 | * This driver is a port from stlc45xx: | ||
5 | * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef P54SPI_H | ||
23 | #define P54SPI_H | ||
24 | |||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/list.h> | ||
27 | #include <net/mac80211.h> | ||
28 | |||
29 | #include "p54.h" | ||
30 | |||
31 | /* Bit 15 is read/write bit; ON = READ, OFF = WRITE */ | ||
32 | #define SPI_ADRS_READ_BIT_15 0x8000 | ||
33 | |||
34 | #define SPI_ADRS_ARM_INTERRUPTS 0x00 | ||
35 | #define SPI_ADRS_ARM_INT_EN 0x04 | ||
36 | |||
37 | #define SPI_ADRS_HOST_INTERRUPTS 0x08 | ||
38 | #define SPI_ADRS_HOST_INT_EN 0x0c | ||
39 | #define SPI_ADRS_HOST_INT_ACK 0x10 | ||
40 | |||
41 | #define SPI_ADRS_GEN_PURP_1 0x14 | ||
42 | #define SPI_ADRS_GEN_PURP_2 0x18 | ||
43 | |||
44 | #define SPI_ADRS_DEV_CTRL_STAT 0x26 /* high word */ | ||
45 | |||
46 | #define SPI_ADRS_DMA_DATA 0x28 | ||
47 | |||
48 | #define SPI_ADRS_DMA_WRITE_CTRL 0x2c | ||
49 | #define SPI_ADRS_DMA_WRITE_LEN 0x2e | ||
50 | #define SPI_ADRS_DMA_WRITE_BASE 0x30 | ||
51 | |||
52 | #define SPI_ADRS_DMA_READ_CTRL 0x34 | ||
53 | #define SPI_ADRS_DMA_READ_LEN 0x36 | ||
54 | #define SPI_ADRS_DMA_READ_BASE 0x38 | ||
55 | |||
56 | #define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000 | ||
57 | #define SPI_CTRL_STAT_START_HALTED 0x4000 | ||
58 | #define SPI_CTRL_STAT_RAM_BOOT 0x2000 | ||
59 | #define SPI_CTRL_STAT_HOST_RESET 0x1000 | ||
60 | #define SPI_CTRL_STAT_HOST_CPU_EN 0x0800 | ||
61 | |||
62 | #define SPI_DMA_WRITE_CTRL_ENABLE 0x0001 | ||
63 | #define SPI_DMA_READ_CTRL_ENABLE 0x0001 | ||
64 | #define HOST_ALLOWED (1 << 7) | ||
65 | |||
66 | #define SPI_TIMEOUT 100 /* msec */ | ||
67 | |||
68 | #define SPI_MAX_TX_PACKETS 32 | ||
69 | |||
70 | #define SPI_MAX_PACKET_SIZE 32767 | ||
71 | |||
72 | #define SPI_TARGET_INT_WAKEUP 0x00000001 | ||
73 | #define SPI_TARGET_INT_SLEEP 0x00000002 | ||
74 | #define SPI_TARGET_INT_RDDONE 0x00000004 | ||
75 | |||
76 | #define SPI_TARGET_INT_CTS 0x00004000 | ||
77 | #define SPI_TARGET_INT_DR 0x00008000 | ||
78 | |||
79 | #define SPI_HOST_INT_READY 0x00000001 | ||
80 | #define SPI_HOST_INT_WR_READY 0x00000002 | ||
81 | #define SPI_HOST_INT_SW_UPDATE 0x00000004 | ||
82 | #define SPI_HOST_INT_UPDATE 0x10000000 | ||
83 | |||
84 | /* clear to send */ | ||
85 | #define SPI_HOST_INT_CR 0x00004000 | ||
86 | |||
87 | /* data ready */ | ||
88 | #define SPI_HOST_INT_DR 0x00008000 | ||
89 | |||
90 | #define SPI_HOST_INTS_DEFAULT \ | ||
91 | (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE) | ||
92 | |||
93 | #define TARGET_BOOT_SLEEP 50 | ||
94 | |||
95 | struct p54s_dma_regs { | ||
96 | __le16 cmd; | ||
97 | __le16 len; | ||
98 | __le32 addr; | ||
99 | } __attribute__ ((packed)); | ||
100 | |||
101 | struct p54s_tx_info { | ||
102 | struct list_head tx_list; | ||
103 | }; | ||
104 | |||
105 | struct p54s_priv { | ||
106 | /* p54_common has to be the first entry */ | ||
107 | struct p54_common common; | ||
108 | struct ieee80211_hw *hw; | ||
109 | struct spi_device *spi; | ||
110 | |||
111 | struct work_struct work; | ||
112 | |||
113 | struct mutex mutex; | ||
114 | struct completion fw_comp; | ||
115 | |||
116 | spinlock_t tx_lock; | ||
117 | |||
118 | /* protected by tx_lock */ | ||
119 | struct list_head tx_pending; | ||
120 | |||
121 | enum fw_state fw_state; | ||
122 | const struct firmware *firmware; | ||
123 | }; | ||
124 | |||
125 | #endif /* P54SPI_H */ | ||
diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h new file mode 100644 index 000000000000..1ea1050911d9 --- /dev/null +++ b/drivers/net/wireless/p54/p54spi_eeprom.h | |||
@@ -0,0 +1,678 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003 Conexant Americas Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2004, 2005, 2006 Nokia Corporation | ||
4 | * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * Copyright 2008 Christian Lamparter <chunkeey@web.de> | ||
6 | * | ||
7 | * based on: | ||
8 | * - cx3110x's pda.h from Nokia | ||
9 | * - cx3110-transfer.log by Johannes Berg | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * version 2 as published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but | ||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
23 | * 02110-1301 USA | ||
24 | */ | ||
25 | |||
26 | #ifndef P54SPI_EEPROM_H | ||
27 | #define P54SPI_EEPROM_H | ||
28 | |||
29 | static unsigned char p54spi_eeprom[] = { | ||
30 | |||
31 | /* struct eeprom_pda_wrap */ | ||
32 | 0x47, 0x4d, 0x55, 0xaa, /* magic */ | ||
33 | 0x00, 0x00, /* pad */ | ||
34 | 0x00, 0x00, /* eeprom_pda_data_wrap length */ | ||
35 | 0x00, 0x00, 0x00, 0x00, /* arm opcode */ | ||
36 | |||
37 | /* bogus MAC address */ | ||
38 | 0x04, 0x00, 0x01, 0x01, /* PDR_MAC_ADDRESS */ | ||
39 | 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee, | ||
40 | |||
41 | /* struct bootrec_exp_if */ | ||
42 | 0x06, 0x00, 0x01, 0x10, /* PDR_INTERFACE_LIST */ | ||
43 | 0x00, 0x00, /* role */ | ||
44 | 0x0f, 0x00, /* if_id */ | ||
45 | 0x85, 0x00, /* variant = Longbow RF, 2GHz */ | ||
46 | 0x01, 0x00, /* btm_compat */ | ||
47 | 0x1f, 0x00, /* top_compat */ | ||
48 | |||
49 | 0x03, 0x00, 0x02, 0x10, /* PDR_HARDWARE_PLATFORM_COMPONENT_ID */ | ||
50 | 0x03, 0x20, 0x00, 0x43, | ||
51 | |||
52 | /* struct pda_country[6] */ | ||
53 | 0x0d, 0x00, 0x07, 0x10, /* PDR_COUNTRY_LIST */ | ||
54 | 0x10, 0x00, 0x00, 0x00, | ||
55 | 0x20, 0x00, 0x00, 0x00, | ||
56 | 0x30, 0x00, 0x00, 0x00, | ||
57 | 0x31, 0x00, 0x00, 0x00, | ||
58 | 0x32, 0x00, 0x00, 0x00, | ||
59 | 0x40, 0x00, 0x00, 0x00, | ||
60 | |||
61 | /* struct pda_country */ | ||
62 | 0x03, 0x00, 0x08, 0x10, /* PDR_DEFAULT_COUNTRY */ | ||
63 | 0x30, 0x00, 0x00, 0x00, /* ETSI */ | ||
64 | |||
65 | 0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */ | ||
66 | 0x08, 0x08, 0x08, 0x08, | ||
67 | |||
68 | 0x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */ | ||
69 | 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, | ||
70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
71 | |||
72 | /* struct pda_custom_wrapper */ | ||
73 | 0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */ | ||
74 | 0x0d, 0x00, 0xee, 0x00, /* 13 entries, 238 bytes per entry */ | ||
75 | 0x00, 0x00, 0x16, 0x0c, /* no offset, 3094 total len */ | ||
76 | /* 2412 MHz */ | ||
77 | 0x6c, 0x09, | ||
78 | 0x10, 0x01, 0x9a, 0x84, | ||
79 | 0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a, | ||
80 | 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, | ||
81 | 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, | ||
82 | 0xf0, 0x00, 0x94, 0x6c, | ||
83 | 0x99, 0x82, 0x99, 0x82, 0x99, 0x82, 0x99, 0x82, | ||
84 | 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, | ||
85 | 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, | ||
86 | 0xd0, 0x00, 0xaa, 0x5a, | ||
87 | 0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a, | ||
88 | 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, | ||
89 | 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, | ||
90 | 0xa0, 0x00, 0xf3, 0x47, | ||
91 | 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, | ||
92 | 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, | ||
93 | 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, | ||
94 | 0x50, 0x00, 0x59, 0x36, | ||
95 | 0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a, | ||
96 | 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, | ||
97 | 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, | ||
98 | 0x00, 0x00, 0xe4, 0x2d, | ||
99 | 0x18, 0x46, 0x18, 0x46, 0x18, 0x46, 0x18, 0x46, | ||
100 | 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, | ||
101 | 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, | ||
102 | 0x00, 0x80, 0x00, 0x00, | ||
103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
104 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
106 | 0x00, 0x80, 0x00, 0x00, | ||
107 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
108 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
110 | 0x00, 0x00, 0x00, 0x00, | ||
111 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
112 | |||
113 | /* 2417 MHz */ | ||
114 | 0x71, 0x09, | ||
115 | 0x10, 0x01, 0xb9, 0x83, | ||
116 | 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, | ||
117 | 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, | ||
118 | 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, | ||
119 | 0xf0, 0x00, 0x2e, 0x6c, | ||
120 | 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, | ||
121 | 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, | ||
122 | 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, | ||
123 | 0xd0, 0x00, 0x8d, 0x5a, | ||
124 | 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, | ||
125 | 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, | ||
126 | 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, | ||
127 | 0xa0, 0x00, 0x0a, 0x48, | ||
128 | 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, | ||
129 | 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, | ||
130 | 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, | ||
131 | 0x50, 0x00, 0x7c, 0x36, | ||
132 | 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, | ||
133 | 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, | ||
134 | 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, | ||
135 | 0x00, 0x00, 0xf5, 0x2d, | ||
136 | 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, | ||
137 | 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, | ||
138 | 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, | ||
139 | 0x00, 0x80, 0x00, 0x00, | ||
140 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
141 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
142 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
143 | 0x00, 0x80, 0x00, 0x00, | ||
144 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
145 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
146 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
147 | 0x00, 0x00, 0x00, 0x00, | ||
148 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
149 | |||
150 | /* 2422 MHz */ | ||
151 | 0x76, 0x09, | ||
152 | 0x10, 0x01, 0xb9, 0x83, | ||
153 | 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, | ||
154 | 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, | ||
155 | 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, | ||
156 | 0xf0, 0x00, 0x2e, 0x6c, | ||
157 | 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, | ||
158 | 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, | ||
159 | 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, | ||
160 | 0xd0, 0x00, 0x8d, 0x5a, | ||
161 | 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, | ||
162 | 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, | ||
163 | 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, | ||
164 | 0xa0, 0x00, 0x0a, 0x48, | ||
165 | 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, | ||
166 | 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, | ||
167 | 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, | ||
168 | 0x50, 0x00, 0x7c, 0x36, | ||
169 | 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, | ||
170 | 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, | ||
171 | 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, | ||
172 | 0x00, 0x00, 0xf5, 0x2d, | ||
173 | 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, | ||
174 | 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, | ||
175 | 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, | ||
176 | 0x00, 0x80, 0x00, 0x00, | ||
177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
179 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
180 | 0x00, 0x80, 0x00, 0x00, | ||
181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
183 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
184 | 0x00, 0x00, 0x00, 0x00, | ||
185 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
186 | |||
187 | /* 2427 MHz */ | ||
188 | 0x7b, 0x09, | ||
189 | 0x10, 0x01, 0x48, 0x83, | ||
190 | 0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a, | ||
191 | 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, | ||
192 | 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, | ||
193 | 0xf0, 0x00, 0xfb, 0x6b, | ||
194 | 0x50, 0x82, 0x50, 0x82, 0x50, 0x82, 0x50, 0x82, | ||
195 | 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, | ||
196 | 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, | ||
197 | 0xd0, 0x00, 0x7e, 0x5a, | ||
198 | 0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a, | ||
199 | 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, | ||
200 | 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, | ||
201 | 0xa0, 0x00, 0x15, 0x48, | ||
202 | 0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e, | ||
203 | 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, | ||
204 | 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, | ||
205 | 0x50, 0x00, 0x8e, 0x36, | ||
206 | 0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59, | ||
207 | 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, | ||
208 | 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, | ||
209 | 0x00, 0x00, 0xfe, 0x2d, | ||
210 | 0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45, | ||
211 | 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, | ||
212 | 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, | ||
213 | 0x00, 0x80, 0x00, 0x00, | ||
214 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
215 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
217 | 0x00, 0x80, 0x00, 0x00, | ||
218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
221 | 0x00, 0x00, 0x00, 0x00, | ||
222 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
223 | |||
224 | /* 2432 MHz */ | ||
225 | 0x80, 0x09, | ||
226 | 0x10, 0x01, 0xd7, 0x82, | ||
227 | 0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a, | ||
228 | 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, | ||
229 | 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, | ||
230 | 0xf0, 0x00, 0xc8, 0x6b, | ||
231 | 0x37, 0x82, 0x37, 0x82, 0x37, 0x82, 0x37, 0x82, | ||
232 | 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, | ||
233 | 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, | ||
234 | 0xd0, 0x00, 0x6f, 0x5a, | ||
235 | 0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a, | ||
236 | 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, | ||
237 | 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, | ||
238 | 0xa0, 0x00, 0x20, 0x48, | ||
239 | 0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d, | ||
240 | 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, | ||
241 | 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, | ||
242 | 0x50, 0x00, 0x9f, 0x36, | ||
243 | 0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59, | ||
244 | 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, | ||
245 | 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, | ||
246 | 0x00, 0x00, 0x06, 0x2e, | ||
247 | 0x74, 0x45, 0x74, 0x45, 0x74, 0x45, 0x74, 0x45, | ||
248 | 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, | ||
249 | 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, | ||
250 | 0x00, 0x80, 0x00, 0x00, | ||
251 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
252 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
253 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
254 | 0x00, 0x80, 0x00, 0x00, | ||
255 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
256 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
257 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
258 | 0x00, 0x00, 0x00, 0x00, | ||
259 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
260 | |||
261 | /* 2437 MHz */ | ||
262 | 0x85, 0x09, | ||
263 | 0x10, 0x01, 0x67, 0x82, | ||
264 | 0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a, | ||
265 | 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, | ||
266 | 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, | ||
267 | 0xf0, 0x00, 0x95, 0x6b, | ||
268 | 0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82, | ||
269 | 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, | ||
270 | 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, | ||
271 | 0xd0, 0x00, 0x61, 0x5a, | ||
272 | 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a, | ||
273 | 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, | ||
274 | 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, | ||
275 | 0xa0, 0x00, 0x2c, 0x48, | ||
276 | 0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d, | ||
277 | 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, | ||
278 | 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, | ||
279 | 0x50, 0x00, 0xb1, 0x36, | ||
280 | 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, | ||
281 | 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, | ||
282 | 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, | ||
283 | 0x00, 0x00, 0x0f, 0x2e, | ||
284 | 0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45, | ||
285 | 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, | ||
286 | 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, | ||
287 | 0x00, 0x80, 0x00, 0x00, | ||
288 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
290 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
291 | 0x00, 0x80, 0x00, 0x00, | ||
292 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
293 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
294 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
295 | 0x00, 0x00, 0x00, 0x00, | ||
296 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
297 | |||
298 | /* 2442 MHz */ | ||
299 | 0x8a, 0x09, | ||
300 | 0x10, 0x01, 0xf6, 0x81, | ||
301 | 0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a, | ||
302 | 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, | ||
303 | 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, | ||
304 | 0xf0, 0x00, 0x62, 0x6b, | ||
305 | 0x06, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x82, | ||
306 | 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, | ||
307 | 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, | ||
308 | 0xd0, 0x00, 0x52, 0x5a, | ||
309 | 0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79, | ||
310 | 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, | ||
311 | 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, | ||
312 | 0xa0, 0x00, 0x37, 0x48, | ||
313 | 0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d, | ||
314 | 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, | ||
315 | 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, | ||
316 | 0x50, 0x00, 0xc2, 0x36, | ||
317 | 0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59, | ||
318 | 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, | ||
319 | 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, | ||
320 | 0x00, 0x00, 0x17, 0x2e, | ||
321 | 0x22, 0x45, 0x22, 0x45, 0x22, 0x45, 0x22, 0x45, | ||
322 | 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, | ||
323 | 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, | ||
324 | 0x00, 0x80, 0x00, 0x00, | ||
325 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
326 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
327 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
328 | 0x00, 0x80, 0x00, 0x00, | ||
329 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
330 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
331 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
332 | 0x00, 0x00, 0x00, 0x00, | ||
333 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
334 | |||
335 | /* 2447 MHz */ | ||
336 | 0x8f, 0x09, | ||
337 | 0x10, 0x01, 0x75, 0x83, | ||
338 | 0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a, | ||
339 | 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, | ||
340 | 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, | ||
341 | 0xf0, 0x00, 0x4b, 0x6c, | ||
342 | 0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82, | ||
343 | 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, | ||
344 | 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, | ||
345 | 0xd0, 0x00, 0xda, 0x5a, | ||
346 | 0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a, | ||
347 | 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, | ||
348 | 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, | ||
349 | 0xa0, 0x00, 0x6d, 0x48, | ||
350 | 0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d, | ||
351 | 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, | ||
352 | 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, | ||
353 | 0x50, 0x00, 0xc6, 0x36, | ||
354 | 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, | ||
355 | 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, | ||
356 | 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, | ||
357 | 0x00, 0x00, 0x15, 0x2e, | ||
358 | 0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45, | ||
359 | 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, | ||
360 | 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, | ||
361 | 0x00, 0x80, 0x00, 0x00, | ||
362 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
363 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
364 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
365 | 0x00, 0x80, 0x00, 0x00, | ||
366 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
367 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
368 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
369 | 0x00, 0x00, 0x00, 0x00, | ||
370 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
371 | |||
372 | /* 2452 MHz */ | ||
373 | 0x94, 0x09, | ||
374 | 0x10, 0x01, 0xf4, 0x84, | ||
375 | 0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a, | ||
376 | 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, | ||
377 | 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, | ||
378 | 0xf0, 0x00, 0x34, 0x6d, | ||
379 | 0x77, 0x82, 0x77, 0x82, 0x77, 0x82, 0x77, 0x82, | ||
380 | 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, | ||
381 | 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, | ||
382 | 0xd0, 0x00, 0x62, 0x5b, | ||
383 | 0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a, | ||
384 | 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, | ||
385 | 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, | ||
386 | 0xa0, 0x00, 0xa2, 0x48, | ||
387 | 0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e, | ||
388 | 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, | ||
389 | 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, | ||
390 | 0x50, 0x00, 0xc9, 0x36, | ||
391 | 0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59, | ||
392 | 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, | ||
393 | 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, | ||
394 | 0x00, 0x00, 0x12, 0x2e, | ||
395 | 0x57, 0x45, 0x57, 0x45, 0x57, 0x45, 0x57, 0x45, | ||
396 | 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, | ||
397 | 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, | ||
398 | 0x00, 0x80, 0x00, 0x00, | ||
399 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
400 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
401 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
402 | 0x00, 0x80, 0x00, 0x00, | ||
403 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
404 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
405 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
406 | 0x00, 0x00, 0x00, 0x00, | ||
407 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
408 | |||
409 | /* 2452 MHz */ | ||
410 | 0x99, 0x09, | ||
411 | 0x10, 0x01, 0x74, 0x86, | ||
412 | 0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a, | ||
413 | 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, | ||
414 | 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, | ||
415 | 0xf0, 0x00, 0x1e, 0x6e, | ||
416 | 0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82, | ||
417 | 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, | ||
418 | 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, | ||
419 | 0xd0, 0x00, 0xeb, 0x5b, | ||
420 | 0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a, | ||
421 | 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, | ||
422 | 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, | ||
423 | 0xa0, 0x00, 0xd8, 0x48, | ||
424 | 0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e, | ||
425 | 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, | ||
426 | 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, | ||
427 | 0x50, 0x00, 0xcd, 0x36, | ||
428 | 0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59, | ||
429 | 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, | ||
430 | 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, | ||
431 | 0x00, 0x00, 0x10, 0x2e, | ||
432 | 0x71, 0x45, 0x71, 0x45, 0x71, 0x45, 0x71, 0x45, | ||
433 | 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, | ||
434 | 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, | ||
435 | 0x00, 0x80, 0x00, 0x00, | ||
436 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
437 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
438 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
439 | 0x00, 0x80, 0x00, 0x00, | ||
440 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
441 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
442 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
443 | 0x00, 0x00, 0x00, 0x00, | ||
444 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
445 | |||
446 | /* 2557 MHz */ | ||
447 | 0x9e, 0x09, | ||
448 | 0x10, 0x01, 0xf3, 0x87, | ||
449 | 0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b, | ||
450 | 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, | ||
451 | 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, | ||
452 | 0xf0, 0x00, 0x07, 0x6f, | ||
453 | 0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82, | ||
454 | 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, | ||
455 | 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, | ||
456 | 0xd0, 0x00, 0x73, 0x5c, | ||
457 | 0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a, | ||
458 | 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, | ||
459 | 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, | ||
460 | 0xa0, 0x00, 0x0d, 0x49, | ||
461 | 0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e, | ||
462 | 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, | ||
463 | 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, | ||
464 | 0x50, 0x00, 0xd1, 0x36, | ||
465 | 0xff, 0x59, 0xff, 0x59, 0xff, 0x59, 0xff, 0x59, | ||
466 | 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, | ||
467 | 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, | ||
468 | 0x00, 0x00, 0x0e, 0x2e, | ||
469 | 0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45, | ||
470 | 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, | ||
471 | 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, | ||
472 | 0x00, 0x80, 0x00, 0x00, | ||
473 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
474 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
475 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
476 | 0x00, 0x80, 0x00, 0x00, | ||
477 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
478 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
479 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
480 | 0x00, 0x00, 0x00, 0x00, | ||
481 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
482 | |||
483 | /* 2562 MHz */ | ||
484 | 0xa3, 0x09, | ||
485 | 0x10, 0x01, 0x72, 0x89, | ||
486 | 0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b, | ||
487 | 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, | ||
488 | 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, | ||
489 | 0xf0, 0x00, 0xf0, 0x6f, | ||
490 | 0x21, 0x83, 0x21, 0x83, 0x21, 0x83, 0x21, 0x83, | ||
491 | 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, | ||
492 | 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, | ||
493 | 0xd0, 0x00, 0xfb, 0x5c, | ||
494 | 0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a, | ||
495 | 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, | ||
496 | 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, | ||
497 | 0xa0, 0x00, 0x43, 0x49, | ||
498 | 0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e, | ||
499 | 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, | ||
500 | 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, | ||
501 | 0x50, 0x00, 0xd4, 0x36, | ||
502 | 0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a, | ||
503 | 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, | ||
504 | 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, | ||
505 | 0x00, 0x00, 0x0b, 0x2e, | ||
506 | 0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45, | ||
507 | 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, | ||
508 | 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, | ||
509 | 0x00, 0x80, 0x00, 0x00, | ||
510 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
511 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
512 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
513 | 0x00, 0x80, 0x00, 0x00, | ||
514 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
515 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
516 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
517 | 0x00, 0x00, 0x00, 0x00, | ||
518 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
519 | |||
520 | /* 2572 MHz */ | ||
521 | 0xa8, 0x09, | ||
522 | 0x10, 0x01, 0xf1, 0x8a, | ||
523 | 0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b, | ||
524 | 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, | ||
525 | 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, | ||
526 | 0xf0, 0x00, 0xd9, 0x70, | ||
527 | 0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83, | ||
528 | 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, | ||
529 | 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, | ||
530 | 0xd0, 0x00, 0x83, 0x5d, | ||
531 | 0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b, | ||
532 | 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, | ||
533 | 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, | ||
534 | 0xa0, 0x00, 0x78, 0x49, | ||
535 | 0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e, | ||
536 | 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, | ||
537 | 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, | ||
538 | 0x50, 0x00, 0xd8, 0x36, | ||
539 | 0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a, | ||
540 | 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, | ||
541 | 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, | ||
542 | 0x00, 0x00, 0x09, 0x2e, | ||
543 | 0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45, | ||
544 | 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, | ||
545 | 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, | ||
546 | 0x00, 0x80, 0x00, 0x00, | ||
547 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
548 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
549 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
550 | 0x00, 0x80, 0x00, 0x00, | ||
551 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
552 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
553 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
554 | 0x00, 0x00, 0x00, 0x00, | ||
555 | 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, | ||
556 | |||
557 | /* | ||
558 | * Not really sure if this is actually the power_limit database, | ||
559 | * it looks a bit "related" to PDR_PRISM_ZIF_TX_IQ_CALIBRATION | ||
560 | */ | ||
561 | /* struct pda_custom_wrapper */ | ||
562 | 0xae, 0x00, 0xef, 0xbe, /* PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM */ | ||
563 | 0x0d, 0x00, 0x1a, 0x00, /* 13 entries, 26 bytes per entry */ | ||
564 | 0x00, 0x00, 0x52, 0x01, /* no offset, 338 bytes total */ | ||
565 | |||
566 | /* 2412 MHz */ | ||
567 | 0x6c, 0x09, | ||
568 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
569 | 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, | ||
570 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
571 | |||
572 | /* 2417 MHz */ | ||
573 | 0x71, 0x09, | ||
574 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
575 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
576 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
577 | |||
578 | /* 2422 MHz */ | ||
579 | 0x76, 0x09, | ||
580 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
581 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
582 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
583 | |||
584 | /* 2427 MHz */ | ||
585 | 0x7b, 0x09, | ||
586 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
587 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
588 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
589 | |||
590 | /* 2432 MHz */ | ||
591 | 0x80, 0x09, | ||
592 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
593 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
594 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
595 | |||
596 | /* 2437 MHz */ | ||
597 | 0x85, 0x09, | ||
598 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
599 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
600 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
601 | |||
602 | /* 2442 MHz */ | ||
603 | 0x8a, 0x09, | ||
604 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
605 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
606 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
607 | |||
608 | /* 2447 MHz */ | ||
609 | 0x8f, 0x09, | ||
610 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
611 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
612 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
613 | |||
614 | /* 2452 MHz */ | ||
615 | 0x94, 0x09, | ||
616 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
617 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
618 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
619 | |||
620 | /* 2457 MHz */ | ||
621 | 0x99, 0x09, | ||
622 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
623 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
624 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
625 | |||
626 | /* 2462 MHz */ | ||
627 | 0x9e, 0x09, | ||
628 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
629 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
630 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
631 | |||
632 | /* 2467 MHz */ | ||
633 | 0xa3, 0x09, | ||
634 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
635 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
636 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
637 | |||
638 | /* 2472 MHz */ | ||
639 | 0xa8, 0x09, | ||
640 | 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, | ||
641 | 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, | ||
642 | 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, | ||
643 | |||
644 | /* struct pda_iq_autocal_entry[13] */ | ||
645 | 0x42, 0x00, 0x06, 0x19, /* PDR_PRISM_ZIF_TX_IQ_CALIBRATION */ | ||
646 | /* 2412 MHz */ | ||
647 | 0x6c, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
648 | /* 2417 MHz */ | ||
649 | 0x71, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
650 | /* 2422 MHz */ | ||
651 | 0x76, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
652 | /* 2427 MHz */ | ||
653 | 0x7b, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
654 | /* 2432 MHz */ | ||
655 | 0x80, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
656 | /* 2437 MHz */ | ||
657 | 0x85, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
658 | /* 2442 MHz */ | ||
659 | 0x8a, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
660 | /* 2447 MHz */ | ||
661 | 0x8f, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
662 | /* 2452 MHz */ | ||
663 | 0x94, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00, | ||
664 | /* 2457 MHz */ | ||
665 | 0x99, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, | ||
666 | /* 2462 MHz */ | ||
667 | 0x9e, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, | ||
668 | /* 2467 MHz */ | ||
669 | 0xa3, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, | ||
670 | /* 2472 MHz */ | ||
671 | 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, | ||
672 | |||
673 | 0x02, 0x00, 0x00, 0x00, /* PDR_END */ | ||
674 | 0xa8, 0xf5 /* bogus data */ | ||
675 | }; | ||
676 | |||
677 | #endif /* P54SPI_EEPROM_H */ | ||
678 | |||
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 5de2ebfb28c7..9539ddcf379f 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -424,9 +424,46 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep, | |||
424 | data, len, &alen, 2000); | 424 | data, len, &alen, 2000); |
425 | } | 425 | } |
426 | 426 | ||
427 | static const char p54u_romboot_3887[] = "~~~~"; | ||
428 | static const char p54u_firmware_upload_3887[] = "<\r"; | ||
429 | |||
430 | static int p54u_device_reset_3887(struct ieee80211_hw *dev) | ||
431 | { | ||
432 | struct p54u_priv *priv = dev->priv; | ||
433 | int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING); | ||
434 | u8 buf[4]; | ||
435 | |||
436 | if (lock) { | ||
437 | ret = usb_lock_device_for_reset(priv->udev, priv->intf); | ||
438 | if (ret < 0) { | ||
439 | dev_err(&priv->udev->dev, "(p54usb) unable to lock " | ||
440 | " device for reset: %d\n", ret); | ||
441 | return ret; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | ret = usb_reset_device(priv->udev); | ||
446 | if (lock) | ||
447 | usb_unlock_device(priv->udev); | ||
448 | |||
449 | if (ret) { | ||
450 | dev_err(&priv->udev->dev, "(p54usb) unable to reset " | ||
451 | "device: %d\n", ret); | ||
452 | return ret; | ||
453 | } | ||
454 | |||
455 | memcpy(&buf, p54u_romboot_3887, sizeof(buf)); | ||
456 | ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, | ||
457 | buf, sizeof(buf)); | ||
458 | if (ret) | ||
459 | dev_err(&priv->udev->dev, "(p54usb) unable to jump to " | ||
460 | "boot ROM: %d\n", ret); | ||
461 | |||
462 | return ret; | ||
463 | } | ||
464 | |||
427 | static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | 465 | static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) |
428 | { | 466 | { |
429 | static char start_string[] = "~~~~<\r"; | ||
430 | struct p54u_priv *priv = dev->priv; | 467 | struct p54u_priv *priv = dev->priv; |
431 | const struct firmware *fw_entry = NULL; | 468 | const struct firmware *fw_entry = NULL; |
432 | int err, alen; | 469 | int err, alen; |
@@ -445,12 +482,9 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
445 | goto err_bufalloc; | 482 | goto err_bufalloc; |
446 | } | 483 | } |
447 | 484 | ||
448 | memcpy(buf, start_string, 4); | 485 | err = p54u_device_reset_3887(dev); |
449 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4); | 486 | if (err) |
450 | if (err) { | ||
451 | dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err); | ||
452 | goto err_reset; | 487 | goto err_reset; |
453 | } | ||
454 | 488 | ||
455 | err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); | 489 | err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev); |
456 | if (err) { | 490 | if (err) { |
@@ -466,15 +500,22 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
466 | if (err) | 500 | if (err) |
467 | goto err_upload_failed; | 501 | goto err_upload_failed; |
468 | 502 | ||
503 | if (priv->common.fw_interface != FW_LM87) { | ||
504 | dev_err(&priv->udev->dev, "wrong firmware, " | ||
505 | "please get a LM87 firmware and try again.\n"); | ||
506 | err = -EINVAL; | ||
507 | goto err_upload_failed; | ||
508 | } | ||
509 | |||
469 | left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); | 510 | left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); |
470 | strcpy(buf, start_string); | 511 | strcpy(buf, p54u_firmware_upload_3887); |
471 | left -= strlen(start_string); | 512 | left -= strlen(p54u_firmware_upload_3887); |
472 | tmp += strlen(start_string); | 513 | tmp += strlen(p54u_firmware_upload_3887); |
473 | 514 | ||
474 | data = fw_entry->data; | 515 | data = fw_entry->data; |
475 | remains = fw_entry->size; | 516 | remains = fw_entry->size; |
476 | 517 | ||
477 | hdr = (struct x2_header *)(buf + strlen(start_string)); | 518 | hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887)); |
478 | memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE); | 519 | memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE); |
479 | hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR); | 520 | hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR); |
480 | hdr->fw_length = cpu_to_le32(fw_entry->size); | 521 | hdr->fw_length = cpu_to_le32(fw_entry->size); |
@@ -616,6 +657,14 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) | |||
616 | return err; | 657 | return err; |
617 | } | 658 | } |
618 | 659 | ||
660 | if (priv->common.fw_interface != FW_LM86) { | ||
661 | dev_err(&priv->udev->dev, "wrong firmware, " | ||
662 | "please get a LM86(USB) firmware and try again.\n"); | ||
663 | kfree(buf); | ||
664 | release_firmware(fw_entry); | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | |||
619 | #define P54U_WRITE(type, addr, data) \ | 668 | #define P54U_WRITE(type, addr, data) \ |
620 | do {\ | 669 | do {\ |
621 | err = p54u_write(priv, buf, type,\ | 670 | err = p54u_write(priv, buf, type,\ |
@@ -876,6 +925,9 @@ static int __devinit p54u_probe(struct usb_interface *intf, | |||
876 | SET_IEEE80211_DEV(dev, &intf->dev); | 925 | SET_IEEE80211_DEV(dev, &intf->dev); |
877 | usb_set_intfdata(intf, dev); | 926 | usb_set_intfdata(intf, dev); |
878 | priv->udev = udev; | 927 | priv->udev = udev; |
928 | priv->intf = intf; | ||
929 | skb_queue_head_init(&priv->rx_queue); | ||
930 | init_usb_anchor(&priv->submitted); | ||
879 | 931 | ||
880 | usb_get_dev(udev); | 932 | usb_get_dev(udev); |
881 | 933 | ||
@@ -918,9 +970,6 @@ static int __devinit p54u_probe(struct usb_interface *intf, | |||
918 | if (err) | 970 | if (err) |
919 | goto err_free_dev; | 971 | goto err_free_dev; |
920 | 972 | ||
921 | skb_queue_head_init(&priv->rx_queue); | ||
922 | init_usb_anchor(&priv->submitted); | ||
923 | |||
924 | p54u_open(dev); | 973 | p54u_open(dev); |
925 | err = p54_read_eeprom(dev); | 974 | err = p54_read_eeprom(dev); |
926 | p54u_stop(dev); | 975 | p54u_stop(dev); |
@@ -958,11 +1007,23 @@ static void __devexit p54u_disconnect(struct usb_interface *intf) | |||
958 | ieee80211_free_hw(dev); | 1007 | ieee80211_free_hw(dev); |
959 | } | 1008 | } |
960 | 1009 | ||
1010 | static int p54u_pre_reset(struct usb_interface *intf) | ||
1011 | { | ||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int p54u_post_reset(struct usb_interface *intf) | ||
1016 | { | ||
1017 | return 0; | ||
1018 | } | ||
1019 | |||
961 | static struct usb_driver p54u_driver = { | 1020 | static struct usb_driver p54u_driver = { |
962 | .name = "p54usb", | 1021 | .name = "p54usb", |
963 | .id_table = p54u_table, | 1022 | .id_table = p54u_table, |
964 | .probe = p54u_probe, | 1023 | .probe = p54u_probe, |
965 | .disconnect = p54u_disconnect, | 1024 | .disconnect = p54u_disconnect, |
1025 | .pre_reset = p54u_pre_reset, | ||
1026 | .post_reset = p54u_post_reset, | ||
966 | }; | 1027 | }; |
967 | 1028 | ||
968 | static int __init p54u_init(void) | 1029 | static int __init p54u_init(void) |
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h index 54ee738bf2af..8bc58982d8dd 100644 --- a/drivers/net/wireless/p54/p54usb.h +++ b/drivers/net/wireless/p54/p54usb.h | |||
@@ -126,6 +126,7 @@ struct p54u_rx_info { | |||
126 | struct p54u_priv { | 126 | struct p54u_priv { |
127 | struct p54_common common; | 127 | struct p54_common common; |
128 | struct usb_device *udev; | 128 | struct usb_device *udev; |
129 | struct usb_interface *intf; | ||
129 | enum { | 130 | enum { |
130 | P54U_NET2280 = 0, | 131 | P54U_NET2280 = 0, |
131 | P54U_3887 | 132 | P54U_3887 |
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index e43bae97ed8f..88895bd9e495 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
24 | #include <linux/etherdevice.h> | 24 | #include <linux/etherdevice.h> |
25 | #include <linux/if_arp.h> | 25 | #include <linux/if_arp.h> |
26 | #include <asm/byteorder.h> | ||
26 | 27 | ||
27 | #include "prismcompat.h" | 28 | #include "prismcompat.h" |
28 | #include "isl_38xx.h" | 29 | #include "isl_38xx.h" |
@@ -471,8 +472,8 @@ islpci_eth_receive(islpci_private *priv) | |||
471 | wmb(); | 472 | wmb(); |
472 | 473 | ||
473 | /* increment the driver read pointer */ | 474 | /* increment the driver read pointer */ |
474 | add_le32p(&control_block-> | 475 | le32_add_cpu(&control_block-> |
475 | driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1); | 476 | driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1); |
476 | } | 477 | } |
477 | 478 | ||
478 | /* trigger the device */ | 479 | /* trigger the device */ |
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h index f91a88fc1e35..87a1734663da 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.h +++ b/drivers/net/wireless/prism54/islpci_mgt.h | |||
@@ -85,12 +85,6 @@ extern int pc_debug; | |||
85 | #define PIMFOR_FLAG_APPLIC_ORIGIN 0x01 | 85 | #define PIMFOR_FLAG_APPLIC_ORIGIN 0x01 |
86 | #define PIMFOR_FLAG_LITTLE_ENDIAN 0x02 | 86 | #define PIMFOR_FLAG_LITTLE_ENDIAN 0x02 |
87 | 87 | ||
88 | static inline void | ||
89 | add_le32p(__le32 * le_number, u32 add) | ||
90 | { | ||
91 | *le_number = cpu_to_le32(le32_to_cpup(le_number) + add); | ||
92 | } | ||
93 | |||
94 | void display_buffer(char *, int); | 88 | void display_buffer(char *, int); |
95 | 89 | ||
96 | /* | 90 | /* |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index ed93ac41297f..105f214e21f4 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -369,9 +369,6 @@ struct rndis_wext_private { | |||
369 | }; | 369 | }; |
370 | 370 | ||
371 | 371 | ||
372 | static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
373 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; | ||
374 | |||
375 | static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 }; | 372 | static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 }; |
376 | 373 | ||
377 | static const int bcm4320_power_output[4] = { 25, 50, 75, 100 }; | 374 | static const int bcm4320_power_output[4] = { 25, 50, 75, 100 }; |
@@ -640,8 +637,8 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq) | |||
640 | static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) | 637 | static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) |
641 | { | 638 | { |
642 | if (freq->m < 1000 && freq->e == 0) { | 639 | if (freq->m < 1000 && freq->e == 0) { |
643 | if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan)) | 640 | if (freq->m >= 1 && freq->m <= 14) |
644 | *dsconfig = freq_chan[freq->m - 1] * 1000; | 641 | *dsconfig = ieee80211_dsss_chan_to_freq(freq->m) * 1000; |
645 | else | 642 | else |
646 | return -1; | 643 | return -1; |
647 | } else { | 644 | } else { |
@@ -1178,11 +1175,11 @@ static int rndis_iw_get_range(struct net_device *dev, | |||
1178 | range->throughput = 11 * 1000 * 1000 / 2; | 1175 | range->throughput = 11 * 1000 * 1000 / 2; |
1179 | } | 1176 | } |
1180 | 1177 | ||
1181 | range->num_channels = ARRAY_SIZE(freq_chan); | 1178 | range->num_channels = 14; |
1182 | 1179 | ||
1183 | for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) { | 1180 | for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) { |
1184 | range->freq[i].i = i + 1; | 1181 | range->freq[i].i = i + 1; |
1185 | range->freq[i].m = freq_chan[i] * 100000; | 1182 | range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000; |
1186 | range->freq[i].e = 1; | 1183 | range->freq[i].e = 1; |
1187 | } | 1184 | } |
1188 | range->num_frequency = i; | 1185 | range->num_frequency = i; |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 178b313293b4..bfc5d9cf716e 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -97,10 +97,11 @@ config RT2X00_LIB_CRYPTO | |||
97 | 97 | ||
98 | config RT2X00_LIB_RFKILL | 98 | config RT2X00_LIB_RFKILL |
99 | boolean | 99 | boolean |
100 | default y if (RT2X00_LIB=y && RFKILL=y) || (RT2X00_LIB=m && RFKILL!=n) | 100 | default y if (RT2X00_LIB=y && INPUT=y) || (RT2X00_LIB=m && INPUT!=n) |
101 | select INPUT_POLLDEV | ||
101 | 102 | ||
102 | comment "rt2x00 rfkill support disabled due to modularized RFKILL and built-in rt2x00" | 103 | comment "rt2x00 rfkill support disabled due to modularized INPUT and built-in rt2x00" |
103 | depends on RT2X00_LIB=y && RFKILL=m | 104 | depends on RT2X00_LIB=y && INPUT=m |
104 | 105 | ||
105 | config RT2X00_LIB_LEDS | 106 | config RT2X00_LIB_LEDS |
106 | boolean | 107 | boolean |
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 917cb4f3b038..f22d808d8c51 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile | |||
@@ -2,6 +2,7 @@ rt2x00lib-y += rt2x00dev.o | |||
2 | rt2x00lib-y += rt2x00mac.o | 2 | rt2x00lib-y += rt2x00mac.o |
3 | rt2x00lib-y += rt2x00config.o | 3 | rt2x00lib-y += rt2x00config.o |
4 | rt2x00lib-y += rt2x00queue.o | 4 | rt2x00lib-y += rt2x00queue.o |
5 | rt2x00lib-y += rt2x00link.o | ||
5 | rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o | 6 | rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o |
6 | rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o | 7 | rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o |
7 | rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o | 8 | rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 6a977679124d..4a2c0b971ca8 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -524,6 +524,32 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
524 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | 524 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); |
525 | } | 525 | } |
526 | 526 | ||
527 | static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev, | ||
528 | struct rt2x00lib_conf *libconf) | ||
529 | { | ||
530 | enum dev_state state = | ||
531 | (libconf->conf->flags & IEEE80211_CONF_PS) ? | ||
532 | STATE_SLEEP : STATE_AWAKE; | ||
533 | u32 reg; | ||
534 | |||
535 | if (state == STATE_SLEEP) { | ||
536 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | ||
537 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, | ||
538 | (libconf->conf->beacon_int - 20) * 16); | ||
539 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, | ||
540 | libconf->conf->listen_interval - 1); | ||
541 | |||
542 | /* We must first disable autowake before it can be enabled */ | ||
543 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | ||
544 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | ||
545 | |||
546 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); | ||
547 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | ||
548 | } | ||
549 | |||
550 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
551 | } | ||
552 | |||
527 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | 553 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, |
528 | struct rt2x00lib_conf *libconf, | 554 | struct rt2x00lib_conf *libconf, |
529 | const unsigned int flags) | 555 | const unsigned int flags) |
@@ -537,6 +563,8 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | |||
537 | rt2400pci_config_retry_limit(rt2x00dev, libconf); | 563 | rt2400pci_config_retry_limit(rt2x00dev, libconf); |
538 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) | 564 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) |
539 | rt2400pci_config_duration(rt2x00dev, libconf); | 565 | rt2400pci_config_duration(rt2x00dev, libconf); |
566 | if (flags & IEEE80211_CONF_CHANGE_PS) | ||
567 | rt2400pci_config_ps(rt2x00dev, libconf); | ||
540 | } | 568 | } |
541 | 569 | ||
542 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, | 570 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, |
@@ -572,35 +600,37 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
572 | qual->false_cca = bbp; | 600 | qual->false_cca = bbp; |
573 | } | 601 | } |
574 | 602 | ||
575 | static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | 603 | static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, |
604 | struct link_qual *qual, u8 vgc_level) | ||
576 | { | 605 | { |
577 | rt2400pci_bbp_write(rt2x00dev, 13, 0x08); | 606 | rt2400pci_bbp_write(rt2x00dev, 13, vgc_level); |
578 | rt2x00dev->link.vgc_level = 0x08; | 607 | qual->vgc_level = vgc_level; |
608 | qual->vgc_level_reg = vgc_level; | ||
579 | } | 609 | } |
580 | 610 | ||
581 | static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | 611 | static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev, |
612 | struct link_qual *qual) | ||
582 | { | 613 | { |
583 | u8 reg; | 614 | rt2400pci_set_vgc(rt2x00dev, qual, 0x08); |
615 | } | ||
584 | 616 | ||
617 | static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev, | ||
618 | struct link_qual *qual, const u32 count) | ||
619 | { | ||
585 | /* | 620 | /* |
586 | * The link tuner should not run longer then 60 seconds, | 621 | * The link tuner should not run longer then 60 seconds, |
587 | * and should run once every 2 seconds. | 622 | * and should run once every 2 seconds. |
588 | */ | 623 | */ |
589 | if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1)) | 624 | if (count > 60 || !(count & 1)) |
590 | return; | 625 | return; |
591 | 626 | ||
592 | /* | 627 | /* |
593 | * Base r13 link tuning on the false cca count. | 628 | * Base r13 link tuning on the false cca count. |
594 | */ | 629 | */ |
595 | rt2400pci_bbp_read(rt2x00dev, 13, ®); | 630 | if ((qual->false_cca > 512) && (qual->vgc_level < 0x20)) |
596 | 631 | rt2400pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level); | |
597 | if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) { | 632 | else if ((qual->false_cca < 100) && (qual->vgc_level > 0x08)) |
598 | rt2400pci_bbp_write(rt2x00dev, 13, ++reg); | 633 | rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level); |
599 | rt2x00dev->link.vgc_level = reg; | ||
600 | } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) { | ||
601 | rt2400pci_bbp_write(rt2x00dev, 13, --reg); | ||
602 | rt2x00dev->link.vgc_level = reg; | ||
603 | } | ||
604 | } | 634 | } |
605 | 635 | ||
606 | /* | 636 | /* |
@@ -1365,7 +1395,9 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1365 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1395 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1366 | 1396 | ||
1367 | rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | 1397 | rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1368 | if (value == LED_MODE_TXRX_ACTIVITY) | 1398 | if (value == LED_MODE_TXRX_ACTIVITY || |
1399 | value == LED_MODE_DEFAULT || | ||
1400 | value == LED_MODE_ASUS) | ||
1369 | rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual, | 1401 | rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1370 | LED_TYPE_ACTIVITY); | 1402 | LED_TYPE_ACTIVITY); |
1371 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 1403 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
@@ -1419,7 +1451,9 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1419 | * Initialize all hw fields. | 1451 | * Initialize all hw fields. |
1420 | */ | 1452 | */ |
1421 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1453 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1422 | IEEE80211_HW_SIGNAL_DBM; | 1454 | IEEE80211_HW_SIGNAL_DBM | |
1455 | IEEE80211_HW_SUPPORTS_PS | | ||
1456 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
1423 | rt2x00dev->hw->extra_tx_headroom = 0; | 1457 | rt2x00dev->hw->extra_tx_headroom = 0; |
1424 | 1458 | ||
1425 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 1459 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index 9aefda4ab3c2..72ac31c3cb75 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d3bc218ec85c..b9104e28bc2e 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -573,6 +573,32 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
573 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); | 573 | rt2x00pci_register_write(rt2x00dev, CSR12, reg); |
574 | } | 574 | } |
575 | 575 | ||
576 | static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev, | ||
577 | struct rt2x00lib_conf *libconf) | ||
578 | { | ||
579 | enum dev_state state = | ||
580 | (libconf->conf->flags & IEEE80211_CONF_PS) ? | ||
581 | STATE_SLEEP : STATE_AWAKE; | ||
582 | u32 reg; | ||
583 | |||
584 | if (state == STATE_SLEEP) { | ||
585 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); | ||
586 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, | ||
587 | (libconf->conf->beacon_int - 20) * 16); | ||
588 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, | ||
589 | libconf->conf->listen_interval - 1); | ||
590 | |||
591 | /* We must first disable autowake before it can be enabled */ | ||
592 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 0); | ||
593 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | ||
594 | |||
595 | rt2x00_set_field32(®, CSR20_AUTOWAKE, 1); | ||
596 | rt2x00pci_register_write(rt2x00dev, CSR20, reg); | ||
597 | } | ||
598 | |||
599 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
600 | } | ||
601 | |||
576 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 602 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
577 | struct rt2x00lib_conf *libconf, | 603 | struct rt2x00lib_conf *libconf, |
578 | const unsigned int flags) | 604 | const unsigned int flags) |
@@ -588,6 +614,8 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | |||
588 | rt2500pci_config_retry_limit(rt2x00dev, libconf); | 614 | rt2500pci_config_retry_limit(rt2x00dev, libconf); |
589 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) | 615 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) |
590 | rt2500pci_config_duration(rt2x00dev, libconf); | 616 | rt2500pci_config_duration(rt2x00dev, libconf); |
617 | if (flags & IEEE80211_CONF_CHANGE_PS) | ||
618 | rt2500pci_config_ps(rt2x00dev, libconf); | ||
591 | } | 619 | } |
592 | 620 | ||
593 | /* | 621 | /* |
@@ -611,29 +639,33 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
611 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); | 639 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); |
612 | } | 640 | } |
613 | 641 | ||
614 | static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | 642 | static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, |
643 | struct link_qual *qual, u8 vgc_level) | ||
615 | { | 644 | { |
616 | rt2500pci_bbp_write(rt2x00dev, 17, 0x48); | 645 | if (qual->vgc_level_reg != vgc_level) { |
617 | rt2x00dev->link.vgc_level = 0x48; | 646 | rt2500pci_bbp_write(rt2x00dev, 17, vgc_level); |
647 | qual->vgc_level_reg = vgc_level; | ||
648 | } | ||
618 | } | 649 | } |
619 | 650 | ||
620 | static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | 651 | static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev, |
652 | struct link_qual *qual) | ||
621 | { | 653 | { |
622 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | 654 | rt2500pci_set_vgc(rt2x00dev, qual, 0x48); |
623 | u8 r17; | 655 | } |
624 | 656 | ||
657 | static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev, | ||
658 | struct link_qual *qual, const u32 count) | ||
659 | { | ||
625 | /* | 660 | /* |
626 | * To prevent collisions with MAC ASIC on chipsets | 661 | * To prevent collisions with MAC ASIC on chipsets |
627 | * up to version C the link tuning should halt after 20 | 662 | * up to version C the link tuning should halt after 20 |
628 | * seconds while being associated. | 663 | * seconds while being associated. |
629 | */ | 664 | */ |
630 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 665 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
631 | rt2x00dev->intf_associated && | 666 | rt2x00dev->intf_associated && count > 20) |
632 | rt2x00dev->link.count > 20) | ||
633 | return; | 667 | return; |
634 | 668 | ||
635 | rt2500pci_bbp_read(rt2x00dev, 17, &r17); | ||
636 | |||
637 | /* | 669 | /* |
638 | * Chipset versions C and lower should directly continue | 670 | * Chipset versions C and lower should directly continue |
639 | * to the dynamic CCA tuning. Chipset version D and higher | 671 | * to the dynamic CCA tuning. Chipset version D and higher |
@@ -649,29 +681,25 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
649 | * then corrupt the R17 tuning. To remidy this the tuning should | 681 | * then corrupt the R17 tuning. To remidy this the tuning should |
650 | * be stopped (While making sure the R17 value will not exceed limits) | 682 | * be stopped (While making sure the R17 value will not exceed limits) |
651 | */ | 683 | */ |
652 | if (rssi < -80 && rt2x00dev->link.count > 20) { | 684 | if (qual->rssi < -80 && count > 20) { |
653 | if (r17 >= 0x41) { | 685 | if (qual->vgc_level_reg >= 0x41) |
654 | r17 = rt2x00dev->link.vgc_level; | 686 | rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level); |
655 | rt2500pci_bbp_write(rt2x00dev, 17, r17); | ||
656 | } | ||
657 | return; | 687 | return; |
658 | } | 688 | } |
659 | 689 | ||
660 | /* | 690 | /* |
661 | * Special big-R17 for short distance | 691 | * Special big-R17 for short distance |
662 | */ | 692 | */ |
663 | if (rssi >= -58) { | 693 | if (qual->rssi >= -58) { |
664 | if (r17 != 0x50) | 694 | rt2500pci_set_vgc(rt2x00dev, qual, 0x50); |
665 | rt2500pci_bbp_write(rt2x00dev, 17, 0x50); | ||
666 | return; | 695 | return; |
667 | } | 696 | } |
668 | 697 | ||
669 | /* | 698 | /* |
670 | * Special mid-R17 for middle distance | 699 | * Special mid-R17 for middle distance |
671 | */ | 700 | */ |
672 | if (rssi >= -74) { | 701 | if (qual->rssi >= -74) { |
673 | if (r17 != 0x41) | 702 | rt2500pci_set_vgc(rt2x00dev, qual, 0x41); |
674 | rt2500pci_bbp_write(rt2x00dev, 17, 0x41); | ||
675 | return; | 703 | return; |
676 | } | 704 | } |
677 | 705 | ||
@@ -679,8 +707,8 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
679 | * Leave short or middle distance condition, restore r17 | 707 | * Leave short or middle distance condition, restore r17 |
680 | * to the dynamic tuning range. | 708 | * to the dynamic tuning range. |
681 | */ | 709 | */ |
682 | if (r17 >= 0x41) { | 710 | if (qual->vgc_level_reg >= 0x41) { |
683 | rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level); | 711 | rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level); |
684 | return; | 712 | return; |
685 | } | 713 | } |
686 | 714 | ||
@@ -690,12 +718,12 @@ dynamic_cca_tune: | |||
690 | * R17 is inside the dynamic tuning range, | 718 | * R17 is inside the dynamic tuning range, |
691 | * start tuning the link based on the false cca counter. | 719 | * start tuning the link based on the false cca counter. |
692 | */ | 720 | */ |
693 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) { | 721 | if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) { |
694 | rt2500pci_bbp_write(rt2x00dev, 17, ++r17); | 722 | rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg); |
695 | rt2x00dev->link.vgc_level = r17; | 723 | qual->vgc_level = qual->vgc_level_reg; |
696 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) { | 724 | } else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) { |
697 | rt2500pci_bbp_write(rt2x00dev, 17, --r17); | 725 | rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg); |
698 | rt2x00dev->link.vgc_level = r17; | 726 | qual->vgc_level = qual->vgc_level_reg; |
699 | } | 727 | } |
700 | } | 728 | } |
701 | 729 | ||
@@ -1205,7 +1233,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1205 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1233 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1206 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1234 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1207 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1235 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1208 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1236 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1209 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1237 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1210 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1238 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1211 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1239 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
@@ -1524,7 +1552,9 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1524 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1552 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1525 | 1553 | ||
1526 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | 1554 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1527 | if (value == LED_MODE_TXRX_ACTIVITY) | 1555 | if (value == LED_MODE_TXRX_ACTIVITY || |
1556 | value == LED_MODE_DEFAULT || | ||
1557 | value == LED_MODE_ASUS) | ||
1528 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, | 1558 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1529 | LED_TYPE_ACTIVITY); | 1559 | LED_TYPE_ACTIVITY); |
1530 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 1560 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
@@ -1721,7 +1751,9 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1721 | * Initialize all hw fields. | 1751 | * Initialize all hw fields. |
1722 | */ | 1752 | */ |
1723 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1753 | rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1724 | IEEE80211_HW_SIGNAL_DBM; | 1754 | IEEE80211_HW_SIGNAL_DBM | |
1755 | IEEE80211_HW_SUPPORTS_PS | | ||
1756 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
1725 | 1757 | ||
1726 | rt2x00dev->hw->extra_tx_headroom = 0; | 1758 | rt2x00dev->hw->extra_tx_headroom = 0; |
1727 | 1759 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index e135247f7f89..17a0c9c8c184 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index af6b5847be5c..c526e737fcad 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -280,6 +280,18 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = { | |||
280 | }; | 280 | }; |
281 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 281 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
282 | 282 | ||
283 | #ifdef CONFIG_RT2X00_LIB_RFKILL | ||
284 | static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) | ||
285 | { | ||
286 | u16 reg; | ||
287 | |||
288 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | ||
289 | return rt2x00_get_field32(reg, MAC_CSR19_BIT7); | ||
290 | } | ||
291 | #else | ||
292 | #define rt2500usb_rfkill_poll NULL | ||
293 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | ||
294 | |||
283 | #ifdef CONFIG_RT2X00_LIB_LEDS | 295 | #ifdef CONFIG_RT2X00_LIB_LEDS |
284 | static void rt2500usb_brightness_set(struct led_classdev *led_cdev, | 296 | static void rt2500usb_brightness_set(struct led_classdev *led_cdev, |
285 | enum led_brightness brightness) | 297 | enum led_brightness brightness) |
@@ -634,6 +646,32 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
634 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | 646 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); |
635 | } | 647 | } |
636 | 648 | ||
649 | static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev, | ||
650 | struct rt2x00lib_conf *libconf) | ||
651 | { | ||
652 | enum dev_state state = | ||
653 | (libconf->conf->flags & IEEE80211_CONF_PS) ? | ||
654 | STATE_SLEEP : STATE_AWAKE; | ||
655 | u16 reg; | ||
656 | |||
657 | if (state == STATE_SLEEP) { | ||
658 | rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); | ||
659 | rt2x00_set_field16(®, MAC_CSR18_DELAY_AFTER_BEACON, | ||
660 | libconf->conf->beacon_int - 20); | ||
661 | rt2x00_set_field16(®, MAC_CSR18_BEACONS_BEFORE_WAKEUP, | ||
662 | libconf->conf->listen_interval - 1); | ||
663 | |||
664 | /* We must first disable autowake before it can be enabled */ | ||
665 | rt2x00_set_field16(®, MAC_CSR18_AUTO_WAKE, 0); | ||
666 | rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg); | ||
667 | |||
668 | rt2x00_set_field16(®, MAC_CSR18_AUTO_WAKE, 1); | ||
669 | rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg); | ||
670 | } | ||
671 | |||
672 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | ||
673 | } | ||
674 | |||
637 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | 675 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, |
638 | struct rt2x00lib_conf *libconf, | 676 | struct rt2x00lib_conf *libconf, |
639 | const unsigned int flags) | 677 | const unsigned int flags) |
@@ -647,6 +685,8 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | |||
647 | libconf->conf->power_level); | 685 | libconf->conf->power_level); |
648 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) | 686 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) |
649 | rt2500usb_config_duration(rt2x00dev, libconf); | 687 | rt2500usb_config_duration(rt2x00dev, libconf); |
688 | if (flags & IEEE80211_CONF_CHANGE_PS) | ||
689 | rt2500usb_config_ps(rt2x00dev, libconf); | ||
650 | } | 690 | } |
651 | 691 | ||
652 | /* | 692 | /* |
@@ -670,7 +710,8 @@ static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, | |||
670 | qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR); | 710 | qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR); |
671 | } | 711 | } |
672 | 712 | ||
673 | static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | 713 | static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev, |
714 | struct link_qual *qual) | ||
674 | { | 715 | { |
675 | u16 eeprom; | 716 | u16 eeprom; |
676 | u16 value; | 717 | u16 value; |
@@ -691,7 +732,7 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | |||
691 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER); | 732 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER); |
692 | rt2500usb_bbp_write(rt2x00dev, 17, value); | 733 | rt2500usb_bbp_write(rt2x00dev, 17, value); |
693 | 734 | ||
694 | rt2x00dev->link.vgc_level = value; | 735 | qual->vgc_level = value; |
695 | } | 736 | } |
696 | 737 | ||
697 | /* | 738 | /* |
@@ -1176,7 +1217,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1176 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1217 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1177 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1218 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1178 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1219 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1179 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1220 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1180 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1221 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1181 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); | 1222 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); |
1182 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1223 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
@@ -1562,12 +1603,22 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1562 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1603 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1563 | 1604 | ||
1564 | rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); | 1605 | rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1565 | if (value == LED_MODE_TXRX_ACTIVITY) | 1606 | if (value == LED_MODE_TXRX_ACTIVITY || |
1607 | value == LED_MODE_DEFAULT || | ||
1608 | value == LED_MODE_ASUS) | ||
1566 | rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual, | 1609 | rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1567 | LED_TYPE_ACTIVITY); | 1610 | LED_TYPE_ACTIVITY); |
1568 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 1611 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
1569 | 1612 | ||
1570 | /* | 1613 | /* |
1614 | * Detect if this device has an hardware controlled radio. | ||
1615 | */ | ||
1616 | #ifdef CONFIG_RT2X00_LIB_RFKILL | ||
1617 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | ||
1618 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
1619 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | ||
1620 | |||
1621 | /* | ||
1571 | * Check if the BBP tuning should be disabled. | 1622 | * Check if the BBP tuning should be disabled. |
1572 | */ | 1623 | */ |
1573 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 1624 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); |
@@ -1752,7 +1803,9 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1752 | rt2x00dev->hw->flags = | 1803 | rt2x00dev->hw->flags = |
1753 | IEEE80211_HW_RX_INCLUDES_FCS | | 1804 | IEEE80211_HW_RX_INCLUDES_FCS | |
1754 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1805 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1755 | IEEE80211_HW_SIGNAL_DBM; | 1806 | IEEE80211_HW_SIGNAL_DBM | |
1807 | IEEE80211_HW_SUPPORTS_PS | | ||
1808 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
1756 | 1809 | ||
1757 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1810 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1758 | 1811 | ||
@@ -1839,7 +1892,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1839 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | 1892 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); |
1840 | if (!modparam_nohwcrypt) { | 1893 | if (!modparam_nohwcrypt) { |
1841 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 1894 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); |
1842 | __set_bit(CONFIG_CRYPTO_COPY_IV, &rt2x00dev->flags); | 1895 | __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); |
1843 | } | 1896 | } |
1844 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); | 1897 | __set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags); |
1845 | 1898 | ||
@@ -1873,6 +1926,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1873 | .uninitialize = rt2x00usb_uninitialize, | 1926 | .uninitialize = rt2x00usb_uninitialize, |
1874 | .clear_entry = rt2x00usb_clear_entry, | 1927 | .clear_entry = rt2x00usb_clear_entry, |
1875 | .set_device_state = rt2500usb_set_device_state, | 1928 | .set_device_state = rt2500usb_set_device_state, |
1929 | .rfkill_poll = rt2500usb_rfkill_poll, | ||
1876 | .link_stats = rt2500usb_link_stats, | 1930 | .link_stats = rt2500usb_link_stats, |
1877 | .reset_tuner = rt2500usb_reset_tuner, | 1931 | .reset_tuner = rt2500usb_reset_tuner, |
1878 | .link_tuner = rt2500usb_link_tuner, | 1932 | .link_tuner = rt2500usb_link_tuner, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index 4347dfdabcd4..afce0e0322c3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -189,6 +189,14 @@ | |||
189 | * MAC_CSR19: GPIO control register. | 189 | * MAC_CSR19: GPIO control register. |
190 | */ | 190 | */ |
191 | #define MAC_CSR19 0x0426 | 191 | #define MAC_CSR19 0x0426 |
192 | #define MAC_CSR19_BIT0 FIELD32(0x0001) | ||
193 | #define MAC_CSR19_BIT1 FIELD32(0x0002) | ||
194 | #define MAC_CSR19_BIT2 FIELD32(0x0004) | ||
195 | #define MAC_CSR19_BIT3 FIELD32(0x0008) | ||
196 | #define MAC_CSR19_BIT4 FIELD32(0x0010) | ||
197 | #define MAC_CSR19_BIT5 FIELD32(0x0020) | ||
198 | #define MAC_CSR19_BIT6 FIELD32(0x0040) | ||
199 | #define MAC_CSR19_BIT7 FIELD32(0x0080) | ||
192 | 200 | ||
193 | /* | 201 | /* |
194 | * MAC_CSR20: LED control register. | 202 | * MAC_CSR20: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 39ecf3b82ca1..d0a825638188 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/leds.h> | 33 | #include <linux/leds.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | #include <linux/input-polldev.h> | ||
36 | 37 | ||
37 | #include <net/mac80211.h> | 38 | #include <net/mac80211.h> |
38 | 39 | ||
@@ -44,7 +45,7 @@ | |||
44 | /* | 45 | /* |
45 | * Module information. | 46 | * Module information. |
46 | */ | 47 | */ |
47 | #define DRV_VERSION "2.2.3" | 48 | #define DRV_VERSION "2.3.0" |
48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 49 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
49 | 50 | ||
50 | /* | 51 | /* |
@@ -177,52 +178,41 @@ struct antenna_setup { | |||
177 | */ | 178 | */ |
178 | struct link_qual { | 179 | struct link_qual { |
179 | /* | 180 | /* |
180 | * Statistics required for Link tuning. | 181 | * Statistics required for Link tuning by driver |
181 | * For the average RSSI value we use the "Walking average" approach. | 182 | * The rssi value is provided by rt2x00lib during the |
182 | * When adding RSSI to the average value the following calculation | 183 | * link_tuner() callback function. |
183 | * is needed: | 184 | * The false_cca field is filled during the link_stats() |
184 | * | 185 | * callback function and could be used during the |
185 | * avg_rssi = ((avg_rssi * 7) + rssi) / 8; | 186 | * link_tuner() callback function. |
186 | * | ||
187 | * The advantage of this approach is that we only need 1 variable | ||
188 | * to store the average in (No need for a count and a total). | ||
189 | * But more importantly, normal average values will over time | ||
190 | * move less and less towards newly added values this results | ||
191 | * that with link tuning, the device can have a very good RSSI | ||
192 | * for a few minutes but when the device is moved away from the AP | ||
193 | * the average will not decrease fast enough to compensate. | ||
194 | * The walking average compensates this and will move towards | ||
195 | * the new values correctly allowing a effective link tuning. | ||
196 | */ | 187 | */ |
197 | int avg_rssi; | 188 | int rssi; |
198 | int false_cca; | 189 | int false_cca; |
199 | 190 | ||
200 | /* | 191 | /* |
201 | * Statistics required for Signal quality calculation. | 192 | * VGC levels |
202 | * For calculating the Signal quality we have to determine | 193 | * Hardware driver will tune the VGC level during each call |
203 | * the total number of success and failed RX and TX frames. | 194 | * to the link_tuner() callback function. This vgc_level is |
204 | * After that we also use the average RSSI value to help | 195 | * is determined based on the link quality statistics like |
205 | * determining the signal quality. | 196 | * average RSSI and the false CCA count. |
206 | * For the calculation we will use the following algorithm: | ||
207 | * | ||
208 | * rssi_percentage = (avg_rssi * 100) / rssi_offset | ||
209 | * rx_percentage = (rx_success * 100) / rx_total | ||
210 | * tx_percentage = (tx_success * 100) / tx_total | ||
211 | * avg_signal = ((WEIGHT_RSSI * avg_rssi) + | ||
212 | * (WEIGHT_TX * tx_percentage) + | ||
213 | * (WEIGHT_RX * rx_percentage)) / 100 | ||
214 | * | 197 | * |
215 | * This value should then be checked to not be greated then 100. | 198 | * In some cases the drivers need to differentiate between |
199 | * the currently "desired" VGC level and the level configured | ||
200 | * in the hardware. The latter is important to reduce the | ||
201 | * number of BBP register reads to reduce register access | ||
202 | * overhead. For this reason we store both values here. | ||
203 | */ | ||
204 | u8 vgc_level; | ||
205 | u8 vgc_level_reg; | ||
206 | |||
207 | /* | ||
208 | * Statistics required for Signal quality calculation. | ||
209 | * These fields might be changed during the link_stats() | ||
210 | * callback function. | ||
216 | */ | 211 | */ |
217 | int rx_percentage; | ||
218 | int rx_success; | 212 | int rx_success; |
219 | int rx_failed; | 213 | int rx_failed; |
220 | int tx_percentage; | ||
221 | int tx_success; | 214 | int tx_success; |
222 | int tx_failed; | 215 | int tx_failed; |
223 | #define WEIGHT_RSSI 20 | ||
224 | #define WEIGHT_RX 40 | ||
225 | #define WEIGHT_TX 40 | ||
226 | }; | 216 | }; |
227 | 217 | ||
228 | /* | 218 | /* |
@@ -286,9 +276,16 @@ struct link { | |||
286 | struct link_ant ant; | 276 | struct link_ant ant; |
287 | 277 | ||
288 | /* | 278 | /* |
289 | * Active VGC level | 279 | * Currently active average RSSI value |
280 | */ | ||
281 | int avg_rssi; | ||
282 | |||
283 | /* | ||
284 | * Currently precalculated percentages of successful | ||
285 | * TX and RX frames. | ||
290 | */ | 286 | */ |
291 | int vgc_level; | 287 | int rx_percentage; |
288 | int tx_percentage; | ||
292 | 289 | ||
293 | /* | 290 | /* |
294 | * Work structure for scheduling periodic link tuning. | 291 | * Work structure for scheduling periodic link tuning. |
@@ -297,55 +294,6 @@ struct link { | |||
297 | }; | 294 | }; |
298 | 295 | ||
299 | /* | 296 | /* |
300 | * Small helper macro to work with moving/walking averages. | ||
301 | */ | ||
302 | #define MOVING_AVERAGE(__avg, __val, __samples) \ | ||
303 | ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) ) | ||
304 | |||
305 | /* | ||
306 | * When we lack RSSI information return something less then -80 to | ||
307 | * tell the driver to tune the device to maximum sensitivity. | ||
308 | */ | ||
309 | #define DEFAULT_RSSI ( -128 ) | ||
310 | |||
311 | /* | ||
312 | * Link quality access functions. | ||
313 | */ | ||
314 | static inline int rt2x00_get_link_rssi(struct link *link) | ||
315 | { | ||
316 | if (link->qual.avg_rssi && link->qual.rx_success) | ||
317 | return link->qual.avg_rssi; | ||
318 | return DEFAULT_RSSI; | ||
319 | } | ||
320 | |||
321 | static inline int rt2x00_get_link_ant_rssi(struct link *link) | ||
322 | { | ||
323 | if (link->ant.rssi_ant && link->qual.rx_success) | ||
324 | return link->ant.rssi_ant; | ||
325 | return DEFAULT_RSSI; | ||
326 | } | ||
327 | |||
328 | static inline void rt2x00_reset_link_ant_rssi(struct link *link) | ||
329 | { | ||
330 | link->ant.rssi_ant = 0; | ||
331 | } | ||
332 | |||
333 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, | ||
334 | enum antenna ant) | ||
335 | { | ||
336 | if (link->ant.rssi_history[ant - ANTENNA_A]) | ||
337 | return link->ant.rssi_history[ant - ANTENNA_A]; | ||
338 | return DEFAULT_RSSI; | ||
339 | } | ||
340 | |||
341 | static inline int rt2x00_update_ant_rssi(struct link *link, int rssi) | ||
342 | { | ||
343 | int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A]; | ||
344 | link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi; | ||
345 | return old_rssi; | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * Interface structure | 297 | * Interface structure |
350 | * Per interface configuration details, this structure | 298 | * Per interface configuration details, this structure |
351 | * is allocated as the private data for ieee80211_vif. | 299 | * is allocated as the private data for ieee80211_vif. |
@@ -448,7 +396,7 @@ struct rt2x00lib_erp { | |||
448 | int ack_timeout; | 396 | int ack_timeout; |
449 | int ack_consume_time; | 397 | int ack_consume_time; |
450 | 398 | ||
451 | u64 basic_rates; | 399 | u32 basic_rates; |
452 | 400 | ||
453 | int slot_time; | 401 | int slot_time; |
454 | 402 | ||
@@ -544,8 +492,10 @@ struct rt2x00lib_ops { | |||
544 | int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev); | 492 | int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev); |
545 | void (*link_stats) (struct rt2x00_dev *rt2x00dev, | 493 | void (*link_stats) (struct rt2x00_dev *rt2x00dev, |
546 | struct link_qual *qual); | 494 | struct link_qual *qual); |
547 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); | 495 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev, |
548 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); | 496 | struct link_qual *qual); |
497 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev, | ||
498 | struct link_qual *qual, const u32 count); | ||
549 | 499 | ||
550 | /* | 500 | /* |
551 | * TX control handlers | 501 | * TX control handlers |
@@ -625,7 +575,6 @@ enum rt2x00_flags { | |||
625 | DEVICE_STATE_REGISTERED_HW, | 575 | DEVICE_STATE_REGISTERED_HW, |
626 | DEVICE_STATE_INITIALIZED, | 576 | DEVICE_STATE_INITIALIZED, |
627 | DEVICE_STATE_STARTED, | 577 | DEVICE_STATE_STARTED, |
628 | DEVICE_STATE_STARTED_SUSPEND, | ||
629 | DEVICE_STATE_ENABLED_RADIO, | 578 | DEVICE_STATE_ENABLED_RADIO, |
630 | DEVICE_STATE_DISABLED_RADIO_HW, | 579 | DEVICE_STATE_DISABLED_RADIO_HW, |
631 | 580 | ||
@@ -637,6 +586,7 @@ enum rt2x00_flags { | |||
637 | DRIVER_REQUIRE_ATIM_QUEUE, | 586 | DRIVER_REQUIRE_ATIM_QUEUE, |
638 | DRIVER_REQUIRE_SCHEDULED, | 587 | DRIVER_REQUIRE_SCHEDULED, |
639 | DRIVER_REQUIRE_DMA, | 588 | DRIVER_REQUIRE_DMA, |
589 | DRIVER_REQUIRE_COPY_IV, | ||
640 | 590 | ||
641 | /* | 591 | /* |
642 | * Driver features | 592 | * Driver features |
@@ -653,7 +603,6 @@ enum rt2x00_flags { | |||
653 | CONFIG_EXTERNAL_LNA_BG, | 603 | CONFIG_EXTERNAL_LNA_BG, |
654 | CONFIG_DOUBLE_ANTENNA, | 604 | CONFIG_DOUBLE_ANTENNA, |
655 | CONFIG_DISABLE_LINK_TUNING, | 605 | CONFIG_DISABLE_LINK_TUNING, |
656 | CONFIG_CRYPTO_COPY_IV, | ||
657 | }; | 606 | }; |
658 | 607 | ||
659 | /* | 608 | /* |
@@ -689,8 +638,8 @@ struct rt2x00_dev { | |||
689 | unsigned long rfkill_state; | 638 | unsigned long rfkill_state; |
690 | #define RFKILL_STATE_ALLOCATED 1 | 639 | #define RFKILL_STATE_ALLOCATED 1 |
691 | #define RFKILL_STATE_REGISTERED 2 | 640 | #define RFKILL_STATE_REGISTERED 2 |
692 | struct rfkill *rfkill; | 641 | #define RFKILL_STATE_BLOCKED 3 |
693 | struct delayed_work rfkill_work; | 642 | struct input_polled_dev *rfkill_poll_dev; |
694 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | 643 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ |
695 | 644 | ||
696 | /* | 645 | /* |
@@ -918,7 +867,7 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip) | |||
918 | return (chipset->rf == chip); | 867 | return (chipset->rf == chip); |
919 | } | 868 | } |
920 | 869 | ||
921 | static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset) | 870 | static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset) |
922 | { | 871 | { |
923 | return chipset->rev; | 872 | return chipset->rev; |
924 | } | 873 | } |
@@ -982,7 +931,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
982 | int mc_count, struct dev_addr_list *mc_list); | 931 | int mc_count, struct dev_addr_list *mc_list); |
983 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 932 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
984 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 933 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
985 | const u8 *local_address, const u8 *address, | 934 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
986 | struct ieee80211_key_conf *key); | 935 | struct ieee80211_key_conf *key); |
987 | #else | 936 | #else |
988 | #define rt2x00mac_set_key NULL | 937 | #define rt2x00mac_set_key NULL |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index e66fb316cd61..9c2f5517af2a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -32,7 +32,7 @@ | |||
32 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | 32 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, |
33 | struct rt2x00_intf *intf, | 33 | struct rt2x00_intf *intf, |
34 | enum nl80211_iftype type, | 34 | enum nl80211_iftype type, |
35 | u8 *mac, u8 *bssid) | 35 | const u8 *mac, const u8 *bssid) |
36 | { | 36 | { |
37 | struct rt2x00intf_conf conf; | 37 | struct rt2x00intf_conf conf; |
38 | unsigned int flags = 0; | 38 | unsigned int flags = 0; |
@@ -42,6 +42,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | |||
42 | switch (type) { | 42 | switch (type) { |
43 | case NL80211_IFTYPE_ADHOC: | 43 | case NL80211_IFTYPE_ADHOC: |
44 | case NL80211_IFTYPE_AP: | 44 | case NL80211_IFTYPE_AP: |
45 | case NL80211_IFTYPE_MESH_POINT: | ||
46 | case NL80211_IFTYPE_WDS: | ||
45 | conf.sync = TSF_SYNC_BEACON; | 47 | conf.sync = TSF_SYNC_BEACON; |
46 | break; | 48 | break; |
47 | case NL80211_IFTYPE_STATION: | 49 | case NL80211_IFTYPE_STATION: |
@@ -152,8 +154,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
152 | */ | 154 | */ |
153 | rt2x00dev->ops->lib->config_ant(rt2x00dev, ant); | 155 | rt2x00dev->ops->lib->config_ant(rt2x00dev, ant); |
154 | 156 | ||
155 | rt2x00lib_reset_link_tuner(rt2x00dev); | 157 | rt2x00link_reset_tuner(rt2x00dev, true); |
156 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); | ||
157 | 158 | ||
158 | memcpy(active, ant, sizeof(*ant)); | 159 | memcpy(active, ant, sizeof(*ant)); |
159 | 160 | ||
@@ -191,7 +192,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
191 | * which means we need to reset the link tuner. | 192 | * which means we need to reset the link tuner. |
192 | */ | 193 | */ |
193 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) | 194 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) |
194 | rt2x00lib_reset_link_tuner(rt2x00dev); | 195 | rt2x00link_reset_tuner(rt2x00dev, false); |
195 | 196 | ||
196 | rt2x00dev->curr_band = conf->channel->band; | 197 | rt2x00dev->curr_band = conf->channel->band; |
197 | rt2x00dev->tx_power = conf->power_level; | 198 | rt2x00dev->tx_power = conf->power_level; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index aee9cba13eb3..0b41845d9543 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -49,9 +49,14 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) | |||
49 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | 49 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, |
50 | struct txentry_desc *txdesc) | 50 | struct txentry_desc *txdesc) |
51 | { | 51 | { |
52 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
52 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 53 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
53 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 54 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
54 | 55 | ||
56 | if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || | ||
57 | !hw_key || entry->skb->do_not_encrypt) | ||
58 | return; | ||
59 | |||
55 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); | 60 | __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); |
56 | 61 | ||
57 | txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); | 62 | txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); |
@@ -69,11 +74,17 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | |||
69 | __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); | 74 | __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); |
70 | } | 75 | } |
71 | 76 | ||
72 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | 77 | unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, |
78 | struct sk_buff *skb) | ||
73 | { | 79 | { |
80 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
74 | struct ieee80211_key_conf *key = tx_info->control.hw_key; | 81 | struct ieee80211_key_conf *key = tx_info->control.hw_key; |
75 | unsigned int overhead = 0; | 82 | unsigned int overhead = 0; |
76 | 83 | ||
84 | if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || | ||
85 | !key || skb->do_not_encrypt) | ||
86 | return overhead; | ||
87 | |||
77 | /* | 88 | /* |
78 | * Extend frame length to include IV/EIV/ICV/MMIC, | 89 | * Extend frame length to include IV/EIV/ICV/MMIC, |
79 | * note that these lengths should only be added when | 90 | * note that these lengths should only be added when |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 54dd10060bf1..dcdce7f746b5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -130,9 +130,11 @@ struct rt2x00debug_intf { | |||
130 | }; | 130 | }; |
131 | 131 | ||
132 | void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | 132 | void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, |
133 | enum cipher cipher, enum rx_crypto status) | 133 | struct rxdone_entry_desc *rxdesc) |
134 | { | 134 | { |
135 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; | 135 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; |
136 | enum cipher cipher = rxdesc->cipher; | ||
137 | enum rx_crypto status = rxdesc->cipher_status; | ||
136 | 138 | ||
137 | if (cipher == CIPHER_TKIP_NO_MIC) | 139 | if (cipher == CIPHER_TKIP_NO_MIC) |
138 | cipher = CIPHER_TKIP; | 140 | cipher = CIPHER_TKIP; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h index a92104dfee9a..035cbc98c593 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.h +++ b/drivers/net/wireless/rt2x00/rt2x00debug.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 87c0f2c83077..e1b40545a9be 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -30,60 +30,6 @@ | |||
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Link tuning handlers | ||
34 | */ | ||
35 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
36 | { | ||
37 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
38 | return; | ||
39 | |||
40 | /* | ||
41 | * Reset link information. | ||
42 | * Both the currently active vgc level as well as | ||
43 | * the link tuner counter should be reset. Resetting | ||
44 | * the counter is important for devices where the | ||
45 | * device should only perform link tuning during the | ||
46 | * first minute after being enabled. | ||
47 | */ | ||
48 | rt2x00dev->link.count = 0; | ||
49 | rt2x00dev->link.vgc_level = 0; | ||
50 | |||
51 | /* | ||
52 | * Reset the link tuner. | ||
53 | */ | ||
54 | rt2x00dev->ops->lib->reset_tuner(rt2x00dev); | ||
55 | } | ||
56 | |||
57 | static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
58 | { | ||
59 | /* | ||
60 | * Clear all (possibly) pre-existing quality statistics. | ||
61 | */ | ||
62 | memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual)); | ||
63 | |||
64 | /* | ||
65 | * The RX and TX percentage should start at 50% | ||
66 | * this will assure we will get at least get some | ||
67 | * decent value when the link tuner starts. | ||
68 | * The value will be dropped and overwritten with | ||
69 | * the correct (measured )value anyway during the | ||
70 | * first run of the link tuner. | ||
71 | */ | ||
72 | rt2x00dev->link.qual.rx_percentage = 50; | ||
73 | rt2x00dev->link.qual.tx_percentage = 50; | ||
74 | |||
75 | rt2x00lib_reset_link_tuner(rt2x00dev); | ||
76 | |||
77 | queue_delayed_work(rt2x00dev->hw->workqueue, | ||
78 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | ||
79 | } | ||
80 | |||
81 | static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) | ||
82 | { | ||
83 | cancel_delayed_work_sync(&rt2x00dev->link.work); | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Radio control handlers. | 33 | * Radio control handlers. |
88 | */ | 34 | */ |
89 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | 35 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) |
@@ -161,238 +107,15 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
161 | * When we are disabling the RX, we should also stop the link tuner. | 107 | * When we are disabling the RX, we should also stop the link tuner. |
162 | */ | 108 | */ |
163 | if (state == STATE_RADIO_RX_OFF) | 109 | if (state == STATE_RADIO_RX_OFF) |
164 | rt2x00lib_stop_link_tuner(rt2x00dev); | 110 | rt2x00link_stop_tuner(rt2x00dev); |
165 | 111 | ||
166 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); | 112 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, state); |
167 | 113 | ||
168 | /* | 114 | /* |
169 | * When we are enabling the RX, we should also start the link tuner. | 115 | * When we are enabling the RX, we should also start the link tuner. |
170 | */ | 116 | */ |
171 | if (state == STATE_RADIO_RX_ON && | 117 | if (state == STATE_RADIO_RX_ON) |
172 | (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count)) | 118 | rt2x00link_start_tuner(rt2x00dev); |
173 | rt2x00lib_start_link_tuner(rt2x00dev); | ||
174 | } | ||
175 | |||
176 | static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev) | ||
177 | { | ||
178 | struct antenna_setup ant; | ||
179 | int sample_a = | ||
180 | rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A); | ||
181 | int sample_b = | ||
182 | rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B); | ||
183 | |||
184 | memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant)); | ||
185 | |||
186 | /* | ||
187 | * We are done sampling. Now we should evaluate the results. | ||
188 | */ | ||
189 | rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE; | ||
190 | |||
191 | /* | ||
192 | * During the last period we have sampled the RSSI | ||
193 | * from both antenna's. It now is time to determine | ||
194 | * which antenna demonstrated the best performance. | ||
195 | * When we are already on the antenna with the best | ||
196 | * performance, then there really is nothing for us | ||
197 | * left to do. | ||
198 | */ | ||
199 | if (sample_a == sample_b) | ||
200 | return; | ||
201 | |||
202 | if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) | ||
203 | ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; | ||
204 | |||
205 | if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) | ||
206 | ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; | ||
207 | |||
208 | rt2x00lib_config_antenna(rt2x00dev, &ant); | ||
209 | } | ||
210 | |||
211 | static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev) | ||
212 | { | ||
213 | struct antenna_setup ant; | ||
214 | int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link); | ||
215 | int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr); | ||
216 | |||
217 | memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant)); | ||
218 | |||
219 | /* | ||
220 | * Legacy driver indicates that we should swap antenna's | ||
221 | * when the difference in RSSI is greater that 5. This | ||
222 | * also should be done when the RSSI was actually better | ||
223 | * then the previous sample. | ||
224 | * When the difference exceeds the threshold we should | ||
225 | * sample the rssi from the other antenna to make a valid | ||
226 | * comparison between the 2 antennas. | ||
227 | */ | ||
228 | if (abs(rssi_curr - rssi_old) < 5) | ||
229 | return; | ||
230 | |||
231 | rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE; | ||
232 | |||
233 | if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) | ||
234 | ant.rx = (ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; | ||
235 | |||
236 | if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) | ||
237 | ant.tx = (ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; | ||
238 | |||
239 | rt2x00lib_config_antenna(rt2x00dev, &ant); | ||
240 | } | ||
241 | |||
242 | static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev) | ||
243 | { | ||
244 | /* | ||
245 | * Determine if software diversity is enabled for | ||
246 | * either the TX or RX antenna (or both). | ||
247 | * Always perform this check since within the link | ||
248 | * tuner interval the configuration might have changed. | ||
249 | */ | ||
250 | rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY; | ||
251 | rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY; | ||
252 | |||
253 | if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) | ||
254 | rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY; | ||
255 | if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) | ||
256 | rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY; | ||
257 | |||
258 | if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) && | ||
259 | !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) { | ||
260 | rt2x00dev->link.ant.flags = 0; | ||
261 | return; | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * If we have only sampled the data over the last period | ||
266 | * we should now harvest the data. Otherwise just evaluate | ||
267 | * the data. The latter should only be performed once | ||
268 | * every 2 seconds. | ||
269 | */ | ||
270 | if (rt2x00dev->link.ant.flags & ANTENNA_MODE_SAMPLE) | ||
271 | rt2x00lib_evaluate_antenna_sample(rt2x00dev); | ||
272 | else if (rt2x00dev->link.count & 1) | ||
273 | rt2x00lib_evaluate_antenna_eval(rt2x00dev); | ||
274 | } | ||
275 | |||
276 | static void rt2x00lib_update_link_stats(struct link *link, int rssi) | ||
277 | { | ||
278 | int avg_rssi = rssi; | ||
279 | |||
280 | /* | ||
281 | * Update global RSSI | ||
282 | */ | ||
283 | if (link->qual.avg_rssi) | ||
284 | avg_rssi = MOVING_AVERAGE(link->qual.avg_rssi, rssi, 8); | ||
285 | link->qual.avg_rssi = avg_rssi; | ||
286 | |||
287 | /* | ||
288 | * Update antenna RSSI | ||
289 | */ | ||
290 | if (link->ant.rssi_ant) | ||
291 | rssi = MOVING_AVERAGE(link->ant.rssi_ant, rssi, 8); | ||
292 | link->ant.rssi_ant = rssi; | ||
293 | } | ||
294 | |||
295 | static void rt2x00lib_precalculate_link_signal(struct link_qual *qual) | ||
296 | { | ||
297 | if (qual->rx_failed || qual->rx_success) | ||
298 | qual->rx_percentage = | ||
299 | (qual->rx_success * 100) / | ||
300 | (qual->rx_failed + qual->rx_success); | ||
301 | else | ||
302 | qual->rx_percentage = 50; | ||
303 | |||
304 | if (qual->tx_failed || qual->tx_success) | ||
305 | qual->tx_percentage = | ||
306 | (qual->tx_success * 100) / | ||
307 | (qual->tx_failed + qual->tx_success); | ||
308 | else | ||
309 | qual->tx_percentage = 50; | ||
310 | |||
311 | qual->rx_success = 0; | ||
312 | qual->rx_failed = 0; | ||
313 | qual->tx_success = 0; | ||
314 | qual->tx_failed = 0; | ||
315 | } | ||
316 | |||
317 | static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev, | ||
318 | int rssi) | ||
319 | { | ||
320 | int rssi_percentage = 0; | ||
321 | int signal; | ||
322 | |||
323 | /* | ||
324 | * We need a positive value for the RSSI. | ||
325 | */ | ||
326 | if (rssi < 0) | ||
327 | rssi += rt2x00dev->rssi_offset; | ||
328 | |||
329 | /* | ||
330 | * Calculate the different percentages, | ||
331 | * which will be used for the signal. | ||
332 | */ | ||
333 | if (rt2x00dev->rssi_offset) | ||
334 | rssi_percentage = (rssi * 100) / rt2x00dev->rssi_offset; | ||
335 | |||
336 | /* | ||
337 | * Add the individual percentages and use the WEIGHT | ||
338 | * defines to calculate the current link signal. | ||
339 | */ | ||
340 | signal = ((WEIGHT_RSSI * rssi_percentage) + | ||
341 | (WEIGHT_TX * rt2x00dev->link.qual.tx_percentage) + | ||
342 | (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100; | ||
343 | |||
344 | return (signal > 100) ? 100 : signal; | ||
345 | } | ||
346 | |||
347 | static void rt2x00lib_link_tuner(struct work_struct *work) | ||
348 | { | ||
349 | struct rt2x00_dev *rt2x00dev = | ||
350 | container_of(work, struct rt2x00_dev, link.work.work); | ||
351 | |||
352 | /* | ||
353 | * When the radio is shutting down we should | ||
354 | * immediately cease all link tuning. | ||
355 | */ | ||
356 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
357 | return; | ||
358 | |||
359 | /* | ||
360 | * Update statistics. | ||
361 | */ | ||
362 | rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual); | ||
363 | rt2x00dev->low_level_stats.dot11FCSErrorCount += | ||
364 | rt2x00dev->link.qual.rx_failed; | ||
365 | |||
366 | /* | ||
367 | * Only perform the link tuning when Link tuning | ||
368 | * has been enabled (This could have been disabled from the EEPROM). | ||
369 | */ | ||
370 | if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags)) | ||
371 | rt2x00dev->ops->lib->link_tuner(rt2x00dev); | ||
372 | |||
373 | /* | ||
374 | * Precalculate a portion of the link signal which is | ||
375 | * in based on the tx/rx success/failure counters. | ||
376 | */ | ||
377 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); | ||
378 | |||
379 | /* | ||
380 | * Send a signal to the led to update the led signal strength. | ||
381 | */ | ||
382 | rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi); | ||
383 | |||
384 | /* | ||
385 | * Evaluate antenna setup, make this the last step since this could | ||
386 | * possibly reset some statistics. | ||
387 | */ | ||
388 | rt2x00lib_evaluate_antenna(rt2x00dev); | ||
389 | |||
390 | /* | ||
391 | * Increase tuner counter, and reschedule the next link tuner run. | ||
392 | */ | ||
393 | rt2x00dev->link.count++; | ||
394 | queue_delayed_work(rt2x00dev->hw->workqueue, | ||
395 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | ||
396 | } | 119 | } |
397 | 120 | ||
398 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | 121 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) |
@@ -467,7 +190,9 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac, | |||
467 | struct rt2x00_intf *intf = vif_to_intf(vif); | 190 | struct rt2x00_intf *intf = vif_to_intf(vif); |
468 | 191 | ||
469 | if (vif->type != NL80211_IFTYPE_AP && | 192 | if (vif->type != NL80211_IFTYPE_AP && |
470 | vif->type != NL80211_IFTYPE_ADHOC) | 193 | vif->type != NL80211_IFTYPE_ADHOC && |
194 | vif->type != NL80211_IFTYPE_MESH_POINT && | ||
195 | vif->type != NL80211_IFTYPE_WDS) | ||
471 | return; | 196 | return; |
472 | 197 | ||
473 | /* | 198 | /* |
@@ -597,7 +322,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
597 | struct sk_buff *skb; | 322 | struct sk_buff *skb; |
598 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 323 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
599 | struct ieee80211_supported_band *sband; | 324 | struct ieee80211_supported_band *sband; |
600 | struct ieee80211_hdr *hdr; | ||
601 | const struct rt2x00_rate *rate; | 325 | const struct rt2x00_rate *rate; |
602 | unsigned int header_length; | 326 | unsigned int header_length; |
603 | unsigned int align; | 327 | unsigned int align; |
@@ -668,30 +392,22 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, | |||
668 | 392 | ||
669 | if (idx < 0) { | 393 | if (idx < 0) { |
670 | WARNING(rt2x00dev, "Frame received with unrecognized signal," | 394 | WARNING(rt2x00dev, "Frame received with unrecognized signal," |
671 | "signal=0x%.2x, plcp=%d.\n", rxdesc.signal, | 395 | "signal=0x%.2x, type=%d.\n", rxdesc.signal, |
672 | !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP)); | 396 | (rxdesc.dev_flags & RXDONE_SIGNAL_MASK)); |
673 | idx = 0; | 397 | idx = 0; |
674 | } | 398 | } |
675 | 399 | ||
676 | /* | 400 | /* |
677 | * Only update link status if this is a beacon frame carrying our bssid. | 401 | * Update extra components |
678 | */ | 402 | */ |
679 | hdr = (struct ieee80211_hdr *)entry->skb->data; | 403 | rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); |
680 | if (ieee80211_is_beacon(hdr->frame_control) && | 404 | rt2x00debug_update_crypto(rt2x00dev, &rxdesc); |
681 | (rxdesc.dev_flags & RXDONE_MY_BSS)) | ||
682 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi); | ||
683 | |||
684 | rt2x00debug_update_crypto(rt2x00dev, | ||
685 | rxdesc.cipher, | ||
686 | rxdesc.cipher_status); | ||
687 | |||
688 | rt2x00dev->link.qual.rx_success++; | ||
689 | 405 | ||
690 | rx_status->mactime = rxdesc.timestamp; | 406 | rx_status->mactime = rxdesc.timestamp; |
691 | rx_status->rate_idx = idx; | 407 | rx_status->rate_idx = idx; |
692 | rx_status->qual = | 408 | rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi); |
693 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi); | ||
694 | rx_status->signal = rxdesc.rssi; | 409 | rx_status->signal = rxdesc.rssi; |
410 | rx_status->noise = rxdesc.noise; | ||
695 | rx_status->flag = rxdesc.flags; | 411 | rx_status->flag = rxdesc.flags; |
696 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 412 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
697 | 413 | ||
@@ -1067,7 +783,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1067 | if (rt2x00dev->ops->bcn->entry_num > 0) | 783 | if (rt2x00dev->ops->bcn->entry_num > 0) |
1068 | rt2x00dev->hw->wiphy->interface_modes |= | 784 | rt2x00dev->hw->wiphy->interface_modes |= |
1069 | BIT(NL80211_IFTYPE_ADHOC) | | 785 | BIT(NL80211_IFTYPE_ADHOC) | |
1070 | BIT(NL80211_IFTYPE_AP); | 786 | BIT(NL80211_IFTYPE_AP) | |
787 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
788 | BIT(NL80211_IFTYPE_WDS); | ||
1071 | 789 | ||
1072 | /* | 790 | /* |
1073 | * Let the driver probe the device to detect the capabilities. | 791 | * Let the driver probe the device to detect the capabilities. |
@@ -1083,7 +801,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1083 | */ | 801 | */ |
1084 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 802 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1085 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 803 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1086 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | ||
1087 | 804 | ||
1088 | /* | 805 | /* |
1089 | * Allocate queue array. | 806 | * Allocate queue array. |
@@ -1104,6 +821,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1104 | /* | 821 | /* |
1105 | * Register extra components. | 822 | * Register extra components. |
1106 | */ | 823 | */ |
824 | rt2x00link_register(rt2x00dev); | ||
1107 | rt2x00leds_register(rt2x00dev); | 825 | rt2x00leds_register(rt2x00dev); |
1108 | rt2x00rfkill_allocate(rt2x00dev); | 826 | rt2x00rfkill_allocate(rt2x00dev); |
1109 | rt2x00debug_register(rt2x00dev); | 827 | rt2x00debug_register(rt2x00dev); |
@@ -1163,23 +881,17 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | |||
1163 | #ifdef CONFIG_PM | 881 | #ifdef CONFIG_PM |
1164 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | 882 | int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) |
1165 | { | 883 | { |
1166 | int retval; | ||
1167 | |||
1168 | NOTICE(rt2x00dev, "Going to sleep.\n"); | 884 | NOTICE(rt2x00dev, "Going to sleep.\n"); |
1169 | 885 | ||
1170 | /* | 886 | /* |
1171 | * Only continue if mac80211 has open interfaces. | 887 | * Prevent mac80211 from accessing driver while suspended. |
1172 | */ | 888 | */ |
1173 | if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || | 889 | if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
1174 | !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) | 890 | return 0; |
1175 | goto exit; | ||
1176 | |||
1177 | set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags); | ||
1178 | 891 | ||
1179 | /* | 892 | /* |
1180 | * Disable radio. | 893 | * Cleanup as much as possible. |
1181 | */ | 894 | */ |
1182 | rt2x00lib_stop(rt2x00dev); | ||
1183 | rt2x00lib_uninitialize(rt2x00dev); | 895 | rt2x00lib_uninitialize(rt2x00dev); |
1184 | 896 | ||
1185 | /* | 897 | /* |
@@ -1188,7 +900,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | |||
1188 | rt2x00leds_suspend(rt2x00dev); | 900 | rt2x00leds_suspend(rt2x00dev); |
1189 | rt2x00debug_deregister(rt2x00dev); | 901 | rt2x00debug_deregister(rt2x00dev); |
1190 | 902 | ||
1191 | exit: | ||
1192 | /* | 903 | /* |
1193 | * Set device mode to sleep for power management, | 904 | * Set device mode to sleep for power management, |
1194 | * on some hardware this call seems to consistently fail. | 905 | * on some hardware this call seems to consistently fail. |
@@ -1200,8 +911,7 @@ exit: | |||
1200 | * the radio and the other components already disabled the | 911 | * the radio and the other components already disabled the |
1201 | * device is as good as disabled. | 912 | * device is as good as disabled. |
1202 | */ | 913 | */ |
1203 | retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP); | 914 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP)) |
1204 | if (retval) | ||
1205 | WARNING(rt2x00dev, "Device failed to enter sleep state, " | 915 | WARNING(rt2x00dev, "Device failed to enter sleep state, " |
1206 | "continue suspending.\n"); | 916 | "continue suspending.\n"); |
1207 | 917 | ||
@@ -1209,32 +919,8 @@ exit: | |||
1209 | } | 919 | } |
1210 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | 920 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); |
1211 | 921 | ||
1212 | static void rt2x00lib_resume_intf(void *data, u8 *mac, | ||
1213 | struct ieee80211_vif *vif) | ||
1214 | { | ||
1215 | struct rt2x00_dev *rt2x00dev = data; | ||
1216 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
1217 | |||
1218 | spin_lock(&intf->lock); | ||
1219 | |||
1220 | rt2x00lib_config_intf(rt2x00dev, intf, | ||
1221 | vif->type, intf->mac, intf->bssid); | ||
1222 | |||
1223 | |||
1224 | /* | ||
1225 | * Master or Ad-hoc mode require a new beacon update. | ||
1226 | */ | ||
1227 | if (vif->type == NL80211_IFTYPE_AP || | ||
1228 | vif->type == NL80211_IFTYPE_ADHOC) | ||
1229 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | ||
1230 | |||
1231 | spin_unlock(&intf->lock); | ||
1232 | } | ||
1233 | |||
1234 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 922 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
1235 | { | 923 | { |
1236 | int retval; | ||
1237 | |||
1238 | NOTICE(rt2x00dev, "Waking up.\n"); | 924 | NOTICE(rt2x00dev, "Waking up.\n"); |
1239 | 925 | ||
1240 | /* | 926 | /* |
@@ -1244,60 +930,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1244 | rt2x00leds_resume(rt2x00dev); | 930 | rt2x00leds_resume(rt2x00dev); |
1245 | 931 | ||
1246 | /* | 932 | /* |
1247 | * Only continue if mac80211 had open interfaces. | ||
1248 | */ | ||
1249 | if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags)) | ||
1250 | return 0; | ||
1251 | |||
1252 | /* | ||
1253 | * Reinitialize device and all active interfaces. | ||
1254 | */ | ||
1255 | retval = rt2x00lib_start(rt2x00dev); | ||
1256 | if (retval) | ||
1257 | goto exit; | ||
1258 | |||
1259 | /* | ||
1260 | * Reconfigure device. | ||
1261 | */ | ||
1262 | retval = rt2x00mac_config(rt2x00dev->hw, ~0); | ||
1263 | if (retval) | ||
1264 | goto exit; | ||
1265 | |||
1266 | /* | ||
1267 | * Iterator over each active interface to | ||
1268 | * reconfigure the hardware. | ||
1269 | */ | ||
1270 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | ||
1271 | rt2x00lib_resume_intf, rt2x00dev); | ||
1272 | |||
1273 | /* | ||
1274 | * We are ready again to receive requests from mac80211. | 933 | * We are ready again to receive requests from mac80211. |
1275 | */ | 934 | */ |
1276 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); | 935 | set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); |
1277 | 936 | ||
1278 | /* | ||
1279 | * It is possible that during that mac80211 has attempted | ||
1280 | * to send frames while we were suspending or resuming. | ||
1281 | * In that case we have disabled the TX queue and should | ||
1282 | * now enable it again | ||
1283 | */ | ||
1284 | ieee80211_wake_queues(rt2x00dev->hw); | ||
1285 | |||
1286 | /* | ||
1287 | * During interface iteration we might have changed the | ||
1288 | * delayed_flags, time to handles the event by calling | ||
1289 | * the work handler directly. | ||
1290 | */ | ||
1291 | rt2x00lib_intf_scheduled(&rt2x00dev->intf_work); | ||
1292 | |||
1293 | return 0; | 937 | return 0; |
1294 | |||
1295 | exit: | ||
1296 | rt2x00lib_stop(rt2x00dev); | ||
1297 | rt2x00lib_uninitialize(rt2x00dev); | ||
1298 | rt2x00debug_deregister(rt2x00dev); | ||
1299 | |||
1300 | return retval; | ||
1301 | } | 938 | } |
1302 | EXPORT_SYMBOL_GPL(rt2x00lib_resume); | 939 | EXPORT_SYMBOL_GPL(rt2x00lib_resume); |
1303 | #endif /* CONFIG_PM */ | 940 | #endif /* CONFIG_PM */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index 7169c222a486..fdedb5122928 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index bab05a56e7a0..2a7e8bc0016b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c index a0cd35b6beb5..9b531e0ca0cd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h index 9df4a49bdcad..1046977e6a12 100644 --- a/drivers/net/wireless/rt2x00/rt2x00leds.h +++ b/drivers/net/wireless/rt2x00/rt2x00leds.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 86cd26fbf769..34efe4653549 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -33,7 +33,7 @@ | |||
33 | * Both the link tuner as the rfkill will be called once per second. | 33 | * Both the link tuner as the rfkill will be called once per second. |
34 | */ | 34 | */ |
35 | #define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) ) | 35 | #define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) ) |
36 | #define RFKILL_POLL_INTERVAL ( round_jiffies_relative(HZ) ) | 36 | #define RFKILL_POLL_INTERVAL ( 1000 ) |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * rt2x00_rate: Per rate device information | 39 | * rt2x00_rate: Per rate device information |
@@ -63,7 +63,6 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) | |||
63 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); | 63 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); |
64 | void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev); | 64 | void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev); |
65 | void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state); | 65 | void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state); |
66 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev); | ||
67 | 66 | ||
68 | /* | 67 | /* |
69 | * Initialization handlers. | 68 | * Initialization handlers. |
@@ -77,7 +76,7 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev); | |||
77 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | 76 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, |
78 | struct rt2x00_intf *intf, | 77 | struct rt2x00_intf *intf, |
79 | enum nl80211_iftype type, | 78 | enum nl80211_iftype type, |
80 | u8 *mac, u8 *bssid); | 79 | const u8 *mac, const u8 *bssid); |
81 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | 80 | void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, |
82 | struct rt2x00_intf *intf, | 81 | struct rt2x00_intf *intf, |
83 | struct ieee80211_bss_conf *conf); | 82 | struct ieee80211_bss_conf *conf); |
@@ -154,6 +153,81 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); | |||
154 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); | 153 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); |
155 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev); | 154 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev); |
156 | 155 | ||
156 | /** | ||
157 | * rt2x00link_update_stats - Update link statistics from RX frame | ||
158 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
159 | * @skb: Received frame | ||
160 | * @rxdesc: Received frame descriptor | ||
161 | * | ||
162 | * Update link statistics based on the information from the | ||
163 | * received frame descriptor. | ||
164 | */ | ||
165 | void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | ||
166 | struct sk_buff *skb, | ||
167 | struct rxdone_entry_desc *rxdesc); | ||
168 | |||
169 | /** | ||
170 | * rt2x00link_calculate_signal - Calculate signal quality | ||
171 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
172 | * @rssi: RX Frame RSSI | ||
173 | * | ||
174 | * Calculate the signal quality of a frame based on the rssi | ||
175 | * measured during the receiving of the frame and the global | ||
176 | * link quality statistics measured since the start of the | ||
177 | * link tuning. The result is a value between 0 and 100 which | ||
178 | * is an indication of the signal quality. | ||
179 | */ | ||
180 | int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi); | ||
181 | |||
182 | /** | ||
183 | * rt2x00link_start_tuner - Start periodic link tuner work | ||
184 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
185 | * | ||
186 | * This start the link tuner periodic work, this work will | ||
187 | * be executed periodically until &rt2x00link_stop_tuner has | ||
188 | * been called. | ||
189 | */ | ||
190 | void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev); | ||
191 | |||
192 | /** | ||
193 | * rt2x00link_stop_tuner - Stop periodic link tuner work | ||
194 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
195 | * | ||
196 | * After this function completed the link tuner will not | ||
197 | * be running until &rt2x00link_start_tuner is called. | ||
198 | */ | ||
199 | void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev); | ||
200 | |||
201 | /** | ||
202 | * rt2x00link_reset_tuner - Reset periodic link tuner work | ||
203 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
204 | * @antenna: Should the antenna tuning also be reset | ||
205 | * | ||
206 | * The VGC limit configured in the hardware will be reset to 0 | ||
207 | * which forces the driver to rediscover the correct value for | ||
208 | * the current association. This is needed when configuration | ||
209 | * options have changed which could drastically change the | ||
210 | * SNR level or link quality (i.e. changing the antenna setting). | ||
211 | * | ||
212 | * Resetting the link tuner will also cause the periodic work counter | ||
213 | * to be reset. Any driver which has a fixed limit on the number | ||
214 | * of rounds the link tuner is supposed to work will accept the | ||
215 | * tuner actions again if this limit was previously reached. | ||
216 | * | ||
217 | * If @antenna is set to true a the software antenna diversity | ||
218 | * tuning will also be reset. | ||
219 | */ | ||
220 | void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna); | ||
221 | |||
222 | /** | ||
223 | * rt2x00link_register - Initialize link tuning functionality | ||
224 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
225 | * | ||
226 | * Initialize work structure and all link tuning related | ||
227 | * paramters. This will not start the link tuning process itself. | ||
228 | */ | ||
229 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev); | ||
230 | |||
157 | /* | 231 | /* |
158 | * Firmware handlers. | 232 | * Firmware handlers. |
159 | */ | 233 | */ |
@@ -179,7 +253,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); | |||
179 | void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | 253 | void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, |
180 | enum rt2x00_dump_type type, struct sk_buff *skb); | 254 | enum rt2x00_dump_type type, struct sk_buff *skb); |
181 | void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | 255 | void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, |
182 | enum cipher cipher, enum rx_crypto status); | 256 | struct rxdone_entry_desc *rxdesc); |
183 | #else | 257 | #else |
184 | static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | 258 | static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) |
185 | { | 259 | { |
@@ -196,8 +270,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
196 | } | 270 | } |
197 | 271 | ||
198 | static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | 272 | static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, |
199 | enum cipher cipher, | 273 | struct rxdone_entry_desc *rxdesc) |
200 | enum rx_crypto status) | ||
201 | { | 274 | { |
202 | } | 275 | } |
203 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 276 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
@@ -209,7 +282,8 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | |||
209 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); | 282 | enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key); |
210 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | 283 | void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, |
211 | struct txentry_desc *txdesc); | 284 | struct txentry_desc *txdesc); |
212 | unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info); | 285 | unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, |
286 | struct sk_buff *skb); | ||
213 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); | 287 | void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len); |
214 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); | 288 | void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len); |
215 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); | 289 | void rt2x00crypto_tx_insert_iv(struct sk_buff *skb); |
@@ -227,7 +301,8 @@ static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, | |||
227 | { | 301 | { |
228 | } | 302 | } |
229 | 303 | ||
230 | static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info) | 304 | static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, |
305 | struct sk_buff *skb) | ||
231 | { | 306 | { |
232 | return 0; | 307 | return 0; |
233 | } | 308 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c new file mode 100644 index 000000000000..9223a6d1f1d0 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00link.c | |||
@@ -0,0 +1,461 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 generic link tuning routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | /* | ||
33 | * When we lack RSSI information return something less then -80 to | ||
34 | * tell the driver to tune the device to maximum sensitivity. | ||
35 | */ | ||
36 | #define DEFAULT_RSSI -128 | ||
37 | |||
38 | /* | ||
39 | * When no TX/RX percentage could be calculated due to lack of | ||
40 | * frames on the air, we fallback to a percentage of 50%. | ||
41 | * This will assure we will get at least get some decent value | ||
42 | * when the link tuner starts. | ||
43 | * The value will be dropped and overwritten with the correct (measured) | ||
44 | * value anyway during the first run of the link tuner. | ||
45 | */ | ||
46 | #define DEFAULT_PERCENTAGE 50 | ||
47 | |||
48 | /* | ||
49 | * Small helper macro to work with moving/walking averages. | ||
50 | * When adding a value to the average value the following calculation | ||
51 | * is needed: | ||
52 | * | ||
53 | * avg_rssi = ((avg_rssi * 7) + rssi) / 8; | ||
54 | * | ||
55 | * The advantage of this approach is that we only need 1 variable | ||
56 | * to store the average in (No need for a count and a total). | ||
57 | * But more importantly, normal average values will over time | ||
58 | * move less and less towards newly added values this results | ||
59 | * that with link tuning, the device can have a very good RSSI | ||
60 | * for a few minutes but when the device is moved away from the AP | ||
61 | * the average will not decrease fast enough to compensate. | ||
62 | * The walking average compensates this and will move towards | ||
63 | * the new values correctly allowing a effective link tuning. | ||
64 | */ | ||
65 | #define MOVING_AVERAGE(__avg, __val, __samples) \ | ||
66 | ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) ) | ||
67 | |||
68 | /* | ||
69 | * Small helper macro for percentage calculation | ||
70 | * This is a very simple macro with the only catch that it will | ||
71 | * produce a default value in case no total value was provided. | ||
72 | */ | ||
73 | #define PERCENTAGE(__value, __total) \ | ||
74 | ( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) ) | ||
75 | |||
76 | /* | ||
77 | * For calculating the Signal quality we have determined | ||
78 | * the total number of success and failed RX and TX frames. | ||
79 | * With the addition of the average RSSI value we can determine | ||
80 | * the link quality using the following algorithm: | ||
81 | * | ||
82 | * rssi_percentage = (avg_rssi * 100) / rssi_offset | ||
83 | * rx_percentage = (rx_success * 100) / rx_total | ||
84 | * tx_percentage = (tx_success * 100) / tx_total | ||
85 | * avg_signal = ((WEIGHT_RSSI * avg_rssi) + | ||
86 | * (WEIGHT_TX * tx_percentage) + | ||
87 | * (WEIGHT_RX * rx_percentage)) / 100 | ||
88 | * | ||
89 | * This value should then be checked to not be greater then 100. | ||
90 | * This means the values of WEIGHT_RSSI, WEIGHT_RX, WEIGHT_TX must | ||
91 | * sum up to 100 as well. | ||
92 | */ | ||
93 | #define WEIGHT_RSSI 20 | ||
94 | #define WEIGHT_RX 40 | ||
95 | #define WEIGHT_TX 40 | ||
96 | |||
97 | static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev) | ||
98 | { | ||
99 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
100 | |||
101 | if (ant->rssi_ant && rt2x00dev->link.qual.rx_success) | ||
102 | return ant->rssi_ant; | ||
103 | return DEFAULT_RSSI; | ||
104 | } | ||
105 | |||
106 | static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev, | ||
107 | enum antenna antenna) | ||
108 | { | ||
109 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
110 | |||
111 | if (ant->rssi_history[antenna - ANTENNA_A]) | ||
112 | return ant->rssi_history[antenna - ANTENNA_A]; | ||
113 | return DEFAULT_RSSI; | ||
114 | } | ||
115 | /* Small wrapper for rt2x00link_antenna_get_rssi_history() */ | ||
116 | #define rt2x00link_antenna_get_rssi_rx_history(__dev) \ | ||
117 | rt2x00link_antenna_get_rssi_history((__dev), \ | ||
118 | (__dev)->link.ant.active.rx) | ||
119 | #define rt2x00link_antenna_get_rssi_tx_history(__dev) \ | ||
120 | rt2x00link_antenna_get_rssi_history((__dev), \ | ||
121 | (__dev)->link.ant.active.tx) | ||
122 | |||
123 | static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev, | ||
124 | enum antenna antenna, | ||
125 | int rssi) | ||
126 | { | ||
127 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
128 | ant->rssi_history[ant->active.rx - ANTENNA_A] = rssi; | ||
129 | } | ||
130 | /* Small wrapper for rt2x00link_antenna_get_rssi_history() */ | ||
131 | #define rt2x00link_antenna_update_rssi_rx_history(__dev, __rssi) \ | ||
132 | rt2x00link_antenna_update_rssi_history((__dev), \ | ||
133 | (__dev)->link.ant.active.rx, \ | ||
134 | (__rssi)) | ||
135 | #define rt2x00link_antenna_update_rssi_tx_history(__dev, __rssi) \ | ||
136 | rt2x00link_antenna_update_rssi_history((__dev), \ | ||
137 | (__dev)->link.ant.active.tx, \ | ||
138 | (__rssi)) | ||
139 | |||
140 | static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev) | ||
141 | { | ||
142 | rt2x00dev->link.ant.rssi_ant = 0; | ||
143 | } | ||
144 | |||
145 | static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev) | ||
146 | { | ||
147 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
148 | struct antenna_setup new_ant; | ||
149 | int sample_a = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_A); | ||
150 | int sample_b = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_B); | ||
151 | |||
152 | memcpy(&new_ant, &ant->active, sizeof(new_ant)); | ||
153 | |||
154 | /* | ||
155 | * We are done sampling. Now we should evaluate the results. | ||
156 | */ | ||
157 | ant->flags &= ~ANTENNA_MODE_SAMPLE; | ||
158 | |||
159 | /* | ||
160 | * During the last period we have sampled the RSSI | ||
161 | * from both antenna's. It now is time to determine | ||
162 | * which antenna demonstrated the best performance. | ||
163 | * When we are already on the antenna with the best | ||
164 | * performance, then there really is nothing for us | ||
165 | * left to do. | ||
166 | */ | ||
167 | if (sample_a == sample_b) | ||
168 | return; | ||
169 | |||
170 | if (ant->flags & ANTENNA_RX_DIVERSITY) | ||
171 | new_ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; | ||
172 | |||
173 | if (ant->flags & ANTENNA_TX_DIVERSITY) | ||
174 | new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; | ||
175 | |||
176 | rt2x00lib_config_antenna(rt2x00dev, &new_ant); | ||
177 | } | ||
178 | |||
179 | static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev) | ||
180 | { | ||
181 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
182 | struct antenna_setup new_ant; | ||
183 | int rssi_curr; | ||
184 | int rssi_old; | ||
185 | |||
186 | memcpy(&new_ant, &ant->active, sizeof(new_ant)); | ||
187 | |||
188 | /* | ||
189 | * Get current RSSI value along with the historical value, | ||
190 | * after that update the history with the current value. | ||
191 | */ | ||
192 | rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev); | ||
193 | rssi_old = rt2x00link_antenna_get_rssi_rx_history(rt2x00dev); | ||
194 | rt2x00link_antenna_update_rssi_rx_history(rt2x00dev, rssi_curr); | ||
195 | |||
196 | /* | ||
197 | * Legacy driver indicates that we should swap antenna's | ||
198 | * when the difference in RSSI is greater that 5. This | ||
199 | * also should be done when the RSSI was actually better | ||
200 | * then the previous sample. | ||
201 | * When the difference exceeds the threshold we should | ||
202 | * sample the rssi from the other antenna to make a valid | ||
203 | * comparison between the 2 antennas. | ||
204 | */ | ||
205 | if (abs(rssi_curr - rssi_old) < 5) | ||
206 | return; | ||
207 | |||
208 | ant->flags |= ANTENNA_MODE_SAMPLE; | ||
209 | |||
210 | if (ant->flags & ANTENNA_RX_DIVERSITY) | ||
211 | new_ant.rx = (new_ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; | ||
212 | |||
213 | if (ant->flags & ANTENNA_TX_DIVERSITY) | ||
214 | new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; | ||
215 | |||
216 | rt2x00lib_config_antenna(rt2x00dev, &new_ant); | ||
217 | } | ||
218 | |||
219 | static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) | ||
220 | { | ||
221 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
222 | |||
223 | /* | ||
224 | * Determine if software diversity is enabled for | ||
225 | * either the TX or RX antenna (or both). | ||
226 | * Always perform this check since within the link | ||
227 | * tuner interval the configuration might have changed. | ||
228 | */ | ||
229 | ant->flags &= ~ANTENNA_RX_DIVERSITY; | ||
230 | ant->flags &= ~ANTENNA_TX_DIVERSITY; | ||
231 | |||
232 | if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) | ||
233 | ant->flags |= ANTENNA_RX_DIVERSITY; | ||
234 | if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) | ||
235 | ant->flags |= ANTENNA_TX_DIVERSITY; | ||
236 | |||
237 | if (!(ant->flags & ANTENNA_RX_DIVERSITY) && | ||
238 | !(ant->flags & ANTENNA_TX_DIVERSITY)) { | ||
239 | ant->flags = 0; | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * If we have only sampled the data over the last period | ||
245 | * we should now harvest the data. Otherwise just evaluate | ||
246 | * the data. The latter should only be performed once | ||
247 | * every 2 seconds. | ||
248 | */ | ||
249 | if (ant->flags & ANTENNA_MODE_SAMPLE) | ||
250 | rt2x00lib_antenna_diversity_sample(rt2x00dev); | ||
251 | else if (rt2x00dev->link.count & 1) | ||
252 | rt2x00lib_antenna_diversity_eval(rt2x00dev); | ||
253 | } | ||
254 | |||
255 | void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | ||
256 | struct sk_buff *skb, | ||
257 | struct rxdone_entry_desc *rxdesc) | ||
258 | { | ||
259 | struct link *link = &rt2x00dev->link; | ||
260 | struct link_qual *qual = &rt2x00dev->link.qual; | ||
261 | struct link_ant *ant = &rt2x00dev->link.ant; | ||
262 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
263 | int avg_rssi = rxdesc->rssi; | ||
264 | int ant_rssi = rxdesc->rssi; | ||
265 | |||
266 | /* | ||
267 | * Frame was received successfully since non-succesfull | ||
268 | * frames would have been dropped by the hardware. | ||
269 | */ | ||
270 | qual->rx_success++; | ||
271 | |||
272 | /* | ||
273 | * We are only interested in quality statistics from | ||
274 | * beacons which came from the BSS which we are | ||
275 | * associated with. | ||
276 | */ | ||
277 | if (!ieee80211_is_beacon(hdr->frame_control) || | ||
278 | !(rxdesc->dev_flags & RXDONE_MY_BSS)) | ||
279 | return; | ||
280 | |||
281 | /* | ||
282 | * Update global RSSI | ||
283 | */ | ||
284 | if (link->avg_rssi) | ||
285 | avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi, 8); | ||
286 | link->avg_rssi = avg_rssi; | ||
287 | |||
288 | /* | ||
289 | * Update antenna RSSI | ||
290 | */ | ||
291 | if (ant->rssi_ant) | ||
292 | ant_rssi = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi, 8); | ||
293 | ant->rssi_ant = ant_rssi; | ||
294 | } | ||
295 | |||
296 | static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev) | ||
297 | { | ||
298 | struct link *link = &rt2x00dev->link; | ||
299 | struct link_qual *qual = &rt2x00dev->link.qual; | ||
300 | |||
301 | link->rx_percentage = | ||
302 | PERCENTAGE(qual->rx_success, qual->rx_failed + qual->rx_success); | ||
303 | link->tx_percentage = | ||
304 | PERCENTAGE(qual->tx_success, qual->tx_failed + qual->tx_success); | ||
305 | |||
306 | qual->rx_success = 0; | ||
307 | qual->rx_failed = 0; | ||
308 | qual->tx_success = 0; | ||
309 | qual->tx_failed = 0; | ||
310 | } | ||
311 | |||
312 | int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi) | ||
313 | { | ||
314 | struct link *link = &rt2x00dev->link; | ||
315 | int rssi_percentage = 0; | ||
316 | int signal; | ||
317 | |||
318 | /* | ||
319 | * We need a positive value for the RSSI. | ||
320 | */ | ||
321 | if (rssi < 0) | ||
322 | rssi += rt2x00dev->rssi_offset; | ||
323 | |||
324 | /* | ||
325 | * Calculate the different percentages, | ||
326 | * which will be used for the signal. | ||
327 | */ | ||
328 | rssi_percentage = PERCENTAGE(rssi, rt2x00dev->rssi_offset); | ||
329 | |||
330 | /* | ||
331 | * Add the individual percentages and use the WEIGHT | ||
332 | * defines to calculate the current link signal. | ||
333 | */ | ||
334 | signal = ((WEIGHT_RSSI * rssi_percentage) + | ||
335 | (WEIGHT_TX * link->tx_percentage) + | ||
336 | (WEIGHT_RX * link->rx_percentage)) / 100; | ||
337 | |||
338 | return max_t(int, signal, 100); | ||
339 | } | ||
340 | |||
341 | void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) | ||
342 | { | ||
343 | struct link *link = &rt2x00dev->link; | ||
344 | |||
345 | /* | ||
346 | * Link tuning should only be performed when | ||
347 | * an active sta or master interface exists. | ||
348 | * Single monitor mode interfaces should never have | ||
349 | * work with link tuners. | ||
350 | */ | ||
351 | if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) | ||
352 | return; | ||
353 | |||
354 | link->rx_percentage = DEFAULT_PERCENTAGE; | ||
355 | link->tx_percentage = DEFAULT_PERCENTAGE; | ||
356 | |||
357 | rt2x00link_reset_tuner(rt2x00dev, false); | ||
358 | |||
359 | queue_delayed_work(rt2x00dev->hw->workqueue, | ||
360 | &link->work, LINK_TUNE_INTERVAL); | ||
361 | } | ||
362 | |||
363 | void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) | ||
364 | { | ||
365 | cancel_delayed_work_sync(&rt2x00dev->link.work); | ||
366 | } | ||
367 | |||
368 | void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) | ||
369 | { | ||
370 | struct link_qual *qual = &rt2x00dev->link.qual; | ||
371 | |||
372 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
373 | return; | ||
374 | |||
375 | /* | ||
376 | * Reset link information. | ||
377 | * Both the currently active vgc level as well as | ||
378 | * the link tuner counter should be reset. Resetting | ||
379 | * the counter is important for devices where the | ||
380 | * device should only perform link tuning during the | ||
381 | * first minute after being enabled. | ||
382 | */ | ||
383 | rt2x00dev->link.count = 0; | ||
384 | memset(qual, 0, sizeof(*qual)); | ||
385 | |||
386 | /* | ||
387 | * Reset the link tuner. | ||
388 | */ | ||
389 | rt2x00dev->ops->lib->reset_tuner(rt2x00dev, qual); | ||
390 | |||
391 | if (antenna) | ||
392 | rt2x00link_antenna_reset(rt2x00dev); | ||
393 | } | ||
394 | |||
395 | static void rt2x00link_tuner(struct work_struct *work) | ||
396 | { | ||
397 | struct rt2x00_dev *rt2x00dev = | ||
398 | container_of(work, struct rt2x00_dev, link.work.work); | ||
399 | struct link *link = &rt2x00dev->link; | ||
400 | struct link_qual *qual = &rt2x00dev->link.qual; | ||
401 | |||
402 | /* | ||
403 | * When the radio is shutting down we should | ||
404 | * immediately cease all link tuning. | ||
405 | */ | ||
406 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
407 | return; | ||
408 | |||
409 | /* | ||
410 | * Update statistics. | ||
411 | */ | ||
412 | rt2x00dev->ops->lib->link_stats(rt2x00dev, qual); | ||
413 | rt2x00dev->low_level_stats.dot11FCSErrorCount += qual->rx_failed; | ||
414 | |||
415 | /* | ||
416 | * Update quality RSSI for link tuning, | ||
417 | * when we have received some frames and we managed to | ||
418 | * collect the RSSI data we could use this. Otherwise we | ||
419 | * must fallback to the default RSSI value. | ||
420 | */ | ||
421 | if (!link->avg_rssi || !qual->rx_success) | ||
422 | qual->rssi = DEFAULT_RSSI; | ||
423 | else | ||
424 | qual->rssi = link->avg_rssi; | ||
425 | |||
426 | /* | ||
427 | * Only perform the link tuning when Link tuning | ||
428 | * has been enabled (This could have been disabled from the EEPROM). | ||
429 | */ | ||
430 | if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags)) | ||
431 | rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); | ||
432 | |||
433 | /* | ||
434 | * Precalculate a portion of the link signal which is | ||
435 | * in based on the tx/rx success/failure counters. | ||
436 | */ | ||
437 | rt2x00link_precalculate_signal(rt2x00dev); | ||
438 | |||
439 | /* | ||
440 | * Send a signal to the led to update the led signal strength. | ||
441 | */ | ||
442 | rt2x00leds_led_quality(rt2x00dev, link->avg_rssi); | ||
443 | |||
444 | /* | ||
445 | * Evaluate antenna setup, make this the last step since this could | ||
446 | * possibly reset some statistics. | ||
447 | */ | ||
448 | rt2x00lib_antenna_diversity(rt2x00dev); | ||
449 | |||
450 | /* | ||
451 | * Increase tuner counter, and reschedule the next link tuner run. | ||
452 | */ | ||
453 | link->count++; | ||
454 | queue_delayed_work(rt2x00dev->hw->workqueue, | ||
455 | &link->work, LINK_TUNE_INTERVAL); | ||
456 | } | ||
457 | |||
458 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) | ||
459 | { | ||
460 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); | ||
461 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 38edee5fe168..71de8a7144f9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -79,8 +79,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
79 | * RTS/CTS frame should use the length of the frame plus any | 79 | * RTS/CTS frame should use the length of the frame plus any |
80 | * encryption overhead that will be added by the hardware. | 80 | * encryption overhead that will be added by the hardware. |
81 | */ | 81 | */ |
82 | if (!frag_skb->do_not_encrypt) | 82 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb); |
83 | data_length += rt2x00crypto_tx_overhead(tx_info); | ||
84 | 83 | ||
85 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 84 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
86 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, | 85 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, |
@@ -226,6 +225,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
226 | break; | 225 | break; |
227 | case NL80211_IFTYPE_STATION: | 226 | case NL80211_IFTYPE_STATION: |
228 | case NL80211_IFTYPE_ADHOC: | 227 | case NL80211_IFTYPE_ADHOC: |
228 | case NL80211_IFTYPE_MESH_POINT: | ||
229 | case NL80211_IFTYPE_WDS: | ||
229 | /* | 230 | /* |
230 | * We don't support mixed combinations of | 231 | * We don't support mixed combinations of |
231 | * sta and ap interfaces. | 232 | * sta and ap interfaces. |
@@ -482,16 +483,36 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
482 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 483 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
483 | 484 | ||
484 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 485 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
486 | static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len) | ||
487 | { | ||
488 | if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) | ||
489 | memcpy(&crypto->key, | ||
490 | &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY], | ||
491 | sizeof(crypto->key)); | ||
492 | |||
493 | if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) | ||
494 | memcpy(&crypto->tx_mic, | ||
495 | &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
496 | sizeof(crypto->tx_mic)); | ||
497 | |||
498 | if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY) | ||
499 | memcpy(&crypto->rx_mic, | ||
500 | &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
501 | sizeof(crypto->rx_mic)); | ||
502 | } | ||
503 | |||
485 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 504 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
486 | const u8 *local_address, const u8 *address, | 505 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
487 | struct ieee80211_key_conf *key) | 506 | struct ieee80211_key_conf *key) |
488 | { | 507 | { |
489 | struct rt2x00_dev *rt2x00dev = hw->priv; | 508 | struct rt2x00_dev *rt2x00dev = hw->priv; |
490 | struct ieee80211_sta *sta; | 509 | struct rt2x00_intf *intf = vif_to_intf(vif); |
491 | int (*set_key) (struct rt2x00_dev *rt2x00dev, | 510 | int (*set_key) (struct rt2x00_dev *rt2x00dev, |
492 | struct rt2x00lib_crypto *crypto, | 511 | struct rt2x00lib_crypto *crypto, |
493 | struct ieee80211_key_conf *key); | 512 | struct ieee80211_key_conf *key); |
494 | struct rt2x00lib_crypto crypto; | 513 | struct rt2x00lib_crypto crypto; |
514 | static const u8 bcast_addr[ETH_ALEN] = | ||
515 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; | ||
495 | 516 | ||
496 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | 517 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
497 | return 0; | 518 | return 0; |
@@ -509,45 +530,25 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
509 | if (rt2x00dev->intf_sta_count) | 530 | if (rt2x00dev->intf_sta_count) |
510 | crypto.bssidx = 0; | 531 | crypto.bssidx = 0; |
511 | else | 532 | else |
512 | crypto.bssidx = | 533 | crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1); |
513 | local_address[5] & (rt2x00dev->ops->max_ap_intf - 1); | ||
514 | 534 | ||
515 | crypto.cipher = rt2x00crypto_key_to_cipher(key); | 535 | crypto.cipher = rt2x00crypto_key_to_cipher(key); |
516 | if (crypto.cipher == CIPHER_NONE) | 536 | if (crypto.cipher == CIPHER_NONE) |
517 | return -EOPNOTSUPP; | 537 | return -EOPNOTSUPP; |
518 | 538 | ||
519 | crypto.cmd = cmd; | 539 | crypto.cmd = cmd; |
520 | crypto.address = address; | ||
521 | |||
522 | if (crypto.cipher == CIPHER_TKIP) { | ||
523 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY) | ||
524 | memcpy(&crypto.key, | ||
525 | &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY], | ||
526 | sizeof(crypto.key)); | ||
527 | |||
528 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) | ||
529 | memcpy(&crypto.tx_mic, | ||
530 | &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], | ||
531 | sizeof(crypto.tx_mic)); | ||
532 | |||
533 | if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY) | ||
534 | memcpy(&crypto.rx_mic, | ||
535 | &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], | ||
536 | sizeof(crypto.rx_mic)); | ||
537 | } else | ||
538 | memcpy(&crypto.key, &key->key[0], key->keylen); | ||
539 | 540 | ||
540 | /* | 541 | if (sta) { |
541 | * Discover the Association ID from mac80211. | 542 | /* some drivers need the AID */ |
542 | * Some drivers need this information when updating the | ||
543 | * hardware key (either adding or removing). | ||
544 | */ | ||
545 | rcu_read_lock(); | ||
546 | sta = ieee80211_find_sta(hw, address); | ||
547 | if (sta) | ||
548 | crypto.aid = sta->aid; | 543 | crypto.aid = sta->aid; |
549 | rcu_read_unlock(); | 544 | crypto.address = sta->addr; |
545 | } else | ||
546 | crypto.address = bcast_addr; | ||
550 | 547 | ||
548 | if (crypto.cipher == CIPHER_TKIP) | ||
549 | memcpy_tkip(&crypto, &key->key[0], key->keylen); | ||
550 | else | ||
551 | memcpy(&crypto.key, &key->key[0], key->keylen); | ||
551 | /* | 552 | /* |
552 | * Each BSS has a maximum of 4 shared keys. | 553 | * Each BSS has a maximum of 4 shared keys. |
553 | * Shared key index values: | 554 | * Shared key index values: |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index d52b22b82d1f..e616c20d4a78 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 9c0a4d77bc1b..15a12487e04b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 0709decec9c2..c86fb6471754 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -148,20 +148,105 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
148 | dev_kfree_skb_any(skb); | 148 | dev_kfree_skb_any(skb); |
149 | } | 149 | } |
150 | 150 | ||
151 | static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | ||
152 | struct txentry_desc *txdesc) | ||
153 | { | ||
154 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
155 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
156 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | ||
157 | unsigned long irqflags; | ||
158 | |||
159 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) || | ||
160 | unlikely(!tx_info->control.vif)) | ||
161 | return; | ||
162 | |||
163 | /* | ||
164 | * Hardware should insert sequence counter. | ||
165 | * FIXME: We insert a software sequence counter first for | ||
166 | * hardware that doesn't support hardware sequence counting. | ||
167 | * | ||
168 | * This is wrong because beacons are not getting sequence | ||
169 | * numbers assigned properly. | ||
170 | * | ||
171 | * A secondary problem exists for drivers that cannot toggle | ||
172 | * sequence counting per-frame, since those will override the | ||
173 | * sequence counter given by mac80211. | ||
174 | */ | ||
175 | spin_lock_irqsave(&intf->seqlock, irqflags); | ||
176 | |||
177 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) | ||
178 | intf->seqno += 0x10; | ||
179 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
180 | hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
181 | |||
182 | spin_unlock_irqrestore(&intf->seqlock, irqflags); | ||
183 | |||
184 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | ||
185 | } | ||
186 | |||
187 | static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry, | ||
188 | struct txentry_desc *txdesc, | ||
189 | const struct rt2x00_rate *hwrate) | ||
190 | { | ||
191 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
192 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | ||
193 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | ||
194 | unsigned int data_length; | ||
195 | unsigned int duration; | ||
196 | unsigned int residual; | ||
197 | |||
198 | /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */ | ||
199 | data_length = entry->skb->len + 4; | ||
200 | data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb); | ||
201 | |||
202 | /* | ||
203 | * PLCP setup | ||
204 | * Length calculation depends on OFDM/CCK rate. | ||
205 | */ | ||
206 | txdesc->signal = hwrate->plcp; | ||
207 | txdesc->service = 0x04; | ||
208 | |||
209 | if (hwrate->flags & DEV_RATE_OFDM) { | ||
210 | txdesc->length_high = (data_length >> 6) & 0x3f; | ||
211 | txdesc->length_low = data_length & 0x3f; | ||
212 | } else { | ||
213 | /* | ||
214 | * Convert length to microseconds. | ||
215 | */ | ||
216 | residual = GET_DURATION_RES(data_length, hwrate->bitrate); | ||
217 | duration = GET_DURATION(data_length, hwrate->bitrate); | ||
218 | |||
219 | if (residual != 0) { | ||
220 | duration++; | ||
221 | |||
222 | /* | ||
223 | * Check if we need to set the Length Extension | ||
224 | */ | ||
225 | if (hwrate->bitrate == 110 && residual <= 30) | ||
226 | txdesc->service |= 0x80; | ||
227 | } | ||
228 | |||
229 | txdesc->length_high = (duration >> 8) & 0xff; | ||
230 | txdesc->length_low = duration & 0xff; | ||
231 | |||
232 | /* | ||
233 | * When preamble is enabled we should set the | ||
234 | * preamble bit for the signal. | ||
235 | */ | ||
236 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
237 | txdesc->signal |= 0x08; | ||
238 | } | ||
239 | } | ||
240 | |||
151 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 241 | static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
152 | struct txentry_desc *txdesc) | 242 | struct txentry_desc *txdesc) |
153 | { | 243 | { |
154 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 244 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
155 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 245 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
156 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 246 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; |
157 | struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; | ||
158 | struct ieee80211_rate *rate = | 247 | struct ieee80211_rate *rate = |
159 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); | 248 | ieee80211_get_tx_rate(rt2x00dev->hw, tx_info); |
160 | const struct rt2x00_rate *hwrate; | 249 | const struct rt2x00_rate *hwrate; |
161 | unsigned int data_length; | ||
162 | unsigned int duration; | ||
163 | unsigned int residual; | ||
164 | unsigned long irqflags; | ||
165 | 250 | ||
166 | memset(txdesc, 0, sizeof(*txdesc)); | 251 | memset(txdesc, 0, sizeof(*txdesc)); |
167 | 252 | ||
@@ -173,27 +258,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
173 | txdesc->cw_max = entry->queue->cw_max; | 258 | txdesc->cw_max = entry->queue->cw_max; |
174 | txdesc->aifs = entry->queue->aifs; | 259 | txdesc->aifs = entry->queue->aifs; |
175 | 260 | ||
176 | /* Data length + CRC */ | ||
177 | data_length = entry->skb->len + 4; | ||
178 | |||
179 | /* | 261 | /* |
180 | * Check whether this frame is to be acked. | 262 | * Check whether this frame is to be acked. |
181 | */ | 263 | */ |
182 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) | 264 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) |
183 | __set_bit(ENTRY_TXD_ACK, &txdesc->flags); | 265 | __set_bit(ENTRY_TXD_ACK, &txdesc->flags); |
184 | 266 | ||
185 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) && | ||
186 | !entry->skb->do_not_encrypt) { | ||
187 | /* Apply crypto specific descriptor information */ | ||
188 | rt2x00crypto_create_tx_descriptor(entry, txdesc); | ||
189 | |||
190 | /* | ||
191 | * Extend frame length to include all encryption overhead | ||
192 | * that will be added by the hardware. | ||
193 | */ | ||
194 | data_length += rt2x00crypto_tx_overhead(tx_info); | ||
195 | } | ||
196 | |||
197 | /* | 267 | /* |
198 | * Check if this is a RTS/CTS frame | 268 | * Check if this is a RTS/CTS frame |
199 | */ | 269 | */ |
@@ -237,86 +307,27 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
237 | * Set ifs to IFS_SIFS when the this is not the first fragment, | 307 | * Set ifs to IFS_SIFS when the this is not the first fragment, |
238 | * or this fragment came after RTS/CTS. | 308 | * or this fragment came after RTS/CTS. |
239 | */ | 309 | */ |
240 | if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { | 310 | if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) && |
241 | txdesc->ifs = IFS_SIFS; | 311 | !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) { |
242 | } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { | ||
243 | __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); | 312 | __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags); |
244 | txdesc->ifs = IFS_BACKOFF; | 313 | txdesc->ifs = IFS_BACKOFF; |
245 | } else { | 314 | } else |
246 | txdesc->ifs = IFS_SIFS; | 315 | txdesc->ifs = IFS_SIFS; |
247 | } | ||
248 | 316 | ||
249 | /* | 317 | /* |
250 | * Hardware should insert sequence counter. | 318 | * Determine rate modulation. |
251 | * FIXME: We insert a software sequence counter first for | ||
252 | * hardware that doesn't support hardware sequence counting. | ||
253 | * | ||
254 | * This is wrong because beacons are not getting sequence | ||
255 | * numbers assigned properly. | ||
256 | * | ||
257 | * A secondary problem exists for drivers that cannot toggle | ||
258 | * sequence counting per-frame, since those will override the | ||
259 | * sequence counter given by mac80211. | ||
260 | */ | 319 | */ |
261 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 320 | hwrate = rt2x00_get_rate(rate->hw_value); |
262 | if (likely(tx_info->control.vif)) { | 321 | txdesc->rate_mode = RATE_MODE_CCK; |
263 | struct rt2x00_intf *intf; | 322 | if (hwrate->flags & DEV_RATE_OFDM) |
264 | 323 | txdesc->rate_mode = RATE_MODE_OFDM; | |
265 | intf = vif_to_intf(tx_info->control.vif); | ||
266 | |||
267 | spin_lock_irqsave(&intf->seqlock, irqflags); | ||
268 | |||
269 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) | ||
270 | intf->seqno += 0x10; | ||
271 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
272 | hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | ||
273 | |||
274 | spin_unlock_irqrestore(&intf->seqlock, irqflags); | ||
275 | |||
276 | __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); | ||
277 | } | ||
278 | } | ||
279 | 324 | ||
280 | /* | 325 | /* |
281 | * PLCP setup | 326 | * Apply TX descriptor handling by components |
282 | * Length calculation depends on OFDM/CCK rate. | ||
283 | */ | 327 | */ |
284 | hwrate = rt2x00_get_rate(rate->hw_value); | 328 | rt2x00crypto_create_tx_descriptor(entry, txdesc); |
285 | txdesc->signal = hwrate->plcp; | 329 | rt2x00queue_create_tx_descriptor_seq(entry, txdesc); |
286 | txdesc->service = 0x04; | 330 | rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate); |
287 | |||
288 | if (hwrate->flags & DEV_RATE_OFDM) { | ||
289 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags); | ||
290 | |||
291 | txdesc->length_high = (data_length >> 6) & 0x3f; | ||
292 | txdesc->length_low = data_length & 0x3f; | ||
293 | } else { | ||
294 | /* | ||
295 | * Convert length to microseconds. | ||
296 | */ | ||
297 | residual = GET_DURATION_RES(data_length, hwrate->bitrate); | ||
298 | duration = GET_DURATION(data_length, hwrate->bitrate); | ||
299 | |||
300 | if (residual != 0) { | ||
301 | duration++; | ||
302 | |||
303 | /* | ||
304 | * Check if we need to set the Length Extension | ||
305 | */ | ||
306 | if (hwrate->bitrate == 110 && residual <= 30) | ||
307 | txdesc->service |= 0x80; | ||
308 | } | ||
309 | |||
310 | txdesc->length_high = (duration >> 8) & 0xff; | ||
311 | txdesc->length_low = duration & 0xff; | ||
312 | |||
313 | /* | ||
314 | * When preamble is enabled we should set the | ||
315 | * preamble bit for the signal. | ||
316 | */ | ||
317 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
318 | txdesc->signal |= 0x08; | ||
319 | } | ||
320 | } | 331 | } |
321 | 332 | ||
322 | static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | 333 | static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, |
@@ -403,7 +414,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
403 | */ | 414 | */ |
404 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && | 415 | if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && |
405 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { | 416 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { |
406 | if (test_bit(CONFIG_CRYPTO_COPY_IV, &queue->rt2x00dev->flags)) | 417 | if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags)) |
407 | rt2x00crypto_tx_copy_iv(skb, iv_len); | 418 | rt2x00crypto_tx_copy_iv(skb, iv_len); |
408 | else | 419 | else |
409 | rt2x00crypto_tx_remove_iv(skb, iv_len); | 420 | rt2x00crypto_tx_remove_iv(skb, iv_len); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 282937153408..97e2ab08f080 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -158,6 +158,14 @@ enum rxdone_entry_desc_flags { | |||
158 | }; | 158 | }; |
159 | 159 | ||
160 | /** | 160 | /** |
161 | * RXDONE_SIGNAL_MASK - Define to mask off all &rxdone_entry_desc_flags flags | ||
162 | * except for the RXDONE_SIGNAL_* flags. This is useful to convert the dev_flags | ||
163 | * from &rxdone_entry_desc to a signal value type. | ||
164 | */ | ||
165 | #define RXDONE_SIGNAL_MASK \ | ||
166 | ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE ) | ||
167 | |||
168 | /** | ||
161 | * struct rxdone_entry_desc: RX Entry descriptor | 169 | * struct rxdone_entry_desc: RX Entry descriptor |
162 | * | 170 | * |
163 | * Summary of information that has been read from the RX frame descriptor. | 171 | * Summary of information that has been read from the RX frame descriptor. |
@@ -165,6 +173,7 @@ enum rxdone_entry_desc_flags { | |||
165 | * @timestamp: RX Timestamp | 173 | * @timestamp: RX Timestamp |
166 | * @signal: Signal of the received frame. | 174 | * @signal: Signal of the received frame. |
167 | * @rssi: RSSI of the received frame. | 175 | * @rssi: RSSI of the received frame. |
176 | * @noise: Measured noise during frame reception. | ||
168 | * @size: Data size of the received frame. | 177 | * @size: Data size of the received frame. |
169 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). | 178 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). |
170 | * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). | 179 | * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags). |
@@ -177,6 +186,7 @@ struct rxdone_entry_desc { | |||
177 | u64 timestamp; | 186 | u64 timestamp; |
178 | int signal; | 187 | int signal; |
179 | int rssi; | 188 | int rssi; |
189 | int noise; | ||
180 | int size; | 190 | int size; |
181 | int flags; | 191 | int flags; |
182 | int dev_flags; | 192 | int dev_flags; |
@@ -222,7 +232,6 @@ struct txdone_entry_desc { | |||
222 | * | 232 | * |
223 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. | 233 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. |
224 | * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame. | 234 | * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame. |
225 | * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. | ||
226 | * @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter. | 235 | * @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter. |
227 | * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame. | 236 | * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame. |
228 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. | 237 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. |
@@ -238,7 +247,6 @@ struct txdone_entry_desc { | |||
238 | enum txentry_desc_flags { | 247 | enum txentry_desc_flags { |
239 | ENTRY_TXD_RTS_FRAME, | 248 | ENTRY_TXD_RTS_FRAME, |
240 | ENTRY_TXD_CTS_FRAME, | 249 | ENTRY_TXD_CTS_FRAME, |
241 | ENTRY_TXD_OFDM_RATE, | ||
242 | ENTRY_TXD_GENERATE_SEQ, | 250 | ENTRY_TXD_GENERATE_SEQ, |
243 | ENTRY_TXD_FIRST_FRAGMENT, | 251 | ENTRY_TXD_FIRST_FRAGMENT, |
244 | ENTRY_TXD_MORE_FRAG, | 252 | ENTRY_TXD_MORE_FRAG, |
@@ -263,6 +271,7 @@ enum txentry_desc_flags { | |||
263 | * @length_low: PLCP length low word. | 271 | * @length_low: PLCP length low word. |
264 | * @signal: PLCP signal. | 272 | * @signal: PLCP signal. |
265 | * @service: PLCP service. | 273 | * @service: PLCP service. |
274 | * @rate_mode: Rate mode (See @enum rate_modulation). | ||
266 | * @retry_limit: Max number of retries. | 275 | * @retry_limit: Max number of retries. |
267 | * @aifs: AIFS value. | 276 | * @aifs: AIFS value. |
268 | * @ifs: IFS value. | 277 | * @ifs: IFS value. |
@@ -282,6 +291,8 @@ struct txentry_desc { | |||
282 | u16 signal; | 291 | u16 signal; |
283 | u16 service; | 292 | u16 service; |
284 | 293 | ||
294 | u16 rate_mode; | ||
295 | |||
285 | short retry_limit; | 296 | short retry_limit; |
286 | short aifs; | 297 | short aifs; |
287 | short ifs; | 298 | short ifs; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index c2fba7c9f05c..9ddc2d07eef8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -125,6 +125,16 @@ enum cipher { | |||
125 | }; | 125 | }; |
126 | 126 | ||
127 | /* | 127 | /* |
128 | * Rate modulations | ||
129 | */ | ||
130 | enum rate_modulation { | ||
131 | RATE_MODE_CCK = 0, | ||
132 | RATE_MODE_OFDM = 1, | ||
133 | RATE_MODE_HT_MIX = 2, | ||
134 | RATE_MODE_HT_GREENFIELD = 3, | ||
135 | }; | ||
136 | |||
137 | /* | ||
128 | * Register handlers. | 138 | * Register handlers. |
129 | * We store the position of a register field inside a field structure, | 139 | * We store the position of a register field inside a field structure, |
130 | * This will simplify the process of setting and reading a certain field | 140 | * This will simplify the process of setting and reading a certain field |
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index 3298cae1e12d..b6d4c6700bf3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -25,73 +25,30 @@ | |||
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/rfkill.h> | ||
29 | 28 | ||
30 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
31 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
32 | 31 | ||
33 | static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state) | 32 | static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) |
34 | { | 33 | { |
35 | struct rt2x00_dev *rt2x00dev = data; | 34 | struct rt2x00_dev *rt2x00dev = poll_dev->private; |
36 | int retval = 0; | 35 | int state, old_state; |
37 | |||
38 | if (unlikely(!rt2x00dev)) | ||
39 | return 0; | ||
40 | |||
41 | /* | ||
42 | * Only continue if there are enabled interfaces. | ||
43 | */ | ||
44 | if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) | ||
45 | return 0; | ||
46 | |||
47 | if (state == RFKILL_STATE_UNBLOCKED) { | ||
48 | INFO(rt2x00dev, "RFKILL event: enabling radio.\n"); | ||
49 | clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags); | ||
50 | retval = rt2x00lib_enable_radio(rt2x00dev); | ||
51 | } else if (state == RFKILL_STATE_SOFT_BLOCKED) { | ||
52 | INFO(rt2x00dev, "RFKILL event: disabling radio.\n"); | ||
53 | set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags); | ||
54 | rt2x00lib_disable_radio(rt2x00dev); | ||
55 | } else { | ||
56 | WARNING(rt2x00dev, "RFKILL event: unknown state %d.\n", state); | ||
57 | } | ||
58 | |||
59 | return retval; | ||
60 | } | ||
61 | |||
62 | static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state) | ||
63 | { | ||
64 | struct rt2x00_dev *rt2x00dev = data; | ||
65 | |||
66 | /* | ||
67 | * rfkill_poll reports 1 when the key has been pressed and the | ||
68 | * radio should be blocked. | ||
69 | */ | ||
70 | *state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ? | ||
71 | RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED; | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static void rt2x00rfkill_poll(struct work_struct *work) | ||
77 | { | ||
78 | struct rt2x00_dev *rt2x00dev = | ||
79 | container_of(work, struct rt2x00_dev, rfkill_work.work); | ||
80 | enum rfkill_state state; | ||
81 | 36 | ||
82 | if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) || | 37 | if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) || |
83 | !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | 38 | !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) |
84 | return; | 39 | return; |
85 | 40 | ||
86 | /* | 41 | /* |
87 | * Poll latest state and report it to rfkill who should sort | 42 | * Poll latest state, if the state is different then the previous state, |
88 | * out if the state should be toggled or not. | 43 | * we should generate an input event. |
89 | */ | 44 | */ |
90 | if (!rt2x00rfkill_get_state(rt2x00dev, &state)) | 45 | state = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev); |
91 | rfkill_force_state(rt2x00dev->rfkill, state); | 46 | old_state = !!test_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state); |
92 | 47 | ||
93 | queue_delayed_work(rt2x00dev->hw->workqueue, | 48 | if (old_state != state) { |
94 | &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL); | 49 | input_report_switch(poll_dev->input, SW_RFKILL_ALL, state); |
50 | change_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state); | ||
51 | } | ||
95 | } | 52 | } |
96 | 53 | ||
97 | void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | 54 | void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) |
@@ -100,8 +57,8 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | |||
100 | test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) | 57 | test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) |
101 | return; | 58 | return; |
102 | 59 | ||
103 | if (rfkill_register(rt2x00dev->rfkill)) { | 60 | if (input_register_polled_device(rt2x00dev->rfkill_poll_dev)) { |
104 | ERROR(rt2x00dev, "Failed to register rfkill handler.\n"); | 61 | ERROR(rt2x00dev, "Failed to register polled device.\n"); |
105 | return; | 62 | return; |
106 | } | 63 | } |
107 | 64 | ||
@@ -109,10 +66,10 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) | |||
109 | 66 | ||
110 | /* | 67 | /* |
111 | * Force initial poll which will detect the initial device state, | 68 | * Force initial poll which will detect the initial device state, |
112 | * and correctly sends the signal to the rfkill layer about this | 69 | * and correctly sends the signal to the input layer about this |
113 | * state. | 70 | * state. |
114 | */ | 71 | */ |
115 | rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work); | 72 | rt2x00rfkill_poll(rt2x00dev->rfkill_poll_dev); |
116 | } | 73 | } |
117 | 74 | ||
118 | void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | 75 | void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) |
@@ -121,52 +78,50 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) | |||
121 | !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) | 78 | !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) |
122 | return; | 79 | return; |
123 | 80 | ||
124 | cancel_delayed_work_sync(&rt2x00dev->rfkill_work); | 81 | input_unregister_polled_device(rt2x00dev->rfkill_poll_dev); |
125 | |||
126 | rfkill_unregister(rt2x00dev->rfkill); | ||
127 | 82 | ||
128 | __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); | 83 | __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); |
129 | } | 84 | } |
130 | 85 | ||
131 | void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) | 86 | void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) |
132 | { | 87 | { |
133 | struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy); | 88 | struct input_polled_dev *poll_dev; |
134 | 89 | ||
135 | if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) | 90 | if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) || |
91 | !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) | ||
136 | return; | 92 | return; |
137 | 93 | ||
138 | rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN); | 94 | poll_dev = input_allocate_polled_device(); |
139 | if (!rt2x00dev->rfkill) { | 95 | if (!poll_dev) { |
140 | ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n"); | 96 | ERROR(rt2x00dev, "Failed to allocate polled device.\n"); |
141 | return; | 97 | return; |
142 | } | 98 | } |
143 | 99 | ||
144 | __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state); | 100 | poll_dev->private = rt2x00dev; |
101 | poll_dev->poll = rt2x00rfkill_poll; | ||
102 | poll_dev->poll_interval = RFKILL_POLL_INTERVAL; | ||
145 | 103 | ||
146 | rt2x00dev->rfkill->name = rt2x00dev->ops->name; | 104 | poll_dev->input->name = rt2x00dev->ops->name; |
147 | rt2x00dev->rfkill->data = rt2x00dev; | 105 | poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy); |
148 | rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; | 106 | poll_dev->input->id.bustype = BUS_HOST; |
149 | if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) { | 107 | poll_dev->input->id.vendor = 0x1814; |
150 | rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state; | 108 | poll_dev->input->id.product = rt2x00dev->chip.rt; |
151 | rt2x00dev->rfkill->state = | 109 | poll_dev->input->id.version = rt2x00dev->chip.rev; |
152 | rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ? | 110 | poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy); |
153 | RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED; | 111 | poll_dev->input->evbit[0] = BIT(EV_SW); |
154 | } else { | 112 | poll_dev->input->swbit[0] = BIT(SW_RFKILL_ALL); |
155 | rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
156 | } | ||
157 | 113 | ||
158 | INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll); | 114 | rt2x00dev->rfkill_poll_dev = poll_dev; |
159 | 115 | ||
160 | return; | 116 | __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state); |
161 | } | 117 | } |
162 | 118 | ||
163 | void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) | 119 | void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) |
164 | { | 120 | { |
165 | if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) | 121 | if (!__test_and_clear_bit(RFKILL_STATE_ALLOCATED, |
122 | &rt2x00dev->rfkill_state)) | ||
166 | return; | 123 | return; |
167 | 124 | ||
168 | cancel_delayed_work_sync(&rt2x00dev->rfkill_work); | 125 | input_free_polled_device(rt2x00dev->rfkill_poll_dev); |
169 | 126 | rt2x00dev->rfkill_poll_dev = NULL; | |
170 | rfkill_free(rt2x00dev->rfkill); | ||
171 | rt2x00dev->rfkill = NULL; | ||
172 | } | 127 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 0b29d767a258..c89d1520838c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 2bd4ac855f52..fe4523887bdf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 987e89009f74..d81a8de9dc17 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -146,12 +146,6 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, | |||
146 | mutex_unlock(&rt2x00dev->csr_mutex); | 146 | mutex_unlock(&rt2x00dev->csr_mutex); |
147 | } | 147 | } |
148 | 148 | ||
149 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
150 | /* | ||
151 | * This function is only called from rt61pci_led_brightness() | ||
152 | * make gcc happy by placing this function inside the | ||
153 | * same ifdef statement as the caller. | ||
154 | */ | ||
155 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | 149 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, |
156 | const u8 command, const u8 token, | 150 | const u8 command, const u8 token, |
157 | const u8 arg0, const u8 arg1) | 151 | const u8 arg0, const u8 arg1) |
@@ -180,7 +174,6 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
180 | mutex_unlock(&rt2x00dev->csr_mutex); | 174 | mutex_unlock(&rt2x00dev->csr_mutex); |
181 | 175 | ||
182 | } | 176 | } |
183 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
184 | 177 | ||
185 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 178 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
186 | { | 179 | { |
@@ -967,6 +960,50 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
967 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 960 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); |
968 | } | 961 | } |
969 | 962 | ||
963 | static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev, | ||
964 | struct rt2x00lib_conf *libconf) | ||
965 | { | ||
966 | enum dev_state state = | ||
967 | (libconf->conf->flags & IEEE80211_CONF_PS) ? | ||
968 | STATE_SLEEP : STATE_AWAKE; | ||
969 | u32 reg; | ||
970 | |||
971 | if (state == STATE_SLEEP) { | ||
972 | rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); | ||
973 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, | ||
974 | libconf->conf->beacon_int - 10); | ||
975 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, | ||
976 | libconf->conf->listen_interval - 1); | ||
977 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5); | ||
978 | |||
979 | /* We must first disable autowake before it can be enabled */ | ||
980 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); | ||
981 | rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); | ||
982 | |||
983 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 1); | ||
984 | rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); | ||
985 | |||
986 | rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000005); | ||
987 | rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c); | ||
988 | rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060); | ||
989 | |||
990 | rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0); | ||
991 | } else { | ||
992 | rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); | ||
993 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, 0); | ||
994 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0); | ||
995 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); | ||
996 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 0); | ||
997 | rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg); | ||
998 | |||
999 | rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007); | ||
1000 | rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018); | ||
1001 | rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020); | ||
1002 | |||
1003 | rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0); | ||
1004 | } | ||
1005 | } | ||
1006 | |||
970 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | 1007 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, |
971 | struct rt2x00lib_conf *libconf, | 1008 | struct rt2x00lib_conf *libconf, |
972 | const unsigned int flags) | 1009 | const unsigned int flags) |
@@ -984,6 +1021,8 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | |||
984 | rt61pci_config_retry_limit(rt2x00dev, libconf); | 1021 | rt61pci_config_retry_limit(rt2x00dev, libconf); |
985 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) | 1022 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) |
986 | rt61pci_config_duration(rt2x00dev, libconf); | 1023 | rt61pci_config_duration(rt2x00dev, libconf); |
1024 | if (flags & IEEE80211_CONF_CHANGE_PS) | ||
1025 | rt61pci_config_ps(rt2x00dev, libconf); | ||
987 | } | 1026 | } |
988 | 1027 | ||
989 | /* | 1028 | /* |
@@ -1007,21 +1046,28 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
1007 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | 1046 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); |
1008 | } | 1047 | } |
1009 | 1048 | ||
1010 | static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | 1049 | static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev, |
1050 | struct link_qual *qual, u8 vgc_level) | ||
1051 | { | ||
1052 | if (qual->vgc_level != vgc_level) { | ||
1053 | rt61pci_bbp_write(rt2x00dev, 17, vgc_level); | ||
1054 | qual->vgc_level = vgc_level; | ||
1055 | qual->vgc_level_reg = vgc_level; | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev, | ||
1060 | struct link_qual *qual) | ||
1011 | { | 1061 | { |
1012 | rt61pci_bbp_write(rt2x00dev, 17, 0x20); | 1062 | rt61pci_set_vgc(rt2x00dev, qual, 0x20); |
1013 | rt2x00dev->link.vgc_level = 0x20; | ||
1014 | } | 1063 | } |
1015 | 1064 | ||
1016 | static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | 1065 | static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, |
1066 | struct link_qual *qual, const u32 count) | ||
1017 | { | 1067 | { |
1018 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
1019 | u8 r17; | ||
1020 | u8 up_bound; | 1068 | u8 up_bound; |
1021 | u8 low_bound; | 1069 | u8 low_bound; |
1022 | 1070 | ||
1023 | rt61pci_bbp_read(rt2x00dev, 17, &r17); | ||
1024 | |||
1025 | /* | 1071 | /* |
1026 | * Determine r17 bounds. | 1072 | * Determine r17 bounds. |
1027 | */ | 1073 | */ |
@@ -1051,38 +1097,32 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
1051 | /* | 1097 | /* |
1052 | * Special big-R17 for very short distance | 1098 | * Special big-R17 for very short distance |
1053 | */ | 1099 | */ |
1054 | if (rssi >= -35) { | 1100 | if (qual->rssi >= -35) { |
1055 | if (r17 != 0x60) | 1101 | rt61pci_set_vgc(rt2x00dev, qual, 0x60); |
1056 | rt61pci_bbp_write(rt2x00dev, 17, 0x60); | ||
1057 | return; | 1102 | return; |
1058 | } | 1103 | } |
1059 | 1104 | ||
1060 | /* | 1105 | /* |
1061 | * Special big-R17 for short distance | 1106 | * Special big-R17 for short distance |
1062 | */ | 1107 | */ |
1063 | if (rssi >= -58) { | 1108 | if (qual->rssi >= -58) { |
1064 | if (r17 != up_bound) | 1109 | rt61pci_set_vgc(rt2x00dev, qual, up_bound); |
1065 | rt61pci_bbp_write(rt2x00dev, 17, up_bound); | ||
1066 | return; | 1110 | return; |
1067 | } | 1111 | } |
1068 | 1112 | ||
1069 | /* | 1113 | /* |
1070 | * Special big-R17 for middle-short distance | 1114 | * Special big-R17 for middle-short distance |
1071 | */ | 1115 | */ |
1072 | if (rssi >= -66) { | 1116 | if (qual->rssi >= -66) { |
1073 | low_bound += 0x10; | 1117 | rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x10); |
1074 | if (r17 != low_bound) | ||
1075 | rt61pci_bbp_write(rt2x00dev, 17, low_bound); | ||
1076 | return; | 1118 | return; |
1077 | } | 1119 | } |
1078 | 1120 | ||
1079 | /* | 1121 | /* |
1080 | * Special mid-R17 for middle distance | 1122 | * Special mid-R17 for middle distance |
1081 | */ | 1123 | */ |
1082 | if (rssi >= -74) { | 1124 | if (qual->rssi >= -74) { |
1083 | low_bound += 0x08; | 1125 | rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x08); |
1084 | if (r17 != low_bound) | ||
1085 | rt61pci_bbp_write(rt2x00dev, 17, low_bound); | ||
1086 | return; | 1126 | return; |
1087 | } | 1127 | } |
1088 | 1128 | ||
@@ -1090,12 +1130,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
1090 | * Special case: Change up_bound based on the rssi. | 1130 | * Special case: Change up_bound based on the rssi. |
1091 | * Lower up_bound when rssi is weaker then -74 dBm. | 1131 | * Lower up_bound when rssi is weaker then -74 dBm. |
1092 | */ | 1132 | */ |
1093 | up_bound -= 2 * (-74 - rssi); | 1133 | up_bound -= 2 * (-74 - qual->rssi); |
1094 | if (low_bound > up_bound) | 1134 | if (low_bound > up_bound) |
1095 | up_bound = low_bound; | 1135 | up_bound = low_bound; |
1096 | 1136 | ||
1097 | if (r17 > up_bound) { | 1137 | if (qual->vgc_level > up_bound) { |
1098 | rt61pci_bbp_write(rt2x00dev, 17, up_bound); | 1138 | rt61pci_set_vgc(rt2x00dev, qual, up_bound); |
1099 | return; | 1139 | return; |
1100 | } | 1140 | } |
1101 | 1141 | ||
@@ -1105,15 +1145,10 @@ dynamic_cca_tune: | |||
1105 | * r17 does not yet exceed upper limit, continue and base | 1145 | * r17 does not yet exceed upper limit, continue and base |
1106 | * the r17 tuning on the false CCA count. | 1146 | * the r17 tuning on the false CCA count. |
1107 | */ | 1147 | */ |
1108 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | 1148 | if ((qual->false_cca > 512) && (qual->vgc_level < up_bound)) |
1109 | if (++r17 > up_bound) | 1149 | rt61pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level); |
1110 | r17 = up_bound; | 1150 | else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound)) |
1111 | rt61pci_bbp_write(rt2x00dev, 17, r17); | 1151 | rt61pci_set_vgc(rt2x00dev, qual, --qual->vgc_level); |
1112 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | ||
1113 | if (--r17 < low_bound) | ||
1114 | r17 = low_bound; | ||
1115 | rt61pci_bbp_write(rt2x00dev, 17, r17); | ||
1116 | } | ||
1117 | } | 1152 | } |
1118 | 1153 | ||
1119 | /* | 1154 | /* |
@@ -1164,6 +1199,11 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, | |||
1164 | int i; | 1199 | int i; |
1165 | u32 reg; | 1200 | u32 reg; |
1166 | 1201 | ||
1202 | if (len != 8192) { | ||
1203 | ERROR(rt2x00dev, "Invalid firmware file length (len=%zu)\n", len); | ||
1204 | return -ENOENT; | ||
1205 | } | ||
1206 | |||
1167 | /* | 1207 | /* |
1168 | * Wait for stable hardware. | 1208 | * Wait for stable hardware. |
1169 | */ | 1209 | */ |
@@ -1812,7 +1852,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1812 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1852 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1813 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1853 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1814 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1854 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1815 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1855 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1816 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1856 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1817 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1857 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1818 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1858 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
@@ -2195,7 +2235,8 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2195 | if (word == 0xffff) { | 2235 | if (word == 0xffff) { |
2196 | rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0); | 2236 | rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0); |
2197 | rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0); | 2237 | rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0); |
2198 | rt2x00_set_field16(&word, EEPROM_NIC_TX_RX_FIXED, 0); | 2238 | rt2x00_set_field16(&word, EEPROM_NIC_RX_FIXED, 0); |
2239 | rt2x00_set_field16(&word, EEPROM_NIC_TX_FIXED, 0); | ||
2199 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); | 2240 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0); |
2200 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); | 2241 | rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0); |
2201 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); | 2242 | rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0); |
@@ -2339,24 +2380,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2339 | */ | 2380 | */ |
2340 | if (rt2x00_rf(&rt2x00dev->chip, RF2529) && | 2381 | if (rt2x00_rf(&rt2x00dev->chip, RF2529) && |
2341 | !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) { | 2382 | !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) { |
2342 | switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { | 2383 | rt2x00dev->default_ant.rx = |
2343 | case 0: | 2384 | ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED); |
2344 | rt2x00dev->default_ant.tx = ANTENNA_B; | 2385 | rt2x00dev->default_ant.tx = |
2345 | rt2x00dev->default_ant.rx = ANTENNA_A; | 2386 | ANTENNA_B - rt2x00_get_field16(eeprom, EEPROM_NIC_TX_FIXED); |
2346 | break; | ||
2347 | case 1: | ||
2348 | rt2x00dev->default_ant.tx = ANTENNA_B; | ||
2349 | rt2x00dev->default_ant.rx = ANTENNA_B; | ||
2350 | break; | ||
2351 | case 2: | ||
2352 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
2353 | rt2x00dev->default_ant.rx = ANTENNA_A; | ||
2354 | break; | ||
2355 | case 3: | ||
2356 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
2357 | rt2x00dev->default_ant.rx = ANTENNA_B; | ||
2358 | break; | ||
2359 | } | ||
2360 | 2387 | ||
2361 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) | 2388 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) |
2362 | rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY; | 2389 | rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY; |
@@ -2534,7 +2561,9 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2534 | */ | 2561 | */ |
2535 | rt2x00dev->hw->flags = | 2562 | rt2x00dev->hw->flags = |
2536 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 2563 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2537 | IEEE80211_HW_SIGNAL_DBM; | 2564 | IEEE80211_HW_SIGNAL_DBM | |
2565 | IEEE80211_HW_SUPPORTS_PS | | ||
2566 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
2538 | rt2x00dev->hw->extra_tx_headroom = 0; | 2567 | rt2x00dev->hw->extra_tx_headroom = 0; |
2539 | 2568 | ||
2540 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 2569 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
@@ -2633,6 +2662,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2633 | struct rt2x00_field32 field; | 2662 | struct rt2x00_field32 field; |
2634 | int retval; | 2663 | int retval; |
2635 | u32 reg; | 2664 | u32 reg; |
2665 | u32 offset; | ||
2636 | 2666 | ||
2637 | /* | 2667 | /* |
2638 | * First pass the configuration through rt2x00lib, that will | 2668 | * First pass the configuration through rt2x00lib, that will |
@@ -2644,24 +2674,23 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2644 | if (retval) | 2674 | if (retval) |
2645 | return retval; | 2675 | return retval; |
2646 | 2676 | ||
2677 | /* | ||
2678 | * We only need to perform additional register initialization | ||
2679 | * for WMM queues/ | ||
2680 | */ | ||
2681 | if (queue_idx >= 4) | ||
2682 | return 0; | ||
2683 | |||
2647 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 2684 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
2648 | 2685 | ||
2649 | /* Update WMM TXOP register */ | 2686 | /* Update WMM TXOP register */ |
2650 | if (queue_idx < 2) { | 2687 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); |
2651 | field.bit_offset = queue_idx * 16; | 2688 | field.bit_offset = (queue_idx & 1) * 16; |
2652 | field.bit_mask = 0xffff << field.bit_offset; | 2689 | field.bit_mask = 0xffff << field.bit_offset; |
2653 | 2690 | ||
2654 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, ®); | 2691 | rt2x00pci_register_read(rt2x00dev, offset, ®); |
2655 | rt2x00_set_field32(®, field, queue->txop); | 2692 | rt2x00_set_field32(®, field, queue->txop); |
2656 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg); | 2693 | rt2x00pci_register_write(rt2x00dev, offset, reg); |
2657 | } else if (queue_idx < 4) { | ||
2658 | field.bit_offset = (queue_idx - 2) * 16; | ||
2659 | field.bit_mask = 0xffff << field.bit_offset; | ||
2660 | |||
2661 | rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, ®); | ||
2662 | rt2x00_set_field32(®, field, queue->txop); | ||
2663 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | ||
2664 | } | ||
2665 | 2694 | ||
2666 | /* Update WMM registers */ | 2695 | /* Update WMM registers */ |
2667 | field.bit_offset = queue_idx * 4; | 2696 | field.bit_offset = queue_idx * 4; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 65fe3332364a..2f97fee7a8de 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -88,8 +88,10 @@ | |||
88 | 88 | ||
89 | /* | 89 | /* |
90 | * SOFT_RESET_CSR | 90 | * SOFT_RESET_CSR |
91 | * FORCE_CLOCK_ON: Host force MAC clock ON | ||
91 | */ | 92 | */ |
92 | #define SOFT_RESET_CSR 0x0010 | 93 | #define SOFT_RESET_CSR 0x0010 |
94 | #define SOFT_RESET_CSR_FORCE_CLOCK_ON FIELD32(0x00000002) | ||
93 | 95 | ||
94 | /* | 96 | /* |
95 | * MCU_INT_SOURCE_CSR: MCU interrupt source/mask register. | 97 | * MCU_INT_SOURCE_CSR: MCU interrupt source/mask register. |
@@ -1054,8 +1056,10 @@ struct hw_pairwise_ta_entry { | |||
1054 | 1056 | ||
1055 | /* | 1057 | /* |
1056 | * IO_CNTL_CSR | 1058 | * IO_CNTL_CSR |
1059 | * RF_PS: Set RF interface value to power save | ||
1057 | */ | 1060 | */ |
1058 | #define IO_CNTL_CSR 0x3498 | 1061 | #define IO_CNTL_CSR 0x3498 |
1062 | #define IO_CNTL_CSR_RF_PS FIELD32(0x00000004) | ||
1059 | 1063 | ||
1060 | /* | 1064 | /* |
1061 | * UART_INT_SOURCE_CSR | 1065 | * UART_INT_SOURCE_CSR |
@@ -1186,7 +1190,8 @@ struct hw_pairwise_ta_entry { | |||
1186 | #define EEPROM_NIC 0x0011 | 1190 | #define EEPROM_NIC 0x0011 |
1187 | #define EEPROM_NIC_ENABLE_DIVERSITY FIELD16(0x0001) | 1191 | #define EEPROM_NIC_ENABLE_DIVERSITY FIELD16(0x0001) |
1188 | #define EEPROM_NIC_TX_DIVERSITY FIELD16(0x0002) | 1192 | #define EEPROM_NIC_TX_DIVERSITY FIELD16(0x0002) |
1189 | #define EEPROM_NIC_TX_RX_FIXED FIELD16(0x000c) | 1193 | #define EEPROM_NIC_RX_FIXED FIELD16(0x0004) |
1194 | #define EEPROM_NIC_TX_FIXED FIELD16(0x0008) | ||
1190 | #define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0010) | 1195 | #define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0010) |
1191 | #define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0020) | 1196 | #define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0020) |
1192 | #define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0040) | 1197 | #define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0040) |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 96a8d69f8790..f854551be75d 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -186,6 +186,18 @@ static const struct rt2x00debug rt73usb_rt2x00debug = { | |||
186 | }; | 186 | }; |
187 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 187 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
188 | 188 | ||
189 | #ifdef CONFIG_RT2X00_LIB_RFKILL | ||
190 | static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) | ||
191 | { | ||
192 | u32 reg; | ||
193 | |||
194 | rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); | ||
195 | return rt2x00_get_field32(reg, MAC_CSR13_BIT7); | ||
196 | } | ||
197 | #else | ||
198 | #define rt73usb_rfkill_poll NULL | ||
199 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | ||
200 | |||
189 | #ifdef CONFIG_RT2X00_LIB_LEDS | 201 | #ifdef CONFIG_RT2X00_LIB_LEDS |
190 | static void rt73usb_brightness_set(struct led_classdev *led_cdev, | 202 | static void rt73usb_brightness_set(struct led_classdev *led_cdev, |
191 | enum led_brightness brightness) | 203 | enum led_brightness brightness) |
@@ -844,6 +856,44 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
844 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 856 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
845 | } | 857 | } |
846 | 858 | ||
859 | static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev, | ||
860 | struct rt2x00lib_conf *libconf) | ||
861 | { | ||
862 | enum dev_state state = | ||
863 | (libconf->conf->flags & IEEE80211_CONF_PS) ? | ||
864 | STATE_SLEEP : STATE_AWAKE; | ||
865 | u32 reg; | ||
866 | |||
867 | if (state == STATE_SLEEP) { | ||
868 | rt2x00usb_register_read(rt2x00dev, MAC_CSR11, ®); | ||
869 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, | ||
870 | libconf->conf->beacon_int - 10); | ||
871 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, | ||
872 | libconf->conf->listen_interval - 1); | ||
873 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5); | ||
874 | |||
875 | /* We must first disable autowake before it can be enabled */ | ||
876 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); | ||
877 | rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg); | ||
878 | |||
879 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 1); | ||
880 | rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg); | ||
881 | |||
882 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | ||
883 | USB_MODE_SLEEP, REGISTER_TIMEOUT); | ||
884 | } else { | ||
885 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | ||
886 | USB_MODE_WAKEUP, REGISTER_TIMEOUT); | ||
887 | |||
888 | rt2x00usb_register_read(rt2x00dev, MAC_CSR11, ®); | ||
889 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, 0); | ||
890 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0); | ||
891 | rt2x00_set_field32(®, MAC_CSR11_AUTOWAKE, 0); | ||
892 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 0); | ||
893 | rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg); | ||
894 | } | ||
895 | } | ||
896 | |||
847 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 897 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
848 | struct rt2x00lib_conf *libconf, | 898 | struct rt2x00lib_conf *libconf, |
849 | const unsigned int flags) | 899 | const unsigned int flags) |
@@ -861,6 +911,8 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | |||
861 | rt73usb_config_retry_limit(rt2x00dev, libconf); | 911 | rt73usb_config_retry_limit(rt2x00dev, libconf); |
862 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) | 912 | if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) |
863 | rt73usb_config_duration(rt2x00dev, libconf); | 913 | rt73usb_config_duration(rt2x00dev, libconf); |
914 | if (flags & IEEE80211_CONF_CHANGE_PS) | ||
915 | rt73usb_config_ps(rt2x00dev, libconf); | ||
864 | } | 916 | } |
865 | 917 | ||
866 | /* | 918 | /* |
@@ -884,21 +936,28 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, | |||
884 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | 936 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); |
885 | } | 937 | } |
886 | 938 | ||
887 | static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | 939 | static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev, |
940 | struct link_qual *qual, u8 vgc_level) | ||
888 | { | 941 | { |
889 | rt73usb_bbp_write(rt2x00dev, 17, 0x20); | 942 | if (qual->vgc_level != vgc_level) { |
890 | rt2x00dev->link.vgc_level = 0x20; | 943 | rt73usb_bbp_write(rt2x00dev, 17, vgc_level); |
944 | qual->vgc_level = vgc_level; | ||
945 | qual->vgc_level_reg = vgc_level; | ||
946 | } | ||
891 | } | 947 | } |
892 | 948 | ||
893 | static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | 949 | static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev, |
950 | struct link_qual *qual) | ||
951 | { | ||
952 | rt73usb_set_vgc(rt2x00dev, qual, 0x20); | ||
953 | } | ||
954 | |||
955 | static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, | ||
956 | struct link_qual *qual, const u32 count) | ||
894 | { | 957 | { |
895 | int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); | ||
896 | u8 r17; | ||
897 | u8 up_bound; | 958 | u8 up_bound; |
898 | u8 low_bound; | 959 | u8 low_bound; |
899 | 960 | ||
900 | rt73usb_bbp_read(rt2x00dev, 17, &r17); | ||
901 | |||
902 | /* | 961 | /* |
903 | * Determine r17 bounds. | 962 | * Determine r17 bounds. |
904 | */ | 963 | */ |
@@ -911,10 +970,10 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
911 | up_bound += 0x10; | 970 | up_bound += 0x10; |
912 | } | 971 | } |
913 | } else { | 972 | } else { |
914 | if (rssi > -82) { | 973 | if (qual->rssi > -82) { |
915 | low_bound = 0x1c; | 974 | low_bound = 0x1c; |
916 | up_bound = 0x40; | 975 | up_bound = 0x40; |
917 | } else if (rssi > -84) { | 976 | } else if (qual->rssi > -84) { |
918 | low_bound = 0x1c; | 977 | low_bound = 0x1c; |
919 | up_bound = 0x20; | 978 | up_bound = 0x20; |
920 | } else { | 979 | } else { |
@@ -938,37 +997,32 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
938 | /* | 997 | /* |
939 | * Special big-R17 for very short distance | 998 | * Special big-R17 for very short distance |
940 | */ | 999 | */ |
941 | if (rssi > -35) { | 1000 | if (qual->rssi > -35) { |
942 | if (r17 != 0x60) | 1001 | rt73usb_set_vgc(rt2x00dev, qual, 0x60); |
943 | rt73usb_bbp_write(rt2x00dev, 17, 0x60); | ||
944 | return; | 1002 | return; |
945 | } | 1003 | } |
946 | 1004 | ||
947 | /* | 1005 | /* |
948 | * Special big-R17 for short distance | 1006 | * Special big-R17 for short distance |
949 | */ | 1007 | */ |
950 | if (rssi >= -58) { | 1008 | if (qual->rssi >= -58) { |
951 | if (r17 != up_bound) | 1009 | rt73usb_set_vgc(rt2x00dev, qual, up_bound); |
952 | rt73usb_bbp_write(rt2x00dev, 17, up_bound); | ||
953 | return; | 1010 | return; |
954 | } | 1011 | } |
955 | 1012 | ||
956 | /* | 1013 | /* |
957 | * Special big-R17 for middle-short distance | 1014 | * Special big-R17 for middle-short distance |
958 | */ | 1015 | */ |
959 | if (rssi >= -66) { | 1016 | if (qual->rssi >= -66) { |
960 | low_bound += 0x10; | 1017 | rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x10); |
961 | if (r17 != low_bound) | ||
962 | rt73usb_bbp_write(rt2x00dev, 17, low_bound); | ||
963 | return; | 1018 | return; |
964 | } | 1019 | } |
965 | 1020 | ||
966 | /* | 1021 | /* |
967 | * Special mid-R17 for middle distance | 1022 | * Special mid-R17 for middle distance |
968 | */ | 1023 | */ |
969 | if (rssi >= -74) { | 1024 | if (qual->rssi >= -74) { |
970 | if (r17 != (low_bound + 0x10)) | 1025 | rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x08); |
971 | rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08); | ||
972 | return; | 1026 | return; |
973 | } | 1027 | } |
974 | 1028 | ||
@@ -976,12 +1030,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
976 | * Special case: Change up_bound based on the rssi. | 1030 | * Special case: Change up_bound based on the rssi. |
977 | * Lower up_bound when rssi is weaker then -74 dBm. | 1031 | * Lower up_bound when rssi is weaker then -74 dBm. |
978 | */ | 1032 | */ |
979 | up_bound -= 2 * (-74 - rssi); | 1033 | up_bound -= 2 * (-74 - qual->rssi); |
980 | if (low_bound > up_bound) | 1034 | if (low_bound > up_bound) |
981 | up_bound = low_bound; | 1035 | up_bound = low_bound; |
982 | 1036 | ||
983 | if (r17 > up_bound) { | 1037 | if (qual->vgc_level > up_bound) { |
984 | rt73usb_bbp_write(rt2x00dev, 17, up_bound); | 1038 | rt73usb_set_vgc(rt2x00dev, qual, up_bound); |
985 | return; | 1039 | return; |
986 | } | 1040 | } |
987 | 1041 | ||
@@ -991,17 +1045,12 @@ dynamic_cca_tune: | |||
991 | * r17 does not yet exceed upper limit, continue and base | 1045 | * r17 does not yet exceed upper limit, continue and base |
992 | * the r17 tuning on the false CCA count. | 1046 | * the r17 tuning on the false CCA count. |
993 | */ | 1047 | */ |
994 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | 1048 | if ((qual->false_cca > 512) && (qual->vgc_level < up_bound)) |
995 | r17 += 4; | 1049 | rt73usb_set_vgc(rt2x00dev, qual, |
996 | if (r17 > up_bound) | 1050 | min_t(u8, qual->vgc_level + 4, up_bound)); |
997 | r17 = up_bound; | 1051 | else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound)) |
998 | rt73usb_bbp_write(rt2x00dev, 17, r17); | 1052 | rt73usb_set_vgc(rt2x00dev, qual, |
999 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | 1053 | max_t(u8, qual->vgc_level - 4, low_bound)); |
1000 | r17 -= 4; | ||
1001 | if (r17 < low_bound) | ||
1002 | r17 = low_bound; | ||
1003 | rt73usb_bbp_write(rt2x00dev, 17, r17); | ||
1004 | } | ||
1005 | } | 1054 | } |
1006 | 1055 | ||
1007 | /* | 1056 | /* |
@@ -1036,6 +1085,11 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, | |||
1036 | int status; | 1085 | int status; |
1037 | u32 reg; | 1086 | u32 reg; |
1038 | 1087 | ||
1088 | if (len != 2048) { | ||
1089 | ERROR(rt2x00dev, "Invalid firmware file length (len=%zu)\n", len); | ||
1090 | return -ENOENT; | ||
1091 | } | ||
1092 | |||
1039 | /* | 1093 | /* |
1040 | * Wait for stable hardware. | 1094 | * Wait for stable hardware. |
1041 | */ | 1095 | */ |
@@ -1449,7 +1503,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1449 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1503 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1450 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); | 1504 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1451 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1505 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1452 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1506 | (txdesc->rate_mode == RATE_MODE_OFDM)); |
1453 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1507 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1454 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1508 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1455 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1509 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
@@ -1816,6 +1870,14 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1816 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); | 1870 | __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); |
1817 | 1871 | ||
1818 | /* | 1872 | /* |
1873 | * Detect if this device has an hardware controlled radio. | ||
1874 | */ | ||
1875 | #ifdef CONFIG_RT2X00_LIB_RFKILL | ||
1876 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) | ||
1877 | __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags); | ||
1878 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | ||
1879 | |||
1880 | /* | ||
1819 | * Read frequency offset. | 1881 | * Read frequency offset. |
1820 | */ | 1882 | */ |
1821 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | 1883 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); |
@@ -2020,7 +2082,9 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2020 | */ | 2082 | */ |
2021 | rt2x00dev->hw->flags = | 2083 | rt2x00dev->hw->flags = |
2022 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 2084 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2023 | IEEE80211_HW_SIGNAL_DBM; | 2085 | IEEE80211_HW_SIGNAL_DBM | |
2086 | IEEE80211_HW_SUPPORTS_PS | | ||
2087 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
2024 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 2088 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
2025 | 2089 | ||
2026 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 2090 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
@@ -2121,6 +2185,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2121 | struct rt2x00_field32 field; | 2185 | struct rt2x00_field32 field; |
2122 | int retval; | 2186 | int retval; |
2123 | u32 reg; | 2187 | u32 reg; |
2188 | u32 offset; | ||
2124 | 2189 | ||
2125 | /* | 2190 | /* |
2126 | * First pass the configuration through rt2x00lib, that will | 2191 | * First pass the configuration through rt2x00lib, that will |
@@ -2132,24 +2197,23 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx, | |||
2132 | if (retval) | 2197 | if (retval) |
2133 | return retval; | 2198 | return retval; |
2134 | 2199 | ||
2200 | /* | ||
2201 | * We only need to perform additional register initialization | ||
2202 | * for WMM queues/ | ||
2203 | */ | ||
2204 | if (queue_idx >= 4) | ||
2205 | return 0; | ||
2206 | |||
2135 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); | 2207 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
2136 | 2208 | ||
2137 | /* Update WMM TXOP register */ | 2209 | /* Update WMM TXOP register */ |
2138 | if (queue_idx < 2) { | 2210 | offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2))); |
2139 | field.bit_offset = queue_idx * 16; | 2211 | field.bit_offset = (queue_idx & 1) * 16; |
2140 | field.bit_mask = 0xffff << field.bit_offset; | 2212 | field.bit_mask = 0xffff << field.bit_offset; |
2141 | 2213 | ||
2142 | rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR0, ®); | 2214 | rt2x00usb_register_read(rt2x00dev, offset, ®); |
2143 | rt2x00_set_field32(®, field, queue->txop); | 2215 | rt2x00_set_field32(®, field, queue->txop); |
2144 | rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg); | 2216 | rt2x00usb_register_write(rt2x00dev, offset, reg); |
2145 | } else if (queue_idx < 4) { | ||
2146 | field.bit_offset = (queue_idx - 2) * 16; | ||
2147 | field.bit_mask = 0xffff << field.bit_offset; | ||
2148 | |||
2149 | rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR1, ®); | ||
2150 | rt2x00_set_field32(®, field, queue->txop); | ||
2151 | rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | ||
2152 | } | ||
2153 | 2217 | ||
2154 | /* Update WMM registers */ | 2218 | /* Update WMM registers */ |
2155 | field.bit_offset = queue_idx * 4; | 2219 | field.bit_offset = queue_idx * 4; |
@@ -2220,6 +2284,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2220 | .uninitialize = rt2x00usb_uninitialize, | 2284 | .uninitialize = rt2x00usb_uninitialize, |
2221 | .clear_entry = rt2x00usb_clear_entry, | 2285 | .clear_entry = rt2x00usb_clear_entry, |
2222 | .set_device_state = rt73usb_set_device_state, | 2286 | .set_device_state = rt73usb_set_device_state, |
2287 | .rfkill_poll = rt73usb_rfkill_poll, | ||
2223 | .link_stats = rt73usb_link_stats, | 2288 | .link_stats = rt73usb_link_stats, |
2224 | .reset_tuner = rt73usb_reset_tuner, | 2289 | .reset_tuner = rt73usb_reset_tuner, |
2225 | .link_tuner = rt73usb_link_tuner, | 2290 | .link_tuner = rt73usb_link_tuner, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 46e1405eb0e2..834b28ce6cde 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2009 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -267,6 +267,19 @@ struct hw_pairwise_ta_entry { | |||
267 | * MAC_CSR13: GPIO. | 267 | * MAC_CSR13: GPIO. |
268 | */ | 268 | */ |
269 | #define MAC_CSR13 0x3034 | 269 | #define MAC_CSR13 0x3034 |
270 | #define MAC_CSR13_BIT0 FIELD32(0x00000001) | ||
271 | #define MAC_CSR13_BIT1 FIELD32(0x00000002) | ||
272 | #define MAC_CSR13_BIT2 FIELD32(0x00000004) | ||
273 | #define MAC_CSR13_BIT3 FIELD32(0x00000008) | ||
274 | #define MAC_CSR13_BIT4 FIELD32(0x00000010) | ||
275 | #define MAC_CSR13_BIT5 FIELD32(0x00000020) | ||
276 | #define MAC_CSR13_BIT6 FIELD32(0x00000040) | ||
277 | #define MAC_CSR13_BIT7 FIELD32(0x00000080) | ||
278 | #define MAC_CSR13_BIT8 FIELD32(0x00000100) | ||
279 | #define MAC_CSR13_BIT9 FIELD32(0x00000200) | ||
280 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | ||
281 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | ||
282 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | ||
270 | 283 | ||
271 | /* | 284 | /* |
272 | * MAC_CSR14: LED control register. | 285 | * MAC_CSR14: LED control register. |
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index 3b1e1c2aad26..9718f61809cf 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h | |||
@@ -100,6 +100,8 @@ struct rtl8187_priv { | |||
100 | struct usb_device *udev; | 100 | struct usb_device *udev; |
101 | u32 rx_conf; | 101 | u32 rx_conf; |
102 | struct usb_anchor anchored; | 102 | struct usb_anchor anchored; |
103 | struct delayed_work work; | ||
104 | struct ieee80211_hw *dev; | ||
103 | u16 txpwr_base; | 105 | u16 txpwr_base; |
104 | u8 asic_rev; | 106 | u8 asic_rev; |
105 | u8 is_rtl8187b; | 107 | u8 is_rtl8187b; |
@@ -117,7 +119,7 @@ struct rtl8187_priv { | |||
117 | struct { | 119 | struct { |
118 | __le64 buf; | 120 | __le64 buf; |
119 | struct sk_buff_head queue; | 121 | struct sk_buff_head queue; |
120 | } b_tx_status; | 122 | } b_tx_status; /* This queue is used by both -b and non-b devices */ |
121 | }; | 123 | }; |
122 | 124 | ||
123 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); | 125 | void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 22bc07ef2f37..82bd47e7c617 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -177,25 +177,33 @@ static void rtl8187_tx_cb(struct urb *urb) | |||
177 | sizeof(struct rtl8187_tx_hdr)); | 177 | sizeof(struct rtl8187_tx_hdr)); |
178 | ieee80211_tx_info_clear_status(info); | 178 | ieee80211_tx_info_clear_status(info); |
179 | 179 | ||
180 | if (!urb->status && | 180 | if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
181 | !(info->flags & IEEE80211_TX_CTL_NO_ACK) && | 181 | if (priv->is_rtl8187b) { |
182 | priv->is_rtl8187b) { | 182 | skb_queue_tail(&priv->b_tx_status.queue, skb); |
183 | skb_queue_tail(&priv->b_tx_status.queue, skb); | ||
184 | 183 | ||
185 | /* queue is "full", discard last items */ | 184 | /* queue is "full", discard last items */ |
186 | while (skb_queue_len(&priv->b_tx_status.queue) > 5) { | 185 | while (skb_queue_len(&priv->b_tx_status.queue) > 5) { |
187 | struct sk_buff *old_skb; | 186 | struct sk_buff *old_skb; |
188 | 187 | ||
189 | dev_dbg(&priv->udev->dev, | 188 | dev_dbg(&priv->udev->dev, |
190 | "transmit status queue full\n"); | 189 | "transmit status queue full\n"); |
191 | 190 | ||
192 | old_skb = skb_dequeue(&priv->b_tx_status.queue); | 191 | old_skb = skb_dequeue(&priv->b_tx_status.queue); |
193 | ieee80211_tx_status_irqsafe(hw, old_skb); | 192 | ieee80211_tx_status_irqsafe(hw, old_skb); |
194 | } | 193 | } |
195 | } else { | 194 | return; |
196 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !urb->status) | 195 | } else { |
197 | info->flags |= IEEE80211_TX_STAT_ACK; | 196 | info->flags |= IEEE80211_TX_STAT_ACK; |
197 | } | ||
198 | } | ||
199 | if (priv->is_rtl8187b) | ||
198 | ieee80211_tx_status_irqsafe(hw, skb); | 200 | ieee80211_tx_status_irqsafe(hw, skb); |
201 | else { | ||
202 | /* Retry information for the RTI8187 is only available by | ||
203 | * reading a register in the device. We are in interrupt mode | ||
204 | * here, thus queue the skb and finish on a work queue. */ | ||
205 | skb_queue_tail(&priv->b_tx_status.queue, skb); | ||
206 | queue_delayed_work(hw->workqueue, &priv->work, 0); | ||
199 | } | 207 | } |
200 | } | 208 | } |
201 | 209 | ||
@@ -391,7 +399,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) | |||
391 | struct rtl8187_rx_info *info; | 399 | struct rtl8187_rx_info *info; |
392 | int ret = 0; | 400 | int ret = 0; |
393 | 401 | ||
394 | while (skb_queue_len(&priv->rx_queue) < 8) { | 402 | while (skb_queue_len(&priv->rx_queue) < 16) { |
395 | skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); | 403 | skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); |
396 | if (!skb) { | 404 | if (!skb) { |
397 | ret = -ENOMEM; | 405 | ret = -ENOMEM; |
@@ -645,7 +653,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev) | |||
645 | 653 | ||
646 | rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); | 654 | rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); |
647 | rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); | 655 | rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); |
648 | rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); | 656 | rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0); |
649 | 657 | ||
650 | // TODO: set RESP_RATE and BRSR properly | 658 | // TODO: set RESP_RATE and BRSR properly |
651 | rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); | 659 | rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); |
@@ -765,9 +773,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) | |||
765 | rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); | 773 | rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); |
766 | 774 | ||
767 | rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); | 775 | rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1); |
768 | reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK); | ||
769 | reg |= RTL818X_RATE_FALLBACK_ENABLE; | ||
770 | rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg); | ||
771 | 776 | ||
772 | rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); | 777 | rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100); |
773 | rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); | 778 | rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2); |
@@ -855,6 +860,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) | |||
855 | return 0; | 860 | return 0; |
856 | } | 861 | } |
857 | 862 | ||
863 | static void rtl8187_work(struct work_struct *work) | ||
864 | { | ||
865 | /* The RTL8187 returns the retry count through register 0xFFFA. In | ||
866 | * addition, it appears to be a cumulative retry count, not the | ||
867 | * value for the current TX packet. When multiple TX entries are | ||
868 | * queued, the retry count will be valid for the last one in the queue. | ||
869 | * The "error" should not matter for purposes of rate setting. */ | ||
870 | struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, | ||
871 | work.work); | ||
872 | struct ieee80211_tx_info *info; | ||
873 | struct ieee80211_hw *dev = priv->dev; | ||
874 | static u16 retry; | ||
875 | u16 tmp; | ||
876 | |||
877 | mutex_lock(&priv->conf_mutex); | ||
878 | tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA); | ||
879 | while (skb_queue_len(&priv->b_tx_status.queue) > 0) { | ||
880 | struct sk_buff *old_skb; | ||
881 | |||
882 | old_skb = skb_dequeue(&priv->b_tx_status.queue); | ||
883 | info = IEEE80211_SKB_CB(old_skb); | ||
884 | info->status.rates[0].count = tmp - retry + 1; | ||
885 | ieee80211_tx_status_irqsafe(dev, old_skb); | ||
886 | } | ||
887 | retry = tmp; | ||
888 | mutex_unlock(&priv->conf_mutex); | ||
889 | } | ||
890 | |||
858 | static int rtl8187_start(struct ieee80211_hw *dev) | 891 | static int rtl8187_start(struct ieee80211_hw *dev) |
859 | { | 892 | { |
860 | struct rtl8187_priv *priv = dev->priv; | 893 | struct rtl8187_priv *priv = dev->priv; |
@@ -869,6 +902,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
869 | mutex_lock(&priv->conf_mutex); | 902 | mutex_lock(&priv->conf_mutex); |
870 | 903 | ||
871 | init_usb_anchor(&priv->anchored); | 904 | init_usb_anchor(&priv->anchored); |
905 | priv->dev = dev; | ||
872 | 906 | ||
873 | if (priv->is_rtl8187b) { | 907 | if (priv->is_rtl8187b) { |
874 | reg = RTL818X_RX_CONF_MGMT | | 908 | reg = RTL818X_RX_CONF_MGMT | |
@@ -936,6 +970,7 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
936 | reg |= RTL818X_CMD_TX_ENABLE; | 970 | reg |= RTL818X_CMD_TX_ENABLE; |
937 | reg |= RTL818X_CMD_RX_ENABLE; | 971 | reg |= RTL818X_CMD_RX_ENABLE; |
938 | rtl818x_iowrite8(priv, &priv->map->CMD, reg); | 972 | rtl818x_iowrite8(priv, &priv->map->CMD, reg); |
973 | INIT_DELAYED_WORK(&priv->work, rtl8187_work); | ||
939 | mutex_unlock(&priv->conf_mutex); | 974 | mutex_unlock(&priv->conf_mutex); |
940 | 975 | ||
941 | return 0; | 976 | return 0; |
@@ -966,6 +1001,8 @@ static void rtl8187_stop(struct ieee80211_hw *dev) | |||
966 | dev_kfree_skb_any(skb); | 1001 | dev_kfree_skb_any(skb); |
967 | 1002 | ||
968 | usb_kill_anchored_urbs(&priv->anchored); | 1003 | usb_kill_anchored_urbs(&priv->anchored); |
1004 | if (!priv->is_rtl8187b) | ||
1005 | cancel_delayed_work_sync(&priv->work); | ||
969 | mutex_unlock(&priv->conf_mutex); | 1006 | mutex_unlock(&priv->conf_mutex); |
970 | } | 1007 | } |
971 | 1008 | ||
@@ -974,19 +1011,21 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
974 | { | 1011 | { |
975 | struct rtl8187_priv *priv = dev->priv; | 1012 | struct rtl8187_priv *priv = dev->priv; |
976 | int i; | 1013 | int i; |
1014 | int ret = -EOPNOTSUPP; | ||
977 | 1015 | ||
1016 | mutex_lock(&priv->conf_mutex); | ||
978 | if (priv->mode != NL80211_IFTYPE_MONITOR) | 1017 | if (priv->mode != NL80211_IFTYPE_MONITOR) |
979 | return -EOPNOTSUPP; | 1018 | goto exit; |
980 | 1019 | ||
981 | switch (conf->type) { | 1020 | switch (conf->type) { |
982 | case NL80211_IFTYPE_STATION: | 1021 | case NL80211_IFTYPE_STATION: |
983 | priv->mode = conf->type; | 1022 | priv->mode = conf->type; |
984 | break; | 1023 | break; |
985 | default: | 1024 | default: |
986 | return -EOPNOTSUPP; | 1025 | goto exit; |
987 | } | 1026 | } |
988 | 1027 | ||
989 | mutex_lock(&priv->conf_mutex); | 1028 | ret = 0; |
990 | priv->vif = conf->vif; | 1029 | priv->vif = conf->vif; |
991 | 1030 | ||
992 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); | 1031 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); |
@@ -995,8 +1034,9 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, | |||
995 | ((u8 *)conf->mac_addr)[i]); | 1034 | ((u8 *)conf->mac_addr)[i]); |
996 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); | 1035 | rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); |
997 | 1036 | ||
1037 | exit: | ||
998 | mutex_unlock(&priv->conf_mutex); | 1038 | mutex_unlock(&priv->conf_mutex); |
999 | return 0; | 1039 | return ret; |
1000 | } | 1040 | } |
1001 | 1041 | ||
1002 | static void rtl8187_remove_interface(struct ieee80211_hw *dev, | 1042 | static void rtl8187_remove_interface(struct ieee80211_hw *dev, |
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index c99a1b6b948f..c8d5c34e8ddf 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/string.h> | 45 | #include <linux/string.h> |
46 | #include <linux/wireless.h> | 46 | #include <linux/wireless.h> |
47 | #include <linux/ieee80211.h> | ||
47 | 48 | ||
48 | #include <net/iw_handler.h> | 49 | #include <net/iw_handler.h> |
49 | 50 | ||
@@ -111,12 +112,6 @@ static void wl3501_release(struct pcmcia_device *link); | |||
111 | */ | 112 | */ |
112 | static dev_info_t wl3501_dev_info = "wl3501_cs"; | 113 | static dev_info_t wl3501_dev_info = "wl3501_cs"; |
113 | 114 | ||
114 | static int wl3501_chan2freq[] = { | ||
115 | [0] = 2412, [1] = 2417, [2] = 2422, [3] = 2427, [4] = 2432, | ||
116 | [5] = 2437, [6] = 2442, [7] = 2447, [8] = 2452, [9] = 2457, | ||
117 | [10] = 2462, [11] = 2467, [12] = 2472, [13] = 2477, | ||
118 | }; | ||
119 | |||
120 | static const struct { | 115 | static const struct { |
121 | int reg_domain; | 116 | int reg_domain; |
122 | int min, max, deflt; | 117 | int min, max, deflt; |
@@ -1510,7 +1505,7 @@ static int wl3501_get_freq(struct net_device *dev, struct iw_request_info *info, | |||
1510 | { | 1505 | { |
1511 | struct wl3501_card *this = netdev_priv(dev); | 1506 | struct wl3501_card *this = netdev_priv(dev); |
1512 | 1507 | ||
1513 | wrqu->freq.m = wl3501_chan2freq[this->chan - 1] * 100000; | 1508 | wrqu->freq.m = ieee80211_dsss_chan_to_freq(this->chan) * 100000; |
1514 | wrqu->freq.e = 1; | 1509 | wrqu->freq.e = 1; |
1515 | return 0; | 1510 | return 0; |
1516 | } | 1511 | } |
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index b45c27d42fd8..6226ac2357f8 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c | |||
@@ -919,10 +919,9 @@ static int zd1201_set_freq(struct net_device *dev, | |||
919 | if (freq->e == 0) | 919 | if (freq->e == 0) |
920 | channel = freq->m; | 920 | channel = freq->m; |
921 | else { | 921 | else { |
922 | if (freq->m >= 2482) | 922 | channel = ieee80211_freq_to_dsss_chan(freq->m); |
923 | channel = 14; | 923 | if (channel < 0) |
924 | if (freq->m >= 2407) | 924 | channel = 0; |
925 | channel = (freq->m-2407)/5; | ||
926 | } | 925 | } |
927 | 926 | ||
928 | err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel); | 927 | err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel); |