diff options
author | David S. Miller <davem@davemloft.net> | 2010-03-22 21:15:15 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-03-22 21:15:15 -0400 |
commit | 33e2bf6aa16061bae1253514e7c32af27d2b4b31 (patch) | |
tree | 652d13b4feea9a8f562186e7badae72d2e22fe1f /drivers/net | |
parent | e880eb6c5c9d98e389ffc0d8947f75d70785361a (diff) | |
parent | 819bfecc4fc6b6e5a793f719a45b7146ce423b79 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/net/wireless/ath/ath5k/phy.c
Diffstat (limited to 'drivers/net')
101 files changed, 3559 insertions, 2267 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index dc5018a6d9ed..a441aad922c2 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -2876,7 +2876,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, | |||
2876 | ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0; | 2876 | ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0; |
2877 | ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0; | 2877 | ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0; |
2878 | 2878 | ||
2879 | airo_print_info(dev->name, "Firmware version %x.%x.%02x", | 2879 | airo_print_info(dev->name, "Firmware version %x.%x.%02d", |
2880 | ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF), | 2880 | ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF), |
2881 | (le16_to_cpu(cap_rid.softVer) & 0xFF), | 2881 | (le16_to_cpu(cap_rid.softVer) & 0xFF), |
2882 | le16_to_cpu(cap_rid.softSubVer)); | 2882 | le16_to_cpu(cap_rid.softSubVer)); |
@@ -3193,19 +3193,26 @@ static void airo_print_status(const char *devname, u16 status) | |||
3193 | { | 3193 | { |
3194 | u8 reason = status & 0xFF; | 3194 | u8 reason = status & 0xFF; |
3195 | 3195 | ||
3196 | switch (status) { | 3196 | switch (status & 0xFF00) { |
3197 | case STAT_NOBEACON: | 3197 | case STAT_NOBEACON: |
3198 | airo_print_dbg(devname, "link lost (missed beacons)"); | 3198 | switch (status) { |
3199 | break; | 3199 | case STAT_NOBEACON: |
3200 | case STAT_MAXRETRIES: | 3200 | airo_print_dbg(devname, "link lost (missed beacons)"); |
3201 | case STAT_MAXARL: | 3201 | break; |
3202 | airo_print_dbg(devname, "link lost (max retries)"); | 3202 | case STAT_MAXRETRIES: |
3203 | break; | 3203 | case STAT_MAXARL: |
3204 | case STAT_FORCELOSS: | 3204 | airo_print_dbg(devname, "link lost (max retries)"); |
3205 | airo_print_dbg(devname, "link lost (local choice)"); | 3205 | break; |
3206 | break; | 3206 | case STAT_FORCELOSS: |
3207 | case STAT_TSFSYNC: | 3207 | airo_print_dbg(devname, "link lost (local choice)"); |
3208 | airo_print_dbg(devname, "link lost (TSF sync lost)"); | 3208 | break; |
3209 | case STAT_TSFSYNC: | ||
3210 | airo_print_dbg(devname, "link lost (TSF sync lost)"); | ||
3211 | break; | ||
3212 | default: | ||
3213 | airo_print_dbg(devname, "unknow status %x\n", status); | ||
3214 | break; | ||
3215 | } | ||
3209 | break; | 3216 | break; |
3210 | case STAT_DEAUTH: | 3217 | case STAT_DEAUTH: |
3211 | airo_print_dbg(devname, "deauthenticated (reason: %d)", reason); | 3218 | airo_print_dbg(devname, "deauthenticated (reason: %d)", reason); |
@@ -3221,7 +3228,11 @@ static void airo_print_status(const char *devname, u16 status) | |||
3221 | airo_print_dbg(devname, "authentication failed (reason: %d)", | 3228 | airo_print_dbg(devname, "authentication failed (reason: %d)", |
3222 | reason); | 3229 | reason); |
3223 | break; | 3230 | break; |
3231 | case STAT_ASSOC: | ||
3232 | case STAT_REASSOC: | ||
3233 | break; | ||
3224 | default: | 3234 | default: |
3235 | airo_print_dbg(devname, "unknow status %x\n", status); | ||
3225 | break; | 3236 | break; |
3226 | } | 3237 | } |
3227 | } | 3238 | } |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ac67f02e26d8..1d7491c85460 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -202,7 +202,6 @@ | |||
202 | #define AR5K_TUNE_MAX_TXPOWER 63 | 202 | #define AR5K_TUNE_MAX_TXPOWER 63 |
203 | #define AR5K_TUNE_DEFAULT_TXPOWER 25 | 203 | #define AR5K_TUNE_DEFAULT_TXPOWER 25 |
204 | #define AR5K_TUNE_TPC_TXPOWER false | 204 | #define AR5K_TUNE_TPC_TXPOWER false |
205 | #define AR5K_TUNE_HWTXTRIES 4 | ||
206 | 205 | ||
207 | #define AR5K_INIT_CARR_SENSE_EN 1 | 206 | #define AR5K_INIT_CARR_SENSE_EN 1 |
208 | 207 | ||
@@ -614,28 +613,6 @@ struct ath5k_rx_status { | |||
614 | #define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ | 613 | #define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ |
615 | #define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ | 614 | #define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ |
616 | 615 | ||
617 | #if 0 | ||
618 | /** | ||
619 | * struct ath5k_beacon_state - Per-station beacon timer state. | ||
620 | * @bs_interval: in TU's, can also include the above flags | ||
621 | * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a | ||
622 | * Point Coordination Function capable AP | ||
623 | */ | ||
624 | struct ath5k_beacon_state { | ||
625 | u32 bs_next_beacon; | ||
626 | u32 bs_next_dtim; | ||
627 | u32 bs_interval; | ||
628 | u8 bs_dtim_period; | ||
629 | u8 bs_cfp_period; | ||
630 | u16 bs_cfp_max_duration; | ||
631 | u16 bs_cfp_du_remain; | ||
632 | u16 bs_tim_offset; | ||
633 | u16 bs_sleep_duration; | ||
634 | u16 bs_bmiss_threshold; | ||
635 | u32 bs_cfp_next; | ||
636 | }; | ||
637 | #endif | ||
638 | |||
639 | 616 | ||
640 | /* | 617 | /* |
641 | * TSF to TU conversion: | 618 | * TSF to TU conversion: |
@@ -1028,7 +1005,6 @@ struct ath5k_nfcal_hist | |||
1028 | 1005 | ||
1029 | /* TODO: Clean up and merge with ath5k_softc */ | 1006 | /* TODO: Clean up and merge with ath5k_softc */ |
1030 | struct ath5k_hw { | 1007 | struct ath5k_hw { |
1031 | u32 ah_magic; | ||
1032 | struct ath_common common; | 1008 | struct ath_common common; |
1033 | 1009 | ||
1034 | struct ath5k_softc *ah_sc; | 1010 | struct ath5k_softc *ah_sc; |
@@ -1036,7 +1012,6 @@ struct ath5k_hw { | |||
1036 | 1012 | ||
1037 | enum ath5k_int ah_imr; | 1013 | enum ath5k_int ah_imr; |
1038 | 1014 | ||
1039 | enum nl80211_iftype ah_op_mode; | ||
1040 | struct ieee80211_channel *ah_current_channel; | 1015 | struct ieee80211_channel *ah_current_channel; |
1041 | bool ah_turbo; | 1016 | bool ah_turbo; |
1042 | bool ah_calibration; | 1017 | bool ah_calibration; |
@@ -1049,7 +1024,6 @@ struct ath5k_hw { | |||
1049 | u32 ah_phy; | 1024 | u32 ah_phy; |
1050 | u32 ah_mac_srev; | 1025 | u32 ah_mac_srev; |
1051 | u16 ah_mac_version; | 1026 | u16 ah_mac_version; |
1052 | u16 ah_mac_revision; | ||
1053 | u16 ah_phy_revision; | 1027 | u16 ah_phy_revision; |
1054 | u16 ah_radio_5ghz_revision; | 1028 | u16 ah_radio_5ghz_revision; |
1055 | u16 ah_radio_2ghz_revision; | 1029 | u16 ah_radio_2ghz_revision; |
@@ -1071,8 +1045,6 @@ struct ath5k_hw { | |||
1071 | u8 ah_def_ant; | 1045 | u8 ah_def_ant; |
1072 | bool ah_software_retry; | 1046 | bool ah_software_retry; |
1073 | 1047 | ||
1074 | int ah_gpio_npins; | ||
1075 | |||
1076 | struct ath5k_capabilities ah_capabilities; | 1048 | struct ath5k_capabilities ah_capabilities; |
1077 | 1049 | ||
1078 | struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; | 1050 | struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; |
@@ -1141,9 +1113,9 @@ struct ath5k_hw { | |||
1141 | int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, | 1113 | int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, |
1142 | u32 size, unsigned int flags); | 1114 | u32 size, unsigned int flags); |
1143 | int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, | 1115 | int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, |
1144 | unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, | 1116 | unsigned int, unsigned int, int, enum ath5k_pkt_type, |
1145 | unsigned int, unsigned int, unsigned int, unsigned int, | 1117 | unsigned int, unsigned int, unsigned int, unsigned int, |
1146 | unsigned int, unsigned int, unsigned int); | 1118 | unsigned int, unsigned int, unsigned int, unsigned int); |
1147 | int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, | 1119 | int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, |
1148 | unsigned int, unsigned int, unsigned int, unsigned int, | 1120 | unsigned int, unsigned int, unsigned int, unsigned int, |
1149 | unsigned int, unsigned int); | 1121 | unsigned int, unsigned int); |
@@ -1158,158 +1130,147 @@ struct ath5k_hw { | |||
1158 | */ | 1130 | */ |
1159 | 1131 | ||
1160 | /* Attach/Detach Functions */ | 1132 | /* Attach/Detach Functions */ |
1161 | extern int ath5k_hw_attach(struct ath5k_softc *sc); | 1133 | int ath5k_hw_attach(struct ath5k_softc *sc); |
1162 | extern void ath5k_hw_detach(struct ath5k_hw *ah); | 1134 | void ath5k_hw_detach(struct ath5k_hw *ah); |
1163 | 1135 | ||
1164 | /* LED functions */ | 1136 | /* LED functions */ |
1165 | extern int ath5k_init_leds(struct ath5k_softc *sc); | 1137 | int ath5k_init_leds(struct ath5k_softc *sc); |
1166 | extern void ath5k_led_enable(struct ath5k_softc *sc); | 1138 | void ath5k_led_enable(struct ath5k_softc *sc); |
1167 | extern void ath5k_led_off(struct ath5k_softc *sc); | 1139 | void ath5k_led_off(struct ath5k_softc *sc); |
1168 | extern void ath5k_unregister_leds(struct ath5k_softc *sc); | 1140 | void ath5k_unregister_leds(struct ath5k_softc *sc); |
1169 | 1141 | ||
1170 | /* Reset Functions */ | 1142 | /* Reset Functions */ |
1171 | extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); | 1143 | int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); |
1172 | extern int ath5k_hw_on_hold(struct ath5k_hw *ah); | 1144 | int ath5k_hw_on_hold(struct ath5k_hw *ah); |
1173 | extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); | 1145 | int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, |
1146 | struct ieee80211_channel *channel, bool change_channel); | ||
1147 | int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, | ||
1148 | bool is_set); | ||
1174 | /* Power management functions */ | 1149 | /* Power management functions */ |
1175 | extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration); | ||
1176 | 1150 | ||
1177 | /* DMA Related Functions */ | 1151 | /* DMA Related Functions */ |
1178 | extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); | 1152 | void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); |
1179 | extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); | 1153 | int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); |
1180 | extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); | 1154 | u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); |
1181 | extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); | 1155 | void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); |
1182 | extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); | 1156 | int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); |
1183 | extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); | 1157 | int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); |
1184 | extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); | 1158 | u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); |
1185 | extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, | 1159 | int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, |
1186 | u32 phys_addr); | 1160 | u32 phys_addr); |
1187 | extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); | 1161 | int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); |
1188 | /* Interrupt handling */ | 1162 | /* Interrupt handling */ |
1189 | extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); | 1163 | bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); |
1190 | extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); | 1164 | int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); |
1191 | extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum | 1165 | enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); |
1192 | ath5k_int new_mask); | 1166 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, |
1193 | extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats); | 1167 | struct ieee80211_low_level_stats *stats); |
1194 | 1168 | ||
1195 | /* EEPROM access functions */ | 1169 | /* EEPROM access functions */ |
1196 | extern int ath5k_eeprom_init(struct ath5k_hw *ah); | 1170 | int ath5k_eeprom_init(struct ath5k_hw *ah); |
1197 | extern void ath5k_eeprom_detach(struct ath5k_hw *ah); | 1171 | void ath5k_eeprom_detach(struct ath5k_hw *ah); |
1198 | extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); | 1172 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); |
1199 | extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah); | ||
1200 | 1173 | ||
1201 | /* Protocol Control Unit Functions */ | 1174 | /* Protocol Control Unit Functions */ |
1202 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); | 1175 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); |
1203 | extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); | 1176 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); |
1204 | /* BSSID Functions */ | 1177 | /* BSSID Functions */ |
1205 | extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); | 1178 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); |
1206 | extern void ath5k_hw_set_associd(struct ath5k_hw *ah); | 1179 | void ath5k_hw_set_associd(struct ath5k_hw *ah); |
1207 | extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); | 1180 | void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); |
1208 | /* Receive start/stop functions */ | 1181 | /* Receive start/stop functions */ |
1209 | extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); | 1182 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); |
1210 | extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); | 1183 | void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); |
1211 | /* RX Filter functions */ | 1184 | /* RX Filter functions */ |
1212 | extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); | 1185 | void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); |
1213 | extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index); | 1186 | u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); |
1214 | extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); | 1187 | void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); |
1215 | extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); | ||
1216 | extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); | ||
1217 | /* Beacon control functions */ | 1188 | /* Beacon control functions */ |
1218 | extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); | 1189 | u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); |
1219 | extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); | 1190 | void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); |
1220 | extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); | 1191 | void ath5k_hw_reset_tsf(struct ath5k_hw *ah); |
1221 | extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); | 1192 | void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); |
1222 | extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); | ||
1223 | #if 0 | ||
1224 | extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state); | ||
1225 | extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah); | ||
1226 | extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr); | ||
1227 | #endif | ||
1228 | /* ACK bit rate */ | 1193 | /* ACK bit rate */ |
1229 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); | 1194 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); |
1230 | /* ACK/CTS Timeouts */ | ||
1231 | extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout); | ||
1232 | extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); | ||
1233 | extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); | ||
1234 | extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); | ||
1235 | /* Clock rate related functions */ | 1195 | /* Clock rate related functions */ |
1236 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); | 1196 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); |
1237 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); | 1197 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); |
1238 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); | 1198 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); |
1239 | /* Key table (WEP) functions */ | 1199 | /* Key table (WEP) functions */ |
1240 | extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); | 1200 | int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); |
1241 | extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); | 1201 | int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, |
1242 | extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); | 1202 | const struct ieee80211_key_conf *key, const u8 *mac); |
1243 | extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); | 1203 | int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); |
1244 | 1204 | ||
1245 | /* Queue Control Unit, DFS Control Unit Functions */ | 1205 | /* Queue Control Unit, DFS Control Unit Functions */ |
1246 | extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); | 1206 | int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, |
1247 | extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, | 1207 | struct ath5k_txq_info *queue_info); |
1248 | const struct ath5k_txq_info *queue_info); | 1208 | int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, |
1249 | extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, | 1209 | const struct ath5k_txq_info *queue_info); |
1250 | enum ath5k_tx_queue queue_type, | 1210 | int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, |
1251 | struct ath5k_txq_info *queue_info); | 1211 | enum ath5k_tx_queue queue_type, |
1252 | extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); | 1212 | struct ath5k_txq_info *queue_info); |
1253 | extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1213 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); |
1254 | extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1214 | void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
1255 | extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); | 1215 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
1256 | extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); | 1216 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); |
1257 | 1217 | ||
1258 | /* Hardware Descriptor Functions */ | 1218 | /* Hardware Descriptor Functions */ |
1259 | extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); | 1219 | int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); |
1260 | 1220 | ||
1261 | /* GPIO Functions */ | 1221 | /* GPIO Functions */ |
1262 | extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); | 1222 | void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); |
1263 | extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); | 1223 | int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); |
1264 | extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); | 1224 | int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); |
1265 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); | 1225 | u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); |
1266 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); | 1226 | int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); |
1267 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); | 1227 | void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, |
1228 | u32 interrupt_level); | ||
1268 | 1229 | ||
1269 | /* rfkill Functions */ | 1230 | /* rfkill Functions */ |
1270 | extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); | 1231 | void ath5k_rfkill_hw_start(struct ath5k_hw *ah); |
1271 | extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); | 1232 | void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); |
1272 | 1233 | ||
1273 | /* Misc functions */ | 1234 | /* Misc functions */ |
1274 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); | 1235 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); |
1275 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); | 1236 | int ath5k_hw_get_capability(struct ath5k_hw *ah, |
1276 | extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); | 1237 | enum ath5k_capability_type cap_type, u32 capability, |
1277 | extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); | 1238 | u32 *result); |
1239 | int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); | ||
1240 | int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); | ||
1278 | 1241 | ||
1279 | /* Initial register settings functions */ | 1242 | /* Initial register settings functions */ |
1280 | extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); | 1243 | int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); |
1281 | 1244 | ||
1282 | /* Initialize RF */ | 1245 | /* Initialize RF */ |
1283 | extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, | 1246 | int ath5k_hw_rfregs_init(struct ath5k_hw *ah, |
1284 | struct ieee80211_channel *channel, | 1247 | struct ieee80211_channel *channel, |
1285 | unsigned int mode); | 1248 | unsigned int mode); |
1286 | extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); | 1249 | int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); |
1287 | extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); | 1250 | enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); |
1288 | extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); | 1251 | int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); |
1289 | /* PHY/RF channel functions */ | 1252 | /* PHY/RF channel functions */ |
1290 | extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); | 1253 | bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); |
1291 | extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); | 1254 | int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); |
1292 | /* PHY calibration */ | 1255 | /* PHY calibration */ |
1293 | void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); | 1256 | void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); |
1294 | extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); | 1257 | int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, |
1295 | extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); | 1258 | struct ieee80211_channel *channel); |
1296 | extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah); | 1259 | void ath5k_hw_calibration_poll(struct ath5k_hw *ah); |
1297 | extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah); | ||
1298 | /* Spur mitigation */ | 1260 | /* Spur mitigation */ |
1299 | bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, | 1261 | bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, |
1300 | struct ieee80211_channel *channel); | 1262 | struct ieee80211_channel *channel); |
1301 | void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | 1263 | void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, |
1302 | struct ieee80211_channel *channel); | 1264 | struct ieee80211_channel *channel); |
1303 | /* Misc PHY functions */ | 1265 | /* Misc PHY functions */ |
1304 | extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); | 1266 | u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); |
1305 | extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); | 1267 | int ath5k_hw_phy_disable(struct ath5k_hw *ah); |
1306 | /* Antenna control */ | 1268 | /* Antenna control */ |
1307 | extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); | 1269 | void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); |
1308 | extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant); | ||
1309 | extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); | ||
1310 | /* TX power setup */ | 1270 | /* TX power setup */ |
1311 | extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); | 1271 | int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
1312 | extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); | 1272 | u8 ee_mode, u8 txpower); |
1273 | int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); | ||
1313 | 1274 | ||
1314 | /* | 1275 | /* |
1315 | * Functions used internaly | 1276 | * Functions used internaly |
@@ -1335,29 +1296,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | |||
1335 | iowrite32(val, ah->ah_iobase + reg); | 1296 | iowrite32(val, ah->ah_iobase + reg); |
1336 | } | 1297 | } |
1337 | 1298 | ||
1338 | #if defined(_ATH5K_RESET) || defined(_ATH5K_PHY) | ||
1339 | /* | ||
1340 | * Check if a register write has been completed | ||
1341 | */ | ||
1342 | static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, | ||
1343 | u32 val, bool is_set) | ||
1344 | { | ||
1345 | int i; | ||
1346 | u32 data; | ||
1347 | |||
1348 | for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { | ||
1349 | data = ath5k_hw_reg_read(ah, reg); | ||
1350 | if (is_set && (data & flag)) | ||
1351 | break; | ||
1352 | else if ((data & flag) == val) | ||
1353 | break; | ||
1354 | udelay(15); | ||
1355 | } | ||
1356 | |||
1357 | return (i <= 0) ? -EAGAIN : 0; | ||
1358 | } | ||
1359 | #endif | ||
1360 | |||
1361 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) | 1299 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) |
1362 | { | 1300 | { |
1363 | u32 retval = 0, bit, i; | 1301 | u32 retval = 0, bit, i; |
@@ -1370,9 +1308,4 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) | |||
1370 | return retval; | 1308 | return retval; |
1371 | } | 1309 | } |
1372 | 1310 | ||
1373 | static inline int ath5k_pad_size(int hdrlen) | ||
1374 | { | ||
1375 | return (hdrlen < 24) ? 0 : hdrlen & 3; | ||
1376 | } | ||
1377 | |||
1378 | #endif | 1311 | #endif |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 42284445b75e..dd4099a2ff15 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -113,7 +113,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
113 | /* | 113 | /* |
114 | * HW information | 114 | * HW information |
115 | */ | 115 | */ |
116 | ah->ah_op_mode = NL80211_IFTYPE_STATION; | ||
117 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | 116 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; |
118 | ah->ah_turbo = false; | 117 | ah->ah_turbo = false; |
119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | 118 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; |
@@ -123,6 +122,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
123 | ah->ah_cw_min = AR5K_TUNE_CWMIN; | 122 | ah->ah_cw_min = AR5K_TUNE_CWMIN; |
124 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; | 123 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; |
125 | ah->ah_software_retry = false; | 124 | ah->ah_software_retry = false; |
125 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; | ||
126 | 126 | ||
127 | /* | 127 | /* |
128 | * Find the mac version | 128 | * Find the mac version |
@@ -148,7 +148,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
148 | /* Get MAC, PHY and RADIO revisions */ | 148 | /* Get MAC, PHY and RADIO revisions */ |
149 | ah->ah_mac_srev = srev; | 149 | ah->ah_mac_srev = srev; |
150 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); | 150 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); |
151 | ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV); | ||
152 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & | 151 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & |
153 | 0xffffffff; | 152 | 0xffffffff; |
154 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, | 153 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, |
@@ -327,7 +326,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
327 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | 326 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ |
328 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); | 327 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); |
329 | ath5k_hw_set_associd(ah); | 328 | ath5k_hw_set_associd(ah); |
330 | ath5k_hw_set_opmode(ah); | 329 | ath5k_hw_set_opmode(ah, sc->opmode); |
331 | 330 | ||
332 | ath5k_hw_rfgain_opt_init(ah); | 331 | ath5k_hw_rfgain_opt_init(ah); |
333 | 332 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8dce0077b023..b142a78ed1e5 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -198,7 +198,7 @@ static void __devexit ath5k_pci_remove(struct pci_dev *pdev); | |||
198 | static int ath5k_pci_suspend(struct device *dev); | 198 | static int ath5k_pci_suspend(struct device *dev); |
199 | static int ath5k_pci_resume(struct device *dev); | 199 | static int ath5k_pci_resume(struct device *dev); |
200 | 200 | ||
201 | SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | 201 | static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); |
202 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | 202 | #define ATH5K_PM_OPS (&ath5k_pm_ops) |
203 | #else | 203 | #else |
204 | #define ATH5K_PM_OPS NULL | 204 | #define ATH5K_PM_OPS NULL |
@@ -307,7 +307,7 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc, | |||
307 | struct ath5k_buf *bf); | 307 | struct ath5k_buf *bf); |
308 | static int ath5k_txbuf_setup(struct ath5k_softc *sc, | 308 | static int ath5k_txbuf_setup(struct ath5k_softc *sc, |
309 | struct ath5k_buf *bf, | 309 | struct ath5k_buf *bf, |
310 | struct ath5k_txq *txq); | 310 | struct ath5k_txq *txq, int padsize); |
311 | static inline void ath5k_txbuf_free(struct ath5k_softc *sc, | 311 | static inline void ath5k_txbuf_free(struct ath5k_softc *sc, |
312 | struct ath5k_buf *bf) | 312 | struct ath5k_buf *bf) |
313 | { | 313 | { |
@@ -1137,8 +1137,6 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1137 | struct ath5k_hw *ah = sc->ah; | 1137 | struct ath5k_hw *ah = sc->ah; |
1138 | u32 rfilt; | 1138 | u32 rfilt; |
1139 | 1139 | ||
1140 | ah->ah_op_mode = sc->opmode; | ||
1141 | |||
1142 | /* configure rx filter */ | 1140 | /* configure rx filter */ |
1143 | rfilt = sc->filter_flags; | 1141 | rfilt = sc->filter_flags; |
1144 | ath5k_hw_set_rx_filter(ah, rfilt); | 1142 | ath5k_hw_set_rx_filter(ah, rfilt); |
@@ -1147,8 +1145,9 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1147 | ath5k_hw_set_bssid_mask(ah, sc->bssidmask); | 1145 | ath5k_hw_set_bssid_mask(ah, sc->bssidmask); |
1148 | 1146 | ||
1149 | /* configure operational mode */ | 1147 | /* configure operational mode */ |
1150 | ath5k_hw_set_opmode(ah); | 1148 | ath5k_hw_set_opmode(ah, sc->opmode); |
1151 | 1149 | ||
1150 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); | ||
1152 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 1151 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1153 | } | 1152 | } |
1154 | 1153 | ||
@@ -1271,7 +1270,7 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1271 | 1270 | ||
1272 | static int | 1271 | static int |
1273 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | 1272 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, |
1274 | struct ath5k_txq *txq) | 1273 | struct ath5k_txq *txq, int padsize) |
1275 | { | 1274 | { |
1276 | struct ath5k_hw *ah = sc->ah; | 1275 | struct ath5k_hw *ah = sc->ah; |
1277 | struct ath5k_desc *ds = bf->desc; | 1276 | struct ath5k_desc *ds = bf->desc; |
@@ -1323,7 +1322,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1323 | sc->vif, pktlen, info)); | 1322 | sc->vif, pktlen, info)); |
1324 | } | 1323 | } |
1325 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1324 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1326 | ieee80211_get_hdrlen_from_skb(skb), | 1325 | ieee80211_get_hdrlen_from_skb(skb), padsize, |
1327 | get_hw_packet_type(skb), | 1326 | get_hw_packet_type(skb), |
1328 | (sc->power_level * 2), | 1327 | (sc->power_level * 2), |
1329 | hw_rate, | 1328 | hw_rate, |
@@ -1805,6 +1804,67 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1805 | } | 1804 | } |
1806 | } | 1805 | } |
1807 | 1806 | ||
1807 | /* | ||
1808 | * Compute padding position. skb must contains an IEEE 802.11 frame | ||
1809 | */ | ||
1810 | static int ath5k_common_padpos(struct sk_buff *skb) | ||
1811 | { | ||
1812 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | ||
1813 | __le16 frame_control = hdr->frame_control; | ||
1814 | int padpos = 24; | ||
1815 | |||
1816 | if (ieee80211_has_a4(frame_control)) { | ||
1817 | padpos += ETH_ALEN; | ||
1818 | } | ||
1819 | if (ieee80211_is_data_qos(frame_control)) { | ||
1820 | padpos += IEEE80211_QOS_CTL_LEN; | ||
1821 | } | ||
1822 | |||
1823 | return padpos; | ||
1824 | } | ||
1825 | |||
1826 | /* | ||
1827 | * This function expects a 802.11 frame and returns the number of | ||
1828 | * bytes added, or -1 if we don't have enought header room. | ||
1829 | */ | ||
1830 | |||
1831 | static int ath5k_add_padding(struct sk_buff *skb) | ||
1832 | { | ||
1833 | int padpos = ath5k_common_padpos(skb); | ||
1834 | int padsize = padpos & 3; | ||
1835 | |||
1836 | if (padsize && skb->len>padpos) { | ||
1837 | |||
1838 | if (skb_headroom(skb) < padsize) | ||
1839 | return -1; | ||
1840 | |||
1841 | skb_push(skb, padsize); | ||
1842 | memmove(skb->data, skb->data+padsize, padpos); | ||
1843 | return padsize; | ||
1844 | } | ||
1845 | |||
1846 | return 0; | ||
1847 | } | ||
1848 | |||
1849 | /* | ||
1850 | * This function expects a 802.11 frame and returns the number of | ||
1851 | * bytes removed | ||
1852 | */ | ||
1853 | |||
1854 | static int ath5k_remove_padding(struct sk_buff *skb) | ||
1855 | { | ||
1856 | int padpos = ath5k_common_padpos(skb); | ||
1857 | int padsize = padpos & 3; | ||
1858 | |||
1859 | if (padsize && skb->len>=padpos+padsize) { | ||
1860 | memmove(skb->data + padsize, skb->data, padpos); | ||
1861 | skb_pull(skb, padsize); | ||
1862 | return padsize; | ||
1863 | } | ||
1864 | |||
1865 | return 0; | ||
1866 | } | ||
1867 | |||
1808 | static void | 1868 | static void |
1809 | ath5k_tasklet_rx(unsigned long data) | 1869 | ath5k_tasklet_rx(unsigned long data) |
1810 | { | 1870 | { |
@@ -1818,8 +1878,6 @@ ath5k_tasklet_rx(unsigned long data) | |||
1818 | struct ath5k_buf *bf; | 1878 | struct ath5k_buf *bf; |
1819 | struct ath5k_desc *ds; | 1879 | struct ath5k_desc *ds; |
1820 | int ret; | 1880 | int ret; |
1821 | int hdrlen; | ||
1822 | int padsize; | ||
1823 | int rx_flag; | 1881 | int rx_flag; |
1824 | 1882 | ||
1825 | spin_lock(&sc->rxbuflock); | 1883 | spin_lock(&sc->rxbuflock); |
@@ -1844,18 +1902,28 @@ ath5k_tasklet_rx(unsigned long data) | |||
1844 | break; | 1902 | break; |
1845 | else if (unlikely(ret)) { | 1903 | else if (unlikely(ret)) { |
1846 | ATH5K_ERR(sc, "error in processing rx descriptor\n"); | 1904 | ATH5K_ERR(sc, "error in processing rx descriptor\n"); |
1905 | sc->stats.rxerr_proc++; | ||
1847 | spin_unlock(&sc->rxbuflock); | 1906 | spin_unlock(&sc->rxbuflock); |
1848 | return; | 1907 | return; |
1849 | } | 1908 | } |
1850 | 1909 | ||
1910 | sc->stats.rx_all_count++; | ||
1911 | |||
1851 | if (unlikely(rs.rs_more)) { | 1912 | if (unlikely(rs.rs_more)) { |
1852 | ATH5K_WARN(sc, "unsupported jumbo\n"); | 1913 | ATH5K_WARN(sc, "unsupported jumbo\n"); |
1914 | sc->stats.rxerr_jumbo++; | ||
1853 | goto next; | 1915 | goto next; |
1854 | } | 1916 | } |
1855 | 1917 | ||
1856 | if (unlikely(rs.rs_status)) { | 1918 | if (unlikely(rs.rs_status)) { |
1857 | if (rs.rs_status & AR5K_RXERR_PHY) | 1919 | if (rs.rs_status & AR5K_RXERR_CRC) |
1920 | sc->stats.rxerr_crc++; | ||
1921 | if (rs.rs_status & AR5K_RXERR_FIFO) | ||
1922 | sc->stats.rxerr_fifo++; | ||
1923 | if (rs.rs_status & AR5K_RXERR_PHY) { | ||
1924 | sc->stats.rxerr_phy++; | ||
1858 | goto next; | 1925 | goto next; |
1926 | } | ||
1859 | if (rs.rs_status & AR5K_RXERR_DECRYPT) { | 1927 | if (rs.rs_status & AR5K_RXERR_DECRYPT) { |
1860 | /* | 1928 | /* |
1861 | * Decrypt error. If the error occurred | 1929 | * Decrypt error. If the error occurred |
@@ -1867,12 +1935,14 @@ ath5k_tasklet_rx(unsigned long data) | |||
1867 | * | 1935 | * |
1868 | * XXX do key cache faulting | 1936 | * XXX do key cache faulting |
1869 | */ | 1937 | */ |
1938 | sc->stats.rxerr_decrypt++; | ||
1870 | if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && | 1939 | if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && |
1871 | !(rs.rs_status & AR5K_RXERR_CRC)) | 1940 | !(rs.rs_status & AR5K_RXERR_CRC)) |
1872 | goto accept; | 1941 | goto accept; |
1873 | } | 1942 | } |
1874 | if (rs.rs_status & AR5K_RXERR_MIC) { | 1943 | if (rs.rs_status & AR5K_RXERR_MIC) { |
1875 | rx_flag |= RX_FLAG_MMIC_ERROR; | 1944 | rx_flag |= RX_FLAG_MMIC_ERROR; |
1945 | sc->stats.rxerr_mic++; | ||
1876 | goto accept; | 1946 | goto accept; |
1877 | } | 1947 | } |
1878 | 1948 | ||
@@ -1904,12 +1974,8 @@ accept: | |||
1904 | * bytes and we can optimize this a bit. In addition, we must | 1974 | * bytes and we can optimize this a bit. In addition, we must |
1905 | * not try to remove padding from short control frames that do | 1975 | * not try to remove padding from short control frames that do |
1906 | * not have payload. */ | 1976 | * not have payload. */ |
1907 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1977 | ath5k_remove_padding(skb); |
1908 | padsize = ath5k_pad_size(hdrlen); | 1978 | |
1909 | if (padsize) { | ||
1910 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
1911 | skb_pull(skb, padsize); | ||
1912 | } | ||
1913 | rxs = IEEE80211_SKB_RXCB(skb); | 1979 | rxs = IEEE80211_SKB_RXCB(skb); |
1914 | 1980 | ||
1915 | /* | 1981 | /* |
@@ -1942,6 +2008,12 @@ accept: | |||
1942 | rxs->signal = rxs->noise + rs.rs_rssi; | 2008 | rxs->signal = rxs->noise + rs.rs_rssi; |
1943 | 2009 | ||
1944 | rxs->antenna = rs.rs_antenna; | 2010 | rxs->antenna = rs.rs_antenna; |
2011 | |||
2012 | if (rs.rs_antenna > 0 && rs.rs_antenna < 5) | ||
2013 | sc->stats.antenna_rx[rs.rs_antenna]++; | ||
2014 | else | ||
2015 | sc->stats.antenna_rx[0]++; /* invalid */ | ||
2016 | |||
1945 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 2017 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
1946 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); | 2018 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
1947 | 2019 | ||
@@ -1996,6 +2068,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1996 | break; | 2068 | break; |
1997 | } | 2069 | } |
1998 | 2070 | ||
2071 | sc->stats.tx_all_count++; | ||
1999 | skb = bf->skb; | 2072 | skb = bf->skb; |
2000 | info = IEEE80211_SKB_CB(skb); | 2073 | info = IEEE80211_SKB_CB(skb); |
2001 | bf->skb = NULL; | 2074 | bf->skb = NULL; |
@@ -2022,13 +2095,30 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
2022 | 2095 | ||
2023 | if (unlikely(ts.ts_status)) { | 2096 | if (unlikely(ts.ts_status)) { |
2024 | sc->ll_stats.dot11ACKFailureCount++; | 2097 | sc->ll_stats.dot11ACKFailureCount++; |
2025 | if (ts.ts_status & AR5K_TXERR_FILT) | 2098 | if (ts.ts_status & AR5K_TXERR_FILT) { |
2026 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 2099 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
2100 | sc->stats.txerr_filt++; | ||
2101 | } | ||
2102 | if (ts.ts_status & AR5K_TXERR_XRETRY) | ||
2103 | sc->stats.txerr_retry++; | ||
2104 | if (ts.ts_status & AR5K_TXERR_FIFO) | ||
2105 | sc->stats.txerr_fifo++; | ||
2027 | } else { | 2106 | } else { |
2028 | info->flags |= IEEE80211_TX_STAT_ACK; | 2107 | info->flags |= IEEE80211_TX_STAT_ACK; |
2029 | info->status.ack_signal = ts.ts_rssi; | 2108 | info->status.ack_signal = ts.ts_rssi; |
2030 | } | 2109 | } |
2031 | 2110 | ||
2111 | /* | ||
2112 | * Remove MAC header padding before giving the frame | ||
2113 | * back to mac80211. | ||
2114 | */ | ||
2115 | ath5k_remove_padding(skb); | ||
2116 | |||
2117 | if (ts.ts_antenna > 0 && ts.ts_antenna < 5) | ||
2118 | sc->stats.antenna_tx[ts.ts_antenna]++; | ||
2119 | else | ||
2120 | sc->stats.antenna_tx[0]++; /* invalid */ | ||
2121 | |||
2032 | ieee80211_tx_status(sc->hw, skb); | 2122 | ieee80211_tx_status(sc->hw, skb); |
2033 | 2123 | ||
2034 | spin_lock(&sc->txbuflock); | 2124 | spin_lock(&sc->txbuflock); |
@@ -2072,6 +2162,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2072 | int ret = 0; | 2162 | int ret = 0; |
2073 | u8 antenna; | 2163 | u8 antenna; |
2074 | u32 flags; | 2164 | u32 flags; |
2165 | const int padsize = 0; | ||
2075 | 2166 | ||
2076 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, | 2167 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, |
2077 | PCI_DMA_TODEVICE); | 2168 | PCI_DMA_TODEVICE); |
@@ -2119,7 +2210,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2119 | * from tx power (value is in dB units already) */ | 2210 | * from tx power (value is in dB units already) */ |
2120 | ds->ds_data = bf->skbaddr; | 2211 | ds->ds_data = bf->skbaddr; |
2121 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, | 2212 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, |
2122 | ieee80211_get_hdrlen_from_skb(skb), | 2213 | ieee80211_get_hdrlen_from_skb(skb), padsize, |
2123 | AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), | 2214 | AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), |
2124 | ieee80211_get_tx_rate(sc->hw, info)->hw_value, | 2215 | ieee80211_get_tx_rate(sc->hw, info)->hw_value, |
2125 | 1, AR5K_TXKEYIX_INVALID, | 2216 | 1, AR5K_TXKEYIX_INVALID, |
@@ -2679,7 +2770,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2679 | struct ath5k_softc *sc = hw->priv; | 2770 | struct ath5k_softc *sc = hw->priv; |
2680 | struct ath5k_buf *bf; | 2771 | struct ath5k_buf *bf; |
2681 | unsigned long flags; | 2772 | unsigned long flags; |
2682 | int hdrlen; | ||
2683 | int padsize; | 2773 | int padsize; |
2684 | 2774 | ||
2685 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | 2775 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); |
@@ -2691,17 +2781,11 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2691 | * the hardware expects the header padded to 4 byte boundaries | 2781 | * the hardware expects the header padded to 4 byte boundaries |
2692 | * if this is not the case we add the padding after the header | 2782 | * if this is not the case we add the padding after the header |
2693 | */ | 2783 | */ |
2694 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 2784 | padsize = ath5k_add_padding(skb); |
2695 | padsize = ath5k_pad_size(hdrlen); | 2785 | if (padsize < 0) { |
2696 | if (padsize) { | 2786 | ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" |
2697 | 2787 | " headroom to pad"); | |
2698 | if (skb_headroom(skb) < padsize) { | 2788 | goto drop_packet; |
2699 | ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough" | ||
2700 | " headroom to pad %d\n", hdrlen, padsize); | ||
2701 | goto drop_packet; | ||
2702 | } | ||
2703 | skb_push(skb, padsize); | ||
2704 | memmove(skb->data, skb->data+padsize, hdrlen); | ||
2705 | } | 2789 | } |
2706 | 2790 | ||
2707 | spin_lock_irqsave(&sc->txbuflock, flags); | 2791 | spin_lock_irqsave(&sc->txbuflock, flags); |
@@ -2720,7 +2804,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2720 | 2804 | ||
2721 | bf->skb = skb; | 2805 | bf->skb = skb; |
2722 | 2806 | ||
2723 | if (ath5k_txbuf_setup(sc, bf, txq)) { | 2807 | if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { |
2724 | bf->skb = NULL; | 2808 | bf->skb = NULL; |
2725 | spin_lock_irqsave(&sc->txbuflock, flags); | 2809 | spin_lock_irqsave(&sc->txbuflock, flags); |
2726 | list_add_tail(&bf->list, &sc->txbuf); | 2810 | list_add_tail(&bf->list, &sc->txbuf); |
@@ -2835,6 +2919,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2835 | goto end; | 2919 | goto end; |
2836 | } | 2920 | } |
2837 | 2921 | ||
2922 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); | ||
2923 | |||
2838 | ath5k_hw_set_lladdr(sc->ah, vif->addr); | 2924 | ath5k_hw_set_lladdr(sc->ah, vif->addr); |
2839 | ath5k_mode_setup(sc); | 2925 | ath5k_mode_setup(sc); |
2840 | 2926 | ||
@@ -2905,7 +2991,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) | |||
2905 | * then we must allow the user to set how many tx antennas we | 2991 | * then we must allow the user to set how many tx antennas we |
2906 | * have available | 2992 | * have available |
2907 | */ | 2993 | */ |
2908 | ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); | 2994 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); |
2909 | 2995 | ||
2910 | unlock: | 2996 | unlock: |
2911 | mutex_unlock(&sc->lock); | 2997 | mutex_unlock(&sc->lock); |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 7e1a88a5abdb..33f1d8b87ee1 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -105,6 +105,24 @@ struct ath5k_rfkill { | |||
105 | struct tasklet_struct toggleq; | 105 | struct tasklet_struct toggleq; |
106 | }; | 106 | }; |
107 | 107 | ||
108 | /* statistics (only used for debugging now) */ | ||
109 | struct ath5k_statistics { | ||
110 | unsigned int antenna_rx[5]; /* frames count per antenna RX */ | ||
111 | unsigned int antenna_tx[5]; /* frames count per antenna TX */ | ||
112 | unsigned int rx_all_count; /* all RX frames, including errors */ | ||
113 | unsigned int tx_all_count; /* all TX frames, including errors */ | ||
114 | unsigned int rxerr_crc; | ||
115 | unsigned int rxerr_phy; | ||
116 | unsigned int rxerr_fifo; | ||
117 | unsigned int rxerr_decrypt; | ||
118 | unsigned int rxerr_mic; | ||
119 | unsigned int rxerr_proc; | ||
120 | unsigned int rxerr_jumbo; | ||
121 | unsigned int txerr_retry; | ||
122 | unsigned int txerr_fifo; | ||
123 | unsigned int txerr_filt; | ||
124 | }; | ||
125 | |||
108 | #if CHAN_DEBUG | 126 | #if CHAN_DEBUG |
109 | #define ATH_CHAN_MAX (26+26+26+200+200) | 127 | #define ATH_CHAN_MAX (26+26+26+200+200) |
110 | #else | 128 | #else |
@@ -191,6 +209,8 @@ struct ath5k_softc { | |||
191 | int power_level; /* Requested tx power in dbm */ | 209 | int power_level; /* Requested tx power in dbm */ |
192 | bool assoc; /* associate state */ | 210 | bool assoc; /* associate state */ |
193 | bool enable_beacon; /* true if beacons are on */ | 211 | bool enable_beacon; /* true if beacons are on */ |
212 | |||
213 | struct ath5k_statistics stats; | ||
194 | }; | 214 | }; |
195 | 215 | ||
196 | #define ath5k_hw_hasbssidmask(_ah) \ | 216 | #define ath5k_hw_hasbssidmask(_ah) \ |
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index 367a6c7d3cc7..e618e71b1ce6 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c | |||
@@ -102,9 +102,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | /* GPIO */ | ||
106 | ah->ah_gpio_npins = AR5K_NUM_GPIO; | ||
107 | |||
108 | /* Set number of supported TX queues */ | 105 | /* Set number of supported TX queues */ |
109 | if (ah->ah_version == AR5K_AR5210) | 106 | if (ah->ah_version == AR5K_AR5210) |
110 | ah->ah_capabilities.cap_queues.q_tx_num = | 107 | ah->ah_capabilities.cap_queues.q_tx_num = |
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 747508c15d34..bccd4a78027e 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -364,6 +364,207 @@ static const struct file_operations fops_debug = { | |||
364 | }; | 364 | }; |
365 | 365 | ||
366 | 366 | ||
367 | /* debugfs: antenna */ | ||
368 | |||
369 | static ssize_t read_file_antenna(struct file *file, char __user *user_buf, | ||
370 | size_t count, loff_t *ppos) | ||
371 | { | ||
372 | struct ath5k_softc *sc = file->private_data; | ||
373 | char buf[700]; | ||
374 | unsigned int len = 0; | ||
375 | unsigned int i; | ||
376 | unsigned int v; | ||
377 | |||
378 | len += snprintf(buf+len, sizeof(buf)-len, "antenna mode\t%d\n", | ||
379 | sc->ah->ah_ant_mode); | ||
380 | len += snprintf(buf+len, sizeof(buf)-len, "default antenna\t%d\n", | ||
381 | sc->ah->ah_def_ant); | ||
382 | len += snprintf(buf+len, sizeof(buf)-len, "tx antenna\t%d\n", | ||
383 | sc->ah->ah_tx_ant); | ||
384 | |||
385 | len += snprintf(buf+len, sizeof(buf)-len, "\nANTENNA\t\tRX\tTX\n"); | ||
386 | for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) { | ||
387 | len += snprintf(buf+len, sizeof(buf)-len, | ||
388 | "[antenna %d]\t%d\t%d\n", | ||
389 | i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]); | ||
390 | } | ||
391 | len += snprintf(buf+len, sizeof(buf)-len, "[invalid]\t%d\t%d\n", | ||
392 | sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]); | ||
393 | |||
394 | v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA); | ||
395 | len += snprintf(buf+len, sizeof(buf)-len, | ||
396 | "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v); | ||
397 | |||
398 | v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1); | ||
399 | len += snprintf(buf+len, sizeof(buf)-len, | ||
400 | "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n", | ||
401 | (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0); | ||
402 | len += snprintf(buf+len, sizeof(buf)-len, | ||
403 | "AR5K_STA_ID1_DESC_ANTENNA\t%d\n", | ||
404 | (v & AR5K_STA_ID1_DESC_ANTENNA) != 0); | ||
405 | len += snprintf(buf+len, sizeof(buf)-len, | ||
406 | "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n", | ||
407 | (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0); | ||
408 | len += snprintf(buf+len, sizeof(buf)-len, | ||
409 | "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n", | ||
410 | (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0); | ||
411 | |||
412 | v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL); | ||
413 | len += snprintf(buf+len, sizeof(buf)-len, | ||
414 | "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n", | ||
415 | (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0); | ||
416 | |||
417 | v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART); | ||
418 | len += snprintf(buf+len, sizeof(buf)-len, | ||
419 | "AR5K_PHY_RESTART_DIV_GC\t\t%x\n", | ||
420 | (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S); | ||
421 | |||
422 | v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV); | ||
423 | len += snprintf(buf+len, sizeof(buf)-len, | ||
424 | "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n", | ||
425 | (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0); | ||
426 | |||
427 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
428 | } | ||
429 | |||
430 | static ssize_t write_file_antenna(struct file *file, | ||
431 | const char __user *userbuf, | ||
432 | size_t count, loff_t *ppos) | ||
433 | { | ||
434 | struct ath5k_softc *sc = file->private_data; | ||
435 | unsigned int i; | ||
436 | char buf[20]; | ||
437 | |||
438 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
439 | return -EFAULT; | ||
440 | |||
441 | if (strncmp(buf, "diversity", 9) == 0) { | ||
442 | ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT); | ||
443 | printk(KERN_INFO "ath5k debug: enable diversity\n"); | ||
444 | } else if (strncmp(buf, "fixed-a", 7) == 0) { | ||
445 | ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A); | ||
446 | printk(KERN_INFO "ath5k debugfs: fixed antenna A\n"); | ||
447 | } else if (strncmp(buf, "fixed-b", 7) == 0) { | ||
448 | ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B); | ||
449 | printk(KERN_INFO "ath5k debug: fixed antenna B\n"); | ||
450 | } else if (strncmp(buf, "clear", 5) == 0) { | ||
451 | for (i = 0; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) { | ||
452 | sc->stats.antenna_rx[i] = 0; | ||
453 | sc->stats.antenna_tx[i] = 0; | ||
454 | } | ||
455 | printk(KERN_INFO "ath5k debug: cleared antenna stats\n"); | ||
456 | } | ||
457 | return count; | ||
458 | } | ||
459 | |||
460 | static const struct file_operations fops_antenna = { | ||
461 | .read = read_file_antenna, | ||
462 | .write = write_file_antenna, | ||
463 | .open = ath5k_debugfs_open, | ||
464 | .owner = THIS_MODULE, | ||
465 | }; | ||
466 | |||
467 | |||
468 | /* debugfs: frameerrors */ | ||
469 | |||
470 | static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, | ||
471 | size_t count, loff_t *ppos) | ||
472 | { | ||
473 | struct ath5k_softc *sc = file->private_data; | ||
474 | struct ath5k_statistics *st = &sc->stats; | ||
475 | char buf[700]; | ||
476 | unsigned int len = 0; | ||
477 | |||
478 | len += snprintf(buf+len, sizeof(buf)-len, | ||
479 | "RX\n---------------------\n"); | ||
480 | len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n", | ||
481 | st->rxerr_crc, | ||
482 | st->rx_all_count > 0 ? | ||
483 | st->rxerr_crc*100/st->rx_all_count : 0); | ||
484 | len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n", | ||
485 | st->rxerr_phy, | ||
486 | st->rx_all_count > 0 ? | ||
487 | st->rxerr_phy*100/st->rx_all_count : 0); | ||
488 | len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", | ||
489 | st->rxerr_fifo, | ||
490 | st->rx_all_count > 0 ? | ||
491 | st->rxerr_fifo*100/st->rx_all_count : 0); | ||
492 | len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n", | ||
493 | st->rxerr_decrypt, | ||
494 | st->rx_all_count > 0 ? | ||
495 | st->rxerr_decrypt*100/st->rx_all_count : 0); | ||
496 | len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n", | ||
497 | st->rxerr_mic, | ||
498 | st->rx_all_count > 0 ? | ||
499 | st->rxerr_mic*100/st->rx_all_count : 0); | ||
500 | len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n", | ||
501 | st->rxerr_proc, | ||
502 | st->rx_all_count > 0 ? | ||
503 | st->rxerr_proc*100/st->rx_all_count : 0); | ||
504 | len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n", | ||
505 | st->rxerr_jumbo, | ||
506 | st->rx_all_count > 0 ? | ||
507 | st->rxerr_jumbo*100/st->rx_all_count : 0); | ||
508 | len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", | ||
509 | st->rx_all_count); | ||
510 | |||
511 | len += snprintf(buf+len, sizeof(buf)-len, | ||
512 | "\nTX\n---------------------\n"); | ||
513 | len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n", | ||
514 | st->txerr_retry, | ||
515 | st->tx_all_count > 0 ? | ||
516 | st->txerr_retry*100/st->tx_all_count : 0); | ||
517 | len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", | ||
518 | st->txerr_fifo, | ||
519 | st->tx_all_count > 0 ? | ||
520 | st->txerr_fifo*100/st->tx_all_count : 0); | ||
521 | len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n", | ||
522 | st->txerr_filt, | ||
523 | st->tx_all_count > 0 ? | ||
524 | st->txerr_filt*100/st->tx_all_count : 0); | ||
525 | len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", | ||
526 | st->tx_all_count); | ||
527 | |||
528 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
529 | } | ||
530 | |||
531 | static ssize_t write_file_frameerrors(struct file *file, | ||
532 | const char __user *userbuf, | ||
533 | size_t count, loff_t *ppos) | ||
534 | { | ||
535 | struct ath5k_softc *sc = file->private_data; | ||
536 | struct ath5k_statistics *st = &sc->stats; | ||
537 | char buf[20]; | ||
538 | |||
539 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
540 | return -EFAULT; | ||
541 | |||
542 | if (strncmp(buf, "clear", 5) == 0) { | ||
543 | st->rxerr_crc = 0; | ||
544 | st->rxerr_phy = 0; | ||
545 | st->rxerr_fifo = 0; | ||
546 | st->rxerr_decrypt = 0; | ||
547 | st->rxerr_mic = 0; | ||
548 | st->rxerr_proc = 0; | ||
549 | st->rxerr_jumbo = 0; | ||
550 | st->rx_all_count = 0; | ||
551 | st->txerr_retry = 0; | ||
552 | st->txerr_fifo = 0; | ||
553 | st->txerr_filt = 0; | ||
554 | st->tx_all_count = 0; | ||
555 | printk(KERN_INFO "ath5k debug: cleared frameerrors stats\n"); | ||
556 | } | ||
557 | return count; | ||
558 | } | ||
559 | |||
560 | static const struct file_operations fops_frameerrors = { | ||
561 | .read = read_file_frameerrors, | ||
562 | .write = write_file_frameerrors, | ||
563 | .open = ath5k_debugfs_open, | ||
564 | .owner = THIS_MODULE, | ||
565 | }; | ||
566 | |||
567 | |||
367 | /* init */ | 568 | /* init */ |
368 | 569 | ||
369 | void | 570 | void |
@@ -393,6 +594,15 @@ ath5k_debug_init_device(struct ath5k_softc *sc) | |||
393 | 594 | ||
394 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, | 595 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, |
395 | sc->debug.debugfs_phydir, sc, &fops_reset); | 596 | sc->debug.debugfs_phydir, sc, &fops_reset); |
597 | |||
598 | sc->debug.debugfs_antenna = debugfs_create_file("antenna", | ||
599 | S_IWUSR | S_IRUSR, | ||
600 | sc->debug.debugfs_phydir, sc, &fops_antenna); | ||
601 | |||
602 | sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", | ||
603 | S_IWUSR | S_IRUSR, | ||
604 | sc->debug.debugfs_phydir, sc, | ||
605 | &fops_frameerrors); | ||
396 | } | 606 | } |
397 | 607 | ||
398 | void | 608 | void |
@@ -408,6 +618,8 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) | |||
408 | debugfs_remove(sc->debug.debugfs_registers); | 618 | debugfs_remove(sc->debug.debugfs_registers); |
409 | debugfs_remove(sc->debug.debugfs_beacon); | 619 | debugfs_remove(sc->debug.debugfs_beacon); |
410 | debugfs_remove(sc->debug.debugfs_reset); | 620 | debugfs_remove(sc->debug.debugfs_reset); |
621 | debugfs_remove(sc->debug.debugfs_antenna); | ||
622 | debugfs_remove(sc->debug.debugfs_frameerrors); | ||
411 | debugfs_remove(sc->debug.debugfs_phydir); | 623 | debugfs_remove(sc->debug.debugfs_phydir); |
412 | } | 624 | } |
413 | 625 | ||
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 66f69f04e55e..da24ff52e274 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h | |||
@@ -74,6 +74,8 @@ struct ath5k_dbg_info { | |||
74 | struct dentry *debugfs_registers; | 74 | struct dentry *debugfs_registers; |
75 | struct dentry *debugfs_beacon; | 75 | struct dentry *debugfs_beacon; |
76 | struct dentry *debugfs_reset; | 76 | struct dentry *debugfs_reset; |
77 | struct dentry *debugfs_antenna; | ||
78 | struct dentry *debugfs_frameerrors; | ||
77 | }; | 79 | }; |
78 | 80 | ||
79 | /** | 81 | /** |
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index dc30a2b70a6b..9d920fb14d5d 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
@@ -35,7 +35,8 @@ | |||
35 | */ | 35 | */ |
36 | static int | 36 | static int |
37 | ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | 37 | ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, |
38 | unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, | 38 | unsigned int pkt_len, unsigned int hdr_len, int padsize, |
39 | enum ath5k_pkt_type type, | ||
39 | unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, | 40 | unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, |
40 | unsigned int key_index, unsigned int antenna_mode, unsigned int flags, | 41 | unsigned int key_index, unsigned int antenna_mode, unsigned int flags, |
41 | unsigned int rtscts_rate, unsigned int rtscts_duration) | 42 | unsigned int rtscts_rate, unsigned int rtscts_duration) |
@@ -71,7 +72,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
71 | /* Verify and set frame length */ | 72 | /* Verify and set frame length */ |
72 | 73 | ||
73 | /* remove padding we might have added before */ | 74 | /* remove padding we might have added before */ |
74 | frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; | 75 | frame_len = pkt_len - padsize + FCS_LEN; |
75 | 76 | ||
76 | if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) | 77 | if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) |
77 | return -EINVAL; | 78 | return -EINVAL; |
@@ -100,7 +101,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
100 | AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); | 101 | AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); |
101 | } | 102 | } |
102 | 103 | ||
103 | /*Diferences between 5210-5211*/ | 104 | /*Differences between 5210-5211*/ |
104 | if (ah->ah_version == AR5K_AR5210) { | 105 | if (ah->ah_version == AR5K_AR5210) { |
105 | switch (type) { | 106 | switch (type) { |
106 | case AR5K_PKT_TYPE_BEACON: | 107 | case AR5K_PKT_TYPE_BEACON: |
@@ -165,6 +166,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
165 | */ | 166 | */ |
166 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | 167 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, |
167 | struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, | 168 | struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, |
169 | int padsize, | ||
168 | enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, | 170 | enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, |
169 | unsigned int tx_tries0, unsigned int key_index, | 171 | unsigned int tx_tries0, unsigned int key_index, |
170 | unsigned int antenna_mode, unsigned int flags, | 172 | unsigned int antenna_mode, unsigned int flags, |
@@ -206,7 +208,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
206 | /* Verify and set frame length */ | 208 | /* Verify and set frame length */ |
207 | 209 | ||
208 | /* remove padding we might have added before */ | 210 | /* remove padding we might have added before */ |
209 | frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; | 211 | frame_len = pkt_len - padsize + FCS_LEN; |
210 | 212 | ||
211 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | 213 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) |
212 | return -EINVAL; | 214 | return -EINVAL; |
@@ -229,7 +231,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
229 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | 231 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); |
230 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | 232 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, |
231 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | 233 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); |
232 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, | 234 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, |
233 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | 235 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); |
234 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | 236 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; |
235 | 237 | ||
@@ -668,12 +670,6 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) | |||
668 | ah->ah_version != AR5K_AR5212) | 670 | ah->ah_version != AR5K_AR5212) |
669 | return -ENOTSUPP; | 671 | return -ENOTSUPP; |
670 | 672 | ||
671 | /* XXX: What is this magic value and where is it used ? */ | ||
672 | if (ah->ah_version == AR5K_AR5212) | ||
673 | ah->ah_magic = AR5K_EEPROM_MAGIC_5212; | ||
674 | else if (ah->ah_version == AR5K_AR5211) | ||
675 | ah->ah_magic = AR5K_EEPROM_MAGIC_5211; | ||
676 | |||
677 | if (ah->ah_version == AR5K_AR5212) { | 673 | if (ah->ah_version == AR5K_AR5212) { |
678 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; | 674 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; |
679 | ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; | 675 | ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 10b52262b232..a3cbfe4fc389 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -329,7 +329,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
329 | ee->ee_x_gain[mode] = (val >> 1) & 0xf; | 329 | ee->ee_x_gain[mode] = (val >> 1) & 0xf; |
330 | ee->ee_xpd[mode] = val & 0x1; | 330 | ee->ee_xpd[mode] = val & 0x1; |
331 | 331 | ||
332 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) | 332 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && |
333 | mode != AR5K_EEPROM_MODE_11B) | ||
333 | ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; | 334 | ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; |
334 | 335 | ||
335 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { | 336 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { |
@@ -339,6 +340,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
339 | if (mode == AR5K_EEPROM_MODE_11A) | 340 | if (mode == AR5K_EEPROM_MODE_11A) |
340 | ee->ee_xr_power[mode] = val & 0x3f; | 341 | ee->ee_xr_power[mode] = val & 0x3f; |
341 | else { | 342 | else { |
343 | /* b_DB_11[bg] and b_OB_11[bg] */ | ||
342 | ee->ee_ob[mode][0] = val & 0x7; | 344 | ee->ee_ob[mode][0] = val & 0x7; |
343 | ee->ee_db[mode][0] = (val >> 3) & 0x7; | 345 | ee->ee_db[mode][0] = (val >> 3) & 0x7; |
344 | } | 346 | } |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 473a483bb9c3..c4a6d5f26af4 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h | |||
@@ -24,9 +24,6 @@ | |||
24 | * SERDES infos are present */ | 24 | * SERDES infos are present */ |
25 | #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ | 25 | #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ |
26 | #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ | 26 | #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ |
27 | #define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */ | ||
28 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ | ||
29 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ | ||
30 | 27 | ||
31 | #define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ | 28 | #define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ |
32 | 29 | ||
@@ -78,9 +75,9 @@ | |||
78 | #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) | 75 | #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) |
79 | #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) | 76 | #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) |
80 | #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) | 77 | #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) |
81 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ | 78 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz */ |
82 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ | 79 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for < 2W power consumption */ |
83 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) | 80 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) /* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */ |
84 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ | 81 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ |
85 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ | 82 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ |
86 | 83 | ||
@@ -101,7 +98,7 @@ | |||
101 | 98 | ||
102 | #define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) | 99 | #define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) |
103 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) | 100 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) |
104 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) | 101 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) /* has 32KHz crystal for sleep mode */ |
105 | #define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) | 102 | #define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) |
106 | 103 | ||
107 | #define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) | 104 | #define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) |
@@ -114,26 +111,27 @@ | |||
114 | 111 | ||
115 | #define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) | 112 | #define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) |
116 | #define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) | 113 | #define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) |
117 | #define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) | 114 | #define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) /* modes supported by radio 0 (bit 1: G, bit 2: A) */ |
118 | #define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) | 115 | #define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) /* modes supported by radio 1 (bit 1: G, bit 2: A) */ |
119 | 116 | ||
120 | #define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) | 117 | #define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) |
121 | #define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) | 118 | #define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) /* disable compression */ |
122 | #define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) | 119 | #define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) /* disable AES */ |
123 | #define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) | 120 | #define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) /* disable fast frames */ |
124 | #define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) | 121 | #define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) /* disable bursting */ |
125 | #define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) | 122 | #define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) /* max number of QCUs. defaults to 10 */ |
126 | #define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) | 123 | #define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heayy clipping */ |
127 | #define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) | 124 | #define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) /* key cache size. defaults to 128 */ |
128 | 125 | ||
129 | #define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) | 126 | #define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) |
130 | #define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x8) | 127 | #define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x7) /* MIMO chains disabled for TX bitmask */ |
131 | #define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x8) | 128 | #define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x7) /* MIMO chains disabled for RX bitmask */ |
132 | #define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) | 129 | #define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) /* 5.47-5.7GHz supported */ |
133 | #define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) | 130 | #define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) /* Japan UNII1 band (5.15-5.25GHz) on even channels (5180, 5200, 5220, 5240) supported */ |
134 | #define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) | 131 | #define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) /* Japan UNII2 band (5.25-5.35GHz) supported */ |
135 | #define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 9) & 0x1) | 132 | #define AR5K_EEPROM_JAP_MID_EN (((_v) >> 9) & 0x1) /* Japan band from 5.47-5.7GHz supported */ |
136 | #define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 10) & 0x1) | 133 | #define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 10) & 0x1) /* Japan UNII2 band (5.15-5.25GHz) on odd channels (5170, 5190, 5210, 5230) supported */ |
134 | #define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 11) & 0x1) /* Japan A mode enabled (using even channels) */ | ||
137 | 135 | ||
138 | /* calibration settings */ | 136 | /* calibration settings */ |
139 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) | 137 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) |
@@ -389,7 +387,49 @@ struct ath5k_edge_power { | |||
389 | bool flag; | 387 | bool flag; |
390 | }; | 388 | }; |
391 | 389 | ||
392 | /* EEPROM calibration data */ | 390 | /** |
391 | * struct ath5k_eeprom_info - EEPROM calibration data | ||
392 | * | ||
393 | * @ee_regdomain: ath/regd.c takes care of COUNTRY_ERD and WORLDWIDE_ROAMING | ||
394 | * flags | ||
395 | * @ee_ant_gain: Antenna gain in 0.5dB steps signed [5211 only?] | ||
396 | * @ee_cck_ofdm_gain_delta: difference in gainF to output the same power for | ||
397 | * OFDM and CCK packets | ||
398 | * @ee_cck_ofdm_power_delta: power difference between OFDM (6Mbps) and CCK | ||
399 | * (11Mbps) rate in G mode. 0.1dB steps | ||
400 | * @ee_scaled_cck_delta: for Japan Channel 14: 0.1dB resolution | ||
401 | * | ||
402 | * @ee_i_cal: Initial I coefficient to correct I/Q mismatch in the receive path | ||
403 | * @ee_q_cal: Initial Q coefficient to correct I/Q mismatch in the receive path | ||
404 | * @ee_fixed_bias: use ee_ob and ee_db settings or use automatic control | ||
405 | * @ee_switch_settling: RX/TX Switch settling time | ||
406 | * @ee_atn_tx_rx: Difference in attenuation between TX and RX in 1dB steps | ||
407 | * @ee_ant_control: Antenna Control Settings | ||
408 | * @ee_ob: Bias current for Output stage of PA | ||
409 | * B/G mode: Index [0] is used for AR2112/5112, otherwise [1] | ||
410 | * A mode: [0] 5.15-5.25 [1] 5.25-5.50 [2] 5.50-5.70 [3] 5.70-5.85 GHz | ||
411 | * @ee_db: Bias current for Output stage of PA. see @ee_ob | ||
412 | * @ee_tx_end2xlna_enable: Time difference from when BB finishes sending a frame | ||
413 | * to when the external LNA is activated | ||
414 | * @ee_tx_end2xpa_disable: Time difference from when BB finishes sending a frame | ||
415 | * to when the external PA switch is deactivated | ||
416 | * @ee_tx_frm2xpa_enable: Time difference from when MAC sends frame to when | ||
417 | * external PA switch is activated | ||
418 | * @ee_thr_62: Clear Channel Assessment (CCA) sensitivity | ||
419 | * (IEEE802.11a section 17.3.10.5 ) | ||
420 | * @ee_xlna_gain: Total gain of the LNA (information only) | ||
421 | * @ee_xpd: Use external (1) or internal power detector | ||
422 | * @ee_x_gain: Gain for external power detector output (differences in EEMAP | ||
423 | * versions!) | ||
424 | * @ee_i_gain: Initial gain value after reset | ||
425 | * @ee_margin_tx_rx: Margin in dB when final attenuation stage should be used | ||
426 | * | ||
427 | * @ee_false_detect: Backoff in Sensitivity (dB) on channels with spur signals | ||
428 | * @ee_noise_floor_thr: Noise floor threshold in 1dB steps | ||
429 | * @ee_adc_desired_size: Desired amplitude for ADC, used by AGC; in 0.5 dB steps | ||
430 | * @ee_pga_desired_size: Desired output of PGA (for BB gain) in 0.5 dB steps | ||
431 | * @ee_pd_gain_overlap: PD ADC curves need to overlap in 0.5dB steps (ee_map>=2) | ||
432 | */ | ||
393 | struct ath5k_eeprom_info { | 433 | struct ath5k_eeprom_info { |
394 | 434 | ||
395 | /* Header information */ | 435 | /* Header information */ |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index aefe84f9c04b..1b9fcb842167 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -39,16 +39,16 @@ | |||
39 | * ath5k_hw_set_opmode - Set PCU operating mode | 39 | * ath5k_hw_set_opmode - Set PCU operating mode |
40 | * | 40 | * |
41 | * @ah: The &struct ath5k_hw | 41 | * @ah: The &struct ath5k_hw |
42 | * @op_mode: &enum nl80211_iftype operating mode | ||
42 | * | 43 | * |
43 | * Initialize PCU for the various operating modes (AP/STA etc) | 44 | * Initialize PCU for the various operating modes (AP/STA etc) |
44 | * | ||
45 | * NOTE: ah->ah_op_mode must be set before calling this. | ||
46 | */ | 45 | */ |
47 | int ath5k_hw_set_opmode(struct ath5k_hw *ah) | 46 | int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) |
48 | { | 47 | { |
49 | struct ath_common *common = ath5k_hw_common(ah); | 48 | struct ath_common *common = ath5k_hw_common(ah); |
50 | u32 pcu_reg, beacon_reg, low_id, high_id; | 49 | u32 pcu_reg, beacon_reg, low_id, high_id; |
51 | 50 | ||
51 | ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode); | ||
52 | 52 | ||
53 | /* Preserve rest settings */ | 53 | /* Preserve rest settings */ |
54 | pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; | 54 | pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; |
@@ -61,7 +61,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah) | |||
61 | 61 | ||
62 | ATH5K_TRACE(ah->ah_sc); | 62 | ATH5K_TRACE(ah->ah_sc); |
63 | 63 | ||
64 | switch (ah->ah_op_mode) { | 64 | switch (op_mode) { |
65 | case NL80211_IFTYPE_ADHOC: | 65 | case NL80211_IFTYPE_ADHOC: |
66 | pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; | 66 | pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; |
67 | beacon_reg |= AR5K_BCR_ADHOC; | 67 | beacon_reg |= AR5K_BCR_ADHOC; |
@@ -179,25 +179,12 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) | |||
179 | \******************/ | 179 | \******************/ |
180 | 180 | ||
181 | /** | 181 | /** |
182 | * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec | ||
183 | * | ||
184 | * @ah: The &struct ath5k_hw | ||
185 | */ | ||
186 | unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah) | ||
187 | { | ||
188 | ATH5K_TRACE(ah->ah_sc); | ||
189 | |||
190 | return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
191 | AR5K_TIME_OUT), AR5K_TIME_OUT_ACK)); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU | 182 | * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU |
196 | * | 183 | * |
197 | * @ah: The &struct ath5k_hw | 184 | * @ah: The &struct ath5k_hw |
198 | * @timeout: Timeout in usec | 185 | * @timeout: Timeout in usec |
199 | */ | 186 | */ |
200 | int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | 187 | static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) |
201 | { | 188 | { |
202 | ATH5K_TRACE(ah->ah_sc); | 189 | ATH5K_TRACE(ah->ah_sc); |
203 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) | 190 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) |
@@ -211,24 +198,12 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | |||
211 | } | 198 | } |
212 | 199 | ||
213 | /** | 200 | /** |
214 | * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec | ||
215 | * | ||
216 | * @ah: The &struct ath5k_hw | ||
217 | */ | ||
218 | unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) | ||
219 | { | ||
220 | ATH5K_TRACE(ah->ah_sc); | ||
221 | return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
222 | AR5K_TIME_OUT), AR5K_TIME_OUT_CTS)); | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU | 201 | * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU |
227 | * | 202 | * |
228 | * @ah: The &struct ath5k_hw | 203 | * @ah: The &struct ath5k_hw |
229 | * @timeout: Timeout in usec | 204 | * @timeout: Timeout in usec |
230 | */ | 205 | */ |
231 | int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) | 206 | static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) |
232 | { | 207 | { |
233 | ATH5K_TRACE(ah->ah_sc); | 208 | ATH5K_TRACE(ah->ah_sc); |
234 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) | 209 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) |
@@ -290,7 +265,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) | |||
290 | * | 265 | * |
291 | * @ah: The &struct ath5k_hw | 266 | * @ah: The &struct ath5k_hw |
292 | */ | 267 | */ |
293 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | 268 | static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) |
294 | { | 269 | { |
295 | struct ieee80211_channel *channel = ah->ah_current_channel; | 270 | struct ieee80211_channel *channel = ah->ah_current_channel; |
296 | 271 | ||
@@ -308,7 +283,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | |||
308 | * | 283 | * |
309 | * @ah: The &struct ath5k_hw | 284 | * @ah: The &struct ath5k_hw |
310 | */ | 285 | */ |
311 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) | 286 | static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) |
312 | { | 287 | { |
313 | struct ieee80211_channel *channel = ah->ah_current_channel; | 288 | struct ieee80211_channel *channel = ah->ah_current_channel; |
314 | 289 | ||
@@ -451,42 +426,6 @@ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) | |||
451 | ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); | 426 | ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); |
452 | } | 427 | } |
453 | 428 | ||
454 | /* | ||
455 | * Set multicast filter by index | ||
456 | */ | ||
457 | int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index) | ||
458 | { | ||
459 | |||
460 | ATH5K_TRACE(ah->ah_sc); | ||
461 | if (index >= 64) | ||
462 | return -EINVAL; | ||
463 | else if (index >= 32) | ||
464 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
465 | (1 << (index - 32))); | ||
466 | else | ||
467 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * Clear Multicast filter by index | ||
474 | */ | ||
475 | int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index) | ||
476 | { | ||
477 | |||
478 | ATH5K_TRACE(ah->ah_sc); | ||
479 | if (index >= 64) | ||
480 | return -EINVAL; | ||
481 | else if (index >= 32) | ||
482 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
483 | (1 << (index - 32))); | ||
484 | else | ||
485 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | /** | 429 | /** |
491 | * ath5k_hw_get_rx_filter - Get current rx filter | 430 | * ath5k_hw_get_rx_filter - Get current rx filter |
492 | * | 431 | * |
@@ -572,19 +511,6 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) | |||
572 | \****************/ | 511 | \****************/ |
573 | 512 | ||
574 | /** | 513 | /** |
575 | * ath5k_hw_get_tsf32 - Get a 32bit TSF | ||
576 | * | ||
577 | * @ah: The &struct ath5k_hw | ||
578 | * | ||
579 | * Returns lower 32 bits of current TSF | ||
580 | */ | ||
581 | u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah) | ||
582 | { | ||
583 | ATH5K_TRACE(ah->ah_sc); | ||
584 | return ath5k_hw_reg_read(ah, AR5K_TSF_L32); | ||
585 | } | ||
586 | |||
587 | /** | ||
588 | * ath5k_hw_get_tsf64 - Get the full 64bit TSF | 514 | * ath5k_hw_get_tsf64 - Get the full 64bit TSF |
589 | * | 515 | * |
590 | * @ah: The &struct ath5k_hw | 516 | * @ah: The &struct ath5k_hw |
@@ -651,7 +577,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
651 | /* | 577 | /* |
652 | * Set the additional timers by mode | 578 | * Set the additional timers by mode |
653 | */ | 579 | */ |
654 | switch (ah->ah_op_mode) { | 580 | switch (ah->ah_sc->opmode) { |
655 | case NL80211_IFTYPE_MONITOR: | 581 | case NL80211_IFTYPE_MONITOR: |
656 | case NL80211_IFTYPE_STATION: | 582 | case NL80211_IFTYPE_STATION: |
657 | /* In STA mode timer1 is used as next wakeup | 583 | /* In STA mode timer1 is used as next wakeup |
@@ -688,8 +614,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
688 | * Set the beacon register and enable all timers. | 614 | * Set the beacon register and enable all timers. |
689 | */ | 615 | */ |
690 | /* When in AP or Mesh Point mode zero timer0 to start TSF */ | 616 | /* When in AP or Mesh Point mode zero timer0 to start TSF */ |
691 | if (ah->ah_op_mode == NL80211_IFTYPE_AP || | 617 | if (ah->ah_sc->opmode == NL80211_IFTYPE_AP || |
692 | ah->ah_op_mode == NL80211_IFTYPE_MESH_POINT) | 618 | ah->ah_sc->opmode == NL80211_IFTYPE_MESH_POINT) |
693 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); | 619 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); |
694 | 620 | ||
695 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); | 621 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); |
@@ -722,203 +648,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
722 | 648 | ||
723 | } | 649 | } |
724 | 650 | ||
725 | #if 0 | ||
726 | /* | ||
727 | * Set beacon timers | ||
728 | */ | ||
729 | int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, | ||
730 | const struct ath5k_beacon_state *state) | ||
731 | { | ||
732 | u32 cfp_period, next_cfp, dtim, interval, next_beacon; | ||
733 | |||
734 | /* | ||
735 | * TODO: should be changed through *state | ||
736 | * review struct ath5k_beacon_state struct | ||
737 | * | ||
738 | * XXX: These are used for cfp period bellow, are they | ||
739 | * ok ? Is it O.K. for tsf here to be 0 or should we use | ||
740 | * get_tsf ? | ||
741 | */ | ||
742 | u32 dtim_count = 0; /* XXX */ | ||
743 | u32 cfp_count = 0; /* XXX */ | ||
744 | u32 tsf = 0; /* XXX */ | ||
745 | |||
746 | ATH5K_TRACE(ah->ah_sc); | ||
747 | /* Return on an invalid beacon state */ | ||
748 | if (state->bs_interval < 1) | ||
749 | return -EINVAL; | ||
750 | |||
751 | interval = state->bs_interval; | ||
752 | dtim = state->bs_dtim_period; | ||
753 | |||
754 | /* | ||
755 | * PCF support? | ||
756 | */ | ||
757 | if (state->bs_cfp_period > 0) { | ||
758 | /* | ||
759 | * Enable PCF mode and set the CFP | ||
760 | * (Contention Free Period) and timer registers | ||
761 | */ | ||
762 | cfp_period = state->bs_cfp_period * state->bs_dtim_period * | ||
763 | state->bs_interval; | ||
764 | next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) * | ||
765 | state->bs_interval; | ||
766 | |||
767 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, | ||
768 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
769 | AR5K_STA_ID1_PCF); | ||
770 | ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD); | ||
771 | ath5k_hw_reg_write(ah, state->bs_cfp_max_duration, | ||
772 | AR5K_CFP_DUR); | ||
773 | ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period : | ||
774 | next_cfp)) << 3, AR5K_TIMER2); | ||
775 | } else { | ||
776 | /* Disable PCF mode */ | ||
777 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
778 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
779 | AR5K_STA_ID1_PCF); | ||
780 | } | ||
781 | |||
782 | /* | ||
783 | * Enable the beacon timer register | ||
784 | */ | ||
785 | ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0); | ||
786 | |||
787 | /* | ||
788 | * Start the beacon timers | ||
789 | */ | ||
790 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) & | ||
791 | ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) | | ||
792 | AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0, | ||
793 | AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval, | ||
794 | AR5K_BEACON_PERIOD), AR5K_BEACON); | ||
795 | |||
796 | /* | ||
797 | * Write new beacon miss threshold, if it appears to be valid | ||
798 | * XXX: Figure out right values for min <= bs_bmiss_threshold <= max | ||
799 | * and return if its not in range. We can test this by reading value and | ||
800 | * setting value to a largest value and seeing which values register. | ||
801 | */ | ||
802 | |||
803 | AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS, | ||
804 | state->bs_bmiss_threshold); | ||
805 | |||
806 | /* | ||
807 | * Set sleep control register | ||
808 | * XXX: Didn't find this in 5210 code but since this register | ||
809 | * exists also in ar5k's 5210 headers i leave it as common code. | ||
810 | */ | ||
811 | AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR, | ||
812 | (state->bs_sleep_duration - 3) << 3); | ||
813 | |||
814 | /* | ||
815 | * Set enhanced sleep registers on 5212 | ||
816 | */ | ||
817 | if (ah->ah_version == AR5K_AR5212) { | ||
818 | if (state->bs_sleep_duration > state->bs_interval && | ||
819 | roundup(state->bs_sleep_duration, interval) == | ||
820 | state->bs_sleep_duration) | ||
821 | interval = state->bs_sleep_duration; | ||
822 | |||
823 | if (state->bs_sleep_duration > dtim && (dtim == 0 || | ||
824 | roundup(state->bs_sleep_duration, dtim) == | ||
825 | state->bs_sleep_duration)) | ||
826 | dtim = state->bs_sleep_duration; | ||
827 | |||
828 | if (interval > dtim) | ||
829 | return -EINVAL; | ||
830 | |||
831 | next_beacon = interval == dtim ? state->bs_next_dtim : | ||
832 | state->bs_next_beacon; | ||
833 | |||
834 | ath5k_hw_reg_write(ah, | ||
835 | AR5K_REG_SM((state->bs_next_dtim - 3) << 3, | ||
836 | AR5K_SLEEP0_NEXT_DTIM) | | ||
837 | AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) | | ||
838 | AR5K_SLEEP0_ENH_SLEEP_EN | | ||
839 | AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0); | ||
840 | |||
841 | ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3, | ||
842 | AR5K_SLEEP1_NEXT_TIM) | | ||
843 | AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1); | ||
844 | |||
845 | ath5k_hw_reg_write(ah, | ||
846 | AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) | | ||
847 | AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2); | ||
848 | } | ||
849 | |||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | /* | ||
854 | * Reset beacon timers | ||
855 | */ | ||
856 | void ath5k_hw_reset_beacon(struct ath5k_hw *ah) | ||
857 | { | ||
858 | ATH5K_TRACE(ah->ah_sc); | ||
859 | /* | ||
860 | * Disable beacon timer | ||
861 | */ | ||
862 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); | ||
863 | |||
864 | /* | ||
865 | * Disable some beacon register values | ||
866 | */ | ||
867 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
868 | AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF); | ||
869 | ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON); | ||
870 | } | ||
871 | |||
872 | /* | ||
873 | * Wait for beacon queue to finish | ||
874 | */ | ||
875 | int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr) | ||
876 | { | ||
877 | unsigned int i; | ||
878 | int ret; | ||
879 | |||
880 | ATH5K_TRACE(ah->ah_sc); | ||
881 | |||
882 | /* 5210 doesn't have QCU*/ | ||
883 | if (ah->ah_version == AR5K_AR5210) { | ||
884 | /* | ||
885 | * Wait for beaconn queue to finish by checking | ||
886 | * Control Register and Beacon Status Register. | ||
887 | */ | ||
888 | for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) { | ||
889 | if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F) | ||
890 | || | ||
891 | !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F)) | ||
892 | break; | ||
893 | udelay(10); | ||
894 | } | ||
895 | |||
896 | /* Timeout... */ | ||
897 | if (i <= 0) { | ||
898 | /* | ||
899 | * Re-schedule the beacon queue | ||
900 | */ | ||
901 | ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1); | ||
902 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE, | ||
903 | AR5K_BCR); | ||
904 | |||
905 | return -EIO; | ||
906 | } | ||
907 | ret = 0; | ||
908 | } else { | ||
909 | /*5211/5212*/ | ||
910 | ret = ath5k_hw_register_timeout(ah, | ||
911 | AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON), | ||
912 | AR5K_QCU_STS_FRMPENDCNT, 0, false); | ||
913 | |||
914 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON)) | ||
915 | return -EIO; | ||
916 | } | ||
917 | |||
918 | return ret; | ||
919 | } | ||
920 | #endif | ||
921 | |||
922 | 651 | ||
923 | /*********************\ | 652 | /*********************\ |
924 | * Key table functions * | 653 | * Key table functions * |
@@ -971,19 +700,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) | |||
971 | return 0; | 700 | return 0; |
972 | } | 701 | } |
973 | 702 | ||
974 | /* | ||
975 | * Check if a table entry is valid | ||
976 | */ | ||
977 | int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry) | ||
978 | { | ||
979 | ATH5K_TRACE(ah->ah_sc); | ||
980 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
981 | |||
982 | /* Check the validation flag at the end of the entry */ | ||
983 | return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) & | ||
984 | AR5K_KEYTABLE_VALID; | ||
985 | } | ||
986 | |||
987 | static | 703 | static |
988 | int ath5k_keycache_type(const struct ieee80211_key_conf *key) | 704 | int ath5k_keycache_type(const struct ieee80211_key_conf *key) |
989 | { | 705 | { |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index eff3323efb4b..a8adca62e527 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -20,8 +20,6 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define _ATH5K_PHY | ||
24 | |||
25 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
26 | 24 | ||
27 | #include "ath5k.h" | 25 | #include "ath5k.h" |
@@ -1190,7 +1188,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah) | |||
1190 | * The median of the values in the history is then loaded into the | 1188 | * The median of the values in the history is then loaded into the |
1191 | * hardware for its own use for RSSI and CCA measurements. | 1189 | * hardware for its own use for RSSI and CCA measurements. |
1192 | */ | 1190 | */ |
1193 | void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) | 1191 | static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) |
1194 | { | 1192 | { |
1195 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 1193 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
1196 | u32 val; | 1194 | u32 val; |
@@ -1399,7 +1397,11 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1399 | } | 1397 | } |
1400 | 1398 | ||
1401 | i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; | 1399 | i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; |
1402 | q_coffd = q_pwr >> 7; | 1400 | |
1401 | if (ah->ah_version == AR5K_AR5211) | ||
1402 | q_coffd = q_pwr >> 6; | ||
1403 | else | ||
1404 | q_coffd = q_pwr >> 7; | ||
1403 | 1405 | ||
1404 | /* protect against divide by 0 and loss of sign bits */ | 1406 | /* protect against divide by 0 and loss of sign bits */ |
1405 | if (i_coffd == 0 || q_coffd < 2) | 1407 | if (i_coffd == 0 || q_coffd < 2) |
@@ -1768,7 +1770,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) | |||
1768 | * Antenna control * | 1770 | * Antenna control * |
1769 | \*****************/ | 1771 | \*****************/ |
1770 | 1772 | ||
1771 | void /*TODO:Boundary check*/ | 1773 | static void /*TODO:Boundary check*/ |
1772 | ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) | 1774 | ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) |
1773 | { | 1775 | { |
1774 | ATH5K_TRACE(ah->ah_sc); | 1776 | ATH5K_TRACE(ah->ah_sc); |
@@ -1777,16 +1779,6 @@ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) | |||
1777 | ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); | 1779 | ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); |
1778 | } | 1780 | } |
1779 | 1781 | ||
1780 | unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) | ||
1781 | { | ||
1782 | ATH5K_TRACE(ah->ah_sc); | ||
1783 | |||
1784 | if (ah->ah_version != AR5K_AR5210) | ||
1785 | return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7; | ||
1786 | |||
1787 | return false; /*XXX: What do we return for 5210 ?*/ | ||
1788 | } | ||
1789 | |||
1790 | /* | 1782 | /* |
1791 | * Enable/disable fast rx antenna diversity | 1783 | * Enable/disable fast rx antenna diversity |
1792 | */ | 1784 | */ |
@@ -1930,6 +1922,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
1930 | 1922 | ||
1931 | ah->ah_tx_ant = tx_ant; | 1923 | ah->ah_tx_ant = tx_ant; |
1932 | ah->ah_ant_mode = ant_mode; | 1924 | ah->ah_ant_mode = ant_mode; |
1925 | ah->ah_def_ant = def_ant; | ||
1933 | 1926 | ||
1934 | sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; | 1927 | sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; |
1935 | sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; | 1928 | sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; |
@@ -2440,19 +2433,6 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, | |||
2440 | pcdac_tmp = pcdac_high_pwr; | 2433 | pcdac_tmp = pcdac_high_pwr; |
2441 | 2434 | ||
2442 | edge_flag = 0x40; | 2435 | edge_flag = 0x40; |
2443 | #if 0 | ||
2444 | /* If both min and max power limits are in lower | ||
2445 | * power curve's range, only use the low power curve. | ||
2446 | * TODO: min/max levels are related to target | ||
2447 | * power values requested from driver/user | ||
2448 | * XXX: Is this really needed ? */ | ||
2449 | if (min_pwr < table_max[1] && | ||
2450 | max_pwr < table_max[1]) { | ||
2451 | edge_flag = 0; | ||
2452 | pcdac_tmp = pcdac_low_pwr; | ||
2453 | max_pwr_idx = (table_max[1] - table_min[1])/2; | ||
2454 | } | ||
2455 | #endif | ||
2456 | } else { | 2436 | } else { |
2457 | pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ | 2437 | pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ |
2458 | pcdac_high_pwr = ah->ah_txpower.tmpL[0]; | 2438 | pcdac_high_pwr = ah->ah_txpower.tmpL[0]; |
@@ -3143,5 +3123,3 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) | |||
3143 | 3123 | ||
3144 | return ath5k_hw_txpower(ah, channel, ee_mode, txpower); | 3124 | return ath5k_hw_txpower(ah, channel, ee_mode, txpower); |
3145 | } | 3125 | } |
3146 | |||
3147 | #undef _ATH5K_PHY | ||
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 9122a8556f45..f5831da33f7b 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -517,23 +517,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
517 | } | 517 | } |
518 | 518 | ||
519 | /* | 519 | /* |
520 | * Get slot time from DCU | ||
521 | */ | ||
522 | unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) | ||
523 | { | ||
524 | unsigned int slot_time_clock; | ||
525 | |||
526 | ATH5K_TRACE(ah->ah_sc); | ||
527 | |||
528 | if (ah->ah_version == AR5K_AR5210) | ||
529 | slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME); | ||
530 | else | ||
531 | slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT); | ||
532 | |||
533 | return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff); | ||
534 | } | ||
535 | |||
536 | /* | ||
537 | * Set slot time on DCU | 520 | * Set slot time on DCU |
538 | */ | 521 | */ |
539 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) | 522 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) |
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 1464f89b249c..47f04932ab8b 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h | |||
@@ -1974,7 +1974,7 @@ | |||
1974 | #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ | 1974 | #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ |
1975 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ | 1975 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ |
1976 | #define AR5K_PHY_SETTLING_AGC_S 0 | 1976 | #define AR5K_PHY_SETTLING_AGC_S 0 |
1977 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ | 1977 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settling time */ |
1978 | #define AR5K_PHY_SETTLING_SWITCH_S 7 | 1978 | #define AR5K_PHY_SETTLING_SWITCH_S 7 |
1979 | 1979 | ||
1980 | /* | 1980 | /* |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index cbf28e379843..44bbbf2a6edd 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define _ATH5K_RESET | ||
23 | |||
24 | /*****************************\ | 22 | /*****************************\ |
25 | Reset functions and helpers | 23 | Reset functions and helpers |
26 | \*****************************/ | 24 | \*****************************/ |
@@ -34,6 +32,27 @@ | |||
34 | #include "base.h" | 32 | #include "base.h" |
35 | #include "debug.h" | 33 | #include "debug.h" |
36 | 34 | ||
35 | /* | ||
36 | * Check if a register write has been completed | ||
37 | */ | ||
38 | int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, | ||
39 | bool is_set) | ||
40 | { | ||
41 | int i; | ||
42 | u32 data; | ||
43 | |||
44 | for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { | ||
45 | data = ath5k_hw_reg_read(ah, reg); | ||
46 | if (is_set && (data & flag)) | ||
47 | break; | ||
48 | else if ((data & flag) == val) | ||
49 | break; | ||
50 | udelay(15); | ||
51 | } | ||
52 | |||
53 | return (i <= 0) ? -EAGAIN : 0; | ||
54 | } | ||
55 | |||
37 | /** | 56 | /** |
38 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 | 57 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 |
39 | * | 58 | * |
@@ -221,8 +240,8 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) | |||
221 | /* | 240 | /* |
222 | * Sleep control | 241 | * Sleep control |
223 | */ | 242 | */ |
224 | int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | 243 | static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, |
225 | bool set_chip, u16 sleep_duration) | 244 | bool set_chip, u16 sleep_duration) |
226 | { | 245 | { |
227 | unsigned int i; | 246 | unsigned int i; |
228 | u32 staid, data; | 247 | u32 staid, data; |
@@ -1017,11 +1036,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1017 | if (ret) | 1036 | if (ret) |
1018 | return ret; | 1037 | return ret; |
1019 | 1038 | ||
1020 | /* | ||
1021 | * Initialize operating mode | ||
1022 | */ | ||
1023 | ah->ah_op_mode = op_mode; | ||
1024 | |||
1025 | /* PHY access enable */ | 1039 | /* PHY access enable */ |
1026 | if (ah->ah_mac_srev >= AR5K_SREV_AR5211) | 1040 | if (ah->ah_mac_srev >= AR5K_SREV_AR5211) |
1027 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | 1041 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); |
@@ -1192,7 +1206,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1192 | ath5k_hw_set_associd(ah); | 1206 | ath5k_hw_set_associd(ah); |
1193 | 1207 | ||
1194 | /* Set PCU config */ | 1208 | /* Set PCU config */ |
1195 | ath5k_hw_set_opmode(ah); | 1209 | ath5k_hw_set_opmode(ah, op_mode); |
1196 | 1210 | ||
1197 | /* Clear any pending interrupts | 1211 | /* Clear any pending interrupts |
1198 | * PISR/SISR Not available on 5210 */ | 1212 | * PISR/SISR Not available on 5210 */ |
@@ -1378,7 +1392,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1378 | * external 32KHz crystal when sleeping if one | 1392 | * external 32KHz crystal when sleeping if one |
1379 | * exists */ | 1393 | * exists */ |
1380 | if (ah->ah_version == AR5K_AR5212 && | 1394 | if (ah->ah_version == AR5K_AR5212 && |
1381 | ah->ah_op_mode != NL80211_IFTYPE_AP) | 1395 | op_mode != NL80211_IFTYPE_AP) |
1382 | ath5k_hw_set_sleep_clock(ah, true); | 1396 | ath5k_hw_set_sleep_clock(ah, true); |
1383 | 1397 | ||
1384 | /* | 1398 | /* |
@@ -1388,5 +1402,3 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1388 | ath5k_hw_reset_tsf(ah); | 1402 | ath5k_hw_reset_tsf(ah); |
1389 | return 0; | 1403 | return 0; |
1390 | } | 1404 | } |
1391 | |||
1392 | #undef _ATH5K_RESET | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 2e767cf22f1e..1fb14edfcb2a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1151,7 +1151,8 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
1151 | ah->mask_reg |= AR_IMR_MIB; | 1151 | ah->mask_reg |= AR_IMR_MIB; |
1152 | 1152 | ||
1153 | REG_WRITE(ah, AR_IMR, ah->mask_reg); | 1153 | REG_WRITE(ah, AR_IMR, ah->mask_reg); |
1154 | REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); | 1154 | ah->imrs2_reg |= AR_IMR_S2_GTT; |
1155 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); | ||
1155 | 1156 | ||
1156 | if (!AR_SREV_9100(ah)) { | 1157 | if (!AR_SREV_9100(ah)) { |
1157 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); | 1158 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); |
@@ -2920,14 +2921,11 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
2920 | 2921 | ||
2921 | ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); | 2922 | ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); |
2922 | REG_WRITE(ah, AR_IMR, mask); | 2923 | REG_WRITE(ah, AR_IMR, mask); |
2923 | mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | | 2924 | ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | |
2924 | AR_IMR_S2_DTIM | | 2925 | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | |
2925 | AR_IMR_S2_DTIMSYNC | | 2926 | AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST); |
2926 | AR_IMR_S2_CABEND | | 2927 | ah->imrs2_reg |= mask2; |
2927 | AR_IMR_S2_CABTO | | 2928 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); |
2928 | AR_IMR_S2_TSFOOR | | ||
2929 | AR_IMR_S2_GTT | AR_IMR_S2_CST); | ||
2930 | REG_WRITE(ah, AR_IMR_S2, mask | mask2); | ||
2931 | ah->mask_reg = ints; | 2929 | ah->mask_reg = ints; |
2932 | 2930 | ||
2933 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | 2931 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index dbbf7ca5f97d..20d90268ce31 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -479,6 +479,7 @@ struct ath_hw { | |||
479 | 479 | ||
480 | int16_t curchan_rad_index; | 480 | int16_t curchan_rad_index; |
481 | u32 mask_reg; | 481 | u32 mask_reg; |
482 | u32 imrs2_reg; | ||
482 | u32 txok_interrupt_mask; | 483 | u32 txok_interrupt_mask; |
483 | u32 txerr_interrupt_mask; | 484 | u32 txerr_interrupt_mask; |
484 | u32 txdesc_interrupt_mask; | 485 | u32 txdesc_interrupt_mask; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index efc420cd42bf..589490b69ddc 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -31,8 +31,10 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, | |||
31 | REG_WRITE(ah, AR_IMR_S1, | 31 | REG_WRITE(ah, AR_IMR_S1, |
32 | SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) | 32 | SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) |
33 | | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); | 33 | | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); |
34 | REG_RMW_FIELD(ah, AR_IMR_S2, | 34 | |
35 | AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask); | 35 | ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN; |
36 | ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN); | ||
37 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); | ||
36 | } | 38 | } |
37 | 39 | ||
38 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) | 40 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 0e79e58cf4c9..3c4b5d2d9e16 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1226,8 +1226,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1226 | long_retry = rate->count - 1; | 1226 | long_retry = rate->count - 1; |
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | if (!priv_sta || !ieee80211_is_data(fc) || | 1229 | if (!priv_sta || !ieee80211_is_data(fc)) |
1230 | !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) | 1230 | return; |
1231 | |||
1232 | /* This packet was aggregated but doesn't carry status info */ | ||
1233 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | ||
1234 | !(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) | ||
1231 | return; | 1235 | return; |
1232 | 1236 | ||
1233 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) | 1237 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 4f6d6fd442f4..f4818e4fa4b0 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -172,7 +172,6 @@ struct ath_rate_priv { | |||
172 | 172 | ||
173 | #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) | 173 | #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) |
174 | #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) | 174 | #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) |
175 | #define ATH_TX_INFO_UPDATE_RC (1 << 2) | ||
176 | #define ATH_TX_INFO_XRETRY (1 << 3) | 175 | #define ATH_TX_INFO_XRETRY (1 << 3) |
177 | #define ATH_TX_INFO_UNDERRUN (1 << 4) | 176 | #define ATH_TX_INFO_UNDERRUN (1 << 4) |
178 | 177 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 294b486bc3ed..a3b6cf20f8a1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1928,10 +1928,10 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1928 | tx_rateindex = ds->ds_txstat.ts_rateindex; | 1928 | tx_rateindex = ds->ds_txstat.ts_rateindex; |
1929 | WARN_ON(tx_rateindex >= hw->max_rates); | 1929 | WARN_ON(tx_rateindex >= hw->max_rates); |
1930 | 1930 | ||
1931 | if (update_rc) | ||
1932 | tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC; | ||
1933 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | 1931 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) |
1934 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1932 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1933 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) | ||
1934 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; | ||
1935 | 1935 | ||
1936 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 1936 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && |
1937 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 1937 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index b8807fb12c92..3a003e6803a5 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -104,6 +104,7 @@ | |||
104 | #define B43_MMIO_MACFILTER_CONTROL 0x420 | 104 | #define B43_MMIO_MACFILTER_CONTROL 0x420 |
105 | #define B43_MMIO_MACFILTER_DATA 0x422 | 105 | #define B43_MMIO_MACFILTER_DATA 0x422 |
106 | #define B43_MMIO_RCMTA_COUNT 0x43C | 106 | #define B43_MMIO_RCMTA_COUNT 0x43C |
107 | #define B43_MMIO_PSM_PHY_HDR 0x492 | ||
107 | #define B43_MMIO_RADIO_HWENABLED_LO 0x49A | 108 | #define B43_MMIO_RADIO_HWENABLED_LO 0x49A |
108 | #define B43_MMIO_GPIO_CONTROL 0x49C | 109 | #define B43_MMIO_GPIO_CONTROL 0x49C |
109 | #define B43_MMIO_GPIO_MASK 0x49E | 110 | #define B43_MMIO_GPIO_MASK 0x49E |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 795bb1e3345d..6fd140ac7f9e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -72,6 +72,22 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | |||
72 | u16 value, u8 core, bool off); | 72 | u16 value, u8 core, bool off); |
73 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | 73 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, |
74 | u16 value, u8 core); | 74 | u16 value, u8 core); |
75 | static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel); | ||
76 | |||
77 | static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) | ||
78 | { | ||
79 | return !chanspec->channel && !chanspec->sideband && | ||
80 | !chanspec->b_width && !chanspec->b_freq; | ||
81 | } | ||
82 | |||
83 | static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1, | ||
84 | struct b43_chanspec *chanspec2) | ||
85 | { | ||
86 | return (chanspec1->channel == chanspec2->channel && | ||
87 | chanspec1->sideband == chanspec2->sideband && | ||
88 | chanspec1->b_width == chanspec2->b_width && | ||
89 | chanspec1->b_freq == chanspec2->b_freq); | ||
90 | } | ||
75 | 91 | ||
76 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 92 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) |
77 | {//TODO | 93 | {//TODO |
@@ -90,28 +106,38 @@ static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev, | |||
90 | static void b43_chantab_radio_upload(struct b43_wldev *dev, | 106 | static void b43_chantab_radio_upload(struct b43_wldev *dev, |
91 | const struct b43_nphy_channeltab_entry *e) | 107 | const struct b43_nphy_channeltab_entry *e) |
92 | { | 108 | { |
93 | b43_radio_write16(dev, B2055_PLL_REF, e->radio_pll_ref); | 109 | b43_radio_write(dev, B2055_PLL_REF, e->radio_pll_ref); |
94 | b43_radio_write16(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0); | 110 | b43_radio_write(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0); |
95 | b43_radio_write16(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1); | 111 | b43_radio_write(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1); |
96 | b43_radio_write16(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail); | 112 | b43_radio_write(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail); |
97 | b43_radio_write16(dev, B2055_VCO_CAL1, e->radio_vco_cal1); | 113 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ |
98 | b43_radio_write16(dev, B2055_VCO_CAL2, e->radio_vco_cal2); | 114 | |
99 | b43_radio_write16(dev, B2055_PLL_LFC1, e->radio_pll_lfc1); | 115 | b43_radio_write(dev, B2055_VCO_CAL1, e->radio_vco_cal1); |
100 | b43_radio_write16(dev, B2055_PLL_LFR1, e->radio_pll_lfr1); | 116 | b43_radio_write(dev, B2055_VCO_CAL2, e->radio_vco_cal2); |
101 | b43_radio_write16(dev, B2055_PLL_LFC2, e->radio_pll_lfc2); | 117 | b43_radio_write(dev, B2055_PLL_LFC1, e->radio_pll_lfc1); |
102 | b43_radio_write16(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf); | 118 | b43_radio_write(dev, B2055_PLL_LFR1, e->radio_pll_lfr1); |
103 | b43_radio_write16(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1); | 119 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ |
104 | b43_radio_write16(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2); | 120 | |
105 | b43_radio_write16(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune); | 121 | b43_radio_write(dev, B2055_PLL_LFC2, e->radio_pll_lfc2); |
106 | b43_radio_write16(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune); | 122 | b43_radio_write(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf); |
107 | b43_radio_write16(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1); | 123 | b43_radio_write(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1); |
108 | b43_radio_write16(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn); | 124 | b43_radio_write(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2); |
109 | b43_radio_write16(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim); | 125 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ |
110 | b43_radio_write16(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune); | 126 | |
111 | b43_radio_write16(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune); | 127 | b43_radio_write(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune); |
112 | b43_radio_write16(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1); | 128 | b43_radio_write(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune); |
113 | b43_radio_write16(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn); | 129 | b43_radio_write(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1); |
114 | b43_radio_write16(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); | 130 | b43_radio_write(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn); |
131 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
132 | |||
133 | b43_radio_write(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim); | ||
134 | b43_radio_write(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune); | ||
135 | b43_radio_write(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune); | ||
136 | b43_radio_write(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1); | ||
137 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ | ||
138 | |||
139 | b43_radio_write(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn); | ||
140 | b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); | ||
115 | } | 141 | } |
116 | 142 | ||
117 | static void b43_chantab_phy_upload(struct b43_wldev *dev, | 143 | static void b43_chantab_phy_upload(struct b43_wldev *dev, |
@@ -130,34 +156,20 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) | |||
130 | //TODO | 156 | //TODO |
131 | } | 157 | } |
132 | 158 | ||
133 | /* Tune the hardware to a new channel. */ | ||
134 | static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel) | ||
135 | { | ||
136 | const struct b43_nphy_channeltab_entry *tabent; | ||
137 | 159 | ||
138 | tabent = b43_nphy_get_chantabent(dev, channel); | 160 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */ |
139 | if (!tabent) | 161 | static void b43_radio_2055_setup(struct b43_wldev *dev, |
140 | return -ESRCH; | 162 | const struct b43_nphy_channeltab_entry *e) |
163 | { | ||
164 | B43_WARN_ON(dev->phy.rev >= 3); | ||
141 | 165 | ||
142 | //FIXME enable/disable band select upper20 in RXCTL | 166 | b43_chantab_radio_upload(dev, e); |
143 | if (0 /*FIXME 5Ghz*/) | ||
144 | b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x20); | ||
145 | else | ||
146 | b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x50); | ||
147 | b43_chantab_radio_upload(dev, tabent); | ||
148 | udelay(50); | 167 | udelay(50); |
149 | b43_radio_write16(dev, B2055_VCO_CAL10, 5); | 168 | b43_radio_write(dev, B2055_VCO_CAL10, 5); |
150 | b43_radio_write16(dev, B2055_VCO_CAL10, 45); | 169 | b43_radio_write(dev, B2055_VCO_CAL10, 45); |
151 | b43_radio_write16(dev, B2055_VCO_CAL10, 65); | 170 | b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */ |
171 | b43_radio_write(dev, B2055_VCO_CAL10, 65); | ||
152 | udelay(300); | 172 | udelay(300); |
153 | if (0 /*FIXME 5Ghz*/) | ||
154 | b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); | ||
155 | else | ||
156 | b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); | ||
157 | b43_chantab_phy_upload(dev, tabent); | ||
158 | b43_nphy_tx_power_fix(dev); | ||
159 | |||
160 | return 0; | ||
161 | } | 173 | } |
162 | 174 | ||
163 | static void b43_radio_init2055_pre(struct b43_wldev *dev) | 175 | static void b43_radio_init2055_pre(struct b43_wldev *dev) |
@@ -173,52 +185,64 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev) | |||
173 | 185 | ||
174 | static void b43_radio_init2055_post(struct b43_wldev *dev) | 186 | static void b43_radio_init2055_post(struct b43_wldev *dev) |
175 | { | 187 | { |
188 | struct b43_phy_n *nphy = dev->phy.n; | ||
176 | struct ssb_sprom *sprom = &(dev->dev->bus->sprom); | 189 | struct ssb_sprom *sprom = &(dev->dev->bus->sprom); |
177 | struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); | 190 | struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); |
178 | int i; | 191 | int i; |
179 | u16 val; | 192 | u16 val; |
193 | bool workaround = false; | ||
194 | |||
195 | if (sprom->revision < 4) | ||
196 | workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM || | ||
197 | binfo->type != 0x46D || | ||
198 | binfo->rev < 0x41); | ||
199 | else | ||
200 | workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0); | ||
180 | 201 | ||
181 | b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); | 202 | b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); |
182 | msleep(1); | 203 | if (workaround) { |
183 | if ((sprom->revision != 4) || | 204 | b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F); |
184 | !(sprom->boardflags_hi & B43_BFH_RSSIINV)) { | 205 | b43_radio_mask(dev, B2055_C2_RX_BB_REG, 0x7F); |
185 | if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) || | ||
186 | (binfo->type != 0x46D) || | ||
187 | (binfo->rev < 0x41)) { | ||
188 | b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F); | ||
189 | b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F); | ||
190 | msleep(1); | ||
191 | } | ||
192 | } | 206 | } |
193 | b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0x3F, 0x2C); | 207 | b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C); |
194 | msleep(1); | 208 | b43_radio_write(dev, B2055_CAL_MISC, 0x3C); |
195 | b43_radio_write16(dev, B2055_CAL_MISC, 0x3C); | ||
196 | msleep(1); | ||
197 | b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); | 209 | b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); |
198 | msleep(1); | ||
199 | b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); | 210 | b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); |
200 | msleep(1); | ||
201 | b43_radio_set(dev, B2055_CAL_MISC, 0x1); | 211 | b43_radio_set(dev, B2055_CAL_MISC, 0x1); |
202 | msleep(1); | 212 | msleep(1); |
203 | b43_radio_set(dev, B2055_CAL_MISC, 0x40); | 213 | b43_radio_set(dev, B2055_CAL_MISC, 0x40); |
204 | msleep(1); | 214 | for (i = 0; i < 200; i++) { |
205 | for (i = 0; i < 100; i++) { | 215 | val = b43_radio_read(dev, B2055_CAL_COUT2); |
206 | val = b43_radio_read16(dev, B2055_CAL_COUT2); | 216 | if (val & 0x80) { |
207 | if (val & 0x80) | 217 | i = 0; |
208 | break; | 218 | break; |
219 | } | ||
209 | udelay(10); | 220 | udelay(10); |
210 | } | 221 | } |
211 | msleep(1); | 222 | if (i) |
223 | b43err(dev->wl, "radio post init timeout\n"); | ||
212 | b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); | 224 | b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); |
213 | msleep(1); | ||
214 | nphy_channel_switch(dev, dev->phy.channel); | 225 | nphy_channel_switch(dev, dev->phy.channel); |
215 | b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9); | 226 | b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); |
216 | b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9); | 227 | b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); |
217 | b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83); | 228 | b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); |
218 | b43_radio_write16(dev, B2055_C2_RX_BB_MIDACHP, 0x83); | 229 | b43_radio_write(dev, B2055_C2_RX_BB_MIDACHP, 0x83); |
230 | b43_radio_maskset(dev, B2055_C1_LNA_GAINBST, 0xFFF8, 0x6); | ||
231 | b43_radio_maskset(dev, B2055_C2_LNA_GAINBST, 0xFFF8, 0x6); | ||
232 | if (!nphy->gain_boost) { | ||
233 | b43_radio_set(dev, B2055_C1_RX_RFSPC1, 0x2); | ||
234 | b43_radio_set(dev, B2055_C2_RX_RFSPC1, 0x2); | ||
235 | } else { | ||
236 | b43_radio_mask(dev, B2055_C1_RX_RFSPC1, 0xFFFD); | ||
237 | b43_radio_mask(dev, B2055_C2_RX_RFSPC1, 0xFFFD); | ||
238 | } | ||
239 | udelay(2); | ||
219 | } | 240 | } |
220 | 241 | ||
221 | /* Initialize a Broadcom 2055 N-radio */ | 242 | /* |
243 | * Initialize a Broadcom 2055 N-radio | ||
244 | * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init | ||
245 | */ | ||
222 | static void b43_radio_init2055(struct b43_wldev *dev) | 246 | static void b43_radio_init2055(struct b43_wldev *dev) |
223 | { | 247 | { |
224 | b43_radio_init2055_pre(dev); | 248 | b43_radio_init2055_pre(dev); |
@@ -229,17 +253,6 @@ static void b43_radio_init2055(struct b43_wldev *dev) | |||
229 | b43_radio_init2055_post(dev); | 253 | b43_radio_init2055_post(dev); |
230 | } | 254 | } |
231 | 255 | ||
232 | void b43_nphy_radio_turn_on(struct b43_wldev *dev) | ||
233 | { | ||
234 | b43_radio_init2055(dev); | ||
235 | } | ||
236 | |||
237 | void b43_nphy_radio_turn_off(struct b43_wldev *dev) | ||
238 | { | ||
239 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
240 | ~B43_NPHY_RFCTL_CMD_EN); | ||
241 | } | ||
242 | |||
243 | /* | 256 | /* |
244 | * Upload the N-PHY tables. | 257 | * Upload the N-PHY tables. |
245 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables | 258 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables |
@@ -646,6 +659,41 @@ static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st) | |||
646 | clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); | 659 | clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES); |
647 | } | 660 | } |
648 | 661 | ||
662 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */ | ||
663 | static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) | ||
664 | { | ||
665 | if (dev->phy.rev >= 3) { | ||
666 | if (!init) | ||
667 | return; | ||
668 | if (0 /* FIXME */) { | ||
669 | b43_ntab_write(dev, B43_NTAB16(9, 2), 0x211); | ||
670 | b43_ntab_write(dev, B43_NTAB16(9, 3), 0x222); | ||
671 | b43_ntab_write(dev, B43_NTAB16(9, 8), 0x144); | ||
672 | b43_ntab_write(dev, B43_NTAB16(9, 12), 0x188); | ||
673 | } | ||
674 | } else { | ||
675 | b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); | ||
676 | b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); | ||
677 | |||
678 | ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00, | ||
679 | 0xFC00); | ||
680 | b43_write32(dev, B43_MMIO_MACCTL, | ||
681 | b43_read32(dev, B43_MMIO_MACCTL) & | ||
682 | ~B43_MACCTL_GPOUTSMSK); | ||
683 | b43_write16(dev, B43_MMIO_GPIO_MASK, | ||
684 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00); | ||
685 | b43_write16(dev, B43_MMIO_GPIO_CONTROL, | ||
686 | b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00); | ||
687 | |||
688 | if (init) { | ||
689 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
690 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
691 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
692 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
693 | } | ||
694 | } | ||
695 | } | ||
696 | |||
649 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ | 697 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ |
650 | static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | 698 | static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) |
651 | { | 699 | { |
@@ -722,7 +770,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev) | |||
722 | { | 770 | { |
723 | struct b43_phy_n *nphy = dev->phy.n; | 771 | struct b43_phy_n *nphy = dev->phy.n; |
724 | 772 | ||
725 | unsigned int channel; | 773 | u8 channel = nphy->radio_chanspec.channel; |
726 | int tone[2] = { 57, 58 }; | 774 | int tone[2] = { 57, 58 }; |
727 | u32 noise[2] = { 0x3FF, 0x3FF }; | 775 | u32 noise[2] = { 0x3FF, 0x3FF }; |
728 | 776 | ||
@@ -731,8 +779,6 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev) | |||
731 | if (nphy->hang_avoid) | 779 | if (nphy->hang_avoid) |
732 | b43_nphy_stay_in_carrier_search(dev, 1); | 780 | b43_nphy_stay_in_carrier_search(dev, 1); |
733 | 781 | ||
734 | /* FIXME: channel = radio_chanspec */ | ||
735 | |||
736 | if (nphy->gband_spurwar_en) { | 782 | if (nphy->gband_spurwar_en) { |
737 | /* TODO: N PHY Adjust Analog Pfbw (7) */ | 783 | /* TODO: N PHY Adjust Analog Pfbw (7) */ |
738 | if (channel == 11 && dev->phy.is_40mhz) | 784 | if (channel == 11 && dev->phy.is_40mhz) |
@@ -778,6 +824,62 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev) | |||
778 | b43_nphy_stay_in_carrier_search(dev, 0); | 824 | b43_nphy_stay_in_carrier_search(dev, 0); |
779 | } | 825 | } |
780 | 826 | ||
827 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */ | ||
828 | static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) | ||
829 | { | ||
830 | struct b43_phy_n *nphy = dev->phy.n; | ||
831 | |||
832 | u8 i; | ||
833 | s16 tmp; | ||
834 | u16 data[4]; | ||
835 | s16 gain[2]; | ||
836 | u16 minmax[2]; | ||
837 | u16 lna_gain[4] = { -2, 10, 19, 25 }; | ||
838 | |||
839 | if (nphy->hang_avoid) | ||
840 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
841 | |||
842 | if (nphy->gain_boost) { | ||
843 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
844 | gain[0] = 6; | ||
845 | gain[1] = 6; | ||
846 | } else { | ||
847 | tmp = 40370 - 315 * nphy->radio_chanspec.channel; | ||
848 | gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1)); | ||
849 | tmp = 23242 - 224 * nphy->radio_chanspec.channel; | ||
850 | gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1)); | ||
851 | } | ||
852 | } else { | ||
853 | gain[0] = 0; | ||
854 | gain[1] = 0; | ||
855 | } | ||
856 | |||
857 | for (i = 0; i < 2; i++) { | ||
858 | if (nphy->elna_gain_config) { | ||
859 | data[0] = 19 + gain[i]; | ||
860 | data[1] = 25 + gain[i]; | ||
861 | data[2] = 25 + gain[i]; | ||
862 | data[3] = 25 + gain[i]; | ||
863 | } else { | ||
864 | data[0] = lna_gain[0] + gain[i]; | ||
865 | data[1] = lna_gain[1] + gain[i]; | ||
866 | data[2] = lna_gain[2] + gain[i]; | ||
867 | data[3] = lna_gain[3] + gain[i]; | ||
868 | } | ||
869 | b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data); | ||
870 | |||
871 | minmax[i] = 23 + gain[i]; | ||
872 | } | ||
873 | |||
874 | b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN, | ||
875 | minmax[0] << B43_NPHY_C1_MINGAIN_SHIFT); | ||
876 | b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN, | ||
877 | minmax[1] << B43_NPHY_C2_MINGAIN_SHIFT); | ||
878 | |||
879 | if (nphy->hang_avoid) | ||
880 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
881 | } | ||
882 | |||
781 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ | 883 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ |
782 | static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) | 884 | static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) |
783 | { | 885 | { |
@@ -862,7 +964,7 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) | |||
862 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | 964 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, |
863 | (code << 8 | 0x7C)); | 965 | (code << 8 | 0x7C)); |
864 | 966 | ||
865 | /* TODO: b43_nphy_adjust_lna_gain_table(dev); */ | 967 | b43_nphy_adjust_lna_gain_table(dev); |
866 | 968 | ||
867 | if (nphy->elna_gain_config) { | 969 | if (nphy->elna_gain_config) { |
868 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); | 970 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); |
@@ -1969,12 +2071,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev) | |||
1969 | u16 *rssical_phy_regs = NULL; | 2071 | u16 *rssical_phy_regs = NULL; |
1970 | 2072 | ||
1971 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | 2073 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { |
1972 | if (!nphy->rssical_chanspec_2G) | 2074 | if (b43_empty_chanspec(&nphy->rssical_chanspec_2G)) |
1973 | return; | 2075 | return; |
1974 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; | 2076 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; |
1975 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; | 2077 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; |
1976 | } else { | 2078 | } else { |
1977 | if (!nphy->rssical_chanspec_5G) | 2079 | if (b43_empty_chanspec(&nphy->rssical_chanspec_5G)) |
1978 | return; | 2080 | return; |
1979 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; | 2081 | rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; |
1980 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; | 2082 | rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; |
@@ -2394,7 +2496,7 @@ static void b43_nphy_save_cal(struct b43_wldev *dev) | |||
2394 | 2496 | ||
2395 | struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; | 2497 | struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; |
2396 | u16 *txcal_radio_regs = NULL; | 2498 | u16 *txcal_radio_regs = NULL; |
2397 | u8 *iqcal_chanspec; | 2499 | struct b43_chanspec *iqcal_chanspec; |
2398 | u16 *table = NULL; | 2500 | u16 *table = NULL; |
2399 | 2501 | ||
2400 | if (nphy->hang_avoid) | 2502 | if (nphy->hang_avoid) |
@@ -2450,12 +2552,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) | |||
2450 | struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; | 2552 | struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; |
2451 | 2553 | ||
2452 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | 2554 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { |
2453 | if (nphy->iqcal_chanspec_2G == 0) | 2555 | if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G)) |
2454 | return; | 2556 | return; |
2455 | table = nphy->cal_cache.txcal_coeffs_2G; | 2557 | table = nphy->cal_cache.txcal_coeffs_2G; |
2456 | loft = &nphy->cal_cache.txcal_coeffs_2G[5]; | 2558 | loft = &nphy->cal_cache.txcal_coeffs_2G[5]; |
2457 | } else { | 2559 | } else { |
2458 | if (nphy->iqcal_chanspec_5G == 0) | 2560 | if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G)) |
2459 | return; | 2561 | return; |
2460 | table = nphy->cal_cache.txcal_coeffs_5G; | 2562 | table = nphy->cal_cache.txcal_coeffs_5G; |
2461 | loft = &nphy->cal_cache.txcal_coeffs_5G[5]; | 2563 | loft = &nphy->cal_cache.txcal_coeffs_5G[5]; |
@@ -2700,8 +2802,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
2700 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, | 2802 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, |
2701 | nphy->txiqlocal_bestc); | 2803 | nphy->txiqlocal_bestc); |
2702 | nphy->txiqlocal_coeffsvalid = true; | 2804 | nphy->txiqlocal_coeffsvalid = true; |
2703 | /* TODO: Set nphy->txiqlocal_chanspec to | 2805 | nphy->txiqlocal_chanspec = nphy->radio_chanspec; |
2704 | the current channel */ | ||
2705 | } else { | 2806 | } else { |
2706 | length = 11; | 2807 | length = 11; |
2707 | if (dev->phy.rev < 3) | 2808 | if (dev->phy.rev < 3) |
@@ -2736,7 +2837,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev) | |||
2736 | u16 buffer[7]; | 2837 | u16 buffer[7]; |
2737 | bool equal = true; | 2838 | bool equal = true; |
2738 | 2839 | ||
2739 | if (!nphy->txiqlocal_coeffsvalid || 1 /* FIXME */) | 2840 | if (!nphy->txiqlocal_coeffsvalid || |
2841 | b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec)) | ||
2740 | return; | 2842 | return; |
2741 | 2843 | ||
2742 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); | 2844 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); |
@@ -3091,9 +3193,11 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
3091 | do_rssi_cal = false; | 3193 | do_rssi_cal = false; |
3092 | if (phy->rev >= 3) { | 3194 | if (phy->rev >= 3) { |
3093 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | 3195 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) |
3094 | do_rssi_cal = (nphy->rssical_chanspec_2G == 0); | 3196 | do_rssi_cal = |
3197 | b43_empty_chanspec(&nphy->rssical_chanspec_2G); | ||
3095 | else | 3198 | else |
3096 | do_rssi_cal = (nphy->rssical_chanspec_5G == 0); | 3199 | do_rssi_cal = |
3200 | b43_empty_chanspec(&nphy->rssical_chanspec_5G); | ||
3097 | 3201 | ||
3098 | if (do_rssi_cal) | 3202 | if (do_rssi_cal) |
3099 | b43_nphy_rssi_cal(dev); | 3203 | b43_nphy_rssi_cal(dev); |
@@ -3105,9 +3209,9 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
3105 | 3209 | ||
3106 | if (!((nphy->measure_hold & 0x6) != 0)) { | 3210 | if (!((nphy->measure_hold & 0x6) != 0)) { |
3107 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | 3211 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) |
3108 | do_cal = (nphy->iqcal_chanspec_2G == 0); | 3212 | do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G); |
3109 | else | 3213 | else |
3110 | do_cal = (nphy->iqcal_chanspec_5G == 0); | 3214 | do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G); |
3111 | 3215 | ||
3112 | if (nphy->mute) | 3216 | if (nphy->mute) |
3113 | do_cal = false; | 3217 | do_cal = false; |
@@ -3116,7 +3220,7 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
3116 | target = b43_nphy_get_tx_gains(dev); | 3220 | target = b43_nphy_get_tx_gains(dev); |
3117 | 3221 | ||
3118 | if (nphy->antsel_type == 2) | 3222 | if (nphy->antsel_type == 2) |
3119 | ;/*TODO NPHY Superswitch Init with argument 1*/ | 3223 | b43_nphy_superswitch_init(dev, true); |
3120 | if (nphy->perical != 2) { | 3224 | if (nphy->perical != 2) { |
3121 | b43_nphy_rssi_cal(dev); | 3225 | b43_nphy_rssi_cal(dev); |
3122 | if (phy->rev >= 3) { | 3226 | if (phy->rev >= 3) { |
@@ -3154,6 +3258,129 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
3154 | return 0; | 3258 | return 0; |
3155 | } | 3259 | } |
3156 | 3260 | ||
3261 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ | ||
3262 | static void b43_nphy_chanspec_setup(struct b43_wldev *dev, | ||
3263 | const struct b43_nphy_channeltab_entry *e, | ||
3264 | struct b43_chanspec chanspec) | ||
3265 | { | ||
3266 | struct b43_phy *phy = &dev->phy; | ||
3267 | struct b43_phy_n *nphy = dev->phy.n; | ||
3268 | |||
3269 | u16 tmp; | ||
3270 | u32 tmp32; | ||
3271 | |||
3272 | tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; | ||
3273 | if (chanspec.b_freq == 1 && tmp == 0) { | ||
3274 | tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); | ||
3275 | b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); | ||
3276 | b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000); | ||
3277 | b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); | ||
3278 | b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); | ||
3279 | } else if (chanspec.b_freq == 1) { | ||
3280 | b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); | ||
3281 | tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); | ||
3282 | b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); | ||
3283 | b43_phy_mask(dev, B43_PHY_B_BBCFG, (u16)~0xC000); | ||
3284 | b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); | ||
3285 | } | ||
3286 | |||
3287 | b43_chantab_phy_upload(dev, e); | ||
3288 | |||
3289 | tmp = chanspec.channel; | ||
3290 | if (chanspec.b_freq == 1) | ||
3291 | tmp |= 0x0100; | ||
3292 | if (chanspec.b_width == 3) | ||
3293 | tmp |= 0x0200; | ||
3294 | b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp); | ||
3295 | |||
3296 | if (nphy->radio_chanspec.channel == 14) { | ||
3297 | b43_nphy_classifier(dev, 2, 0); | ||
3298 | b43_phy_set(dev, B43_PHY_B_TEST, 0x0800); | ||
3299 | } else { | ||
3300 | b43_nphy_classifier(dev, 2, 2); | ||
3301 | if (chanspec.b_freq == 2) | ||
3302 | b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840); | ||
3303 | } | ||
3304 | |||
3305 | if (nphy->txpwrctrl) | ||
3306 | b43_nphy_tx_power_fix(dev); | ||
3307 | |||
3308 | if (dev->phy.rev < 3) | ||
3309 | b43_nphy_adjust_lna_gain_table(dev); | ||
3310 | |||
3311 | b43_nphy_tx_lp_fbw(dev); | ||
3312 | |||
3313 | if (dev->phy.rev >= 3 && 0) { | ||
3314 | /* TODO */ | ||
3315 | } | ||
3316 | |||
3317 | b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830); | ||
3318 | |||
3319 | if (phy->rev >= 3) | ||
3320 | b43_nphy_spur_workaround(dev); | ||
3321 | } | ||
3322 | |||
3323 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ | ||
3324 | static int b43_nphy_set_chanspec(struct b43_wldev *dev, | ||
3325 | struct b43_chanspec chanspec) | ||
3326 | { | ||
3327 | struct b43_phy_n *nphy = dev->phy.n; | ||
3328 | |||
3329 | const struct b43_nphy_channeltab_entry *tabent; | ||
3330 | |||
3331 | u8 tmp; | ||
3332 | u8 channel = chanspec.channel; | ||
3333 | |||
3334 | if (dev->phy.rev >= 3) { | ||
3335 | /* TODO */ | ||
3336 | } | ||
3337 | |||
3338 | nphy->radio_chanspec = chanspec; | ||
3339 | |||
3340 | if (chanspec.b_width != nphy->b_width) | ||
3341 | ; /* TODO: BMAC BW Set (chanspec.b_width) */ | ||
3342 | |||
3343 | /* TODO: use defines */ | ||
3344 | if (chanspec.b_width == 3) { | ||
3345 | if (chanspec.sideband == 2) | ||
3346 | b43_phy_set(dev, B43_NPHY_RXCTL, | ||
3347 | B43_NPHY_RXCTL_BSELU20); | ||
3348 | else | ||
3349 | b43_phy_mask(dev, B43_NPHY_RXCTL, | ||
3350 | ~B43_NPHY_RXCTL_BSELU20); | ||
3351 | } | ||
3352 | |||
3353 | if (dev->phy.rev >= 3) { | ||
3354 | tmp = (chanspec.b_freq == 1) ? 4 : 0; | ||
3355 | b43_radio_maskset(dev, 0x08, 0xFFFB, tmp); | ||
3356 | /* TODO: PHY Radio2056 Setup (chan_info_ptr[i]) */ | ||
3357 | /* TODO: N PHY Chanspec Setup (chan_info_ptr[i]) */ | ||
3358 | } else { | ||
3359 | tabent = b43_nphy_get_chantabent(dev, channel); | ||
3360 | if (!tabent) | ||
3361 | return -ESRCH; | ||
3362 | |||
3363 | tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050; | ||
3364 | b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp); | ||
3365 | b43_radio_2055_setup(dev, tabent); | ||
3366 | b43_nphy_chanspec_setup(dev, tabent, chanspec); | ||
3367 | } | ||
3368 | |||
3369 | return 0; | ||
3370 | } | ||
3371 | |||
3372 | /* Tune the hardware to a new channel */ | ||
3373 | static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel) | ||
3374 | { | ||
3375 | struct b43_phy_n *nphy = dev->phy.n; | ||
3376 | |||
3377 | struct b43_chanspec chanspec; | ||
3378 | chanspec = nphy->radio_chanspec; | ||
3379 | chanspec.channel = channel; | ||
3380 | |||
3381 | return b43_nphy_set_chanspec(dev, chanspec); | ||
3382 | } | ||
3383 | |||
3157 | static int b43_nphy_op_allocate(struct b43_wldev *dev) | 3384 | static int b43_nphy_op_allocate(struct b43_wldev *dev) |
3158 | { | 3385 | { |
3159 | struct b43_phy_n *nphy; | 3386 | struct b43_phy_n *nphy; |
@@ -3242,9 +3469,41 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value) | |||
3242 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); | 3469 | b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); |
3243 | } | 3470 | } |
3244 | 3471 | ||
3472 | /* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */ | ||
3245 | static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, | 3473 | static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, |
3246 | bool blocked) | 3474 | bool blocked) |
3247 | {//TODO | 3475 | { |
3476 | if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) | ||
3477 | b43err(dev->wl, "MAC not suspended\n"); | ||
3478 | |||
3479 | if (blocked) { | ||
3480 | b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, | ||
3481 | ~B43_NPHY_RFCTL_CMD_CHIP0PU); | ||
3482 | if (dev->phy.rev >= 3) { | ||
3483 | b43_radio_mask(dev, 0x09, ~0x2); | ||
3484 | |||
3485 | b43_radio_write(dev, 0x204D, 0); | ||
3486 | b43_radio_write(dev, 0x2053, 0); | ||
3487 | b43_radio_write(dev, 0x2058, 0); | ||
3488 | b43_radio_write(dev, 0x205E, 0); | ||
3489 | b43_radio_mask(dev, 0x2062, ~0xF0); | ||
3490 | b43_radio_write(dev, 0x2064, 0); | ||
3491 | |||
3492 | b43_radio_write(dev, 0x304D, 0); | ||
3493 | b43_radio_write(dev, 0x3053, 0); | ||
3494 | b43_radio_write(dev, 0x3058, 0); | ||
3495 | b43_radio_write(dev, 0x305E, 0); | ||
3496 | b43_radio_mask(dev, 0x3062, ~0xF0); | ||
3497 | b43_radio_write(dev, 0x3064, 0); | ||
3498 | } | ||
3499 | } else { | ||
3500 | if (dev->phy.rev >= 3) { | ||
3501 | /* TODO: b43_radio_init2056(dev); */ | ||
3502 | /* TODO: PHY Set Channel Spec (dev, radio_chanspec) */ | ||
3503 | } else { | ||
3504 | b43_radio_init2055(dev); | ||
3505 | } | ||
3506 | } | ||
3248 | } | 3507 | } |
3249 | 3508 | ||
3250 | static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) | 3509 | static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) |
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 403aad3f894f..8b6d570dd0aa 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h | |||
@@ -711,6 +711,8 @@ | |||
711 | #define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ | 711 | #define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */ |
712 | #define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ | 712 | #define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */ |
713 | 713 | ||
714 | #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */ | ||
715 | #define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A) | ||
714 | 716 | ||
715 | 717 | ||
716 | /* Broadcom 2055 radio registers */ | 718 | /* Broadcom 2055 radio registers */ |
@@ -924,6 +926,13 @@ | |||
924 | 926 | ||
925 | struct b43_wldev; | 927 | struct b43_wldev; |
926 | 928 | ||
929 | struct b43_chanspec { | ||
930 | u8 channel; | ||
931 | u8 sideband; | ||
932 | u8 b_width; | ||
933 | u8 b_freq; | ||
934 | }; | ||
935 | |||
927 | struct b43_phy_n_iq_comp { | 936 | struct b43_phy_n_iq_comp { |
928 | s16 a0; | 937 | s16 a0; |
929 | s16 b0; | 938 | s16 b0; |
@@ -975,7 +984,8 @@ struct b43_phy_n { | |||
975 | u16 papd_epsilon_offset[2]; | 984 | u16 papd_epsilon_offset[2]; |
976 | s32 preamble_override; | 985 | s32 preamble_override; |
977 | u32 bb_mult_save; | 986 | u32 bb_mult_save; |
978 | u16 radio_chanspec; | 987 | u8 b_width; |
988 | struct b43_chanspec radio_chanspec; | ||
979 | 989 | ||
980 | bool gain_boost; | 990 | bool gain_boost; |
981 | bool elna_gain_config; | 991 | bool elna_gain_config; |
@@ -991,6 +1001,7 @@ struct b43_phy_n { | |||
991 | u16 txiqlocal_bestc[11]; | 1001 | u16 txiqlocal_bestc[11]; |
992 | bool txiqlocal_coeffsvalid; | 1002 | bool txiqlocal_coeffsvalid; |
993 | struct b43_phy_n_txpwrindex txpwrindex[2]; | 1003 | struct b43_phy_n_txpwrindex txpwrindex[2]; |
1004 | struct b43_chanspec txiqlocal_chanspec; | ||
994 | 1005 | ||
995 | u8 txrx_chain; | 1006 | u8 txrx_chain; |
996 | u16 tx_rx_cal_phy_saveregs[11]; | 1007 | u16 tx_rx_cal_phy_saveregs[11]; |
@@ -1006,12 +1017,12 @@ struct b43_phy_n { | |||
1006 | bool gband_spurwar_en; | 1017 | bool gband_spurwar_en; |
1007 | 1018 | ||
1008 | bool ipa2g_on; | 1019 | bool ipa2g_on; |
1009 | u8 iqcal_chanspec_2G; | 1020 | struct b43_chanspec iqcal_chanspec_2G; |
1010 | u8 rssical_chanspec_2G; | 1021 | struct b43_chanspec rssical_chanspec_2G; |
1011 | 1022 | ||
1012 | bool ipa5g_on; | 1023 | bool ipa5g_on; |
1013 | u8 iqcal_chanspec_5G; | 1024 | struct b43_chanspec iqcal_chanspec_5G; |
1014 | u8 rssical_chanspec_5G; | 1025 | struct b43_chanspec rssical_chanspec_5G; |
1015 | 1026 | ||
1016 | struct b43_phy_n_rssical_cache rssical_cache; | 1027 | struct b43_phy_n_rssical_cache rssical_cache; |
1017 | struct b43_phy_n_cal_cache cal_cache; | 1028 | struct b43_phy_n_cal_cache cal_cache; |
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 9c1c6ecd3672..b23036f7dc19 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h | |||
@@ -4,6 +4,15 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | 6 | ||
7 | struct b43_phy_n_sfo_cfg { | ||
8 | u16 phy_bw1a; | ||
9 | u16 phy_bw2; | ||
10 | u16 phy_bw3; | ||
11 | u16 phy_bw4; | ||
12 | u16 phy_bw5; | ||
13 | u16 phy_bw6; | ||
14 | }; | ||
15 | |||
7 | struct b43_nphy_channeltab_entry { | 16 | struct b43_nphy_channeltab_entry { |
8 | /* The channel number */ | 17 | /* The channel number */ |
9 | u8 channel; | 18 | u8 channel; |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 9b72c45a7748..fe63bf21c67e 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -6102,7 +6102,7 @@ static const struct net_device_ops ipw2100_netdev_ops = { | |||
6102 | .ndo_validate_addr = eth_validate_addr, | 6102 | .ndo_validate_addr = eth_validate_addr, |
6103 | }; | 6103 | }; |
6104 | 6104 | ||
6105 | /* Look into using netdev destructor to shutdown ieee80211? */ | 6105 | /* Look into using netdev destructor to shutdown libipw? */ |
6106 | 6106 | ||
6107 | static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, | 6107 | static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, |
6108 | void __iomem * base_addr, | 6108 | void __iomem * base_addr, |
@@ -6112,7 +6112,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, | |||
6112 | struct ipw2100_priv *priv; | 6112 | struct ipw2100_priv *priv; |
6113 | struct net_device *dev; | 6113 | struct net_device *dev; |
6114 | 6114 | ||
6115 | dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); | 6115 | dev = alloc_libipw(sizeof(struct ipw2100_priv), 0); |
6116 | if (!dev) | 6116 | if (!dev) |
6117 | return NULL; | 6117 | return NULL; |
6118 | priv = libipw_priv(dev); | 6118 | priv = libipw_priv(dev); |
@@ -6425,7 +6425,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, | |||
6425 | sysfs_remove_group(&pci_dev->dev.kobj, | 6425 | sysfs_remove_group(&pci_dev->dev.kobj, |
6426 | &ipw2100_attribute_group); | 6426 | &ipw2100_attribute_group); |
6427 | 6427 | ||
6428 | free_ieee80211(dev, 0); | 6428 | free_libipw(dev, 0); |
6429 | pci_set_drvdata(pci_dev, NULL); | 6429 | pci_set_drvdata(pci_dev, NULL); |
6430 | } | 6430 | } |
6431 | 6431 | ||
@@ -6483,10 +6483,10 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) | |||
6483 | if (dev->base_addr) | 6483 | if (dev->base_addr) |
6484 | iounmap((void __iomem *)dev->base_addr); | 6484 | iounmap((void __iomem *)dev->base_addr); |
6485 | 6485 | ||
6486 | /* wiphy_unregister needs to be here, before free_ieee80211 */ | 6486 | /* wiphy_unregister needs to be here, before free_libipw */ |
6487 | wiphy_unregister(priv->ieee->wdev.wiphy); | 6487 | wiphy_unregister(priv->ieee->wdev.wiphy); |
6488 | kfree(priv->ieee->bg_band.channels); | 6488 | kfree(priv->ieee->bg_band.channels); |
6489 | free_ieee80211(dev, 0); | 6489 | free_libipw(dev, 0); |
6490 | } | 6490 | } |
6491 | 6491 | ||
6492 | pci_release_regions(pci_dev); | 6492 | pci_release_regions(pci_dev); |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 5c7aa1b1eb56..6dc0733df46b 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -11666,7 +11666,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11666 | if (priv->prom_net_dev) | 11666 | if (priv->prom_net_dev) |
11667 | return -EPERM; | 11667 | return -EPERM; |
11668 | 11668 | ||
11669 | priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); | 11669 | priv->prom_net_dev = alloc_libipw(sizeof(struct ipw_prom_priv), 1); |
11670 | if (priv->prom_net_dev == NULL) | 11670 | if (priv->prom_net_dev == NULL) |
11671 | return -ENOMEM; | 11671 | return -ENOMEM; |
11672 | 11672 | ||
@@ -11685,7 +11685,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11685 | 11685 | ||
11686 | rc = register_netdev(priv->prom_net_dev); | 11686 | rc = register_netdev(priv->prom_net_dev); |
11687 | if (rc) { | 11687 | if (rc) { |
11688 | free_ieee80211(priv->prom_net_dev, 1); | 11688 | free_libipw(priv->prom_net_dev, 1); |
11689 | priv->prom_net_dev = NULL; | 11689 | priv->prom_net_dev = NULL; |
11690 | return rc; | 11690 | return rc; |
11691 | } | 11691 | } |
@@ -11699,7 +11699,7 @@ static void ipw_prom_free(struct ipw_priv *priv) | |||
11699 | return; | 11699 | return; |
11700 | 11700 | ||
11701 | unregister_netdev(priv->prom_net_dev); | 11701 | unregister_netdev(priv->prom_net_dev); |
11702 | free_ieee80211(priv->prom_net_dev, 1); | 11702 | free_libipw(priv->prom_net_dev, 1); |
11703 | 11703 | ||
11704 | priv->prom_net_dev = NULL; | 11704 | priv->prom_net_dev = NULL; |
11705 | } | 11705 | } |
@@ -11727,7 +11727,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11727 | struct ipw_priv *priv; | 11727 | struct ipw_priv *priv; |
11728 | int i; | 11728 | int i; |
11729 | 11729 | ||
11730 | net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); | 11730 | net_dev = alloc_libipw(sizeof(struct ipw_priv), 0); |
11731 | if (net_dev == NULL) { | 11731 | if (net_dev == NULL) { |
11732 | err = -ENOMEM; | 11732 | err = -ENOMEM; |
11733 | goto out; | 11733 | goto out; |
@@ -11747,7 +11747,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11747 | mutex_init(&priv->mutex); | 11747 | mutex_init(&priv->mutex); |
11748 | if (pci_enable_device(pdev)) { | 11748 | if (pci_enable_device(pdev)) { |
11749 | err = -ENODEV; | 11749 | err = -ENODEV; |
11750 | goto out_free_ieee80211; | 11750 | goto out_free_libipw; |
11751 | } | 11751 | } |
11752 | 11752 | ||
11753 | pci_set_master(pdev); | 11753 | pci_set_master(pdev); |
@@ -11874,8 +11874,8 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11874 | out_pci_disable_device: | 11874 | out_pci_disable_device: |
11875 | pci_disable_device(pdev); | 11875 | pci_disable_device(pdev); |
11876 | pci_set_drvdata(pdev, NULL); | 11876 | pci_set_drvdata(pdev, NULL); |
11877 | out_free_ieee80211: | 11877 | out_free_libipw: |
11878 | free_ieee80211(priv->net_dev, 0); | 11878 | free_libipw(priv->net_dev, 0); |
11879 | out: | 11879 | out: |
11880 | return err; | 11880 | return err; |
11881 | } | 11881 | } |
@@ -11942,11 +11942,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) | |||
11942 | pci_release_regions(pdev); | 11942 | pci_release_regions(pdev); |
11943 | pci_disable_device(pdev); | 11943 | pci_disable_device(pdev); |
11944 | pci_set_drvdata(pdev, NULL); | 11944 | pci_set_drvdata(pdev, NULL); |
11945 | /* wiphy_unregister needs to be here, before free_ieee80211 */ | 11945 | /* wiphy_unregister needs to be here, before free_libipw */ |
11946 | wiphy_unregister(priv->ieee->wdev.wiphy); | 11946 | wiphy_unregister(priv->ieee->wdev.wiphy); |
11947 | kfree(priv->ieee->a_band.channels); | 11947 | kfree(priv->ieee->a_band.channels); |
11948 | kfree(priv->ieee->bg_band.channels); | 11948 | kfree(priv->ieee->bg_band.channels); |
11949 | free_ieee80211(priv->net_dev, 0); | 11949 | free_libipw(priv->net_dev, 0); |
11950 | free_firmware(); | 11950 | free_firmware(); |
11951 | } | 11951 | } |
11952 | 11952 | ||
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index a6d5e42647e4..284b0e4cb815 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -64,7 +64,7 @@ | |||
64 | extern u32 libipw_debug_level; | 64 | extern u32 libipw_debug_level; |
65 | #define LIBIPW_DEBUG(level, fmt, args...) \ | 65 | #define LIBIPW_DEBUG(level, fmt, args...) \ |
66 | do { if (libipw_debug_level & (level)) \ | 66 | do { if (libipw_debug_level & (level)) \ |
67 | printk(KERN_DEBUG "ieee80211: %c %s " fmt, \ | 67 | printk(KERN_DEBUG "libipw: %c %s " fmt, \ |
68 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) | 68 | in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) |
69 | static inline bool libipw_ratelimit_debug(u32 level) | 69 | static inline bool libipw_ratelimit_debug(u32 level) |
70 | { | 70 | { |
@@ -116,8 +116,8 @@ static inline bool libipw_ratelimit_debug(u32 level) | |||
116 | #define LIBIPW_DL_RX (1<<9) | 116 | #define LIBIPW_DL_RX (1<<9) |
117 | #define LIBIPW_DL_QOS (1<<31) | 117 | #define LIBIPW_DL_QOS (1<<31) |
118 | 118 | ||
119 | #define LIBIPW_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) | 119 | #define LIBIPW_ERROR(f, a...) printk(KERN_ERR "libipw: " f, ## a) |
120 | #define LIBIPW_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) | 120 | #define LIBIPW_WARNING(f, a...) printk(KERN_WARNING "libipw: " f, ## a) |
121 | #define LIBIPW_DEBUG_INFO(f, a...) LIBIPW_DEBUG(LIBIPW_DL_INFO, f, ## a) | 121 | #define LIBIPW_DEBUG_INFO(f, a...) LIBIPW_DEBUG(LIBIPW_DL_INFO, f, ## a) |
122 | 122 | ||
123 | #define LIBIPW_DEBUG_WX(f, a...) LIBIPW_DEBUG(LIBIPW_DL_WX, f, ## a) | 123 | #define LIBIPW_DEBUG_WX(f, a...) LIBIPW_DEBUG(LIBIPW_DL_WX, f, ## a) |
@@ -905,7 +905,7 @@ struct libipw_device { | |||
905 | struct libipw_reassoc_request * req); | 905 | struct libipw_reassoc_request * req); |
906 | 906 | ||
907 | /* This must be the last item so that it points to the data | 907 | /* This must be the last item so that it points to the data |
908 | * allocated beyond this structure by alloc_ieee80211 */ | 908 | * allocated beyond this structure by alloc_libipw */ |
909 | u8 priv[0]; | 909 | u8 priv[0]; |
910 | }; | 910 | }; |
911 | 911 | ||
@@ -1017,9 +1017,9 @@ static inline int libipw_is_cck_rate(u8 rate) | |||
1017 | return 0; | 1017 | return 0; |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | /* ieee80211.c */ | 1020 | /* libipw.c */ |
1021 | extern void free_ieee80211(struct net_device *dev, int monitor); | 1021 | extern void free_libipw(struct net_device *dev, int monitor); |
1022 | extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); | 1022 | extern struct net_device *alloc_libipw(int sizeof_priv, int monitor); |
1023 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); | 1023 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); |
1024 | 1024 | ||
1025 | extern void libipw_networks_age(struct libipw_device *ieee, | 1025 | extern void libipw_networks_age(struct libipw_device *ieee, |
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 2fa55867bd8b..55965408ff3f 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #include "libipw.h" | 53 | #include "libipw.h" |
54 | 54 | ||
55 | #define DRV_DESCRIPTION "802.11 data/management/control stack" | 55 | #define DRV_DESCRIPTION "802.11 data/management/control stack" |
56 | #define DRV_NAME "ieee80211" | 56 | #define DRV_NAME "libipw" |
57 | #define DRV_VERSION LIBIPW_VERSION | 57 | #define DRV_VERSION LIBIPW_VERSION |
58 | #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" | 58 | #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" |
59 | 59 | ||
@@ -140,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu) | |||
140 | } | 140 | } |
141 | EXPORT_SYMBOL(libipw_change_mtu); | 141 | EXPORT_SYMBOL(libipw_change_mtu); |
142 | 142 | ||
143 | struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) | 143 | struct net_device *alloc_libipw(int sizeof_priv, int monitor) |
144 | { | 144 | { |
145 | struct libipw_device *ieee; | 145 | struct libipw_device *ieee; |
146 | struct net_device *dev; | 146 | struct net_device *dev; |
@@ -222,8 +222,9 @@ failed_free_netdev: | |||
222 | failed: | 222 | failed: |
223 | return NULL; | 223 | return NULL; |
224 | } | 224 | } |
225 | EXPORT_SYMBOL(alloc_libipw); | ||
225 | 226 | ||
226 | void free_ieee80211(struct net_device *dev, int monitor) | 227 | void free_libipw(struct net_device *dev, int monitor) |
227 | { | 228 | { |
228 | struct libipw_device *ieee = netdev_priv(dev); | 229 | struct libipw_device *ieee = netdev_priv(dev); |
229 | 230 | ||
@@ -237,6 +238,7 @@ void free_ieee80211(struct net_device *dev, int monitor) | |||
237 | 238 | ||
238 | free_netdev(dev); | 239 | free_netdev(dev); |
239 | } | 240 | } |
241 | EXPORT_SYMBOL(free_libipw); | ||
240 | 242 | ||
241 | #ifdef CONFIG_LIBIPW_DEBUG | 243 | #ifdef CONFIG_LIBIPW_DEBUG |
242 | 244 | ||
@@ -291,7 +293,7 @@ static int __init libipw_init(void) | |||
291 | struct proc_dir_entry *e; | 293 | struct proc_dir_entry *e; |
292 | 294 | ||
293 | libipw_debug_level = debug; | 295 | libipw_debug_level = debug; |
294 | libipw_proc = proc_mkdir(DRV_NAME, init_net.proc_net); | 296 | libipw_proc = proc_mkdir("ieee80211", init_net.proc_net); |
295 | if (libipw_proc == NULL) { | 297 | if (libipw_proc == NULL) { |
296 | LIBIPW_ERROR("Unable to create " DRV_NAME | 298 | LIBIPW_ERROR("Unable to create " DRV_NAME |
297 | " proc directory\n"); | 299 | " proc directory\n"); |
@@ -331,6 +333,3 @@ MODULE_PARM_DESC(debug, "debug output mask"); | |||
331 | 333 | ||
332 | module_exit(libipw_exit); | 334 | module_exit(libipw_exit); |
333 | module_init(libipw_init); | 335 | module_init(libipw_init); |
334 | |||
335 | EXPORT_SYMBOL(alloc_ieee80211); | ||
336 | EXPORT_SYMBOL(free_ieee80211); | ||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 4e378faee650..e31a5ccebea2 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -9,7 +9,7 @@ CFLAGS_iwl-devtrace.o := -I$(src) | |||
9 | 9 | ||
10 | # AGN | 10 | # AGN |
11 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 11 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
12 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o | 12 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o |
13 | 13 | ||
14 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o | 14 | iwlagn-$(CONFIG_IWL4965) += iwl-4965.o |
15 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o | 15 | iwlagn-$(CONFIG_IWL5000) += iwl-5000.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 3bf2e6e9b2d9..59b092eaa829 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "iwl-core.h" | 42 | #include "iwl-core.h" |
43 | #include "iwl-io.h" | 43 | #include "iwl-io.h" |
44 | #include "iwl-sta.h" | 44 | #include "iwl-sta.h" |
45 | #include "iwl-agn.h" | ||
45 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
46 | #include "iwl-5000-hw.h" | 47 | #include "iwl-5000-hw.h" |
47 | #include "iwl-agn-led.h" | 48 | #include "iwl-agn-led.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 3a876a8ece38..074f42a7dcad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h | |||
@@ -78,6 +78,8 @@ | |||
78 | /* RSSI to dBm */ | 78 | /* RSSI to dBm */ |
79 | #define IWL39_RSSI_OFFSET 95 | 79 | #define IWL39_RSSI_OFFSET 95 |
80 | 80 | ||
81 | #define IWL_DEFAULT_TX_POWER 0x0F | ||
82 | |||
81 | /* | 83 | /* |
82 | * EEPROM related constants, enums, and structures. | 84 | * EEPROM related constants, enums, and structures. |
83 | */ | 85 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 47909f94271e..b588cb69536a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -372,11 +372,11 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
372 | } | 372 | } |
373 | } | 373 | } |
374 | 374 | ||
375 | priv->sta_supp_rates = sta->supp_rates[sband->band]; | 375 | priv->_3945.sta_supp_rates = sta->supp_rates[sband->band]; |
376 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ | 376 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ |
377 | if (sband->band == IEEE80211_BAND_5GHZ) { | 377 | if (sband->band == IEEE80211_BAND_5GHZ) { |
378 | rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | 378 | rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
379 | priv->sta_supp_rates = priv->sta_supp_rates << | 379 | priv->_3945.sta_supp_rates = priv->_3945.sta_supp_rates << |
380 | IWL_FIRST_OFDM_RATE; | 380 | IWL_FIRST_OFDM_RATE; |
381 | } | 381 | } |
382 | 382 | ||
@@ -946,7 +946,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
946 | 946 | ||
947 | spin_unlock_irqrestore(&rs_sta->lock, flags); | 947 | spin_unlock_irqrestore(&rs_sta->lock, flags); |
948 | 948 | ||
949 | rssi = priv->last_rx_rssi; | 949 | rssi = priv->_3945.last_rx_rssi; |
950 | if (rssi == 0) | 950 | if (rssi == 0) |
951 | rssi = IWL_MIN_RSSI_VAL; | 951 | rssi = IWL_MIN_RSSI_VAL; |
952 | 952 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index e0678d921055..12a42fc743d7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -242,7 +242,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) | |||
242 | next_rate = IWL_RATE_6M_INDEX; | 242 | next_rate = IWL_RATE_6M_INDEX; |
243 | break; | 243 | break; |
244 | case IEEE80211_BAND_2GHZ: | 244 | case IEEE80211_BAND_2GHZ: |
245 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && | 245 | if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && |
246 | iwl_is_associated(priv)) { | 246 | iwl_is_associated(priv)) { |
247 | if (rate == IWL_RATE_11M_INDEX) | 247 | if (rate == IWL_RATE_11M_INDEX) |
248 | next_rate = IWL_RATE_5M_INDEX; | 248 | next_rate = IWL_RATE_5M_INDEX; |
@@ -359,7 +359,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | |||
359 | (int)sizeof(struct iwl3945_notif_statistics), | 359 | (int)sizeof(struct iwl3945_notif_statistics), |
360 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); | 360 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); |
361 | 361 | ||
362 | memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); | 362 | memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics)); |
363 | } | 363 | } |
364 | 364 | ||
365 | /****************************************************************************** | 365 | /****************************************************************************** |
@@ -705,9 +705,10 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
705 | iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); | 705 | iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header); |
706 | 706 | ||
707 | if (network_packet) { | 707 | if (network_packet) { |
708 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); | 708 | priv->_3945.last_beacon_time = |
709 | priv->last_tsf = le64_to_cpu(rx_end->timestamp); | 709 | le32_to_cpu(rx_end->beacon_timestamp); |
710 | priv->last_rx_rssi = rx_status.signal; | 710 | priv->_3945.last_tsf = le64_to_cpu(rx_end->timestamp); |
711 | priv->_3945.last_rx_rssi = rx_status.signal; | ||
711 | priv->last_rx_noise = rx_status.noise; | 712 | priv->last_rx_noise = rx_status.noise; |
712 | } | 713 | } |
713 | 714 | ||
@@ -956,7 +957,7 @@ static int iwl3945_tx_reset(struct iwl_priv *priv) | |||
956 | iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); | 957 | iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); |
957 | 958 | ||
958 | iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, | 959 | iwl_write_direct32(priv, FH39_TSSR_CBB_BASE, |
959 | priv->shared_phys); | 960 | priv->_3945.shared_phys); |
960 | 961 | ||
961 | iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, | 962 | iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG, |
962 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | | 963 | FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | |
@@ -1606,7 +1607,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv, | |||
1606 | int power; | 1607 | int power; |
1607 | 1608 | ||
1608 | /* Get this chnlgrp's rate-to-max/clip-powers table */ | 1609 | /* Get this chnlgrp's rate-to-max/clip-powers table */ |
1609 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; | 1610 | clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; |
1610 | 1611 | ||
1611 | /* Get this channel's rate-to-current-power settings table */ | 1612 | /* Get this channel's rate-to-current-power settings table */ |
1612 | power_info = ch_info->power_info; | 1613 | power_info = ch_info->power_info; |
@@ -1732,7 +1733,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv) | |||
1732 | } | 1733 | } |
1733 | 1734 | ||
1734 | /* Get this chnlgrp's rate-to-max/clip-powers table */ | 1735 | /* Get this chnlgrp's rate-to-max/clip-powers table */ |
1735 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; | 1736 | clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; |
1736 | 1737 | ||
1737 | /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ | 1738 | /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */ |
1738 | for (scan_tbl_index = 0; | 1739 | for (scan_tbl_index = 0; |
@@ -1997,13 +1998,13 @@ void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) | |||
1997 | 1998 | ||
1998 | reschedule: | 1999 | reschedule: |
1999 | queue_delayed_work(priv->workqueue, | 2000 | queue_delayed_work(priv->workqueue, |
2000 | &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ); | 2001 | &priv->_3945.thermal_periodic, REG_RECALIB_PERIOD * HZ); |
2001 | } | 2002 | } |
2002 | 2003 | ||
2003 | static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) | 2004 | static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) |
2004 | { | 2005 | { |
2005 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 2006 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
2006 | thermal_periodic.work); | 2007 | _3945.thermal_periodic.work); |
2007 | 2008 | ||
2008 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2009 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2009 | return; | 2010 | return; |
@@ -2139,7 +2140,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv) | |||
2139 | * power peaks, without too much distortion (clipping). | 2140 | * power peaks, without too much distortion (clipping). |
2140 | */ | 2141 | */ |
2141 | /* we'll fill in this array with h/w max power levels */ | 2142 | /* we'll fill in this array with h/w max power levels */ |
2142 | clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers; | 2143 | clip_pwrs = (s8 *) priv->_3945.clip_groups[i].clip_powers; |
2143 | 2144 | ||
2144 | /* divide factory saturation power by 2 to find -3dB level */ | 2145 | /* divide factory saturation power by 2 to find -3dB level */ |
2145 | satur_pwr = (s8) (group->saturation_power >> 1); | 2146 | satur_pwr = (s8) (group->saturation_power >> 1); |
@@ -2223,7 +2224,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) | |||
2223 | iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); | 2224 | iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); |
2224 | 2225 | ||
2225 | /* Get this chnlgrp's rate->max/clip-powers table */ | 2226 | /* Get this chnlgrp's rate->max/clip-powers table */ |
2226 | clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers; | 2227 | clip_pwrs = priv->_3945.clip_groups[ch_info->group_index].clip_powers; |
2227 | 2228 | ||
2228 | /* calculate power index *adjustment* value according to | 2229 | /* calculate power index *adjustment* value according to |
2229 | * diff between current temperature and factory temperature */ | 2230 | * diff between current temperature and factory temperature */ |
@@ -2331,7 +2332,7 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
2331 | { | 2332 | { |
2332 | int txq_id = txq->q.id; | 2333 | int txq_id = txq->q.id; |
2333 | 2334 | ||
2334 | struct iwl3945_shared *shared_data = priv->shared_virt; | 2335 | struct iwl3945_shared *shared_data = priv->_3945.shared_virt; |
2335 | 2336 | ||
2336 | shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); | 2337 | shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); |
2337 | 2338 | ||
@@ -2431,7 +2432,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv) | |||
2431 | /* If an OFDM rate is used, have it fall back to the | 2432 | /* If an OFDM rate is used, have it fall back to the |
2432 | * 1M CCK rates */ | 2433 | * 1M CCK rates */ |
2433 | 2434 | ||
2434 | if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) && | 2435 | if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && |
2435 | iwl_is_associated(priv)) { | 2436 | iwl_is_associated(priv)) { |
2436 | 2437 | ||
2437 | index = IWL_FIRST_CCK_RATE; | 2438 | index = IWL_FIRST_CCK_RATE; |
@@ -2470,10 +2471,11 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) | |||
2470 | memset((void *)&priv->hw_params, 0, | 2471 | memset((void *)&priv->hw_params, 0, |
2471 | sizeof(struct iwl_hw_params)); | 2472 | sizeof(struct iwl_hw_params)); |
2472 | 2473 | ||
2473 | priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev, | 2474 | priv->_3945.shared_virt = |
2474 | sizeof(struct iwl3945_shared), | 2475 | dma_alloc_coherent(&priv->pci_dev->dev, |
2475 | &priv->shared_phys, GFP_KERNEL); | 2476 | sizeof(struct iwl3945_shared), |
2476 | if (!priv->shared_virt) { | 2477 | &priv->_3945.shared_phys, GFP_KERNEL); |
2478 | if (!priv->_3945.shared_virt) { | ||
2477 | IWL_ERR(priv, "failed to allocate pci memory\n"); | 2479 | IWL_ERR(priv, "failed to allocate pci memory\n"); |
2478 | mutex_unlock(&priv->mutex); | 2480 | mutex_unlock(&priv->mutex); |
2479 | return -ENOMEM; | 2481 | return -ENOMEM; |
@@ -2536,13 +2538,13 @@ void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv) | |||
2536 | 2538 | ||
2537 | void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) | 2539 | void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv) |
2538 | { | 2540 | { |
2539 | INIT_DELAYED_WORK(&priv->thermal_periodic, | 2541 | INIT_DELAYED_WORK(&priv->_3945.thermal_periodic, |
2540 | iwl3945_bg_reg_txpower_periodic); | 2542 | iwl3945_bg_reg_txpower_periodic); |
2541 | } | 2543 | } |
2542 | 2544 | ||
2543 | void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) | 2545 | void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv) |
2544 | { | 2546 | { |
2545 | cancel_delayed_work(&priv->thermal_periodic); | 2547 | cancel_delayed_work(&priv->_3945.thermal_periodic); |
2546 | } | 2548 | } |
2547 | 2549 | ||
2548 | /* check contents of special bootstrap uCode SRAM */ | 2550 | /* check contents of special bootstrap uCode SRAM */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 1bd2cd836026..644aacfbd7df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -502,14 +502,14 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, | |||
502 | scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); | 502 | scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); |
503 | } | 503 | } |
504 | 504 | ||
505 | static const u16 default_queue_to_tx_fifo[] = { | 505 | static const s8 default_queue_to_tx_fifo[] = { |
506 | IWL_TX_FIFO_AC3, | 506 | IWL_TX_FIFO_VO, |
507 | IWL_TX_FIFO_AC2, | 507 | IWL_TX_FIFO_VI, |
508 | IWL_TX_FIFO_AC1, | 508 | IWL_TX_FIFO_BE, |
509 | IWL_TX_FIFO_AC0, | 509 | IWL_TX_FIFO_BK, |
510 | IWL49_CMD_FIFO_NUM, | 510 | IWL49_CMD_FIFO_NUM, |
511 | IWL_TX_FIFO_HCCA_1, | 511 | IWL_TX_FIFO_UNUSED, |
512 | IWL_TX_FIFO_HCCA_2 | 512 | IWL_TX_FIFO_UNUSED, |
513 | }; | 513 | }; |
514 | 514 | ||
515 | static int iwl4965_alive_notify(struct iwl_priv *priv) | 515 | static int iwl4965_alive_notify(struct iwl_priv *priv) |
@@ -589,9 +589,15 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) | |||
589 | /* reset to 0 to enable all the queue first */ | 589 | /* reset to 0 to enable all the queue first */ |
590 | priv->txq_ctx_active_msk = 0; | 590 | priv->txq_ctx_active_msk = 0; |
591 | /* Map each Tx/cmd queue to its corresponding fifo */ | 591 | /* Map each Tx/cmd queue to its corresponding fifo */ |
592 | BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7); | ||
592 | for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { | 593 | for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { |
593 | int ac = default_queue_to_tx_fifo[i]; | 594 | int ac = default_queue_to_tx_fifo[i]; |
595 | |||
594 | iwl_txq_ctx_activate(priv, i); | 596 | iwl_txq_ctx_activate(priv, i); |
597 | |||
598 | if (ac == IWL_TX_FIFO_UNUSED) | ||
599 | continue; | ||
600 | |||
595 | iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); | 601 | iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); |
596 | } | 602 | } |
597 | 603 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e476acb53aa7..37e1e77f513d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "iwl-io.h" | 43 | #include "iwl-io.h" |
44 | #include "iwl-sta.h" | 44 | #include "iwl-sta.h" |
45 | #include "iwl-helpers.h" | 45 | #include "iwl-helpers.h" |
46 | #include "iwl-agn.h" | ||
46 | #include "iwl-agn-led.h" | 47 | #include "iwl-agn-led.h" |
47 | #include "iwl-5000-hw.h" | 48 | #include "iwl-5000-hw.h" |
48 | #include "iwl-6000-hw.h" | 49 | #include "iwl-6000-hw.h" |
@@ -63,14 +64,17 @@ | |||
63 | #define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" | 64 | #define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" |
64 | #define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) | 65 | #define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api) |
65 | 66 | ||
66 | static const u16 iwl5000_default_queue_to_tx_fifo[] = { | 67 | static const s8 iwl5000_default_queue_to_tx_fifo[] = { |
67 | IWL_TX_FIFO_AC3, | 68 | IWL_TX_FIFO_VO, |
68 | IWL_TX_FIFO_AC2, | 69 | IWL_TX_FIFO_VI, |
69 | IWL_TX_FIFO_AC1, | 70 | IWL_TX_FIFO_BE, |
70 | IWL_TX_FIFO_AC0, | 71 | IWL_TX_FIFO_BK, |
71 | IWL50_CMD_FIFO_NUM, | 72 | IWL50_CMD_FIFO_NUM, |
72 | IWL_TX_FIFO_HCCA_1, | 73 | IWL_TX_FIFO_UNUSED, |
73 | IWL_TX_FIFO_HCCA_2 | 74 | IWL_TX_FIFO_UNUSED, |
75 | IWL_TX_FIFO_UNUSED, | ||
76 | IWL_TX_FIFO_UNUSED, | ||
77 | IWL_TX_FIFO_UNUSED, | ||
74 | }; | 78 | }; |
75 | 79 | ||
76 | /* NIC configuration for 5000 series */ | 80 | /* NIC configuration for 5000 series */ |
@@ -579,9 +583,9 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv, | |||
579 | 583 | ||
580 | txq->sched_retry = scd_retry; | 584 | txq->sched_retry = scd_retry; |
581 | 585 | ||
582 | IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n", | 586 | IWL_DEBUG_INFO(priv, "%s %s Queue %d on FIFO %d\n", |
583 | active ? "Activate" : "Deactivate", | 587 | active ? "Activate" : "Deactivate", |
584 | scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); | 588 | scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); |
585 | } | 589 | } |
586 | 590 | ||
587 | int iwl5000_alive_notify(struct iwl_priv *priv) | 591 | int iwl5000_alive_notify(struct iwl_priv *priv) |
@@ -656,25 +660,21 @@ int iwl5000_alive_notify(struct iwl_priv *priv) | |||
656 | /* reset to 0 to enable all the queue first */ | 660 | /* reset to 0 to enable all the queue first */ |
657 | priv->txq_ctx_active_msk = 0; | 661 | priv->txq_ctx_active_msk = 0; |
658 | /* map qos queues to fifos one-to-one */ | 662 | /* map qos queues to fifos one-to-one */ |
663 | BUILD_BUG_ON(ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo) != 10); | ||
664 | |||
659 | for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { | 665 | for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) { |
660 | int ac = iwl5000_default_queue_to_tx_fifo[i]; | 666 | int ac = iwl5000_default_queue_to_tx_fifo[i]; |
667 | |||
661 | iwl_txq_ctx_activate(priv, i); | 668 | iwl_txq_ctx_activate(priv, i); |
669 | |||
670 | if (ac == IWL_TX_FIFO_UNUSED) | ||
671 | continue; | ||
672 | |||
662 | iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0); | 673 | iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0); |
663 | } | 674 | } |
664 | 675 | ||
665 | /* | ||
666 | * TODO - need to initialize these queues and map them to FIFOs | ||
667 | * in the loop above, not only mark them as active. We do this | ||
668 | * because we want the first aggregation queue to be queue #10, | ||
669 | * but do not use 8 or 9 otherwise yet. | ||
670 | */ | ||
671 | iwl_txq_ctx_activate(priv, 7); | ||
672 | iwl_txq_ctx_activate(priv, 8); | ||
673 | iwl_txq_ctx_activate(priv, 9); | ||
674 | |||
675 | spin_unlock_irqrestore(&priv->lock, flags); | 676 | spin_unlock_irqrestore(&priv->lock, flags); |
676 | 677 | ||
677 | |||
678 | iwl_send_wimax_coex(priv); | 678 | iwl_send_wimax_coex(priv); |
679 | 679 | ||
680 | iwl5000_set_Xtal_calib(priv); | 680 | iwl5000_set_Xtal_calib(priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c4844adff92a..4b7bc008220f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "iwl-core.h" | 42 | #include "iwl-core.h" |
43 | #include "iwl-io.h" | 43 | #include "iwl-io.h" |
44 | #include "iwl-sta.h" | 44 | #include "iwl-sta.h" |
45 | #include "iwl-agn.h" | ||
45 | #include "iwl-helpers.h" | 46 | #include "iwl-helpers.h" |
46 | #include "iwl-5000-hw.h" | 47 | #include "iwl-5000-hw.h" |
47 | #include "iwl-6000-hw.h" | 48 | #include "iwl-6000-hw.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c new file mode 100644 index 000000000000..4c5395eae956 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c | |||
@@ -0,0 +1,305 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * GPL LICENSE SUMMARY | ||
4 | * | ||
5 | * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. | ||
6 | * | ||
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 | ||
9 | * 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 Street, Fifth Floor, Boston, MA 02110, | ||
19 | * USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/etherdevice.h> | ||
32 | #include <linux/sched.h> | ||
33 | #include <net/mac80211.h> | ||
34 | |||
35 | #include "iwl-dev.h" | ||
36 | #include "iwl-core.h" | ||
37 | #include "iwl-agn.h" | ||
38 | #include "iwl-helpers.h" | ||
39 | |||
40 | #define ICT_COUNT (PAGE_SIZE/sizeof(u32)) | ||
41 | |||
42 | /* Free dram table */ | ||
43 | void iwl_free_isr_ict(struct iwl_priv *priv) | ||
44 | { | ||
45 | if (priv->_agn.ict_tbl_vir) { | ||
46 | dma_free_coherent(&priv->pci_dev->dev, | ||
47 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | ||
48 | priv->_agn.ict_tbl_vir, | ||
49 | priv->_agn.ict_tbl_dma); | ||
50 | priv->_agn.ict_tbl_vir = NULL; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | |||
55 | /* allocate dram shared table it is a PAGE_SIZE aligned | ||
56 | * also reset all data related to ICT table interrupt. | ||
57 | */ | ||
58 | int iwl_alloc_isr_ict(struct iwl_priv *priv) | ||
59 | { | ||
60 | |||
61 | if (priv->cfg->use_isr_legacy) | ||
62 | return 0; | ||
63 | /* allocate shrared data table */ | ||
64 | priv->_agn.ict_tbl_vir = | ||
65 | dma_alloc_coherent(&priv->pci_dev->dev, | ||
66 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | ||
67 | &priv->_agn.ict_tbl_dma, GFP_KERNEL); | ||
68 | if (!priv->_agn.ict_tbl_vir) | ||
69 | return -ENOMEM; | ||
70 | |||
71 | /* align table to PAGE_SIZE boundry */ | ||
72 | priv->_agn.aligned_ict_tbl_dma = ALIGN(priv->_agn.ict_tbl_dma, PAGE_SIZE); | ||
73 | |||
74 | IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n", | ||
75 | (unsigned long long)priv->_agn.ict_tbl_dma, | ||
76 | (unsigned long long)priv->_agn.aligned_ict_tbl_dma, | ||
77 | (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma)); | ||
78 | |||
79 | priv->_agn.ict_tbl = priv->_agn.ict_tbl_vir + | ||
80 | (priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma); | ||
81 | |||
82 | IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n", | ||
83 | priv->_agn.ict_tbl, priv->_agn.ict_tbl_vir, | ||
84 | (int)(priv->_agn.aligned_ict_tbl_dma - priv->_agn.ict_tbl_dma)); | ||
85 | |||
86 | /* reset table and index to all 0 */ | ||
87 | memset(priv->_agn.ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE); | ||
88 | priv->_agn.ict_index = 0; | ||
89 | |||
90 | /* add periodic RX interrupt */ | ||
91 | priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC; | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | /* Device is going up inform it about using ICT interrupt table, | ||
96 | * also we need to tell the driver to start using ICT interrupt. | ||
97 | */ | ||
98 | int iwl_reset_ict(struct iwl_priv *priv) | ||
99 | { | ||
100 | u32 val; | ||
101 | unsigned long flags; | ||
102 | |||
103 | if (!priv->_agn.ict_tbl_vir) | ||
104 | return 0; | ||
105 | |||
106 | spin_lock_irqsave(&priv->lock, flags); | ||
107 | iwl_disable_interrupts(priv); | ||
108 | |||
109 | memset(&priv->_agn.ict_tbl[0], 0, sizeof(u32) * ICT_COUNT); | ||
110 | |||
111 | val = priv->_agn.aligned_ict_tbl_dma >> PAGE_SHIFT; | ||
112 | |||
113 | val |= CSR_DRAM_INT_TBL_ENABLE; | ||
114 | val |= CSR_DRAM_INIT_TBL_WRAP_CHECK; | ||
115 | |||
116 | IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X " | ||
117 | "aligned dma address %Lx\n", | ||
118 | val, (unsigned long long)priv->_agn.aligned_ict_tbl_dma); | ||
119 | |||
120 | iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val); | ||
121 | priv->_agn.use_ict = true; | ||
122 | priv->_agn.ict_index = 0; | ||
123 | iwl_write32(priv, CSR_INT, priv->inta_mask); | ||
124 | iwl_enable_interrupts(priv); | ||
125 | spin_unlock_irqrestore(&priv->lock, flags); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | /* Device is going down disable ict interrupt usage */ | ||
131 | void iwl_disable_ict(struct iwl_priv *priv) | ||
132 | { | ||
133 | unsigned long flags; | ||
134 | |||
135 | spin_lock_irqsave(&priv->lock, flags); | ||
136 | priv->_agn.use_ict = false; | ||
137 | spin_unlock_irqrestore(&priv->lock, flags); | ||
138 | } | ||
139 | |||
140 | static irqreturn_t iwl_isr(int irq, void *data) | ||
141 | { | ||
142 | struct iwl_priv *priv = data; | ||
143 | u32 inta, inta_mask; | ||
144 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
145 | u32 inta_fh; | ||
146 | #endif | ||
147 | if (!priv) | ||
148 | return IRQ_NONE; | ||
149 | |||
150 | spin_lock(&priv->lock); | ||
151 | |||
152 | /* Disable (but don't clear!) interrupts here to avoid | ||
153 | * back-to-back ISRs and sporadic interrupts from our NIC. | ||
154 | * If we have something to service, the tasklet will re-enable ints. | ||
155 | * If we *don't* have something, we'll re-enable before leaving here. */ | ||
156 | inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ | ||
157 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); | ||
158 | |||
159 | /* Discover which interrupts are active/pending */ | ||
160 | inta = iwl_read32(priv, CSR_INT); | ||
161 | |||
162 | /* Ignore interrupt if there's nothing in NIC to service. | ||
163 | * This may be due to IRQ shared with another device, | ||
164 | * or due to sporadic interrupts thrown from our NIC. */ | ||
165 | if (!inta) { | ||
166 | IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n"); | ||
167 | goto none; | ||
168 | } | ||
169 | |||
170 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | ||
171 | /* Hardware disappeared. It might have already raised | ||
172 | * an interrupt */ | ||
173 | IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); | ||
174 | goto unplugged; | ||
175 | } | ||
176 | |||
177 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
178 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { | ||
179 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); | ||
180 | IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, " | ||
181 | "fh 0x%08x\n", inta, inta_mask, inta_fh); | ||
182 | } | ||
183 | #endif | ||
184 | |||
185 | priv->_agn.inta |= inta; | ||
186 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | ||
187 | if (likely(inta)) | ||
188 | tasklet_schedule(&priv->irq_tasklet); | ||
189 | else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) | ||
190 | iwl_enable_interrupts(priv); | ||
191 | |||
192 | unplugged: | ||
193 | spin_unlock(&priv->lock); | ||
194 | return IRQ_HANDLED; | ||
195 | |||
196 | none: | ||
197 | /* re-enable interrupts here since we don't have anything to service. */ | ||
198 | /* only Re-enable if diabled by irq and no schedules tasklet. */ | ||
199 | if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) | ||
200 | iwl_enable_interrupts(priv); | ||
201 | |||
202 | spin_unlock(&priv->lock); | ||
203 | return IRQ_NONE; | ||
204 | } | ||
205 | |||
206 | /* interrupt handler using ict table, with this interrupt driver will | ||
207 | * stop using INTA register to get device's interrupt, reading this register | ||
208 | * is expensive, device will write interrupts in ICT dram table, increment | ||
209 | * index then will fire interrupt to driver, driver will OR all ICT table | ||
210 | * entries from current index up to table entry with 0 value. the result is | ||
211 | * the interrupt we need to service, driver will set the entries back to 0 and | ||
212 | * set index. | ||
213 | */ | ||
214 | irqreturn_t iwl_isr_ict(int irq, void *data) | ||
215 | { | ||
216 | struct iwl_priv *priv = data; | ||
217 | u32 inta, inta_mask; | ||
218 | u32 val = 0; | ||
219 | |||
220 | if (!priv) | ||
221 | return IRQ_NONE; | ||
222 | |||
223 | /* dram interrupt table not set yet, | ||
224 | * use legacy interrupt. | ||
225 | */ | ||
226 | if (!priv->_agn.use_ict) | ||
227 | return iwl_isr(irq, data); | ||
228 | |||
229 | spin_lock(&priv->lock); | ||
230 | |||
231 | /* Disable (but don't clear!) interrupts here to avoid | ||
232 | * back-to-back ISRs and sporadic interrupts from our NIC. | ||
233 | * If we have something to service, the tasklet will re-enable ints. | ||
234 | * If we *don't* have something, we'll re-enable before leaving here. | ||
235 | */ | ||
236 | inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ | ||
237 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); | ||
238 | |||
239 | |||
240 | /* Ignore interrupt if there's nothing in NIC to service. | ||
241 | * This may be due to IRQ shared with another device, | ||
242 | * or due to sporadic interrupts thrown from our NIC. */ | ||
243 | if (!priv->_agn.ict_tbl[priv->_agn.ict_index]) { | ||
244 | IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n"); | ||
245 | goto none; | ||
246 | } | ||
247 | |||
248 | /* read all entries that not 0 start with ict_index */ | ||
249 | while (priv->_agn.ict_tbl[priv->_agn.ict_index]) { | ||
250 | |||
251 | val |= le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index]); | ||
252 | IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n", | ||
253 | priv->_agn.ict_index, | ||
254 | le32_to_cpu(priv->_agn.ict_tbl[priv->_agn.ict_index])); | ||
255 | priv->_agn.ict_tbl[priv->_agn.ict_index] = 0; | ||
256 | priv->_agn.ict_index = iwl_queue_inc_wrap(priv->_agn.ict_index, | ||
257 | ICT_COUNT); | ||
258 | |||
259 | } | ||
260 | |||
261 | /* We should not get this value, just ignore it. */ | ||
262 | if (val == 0xffffffff) | ||
263 | val = 0; | ||
264 | |||
265 | /* | ||
266 | * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit | ||
267 | * (bit 15 before shifting it to 31) to clear when using interrupt | ||
268 | * coalescing. fortunately, bits 18 and 19 stay set when this happens | ||
269 | * so we use them to decide on the real state of the Rx bit. | ||
270 | * In order words, bit 15 is set if bit 18 or bit 19 are set. | ||
271 | */ | ||
272 | if (val & 0xC0000) | ||
273 | val |= 0x8000; | ||
274 | |||
275 | inta = (0xff & val) | ((0xff00 & val) << 16); | ||
276 | IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", | ||
277 | inta, inta_mask, val); | ||
278 | |||
279 | inta &= priv->inta_mask; | ||
280 | priv->_agn.inta |= inta; | ||
281 | |||
282 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | ||
283 | if (likely(inta)) | ||
284 | tasklet_schedule(&priv->irq_tasklet); | ||
285 | else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) { | ||
286 | /* Allow interrupt if was disabled by this handler and | ||
287 | * no tasklet was schedules, We should not enable interrupt, | ||
288 | * tasklet will enable it. | ||
289 | */ | ||
290 | iwl_enable_interrupts(priv); | ||
291 | } | ||
292 | |||
293 | spin_unlock(&priv->lock); | ||
294 | return IRQ_HANDLED; | ||
295 | |||
296 | none: | ||
297 | /* re-enable interrupts here since we don't have anything to service. | ||
298 | * only Re-enable if disabled by irq. | ||
299 | */ | ||
300 | if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->_agn.inta) | ||
301 | iwl_enable_interrupts(priv); | ||
302 | |||
303 | spin_unlock(&priv->lock); | ||
304 | return IRQ_NONE; | ||
305 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 8bf7c20b9d39..84271cc62afa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -597,10 +597,6 @@ static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, | |||
597 | struct ieee80211_hdr *hdr, | 597 | struct ieee80211_hdr *hdr, |
598 | enum iwl_table_type rate_type) | 598 | enum iwl_table_type rate_type) |
599 | { | 599 | { |
600 | if (hdr && is_multicast_ether_addr(hdr->addr1) && | ||
601 | lq_sta->active_rate_basic) | ||
602 | return lq_sta->active_rate_basic; | ||
603 | |||
604 | if (is_legacy(rate_type)) { | 600 | if (is_legacy(rate_type)) { |
605 | return lq_sta->active_legacy_rate; | 601 | return lq_sta->active_legacy_rate; |
606 | } else { | 602 | } else { |
@@ -2552,7 +2548,6 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
2552 | lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; | 2548 | lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; |
2553 | lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); | 2549 | lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); |
2554 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); | 2550 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); |
2555 | lq_sta->active_rate_basic = priv->active_rate_basic; | ||
2556 | lq_sta->band = priv->band; | 2551 | lq_sta->band = priv->band; |
2557 | /* | 2552 | /* |
2558 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2553 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
@@ -2956,12 +2951,8 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, | |||
2956 | desc += sprintf(buff+desc, | 2951 | desc += sprintf(buff+desc, |
2957 | "Bit Rate= %d Mb/s\n", | 2952 | "Bit Rate= %d Mb/s\n", |
2958 | iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); | 2953 | iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); |
2959 | desc += sprintf(buff+desc, | 2954 | desc += sprintf(buff+desc, "Noise Level= %d dBm\n", |
2960 | "Signal Level= %d dBm\tNoise Level= %d dBm\n", | 2955 | priv->last_rx_noise); |
2961 | priv->last_rx_rssi, priv->last_rx_noise); | ||
2962 | desc += sprintf(buff+desc, | ||
2963 | "Tsf= 0x%llx\tBeacon time= 0x%08X\n", | ||
2964 | priv->last_tsf, priv->last_beacon_time); | ||
2965 | 2956 | ||
2966 | ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); | 2957 | ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); |
2967 | return ret; | 2958 | return ret; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index e71923961e69..e182f5a0f736 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h | |||
@@ -411,7 +411,6 @@ struct iwl_lq_sta { | |||
411 | u16 active_siso_rate; | 411 | u16 active_siso_rate; |
412 | u16 active_mimo2_rate; | 412 | u16 active_mimo2_rate; |
413 | u16 active_mimo3_rate; | 413 | u16 active_mimo3_rate; |
414 | u16 active_rate_basic; | ||
415 | s8 max_rate_idx; /* Max rate set by user */ | 414 | s8 max_rate_idx; /* Max rate set by user */ |
416 | u8 missed_rate_counter; | 415 | u8 missed_rate_counter; |
417 | 416 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 818367b57bab..efee4e39d282 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include "iwl-helpers.h" | 54 | #include "iwl-helpers.h" |
55 | #include "iwl-sta.h" | 55 | #include "iwl-sta.h" |
56 | #include "iwl-calib.h" | 56 | #include "iwl-calib.h" |
57 | #include "iwl-agn.h" | ||
57 | 58 | ||
58 | 59 | ||
59 | /****************************************************************************** | 60 | /****************************************************************************** |
@@ -1258,9 +1259,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1258 | /* Ack/clear/reset pending uCode interrupts. | 1259 | /* Ack/clear/reset pending uCode interrupts. |
1259 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, | 1260 | * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, |
1260 | */ | 1261 | */ |
1261 | iwl_write32(priv, CSR_INT, priv->inta); | 1262 | iwl_write32(priv, CSR_INT, priv->_agn.inta); |
1262 | 1263 | ||
1263 | inta = priv->inta; | 1264 | inta = priv->_agn.inta; |
1264 | 1265 | ||
1265 | #ifdef CONFIG_IWLWIFI_DEBUG | 1266 | #ifdef CONFIG_IWLWIFI_DEBUG |
1266 | if (iwl_get_debug_level(priv) & IWL_DL_ISR) { | 1267 | if (iwl_get_debug_level(priv) & IWL_DL_ISR) { |
@@ -1273,8 +1274,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1273 | 1274 | ||
1274 | spin_unlock_irqrestore(&priv->lock, flags); | 1275 | spin_unlock_irqrestore(&priv->lock, flags); |
1275 | 1276 | ||
1276 | /* saved interrupt in inta variable now we can reset priv->inta */ | 1277 | /* saved interrupt in inta variable now we can reset priv->_agn.inta */ |
1277 | priv->inta = 0; | 1278 | priv->_agn.inta = 0; |
1278 | 1279 | ||
1279 | /* Now service all interrupt bits discovered above. */ | 1280 | /* Now service all interrupt bits discovered above. */ |
1280 | if (inta & CSR_INT_BIT_HW_ERR) { | 1281 | if (inta & CSR_INT_BIT_HW_ERR) { |
@@ -2102,8 +2103,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2102 | 2103 | ||
2103 | ieee80211_wake_queues(priv->hw); | 2104 | ieee80211_wake_queues(priv->hw); |
2104 | 2105 | ||
2105 | priv->active_rate = priv->rates_mask; | 2106 | priv->active_rate = IWL_RATES_MASK; |
2106 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | ||
2107 | 2107 | ||
2108 | /* Configure Tx antenna selection based on H/W config */ | 2108 | /* Configure Tx antenna selection based on H/W config */ |
2109 | if (priv->cfg->ops->hcmd->set_tx_ant) | 2109 | if (priv->cfg->ops->hcmd->set_tx_ant) |
@@ -2144,18 +2144,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2144 | 2144 | ||
2145 | iwl_power_update_mode(priv, true); | 2145 | iwl_power_update_mode(priv, true); |
2146 | 2146 | ||
2147 | /* reassociate for ADHOC mode */ | ||
2148 | if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { | ||
2149 | struct sk_buff *beacon = ieee80211_beacon_get(priv->hw, | ||
2150 | priv->vif); | ||
2151 | if (beacon) | ||
2152 | iwl_mac_beacon_update(priv->hw, beacon); | ||
2153 | } | ||
2154 | |||
2155 | |||
2156 | if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) | ||
2157 | iwl_set_mode(priv, priv->iw_mode); | ||
2158 | |||
2159 | return; | 2147 | return; |
2160 | 2148 | ||
2161 | restart: | 2149 | restart: |
@@ -2881,7 +2869,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2881 | 2869 | ||
2882 | mutex_lock(&priv->mutex); | 2870 | mutex_lock(&priv->mutex); |
2883 | iwl_scan_cancel_timeout(priv, 100); | 2871 | iwl_scan_cancel_timeout(priv, 100); |
2884 | mutex_unlock(&priv->mutex); | ||
2885 | 2872 | ||
2886 | /* If we are getting WEP group key and we didn't receive any key mapping | 2873 | /* If we are getting WEP group key and we didn't receive any key mapping |
2887 | * so far, we are in legacy wep mode (group key only), otherwise we are | 2874 | * so far, we are in legacy wep mode (group key only), otherwise we are |
@@ -2917,6 +2904,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2917 | ret = -EINVAL; | 2904 | ret = -EINVAL; |
2918 | } | 2905 | } |
2919 | 2906 | ||
2907 | mutex_unlock(&priv->mutex); | ||
2920 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2908 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2921 | 2909 | ||
2922 | return ret; | 2910 | return ret; |
@@ -3121,87 +3109,6 @@ static ssize_t store_tx_power(struct device *d, | |||
3121 | 3109 | ||
3122 | static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); | 3110 | static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); |
3123 | 3111 | ||
3124 | static ssize_t show_flags(struct device *d, | ||
3125 | struct device_attribute *attr, char *buf) | ||
3126 | { | ||
3127 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3128 | |||
3129 | return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); | ||
3130 | } | ||
3131 | |||
3132 | static ssize_t store_flags(struct device *d, | ||
3133 | struct device_attribute *attr, | ||
3134 | const char *buf, size_t count) | ||
3135 | { | ||
3136 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3137 | unsigned long val; | ||
3138 | u32 flags; | ||
3139 | int ret = strict_strtoul(buf, 0, &val); | ||
3140 | if (ret) | ||
3141 | return ret; | ||
3142 | flags = (u32)val; | ||
3143 | |||
3144 | mutex_lock(&priv->mutex); | ||
3145 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { | ||
3146 | /* Cancel any currently running scans... */ | ||
3147 | if (iwl_scan_cancel_timeout(priv, 100)) | ||
3148 | IWL_WARN(priv, "Could not cancel scan.\n"); | ||
3149 | else { | ||
3150 | IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags); | ||
3151 | priv->staging_rxon.flags = cpu_to_le32(flags); | ||
3152 | iwlcore_commit_rxon(priv); | ||
3153 | } | ||
3154 | } | ||
3155 | mutex_unlock(&priv->mutex); | ||
3156 | |||
3157 | return count; | ||
3158 | } | ||
3159 | |||
3160 | static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); | ||
3161 | |||
3162 | static ssize_t show_filter_flags(struct device *d, | ||
3163 | struct device_attribute *attr, char *buf) | ||
3164 | { | ||
3165 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3166 | |||
3167 | return sprintf(buf, "0x%04X\n", | ||
3168 | le32_to_cpu(priv->active_rxon.filter_flags)); | ||
3169 | } | ||
3170 | |||
3171 | static ssize_t store_filter_flags(struct device *d, | ||
3172 | struct device_attribute *attr, | ||
3173 | const char *buf, size_t count) | ||
3174 | { | ||
3175 | struct iwl_priv *priv = dev_get_drvdata(d); | ||
3176 | unsigned long val; | ||
3177 | u32 filter_flags; | ||
3178 | int ret = strict_strtoul(buf, 0, &val); | ||
3179 | if (ret) | ||
3180 | return ret; | ||
3181 | filter_flags = (u32)val; | ||
3182 | |||
3183 | mutex_lock(&priv->mutex); | ||
3184 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { | ||
3185 | /* Cancel any currently running scans... */ | ||
3186 | if (iwl_scan_cancel_timeout(priv, 100)) | ||
3187 | IWL_WARN(priv, "Could not cancel scan.\n"); | ||
3188 | else { | ||
3189 | IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " | ||
3190 | "0x%04X\n", filter_flags); | ||
3191 | priv->staging_rxon.filter_flags = | ||
3192 | cpu_to_le32(filter_flags); | ||
3193 | iwlcore_commit_rxon(priv); | ||
3194 | } | ||
3195 | } | ||
3196 | mutex_unlock(&priv->mutex); | ||
3197 | |||
3198 | return count; | ||
3199 | } | ||
3200 | |||
3201 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | ||
3202 | store_filter_flags); | ||
3203 | |||
3204 | |||
3205 | static ssize_t show_statistics(struct device *d, | 3112 | static ssize_t show_statistics(struct device *d, |
3206 | struct device_attribute *attr, char *buf) | 3113 | struct device_attribute *attr, char *buf) |
3207 | { | 3114 | { |
@@ -3391,7 +3298,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3391 | priv->qos_data.qos_active = 0; | 3298 | priv->qos_data.qos_active = 0; |
3392 | priv->qos_data.qos_cap.val = 0; | 3299 | priv->qos_data.qos_cap.val = 0; |
3393 | 3300 | ||
3394 | priv->rates_mask = IWL_RATES_MASK; | ||
3395 | /* Set the tx_power_user_lmt to the lowest power level | 3301 | /* Set the tx_power_user_lmt to the lowest power level |
3396 | * this value will get overwritten by channel max power avg | 3302 | * this value will get overwritten by channel max power avg |
3397 | * from eeprom */ | 3303 | * from eeprom */ |
@@ -3427,8 +3333,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
3427 | } | 3333 | } |
3428 | 3334 | ||
3429 | static struct attribute *iwl_sysfs_entries[] = { | 3335 | static struct attribute *iwl_sysfs_entries[] = { |
3430 | &dev_attr_flags.attr, | ||
3431 | &dev_attr_filter_flags.attr, | ||
3432 | &dev_attr_statistics.attr, | 3336 | &dev_attr_statistics.attr, |
3433 | &dev_attr_temperature.attr, | 3337 | &dev_attr_temperature.attr, |
3434 | &dev_attr_tx_power.attr, | 3338 | &dev_attr_tx_power.attr, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h new file mode 100644 index 000000000000..26eeb586ee00 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2010 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 - 2010 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_agn_h__ | ||
64 | #define __iwl_agn_h__ | ||
65 | |||
66 | #include "iwl-dev.h" | ||
67 | |||
68 | int iwl_reset_ict(struct iwl_priv *priv); | ||
69 | void iwl_disable_ict(struct iwl_priv *priv); | ||
70 | int iwl_alloc_isr_ict(struct iwl_priv *priv); | ||
71 | void iwl_free_isr_ict(struct iwl_priv *priv); | ||
72 | irqreturn_t iwl_isr_ict(int irq, void *data); | ||
73 | |||
74 | #endif /* __iwl_agn_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 112149e9b31e..ec435e5491d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -114,8 +114,6 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | |||
114 | u32 iwl_debug_level; | 114 | u32 iwl_debug_level; |
115 | EXPORT_SYMBOL(iwl_debug_level); | 115 | EXPORT_SYMBOL(iwl_debug_level); |
116 | 116 | ||
117 | static irqreturn_t iwl_isr(int irq, void *data); | ||
118 | |||
119 | /* | 117 | /* |
120 | * Parameter order: | 118 | * Parameter order: |
121 | * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate | 119 | * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate |
@@ -899,23 +897,10 @@ EXPORT_SYMBOL(iwl_full_rxon_required); | |||
899 | 897 | ||
900 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) | 898 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) |
901 | { | 899 | { |
902 | int i; | 900 | /* |
903 | int rate_mask; | 901 | * Assign the lowest rate -- should really get this from |
904 | 902 | * the beacon skb from mac80211. | |
905 | /* Set rate mask*/ | 903 | */ |
906 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) | ||
907 | rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK; | ||
908 | else | ||
909 | rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK; | ||
910 | |||
911 | /* Find lowest valid rate */ | ||
912 | for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID; | ||
913 | i = iwl_rates[i].next_ieee) { | ||
914 | if (rate_mask & (1 << i)) | ||
915 | return iwl_rates[i].plcp; | ||
916 | } | ||
917 | |||
918 | /* No valid rate was found. Assign the lowest one */ | ||
919 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) | 904 | if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) |
920 | return IWL_RATE_1M_PLCP; | 905 | return IWL_RATE_1M_PLCP; |
921 | else | 906 | else |
@@ -1240,14 +1225,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) | |||
1240 | if (!ch_info) | 1225 | if (!ch_info) |
1241 | ch_info = &priv->channel_info[0]; | 1226 | ch_info = &priv->channel_info[0]; |
1242 | 1227 | ||
1243 | /* | ||
1244 | * in some case A channels are all non IBSS | ||
1245 | * in this case force B/G channel | ||
1246 | */ | ||
1247 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && | ||
1248 | !(is_channel_ibss(ch_info))) | ||
1249 | ch_info = &priv->channel_info[0]; | ||
1250 | |||
1251 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 1228 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
1252 | priv->band = ch_info->band; | 1229 | priv->band = ch_info->band; |
1253 | 1230 | ||
@@ -1282,7 +1259,6 @@ static void iwl_set_rate(struct iwl_priv *priv) | |||
1282 | } | 1259 | } |
1283 | 1260 | ||
1284 | priv->active_rate = 0; | 1261 | priv->active_rate = 0; |
1285 | priv->active_rate_basic = 0; | ||
1286 | 1262 | ||
1287 | for (i = 0; i < hw->n_bitrates; i++) { | 1263 | for (i = 0; i < hw->n_bitrates; i++) { |
1288 | rate = &(hw->bitrates[i]); | 1264 | rate = &(hw->bitrates[i]); |
@@ -1290,30 +1266,13 @@ static void iwl_set_rate(struct iwl_priv *priv) | |||
1290 | priv->active_rate |= (1 << rate->hw_value); | 1266 | priv->active_rate |= (1 << rate->hw_value); |
1291 | } | 1267 | } |
1292 | 1268 | ||
1293 | IWL_DEBUG_RATE(priv, "Set active_rate = %0x, active_rate_basic = %0x\n", | 1269 | IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate); |
1294 | priv->active_rate, priv->active_rate_basic); | ||
1295 | 1270 | ||
1296 | /* | 1271 | priv->staging_rxon.cck_basic_rates = |
1297 | * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK) | 1272 | (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; |
1298 | * otherwise set it to the default of all CCK rates and 6, 12, 24 for | 1273 | |
1299 | * OFDM | 1274 | priv->staging_rxon.ofdm_basic_rates = |
1300 | */ | 1275 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
1301 | if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK) | ||
1302 | priv->staging_rxon.cck_basic_rates = | ||
1303 | ((priv->active_rate_basic & | ||
1304 | IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF; | ||
1305 | else | ||
1306 | priv->staging_rxon.cck_basic_rates = | ||
1307 | (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | ||
1308 | |||
1309 | if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK) | ||
1310 | priv->staging_rxon.ofdm_basic_rates = | ||
1311 | ((priv->active_rate_basic & | ||
1312 | (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >> | ||
1313 | IWL_FIRST_OFDM_RATE) & 0xFF; | ||
1314 | else | ||
1315 | priv->staging_rxon.ofdm_basic_rates = | ||
1316 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | ||
1317 | } | 1276 | } |
1318 | 1277 | ||
1319 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | 1278 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) |
@@ -1397,7 +1356,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv) | |||
1397 | } | 1356 | } |
1398 | EXPORT_SYMBOL(iwl_irq_handle_error); | 1357 | EXPORT_SYMBOL(iwl_irq_handle_error); |
1399 | 1358 | ||
1400 | int iwl_apm_stop_master(struct iwl_priv *priv) | 1359 | static int iwl_apm_stop_master(struct iwl_priv *priv) |
1401 | { | 1360 | { |
1402 | int ret = 0; | 1361 | int ret = 0; |
1403 | 1362 | ||
@@ -1413,7 +1372,6 @@ int iwl_apm_stop_master(struct iwl_priv *priv) | |||
1413 | 1372 | ||
1414 | return ret; | 1373 | return ret; |
1415 | } | 1374 | } |
1416 | EXPORT_SYMBOL(iwl_apm_stop_master); | ||
1417 | 1375 | ||
1418 | void iwl_apm_stop(struct iwl_priv *priv) | 1376 | void iwl_apm_stop(struct iwl_priv *priv) |
1419 | { | 1377 | { |
@@ -1664,277 +1622,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
1664 | } | 1622 | } |
1665 | EXPORT_SYMBOL(iwl_set_tx_power); | 1623 | EXPORT_SYMBOL(iwl_set_tx_power); |
1666 | 1624 | ||
1667 | #define ICT_COUNT (PAGE_SIZE/sizeof(u32)) | ||
1668 | |||
1669 | /* Free dram table */ | ||
1670 | void iwl_free_isr_ict(struct iwl_priv *priv) | ||
1671 | { | ||
1672 | if (priv->ict_tbl_vir) { | ||
1673 | dma_free_coherent(&priv->pci_dev->dev, | ||
1674 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | ||
1675 | priv->ict_tbl_vir, priv->ict_tbl_dma); | ||
1676 | priv->ict_tbl_vir = NULL; | ||
1677 | } | ||
1678 | } | ||
1679 | EXPORT_SYMBOL(iwl_free_isr_ict); | ||
1680 | |||
1681 | |||
1682 | /* allocate dram shared table it is a PAGE_SIZE aligned | ||
1683 | * also reset all data related to ICT table interrupt. | ||
1684 | */ | ||
1685 | int iwl_alloc_isr_ict(struct iwl_priv *priv) | ||
1686 | { | ||
1687 | |||
1688 | if (priv->cfg->use_isr_legacy) | ||
1689 | return 0; | ||
1690 | /* allocate shrared data table */ | ||
1691 | priv->ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev, | ||
1692 | (sizeof(u32) * ICT_COUNT) + PAGE_SIZE, | ||
1693 | &priv->ict_tbl_dma, GFP_KERNEL); | ||
1694 | if (!priv->ict_tbl_vir) | ||
1695 | return -ENOMEM; | ||
1696 | |||
1697 | /* align table to PAGE_SIZE boundry */ | ||
1698 | priv->aligned_ict_tbl_dma = ALIGN(priv->ict_tbl_dma, PAGE_SIZE); | ||
1699 | |||
1700 | IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n", | ||
1701 | (unsigned long long)priv->ict_tbl_dma, | ||
1702 | (unsigned long long)priv->aligned_ict_tbl_dma, | ||
1703 | (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma)); | ||
1704 | |||
1705 | priv->ict_tbl = priv->ict_tbl_vir + | ||
1706 | (priv->aligned_ict_tbl_dma - priv->ict_tbl_dma); | ||
1707 | |||
1708 | IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n", | ||
1709 | priv->ict_tbl, priv->ict_tbl_vir, | ||
1710 | (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma)); | ||
1711 | |||
1712 | /* reset table and index to all 0 */ | ||
1713 | memset(priv->ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE); | ||
1714 | priv->ict_index = 0; | ||
1715 | |||
1716 | /* add periodic RX interrupt */ | ||
1717 | priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC; | ||
1718 | return 0; | ||
1719 | } | ||
1720 | EXPORT_SYMBOL(iwl_alloc_isr_ict); | ||
1721 | |||
1722 | /* Device is going up inform it about using ICT interrupt table, | ||
1723 | * also we need to tell the driver to start using ICT interrupt. | ||
1724 | */ | ||
1725 | int iwl_reset_ict(struct iwl_priv *priv) | ||
1726 | { | ||
1727 | u32 val; | ||
1728 | unsigned long flags; | ||
1729 | |||
1730 | if (!priv->ict_tbl_vir) | ||
1731 | return 0; | ||
1732 | |||
1733 | spin_lock_irqsave(&priv->lock, flags); | ||
1734 | iwl_disable_interrupts(priv); | ||
1735 | |||
1736 | memset(&priv->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT); | ||
1737 | |||
1738 | val = priv->aligned_ict_tbl_dma >> PAGE_SHIFT; | ||
1739 | |||
1740 | val |= CSR_DRAM_INT_TBL_ENABLE; | ||
1741 | val |= CSR_DRAM_INIT_TBL_WRAP_CHECK; | ||
1742 | |||
1743 | IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X " | ||
1744 | "aligned dma address %Lx\n", | ||
1745 | val, (unsigned long long)priv->aligned_ict_tbl_dma); | ||
1746 | |||
1747 | iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val); | ||
1748 | priv->use_ict = true; | ||
1749 | priv->ict_index = 0; | ||
1750 | iwl_write32(priv, CSR_INT, priv->inta_mask); | ||
1751 | iwl_enable_interrupts(priv); | ||
1752 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1753 | |||
1754 | return 0; | ||
1755 | } | ||
1756 | EXPORT_SYMBOL(iwl_reset_ict); | ||
1757 | |||
1758 | /* Device is going down disable ict interrupt usage */ | ||
1759 | void iwl_disable_ict(struct iwl_priv *priv) | ||
1760 | { | ||
1761 | unsigned long flags; | ||
1762 | |||
1763 | spin_lock_irqsave(&priv->lock, flags); | ||
1764 | priv->use_ict = false; | ||
1765 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1766 | } | ||
1767 | EXPORT_SYMBOL(iwl_disable_ict); | ||
1768 | |||
1769 | /* interrupt handler using ict table, with this interrupt driver will | ||
1770 | * stop using INTA register to get device's interrupt, reading this register | ||
1771 | * is expensive, device will write interrupts in ICT dram table, increment | ||
1772 | * index then will fire interrupt to driver, driver will OR all ICT table | ||
1773 | * entries from current index up to table entry with 0 value. the result is | ||
1774 | * the interrupt we need to service, driver will set the entries back to 0 and | ||
1775 | * set index. | ||
1776 | */ | ||
1777 | irqreturn_t iwl_isr_ict(int irq, void *data) | ||
1778 | { | ||
1779 | struct iwl_priv *priv = data; | ||
1780 | u32 inta, inta_mask; | ||
1781 | u32 val = 0; | ||
1782 | |||
1783 | if (!priv) | ||
1784 | return IRQ_NONE; | ||
1785 | |||
1786 | /* dram interrupt table not set yet, | ||
1787 | * use legacy interrupt. | ||
1788 | */ | ||
1789 | if (!priv->use_ict) | ||
1790 | return iwl_isr(irq, data); | ||
1791 | |||
1792 | spin_lock(&priv->lock); | ||
1793 | |||
1794 | /* Disable (but don't clear!) interrupts here to avoid | ||
1795 | * back-to-back ISRs and sporadic interrupts from our NIC. | ||
1796 | * If we have something to service, the tasklet will re-enable ints. | ||
1797 | * If we *don't* have something, we'll re-enable before leaving here. | ||
1798 | */ | ||
1799 | inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ | ||
1800 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); | ||
1801 | |||
1802 | |||
1803 | /* Ignore interrupt if there's nothing in NIC to service. | ||
1804 | * This may be due to IRQ shared with another device, | ||
1805 | * or due to sporadic interrupts thrown from our NIC. */ | ||
1806 | if (!priv->ict_tbl[priv->ict_index]) { | ||
1807 | IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n"); | ||
1808 | goto none; | ||
1809 | } | ||
1810 | |||
1811 | /* read all entries that not 0 start with ict_index */ | ||
1812 | while (priv->ict_tbl[priv->ict_index]) { | ||
1813 | |||
1814 | val |= le32_to_cpu(priv->ict_tbl[priv->ict_index]); | ||
1815 | IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n", | ||
1816 | priv->ict_index, | ||
1817 | le32_to_cpu(priv->ict_tbl[priv->ict_index])); | ||
1818 | priv->ict_tbl[priv->ict_index] = 0; | ||
1819 | priv->ict_index = iwl_queue_inc_wrap(priv->ict_index, | ||
1820 | ICT_COUNT); | ||
1821 | |||
1822 | } | ||
1823 | |||
1824 | /* We should not get this value, just ignore it. */ | ||
1825 | if (val == 0xffffffff) | ||
1826 | val = 0; | ||
1827 | |||
1828 | /* | ||
1829 | * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit | ||
1830 | * (bit 15 before shifting it to 31) to clear when using interrupt | ||
1831 | * coalescing. fortunately, bits 18 and 19 stay set when this happens | ||
1832 | * so we use them to decide on the real state of the Rx bit. | ||
1833 | * In order words, bit 15 is set if bit 18 or bit 19 are set. | ||
1834 | */ | ||
1835 | if (val & 0xC0000) | ||
1836 | val |= 0x8000; | ||
1837 | |||
1838 | inta = (0xff & val) | ((0xff00 & val) << 16); | ||
1839 | IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", | ||
1840 | inta, inta_mask, val); | ||
1841 | |||
1842 | inta &= priv->inta_mask; | ||
1843 | priv->inta |= inta; | ||
1844 | |||
1845 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | ||
1846 | if (likely(inta)) | ||
1847 | tasklet_schedule(&priv->irq_tasklet); | ||
1848 | else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) { | ||
1849 | /* Allow interrupt if was disabled by this handler and | ||
1850 | * no tasklet was schedules, We should not enable interrupt, | ||
1851 | * tasklet will enable it. | ||
1852 | */ | ||
1853 | iwl_enable_interrupts(priv); | ||
1854 | } | ||
1855 | |||
1856 | spin_unlock(&priv->lock); | ||
1857 | return IRQ_HANDLED; | ||
1858 | |||
1859 | none: | ||
1860 | /* re-enable interrupts here since we don't have anything to service. | ||
1861 | * only Re-enable if disabled by irq. | ||
1862 | */ | ||
1863 | if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) | ||
1864 | iwl_enable_interrupts(priv); | ||
1865 | |||
1866 | spin_unlock(&priv->lock); | ||
1867 | return IRQ_NONE; | ||
1868 | } | ||
1869 | EXPORT_SYMBOL(iwl_isr_ict); | ||
1870 | |||
1871 | |||
1872 | static irqreturn_t iwl_isr(int irq, void *data) | ||
1873 | { | ||
1874 | struct iwl_priv *priv = data; | ||
1875 | u32 inta, inta_mask; | ||
1876 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1877 | u32 inta_fh; | ||
1878 | #endif | ||
1879 | if (!priv) | ||
1880 | return IRQ_NONE; | ||
1881 | |||
1882 | spin_lock(&priv->lock); | ||
1883 | |||
1884 | /* Disable (but don't clear!) interrupts here to avoid | ||
1885 | * back-to-back ISRs and sporadic interrupts from our NIC. | ||
1886 | * If we have something to service, the tasklet will re-enable ints. | ||
1887 | * If we *don't* have something, we'll re-enable before leaving here. */ | ||
1888 | inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ | ||
1889 | iwl_write32(priv, CSR_INT_MASK, 0x00000000); | ||
1890 | |||
1891 | /* Discover which interrupts are active/pending */ | ||
1892 | inta = iwl_read32(priv, CSR_INT); | ||
1893 | |||
1894 | /* Ignore interrupt if there's nothing in NIC to service. | ||
1895 | * This may be due to IRQ shared with another device, | ||
1896 | * or due to sporadic interrupts thrown from our NIC. */ | ||
1897 | if (!inta) { | ||
1898 | IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n"); | ||
1899 | goto none; | ||
1900 | } | ||
1901 | |||
1902 | if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { | ||
1903 | /* Hardware disappeared. It might have already raised | ||
1904 | * an interrupt */ | ||
1905 | IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta); | ||
1906 | goto unplugged; | ||
1907 | } | ||
1908 | |||
1909 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1910 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { | ||
1911 | inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); | ||
1912 | IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, " | ||
1913 | "fh 0x%08x\n", inta, inta_mask, inta_fh); | ||
1914 | } | ||
1915 | #endif | ||
1916 | |||
1917 | priv->inta |= inta; | ||
1918 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | ||
1919 | if (likely(inta)) | ||
1920 | tasklet_schedule(&priv->irq_tasklet); | ||
1921 | else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) | ||
1922 | iwl_enable_interrupts(priv); | ||
1923 | |||
1924 | unplugged: | ||
1925 | spin_unlock(&priv->lock); | ||
1926 | return IRQ_HANDLED; | ||
1927 | |||
1928 | none: | ||
1929 | /* re-enable interrupts here since we don't have anything to service. */ | ||
1930 | /* only Re-enable if diabled by irq and no schedules tasklet. */ | ||
1931 | if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) | ||
1932 | iwl_enable_interrupts(priv); | ||
1933 | |||
1934 | spin_unlock(&priv->lock); | ||
1935 | return IRQ_NONE; | ||
1936 | } | ||
1937 | |||
1938 | irqreturn_t iwl_isr_legacy(int irq, void *data) | 1625 | irqreturn_t iwl_isr_legacy(int irq, void *data) |
1939 | { | 1626 | { |
1940 | struct iwl_priv *priv = data; | 1627 | struct iwl_priv *priv = data; |
@@ -2564,11 +2251,6 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2564 | return -EIO; | 2251 | return -EIO; |
2565 | } | 2252 | } |
2566 | 2253 | ||
2567 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
2568 | IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n"); | ||
2569 | return -EIO; | ||
2570 | } | ||
2571 | |||
2572 | spin_lock_irqsave(&priv->lock, flags); | 2254 | spin_lock_irqsave(&priv->lock, flags); |
2573 | 2255 | ||
2574 | if (priv->ibss_beacon) | 2256 | if (priv->ibss_beacon) |
@@ -2592,23 +2274,9 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2592 | } | 2274 | } |
2593 | EXPORT_SYMBOL(iwl_mac_beacon_update); | 2275 | EXPORT_SYMBOL(iwl_mac_beacon_update); |
2594 | 2276 | ||
2595 | int iwl_set_mode(struct iwl_priv *priv, int mode) | 2277 | static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) |
2596 | { | 2278 | { |
2597 | if (mode == NL80211_IFTYPE_ADHOC) { | 2279 | iwl_connection_init_rx_config(priv, vif->type); |
2598 | const struct iwl_channel_info *ch_info; | ||
2599 | |||
2600 | ch_info = iwl_get_channel_info(priv, | ||
2601 | priv->band, | ||
2602 | le16_to_cpu(priv->staging_rxon.channel)); | ||
2603 | |||
2604 | if (!ch_info || !is_channel_ibss(ch_info)) { | ||
2605 | IWL_ERR(priv, "channel %d not IBSS channel\n", | ||
2606 | le16_to_cpu(priv->staging_rxon.channel)); | ||
2607 | return -EINVAL; | ||
2608 | } | ||
2609 | } | ||
2610 | |||
2611 | iwl_connection_init_rx_config(priv, mode); | ||
2612 | 2280 | ||
2613 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 2281 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2614 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | 2282 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
@@ -2617,18 +2285,10 @@ int iwl_set_mode(struct iwl_priv *priv, int mode) | |||
2617 | 2285 | ||
2618 | iwl_clear_stations_table(priv); | 2286 | iwl_clear_stations_table(priv); |
2619 | 2287 | ||
2620 | /* dont commit rxon if rf-kill is on*/ | 2288 | return iwlcore_commit_rxon(priv); |
2621 | if (!iwl_is_ready_rf(priv)) | ||
2622 | return -EAGAIN; | ||
2623 | |||
2624 | iwlcore_commit_rxon(priv); | ||
2625 | |||
2626 | return 0; | ||
2627 | } | 2289 | } |
2628 | EXPORT_SYMBOL(iwl_set_mode); | ||
2629 | 2290 | ||
2630 | int iwl_mac_add_interface(struct ieee80211_hw *hw, | 2291 | int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
2631 | struct ieee80211_vif *vif) | ||
2632 | { | 2292 | { |
2633 | struct iwl_priv *priv = hw->priv; | 2293 | struct iwl_priv *priv = hw->priv; |
2634 | int err = 0; | 2294 | int err = 0; |
@@ -2637,6 +2297,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, | |||
2637 | 2297 | ||
2638 | mutex_lock(&priv->mutex); | 2298 | mutex_lock(&priv->mutex); |
2639 | 2299 | ||
2300 | if (WARN_ON(!iwl_is_ready_rf(priv))) { | ||
2301 | err = -EINVAL; | ||
2302 | goto out; | ||
2303 | } | ||
2304 | |||
2640 | if (priv->vif) { | 2305 | if (priv->vif) { |
2641 | IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); | 2306 | IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); |
2642 | err = -EOPNOTSUPP; | 2307 | err = -EOPNOTSUPP; |
@@ -2646,15 +2311,17 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, | |||
2646 | priv->vif = vif; | 2311 | priv->vif = vif; |
2647 | priv->iw_mode = vif->type; | 2312 | priv->iw_mode = vif->type; |
2648 | 2313 | ||
2649 | if (vif->addr) { | 2314 | IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); |
2650 | IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); | 2315 | memcpy(priv->mac_addr, vif->addr, ETH_ALEN); |
2651 | memcpy(priv->mac_addr, vif->addr, ETH_ALEN); | ||
2652 | } | ||
2653 | 2316 | ||
2654 | if (iwl_set_mode(priv, vif->type) == -EAGAIN) | 2317 | err = iwl_set_mode(priv, vif); |
2655 | /* we are not ready, will run again when ready */ | 2318 | if (err) |
2656 | set_bit(STATUS_MODE_PENDING, &priv->status); | 2319 | goto out_err; |
2320 | goto out; | ||
2657 | 2321 | ||
2322 | out_err: | ||
2323 | priv->vif = NULL; | ||
2324 | priv->iw_mode = NL80211_IFTYPE_STATION; | ||
2658 | out: | 2325 | out: |
2659 | mutex_unlock(&priv->mutex); | 2326 | mutex_unlock(&priv->mutex); |
2660 | 2327 | ||
@@ -2664,7 +2331,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, | |||
2664 | EXPORT_SYMBOL(iwl_mac_add_interface); | 2331 | EXPORT_SYMBOL(iwl_mac_add_interface); |
2665 | 2332 | ||
2666 | void iwl_mac_remove_interface(struct ieee80211_hw *hw, | 2333 | void iwl_mac_remove_interface(struct ieee80211_hw *hw, |
2667 | struct ieee80211_vif *vif) | 2334 | struct ieee80211_vif *vif) |
2668 | { | 2335 | { |
2669 | struct iwl_priv *priv = hw->priv; | 2336 | struct iwl_priv *priv = hw->priv; |
2670 | 2337 | ||
@@ -2748,15 +2415,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2748 | goto set_ch_out; | 2415 | goto set_ch_out; |
2749 | } | 2416 | } |
2750 | 2417 | ||
2751 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
2752 | !is_channel_ibss(ch_info)) { | ||
2753 | IWL_ERR(priv, "channel %d in band %d not " | ||
2754 | "IBSS channel\n", | ||
2755 | conf->channel->hw_value, conf->channel->band); | ||
2756 | ret = -EINVAL; | ||
2757 | goto set_ch_out; | ||
2758 | } | ||
2759 | |||
2760 | spin_lock_irqsave(&priv->lock, flags); | 2418 | spin_lock_irqsave(&priv->lock, flags); |
2761 | 2419 | ||
2762 | /* Configure HT40 channels */ | 2420 | /* Configure HT40 channels */ |
@@ -2878,8 +2536,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) | |||
2878 | 2536 | ||
2879 | priv->beacon_int = priv->vif->bss_conf.beacon_int; | 2537 | priv->beacon_int = priv->vif->bss_conf.beacon_int; |
2880 | priv->timestamp = 0; | 2538 | priv->timestamp = 0; |
2881 | if ((priv->iw_mode == NL80211_IFTYPE_STATION)) | ||
2882 | priv->beacon_int = 0; | ||
2883 | 2539 | ||
2884 | spin_unlock_irqrestore(&priv->lock, flags); | 2540 | spin_unlock_irqrestore(&priv->lock, flags); |
2885 | 2541 | ||
@@ -2892,17 +2548,9 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) | |||
2892 | /* we are restarting association process | 2548 | /* we are restarting association process |
2893 | * clear RXON_FILTER_ASSOC_MSK bit | 2549 | * clear RXON_FILTER_ASSOC_MSK bit |
2894 | */ | 2550 | */ |
2895 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | 2551 | iwl_scan_cancel_timeout(priv, 100); |
2896 | iwl_scan_cancel_timeout(priv, 100); | 2552 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
2897 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2553 | iwlcore_commit_rxon(priv); |
2898 | iwlcore_commit_rxon(priv); | ||
2899 | } | ||
2900 | |||
2901 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { | ||
2902 | IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); | ||
2903 | mutex_unlock(&priv->mutex); | ||
2904 | return; | ||
2905 | } | ||
2906 | 2554 | ||
2907 | iwl_set_rate(priv); | 2555 | iwl_set_rate(priv); |
2908 | 2556 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4ef7739f9e8e..aced12f1611e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -336,7 +336,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
336 | u32 changes); | 336 | u32 changes); |
337 | int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | 337 | int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); |
338 | int iwl_commit_rxon(struct iwl_priv *priv); | 338 | int iwl_commit_rxon(struct iwl_priv *priv); |
339 | int iwl_set_mode(struct iwl_priv *priv, int mode); | ||
340 | int iwl_mac_add_interface(struct ieee80211_hw *hw, | 339 | int iwl_mac_add_interface(struct ieee80211_hw *hw, |
341 | struct ieee80211_vif *vif); | 340 | struct ieee80211_vif *vif); |
342 | void iwl_mac_remove_interface(struct ieee80211_hw *hw, | 341 | void iwl_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -560,11 +559,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, | |||
560 | * PCI * | 559 | * PCI * |
561 | *****************************************************/ | 560 | *****************************************************/ |
562 | irqreturn_t iwl_isr_legacy(int irq, void *data); | 561 | irqreturn_t iwl_isr_legacy(int irq, void *data); |
563 | int iwl_reset_ict(struct iwl_priv *priv); | ||
564 | void iwl_disable_ict(struct iwl_priv *priv); | ||
565 | int iwl_alloc_isr_ict(struct iwl_priv *priv); | ||
566 | void iwl_free_isr_ict(struct iwl_priv *priv); | ||
567 | irqreturn_t iwl_isr_ict(int irq, void *data); | ||
568 | 562 | ||
569 | static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) | 563 | static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) |
570 | { | 564 | { |
@@ -622,7 +616,6 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
622 | #define STATUS_SCAN_HW 15 | 616 | #define STATUS_SCAN_HW 15 |
623 | #define STATUS_POWER_PMI 16 | 617 | #define STATUS_POWER_PMI 16 |
624 | #define STATUS_FW_ERROR 17 | 618 | #define STATUS_FW_ERROR 17 |
625 | #define STATUS_MODE_PENDING 18 | ||
626 | 619 | ||
627 | 620 | ||
628 | static inline int iwl_is_ready(struct iwl_priv *priv) | 621 | static inline int iwl_is_ready(struct iwl_priv *priv) |
@@ -682,7 +675,6 @@ extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv, | |||
682 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | 675 | void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, |
683 | struct iwl_rx_mem_buffer *rxb); | 676 | struct iwl_rx_mem_buffer *rxb); |
684 | void iwl_apm_stop(struct iwl_priv *priv); | 677 | void iwl_apm_stop(struct iwl_priv *priv); |
685 | int iwl_apm_stop_master(struct iwl_priv *priv); | ||
686 | int iwl_apm_init(struct iwl_priv *priv); | 678 | int iwl_apm_init(struct iwl_priv *priv); |
687 | 679 | ||
688 | void iwl_setup_rxon_timing(struct iwl_priv *priv); | 680 | void iwl_setup_rxon_timing(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 7bf44f146799..5f5820249a29 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -560,8 +560,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
560 | test_bit(STATUS_POWER_PMI, &priv->status)); | 560 | test_bit(STATUS_POWER_PMI, &priv->status)); |
561 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", | 561 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", |
562 | test_bit(STATUS_FW_ERROR, &priv->status)); | 562 | test_bit(STATUS_FW_ERROR, &priv->status)); |
563 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n", | ||
564 | test_bit(STATUS_MODE_PENDING, &priv->status)); | ||
565 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 563 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
566 | } | 564 | } |
567 | 565 | ||
@@ -660,7 +658,6 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, | |||
660 | int pos = 0, i; | 658 | int pos = 0, i; |
661 | char buf[256]; | 659 | char buf[256]; |
662 | const size_t bufsz = sizeof(buf); | 660 | const size_t bufsz = sizeof(buf); |
663 | ssize_t ret; | ||
664 | 661 | ||
665 | for (i = 0; i < AC_NUM; i++) { | 662 | for (i = 0; i < AC_NUM; i++) { |
666 | pos += scnprintf(buf + pos, bufsz - pos, | 663 | pos += scnprintf(buf + pos, bufsz - pos, |
@@ -672,8 +669,7 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, | |||
672 | priv->qos_data.def_qos_parm.ac[i].aifsn, | 669 | priv->qos_data.def_qos_parm.ac[i].aifsn, |
673 | priv->qos_data.def_qos_parm.ac[i].edca_txop); | 670 | priv->qos_data.def_qos_parm.ac[i].edca_txop); |
674 | } | 671 | } |
675 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 672 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
676 | return ret; | ||
677 | } | 673 | } |
678 | 674 | ||
679 | static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, | 675 | static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, |
@@ -683,7 +679,6 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, | |||
683 | int pos = 0; | 679 | int pos = 0; |
684 | char buf[256]; | 680 | char buf[256]; |
685 | const size_t bufsz = sizeof(buf); | 681 | const size_t bufsz = sizeof(buf); |
686 | ssize_t ret; | ||
687 | 682 | ||
688 | pos += scnprintf(buf + pos, bufsz - pos, | 683 | pos += scnprintf(buf + pos, bufsz - pos, |
689 | "allow blinking: %s\n", | 684 | "allow blinking: %s\n", |
@@ -697,8 +692,7 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, | |||
697 | priv->last_blink_time); | 692 | priv->last_blink_time); |
698 | } | 693 | } |
699 | 694 | ||
700 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 695 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
701 | return ret; | ||
702 | } | 696 | } |
703 | 697 | ||
704 | static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, | 698 | static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, |
@@ -711,7 +705,6 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, | |||
711 | char buf[100]; | 705 | char buf[100]; |
712 | int pos = 0; | 706 | int pos = 0; |
713 | const size_t bufsz = sizeof(buf); | 707 | const size_t bufsz = sizeof(buf); |
714 | ssize_t ret; | ||
715 | 708 | ||
716 | pos += scnprintf(buf + pos, bufsz - pos, | 709 | pos += scnprintf(buf + pos, bufsz - pos, |
717 | "Thermal Throttling Mode: %s\n", | 710 | "Thermal Throttling Mode: %s\n", |
@@ -731,8 +724,7 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, | |||
731 | "HT mode: %d\n", | 724 | "HT mode: %d\n", |
732 | restriction->is_ht); | 725 | restriction->is_ht); |
733 | } | 726 | } |
734 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 727 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
735 | return ret; | ||
736 | } | 728 | } |
737 | 729 | ||
738 | static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, | 730 | static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, |
@@ -769,13 +761,11 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file, | |||
769 | char buf[100]; | 761 | char buf[100]; |
770 | int pos = 0; | 762 | int pos = 0; |
771 | const size_t bufsz = sizeof(buf); | 763 | const size_t bufsz = sizeof(buf); |
772 | ssize_t ret; | ||
773 | 764 | ||
774 | pos += scnprintf(buf + pos, bufsz - pos, | 765 | pos += scnprintf(buf + pos, bufsz - pos, |
775 | "11n 40MHz Mode: %s\n", | 766 | "11n 40MHz Mode: %s\n", |
776 | priv->disable_ht40 ? "Disabled" : "Enabled"); | 767 | priv->disable_ht40 ? "Disabled" : "Enabled"); |
777 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 768 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
778 | return ret; | ||
779 | } | 769 | } |
780 | 770 | ||
781 | static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, | 771 | static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, |
@@ -2051,7 +2041,6 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, | |||
2051 | int pos = 0; | 2041 | int pos = 0; |
2052 | char buf[128]; | 2042 | char buf[128]; |
2053 | const size_t bufsz = sizeof(buf); | 2043 | const size_t bufsz = sizeof(buf); |
2054 | ssize_t ret; | ||
2055 | 2044 | ||
2056 | pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", | 2045 | pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", |
2057 | priv->event_log.ucode_trace ? "On" : "Off"); | 2046 | priv->event_log.ucode_trace ? "On" : "Off"); |
@@ -2062,8 +2051,7 @@ static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, | |||
2062 | pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", | 2051 | pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", |
2063 | priv->event_log.wraps_more_count); | 2052 | priv->event_log.wraps_more_count); |
2064 | 2053 | ||
2065 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2054 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
2066 | return ret; | ||
2067 | } | 2055 | } |
2068 | 2056 | ||
2069 | static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, | 2057 | static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, |
@@ -2095,6 +2083,31 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, | |||
2095 | return count; | 2083 | return count; |
2096 | } | 2084 | } |
2097 | 2085 | ||
2086 | static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, | ||
2087 | char __user *user_buf, | ||
2088 | size_t count, loff_t *ppos) { | ||
2089 | |||
2090 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
2091 | int len = 0; | ||
2092 | char buf[20]; | ||
2093 | |||
2094 | len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags)); | ||
2095 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
2096 | } | ||
2097 | |||
2098 | static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, | ||
2099 | char __user *user_buf, | ||
2100 | size_t count, loff_t *ppos) { | ||
2101 | |||
2102 | struct iwl_priv *priv = (struct iwl_priv *)file->private_data; | ||
2103 | int len = 0; | ||
2104 | char buf[20]; | ||
2105 | |||
2106 | len = sprintf(buf, "0x%04X\n", | ||
2107 | le32_to_cpu(priv->active_rxon.filter_flags)); | ||
2108 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
2109 | } | ||
2110 | |||
2098 | static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | 2111 | static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, |
2099 | char __user *user_buf, | 2112 | char __user *user_buf, |
2100 | size_t count, loff_t *ppos) | 2113 | size_t count, loff_t *ppos) |
@@ -2124,13 +2137,11 @@ static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file, | |||
2124 | int pos = 0; | 2137 | int pos = 0; |
2125 | char buf[12]; | 2138 | char buf[12]; |
2126 | const size_t bufsz = sizeof(buf); | 2139 | const size_t bufsz = sizeof(buf); |
2127 | ssize_t ret; | ||
2128 | 2140 | ||
2129 | pos += scnprintf(buf + pos, bufsz - pos, "%d\n", | 2141 | pos += scnprintf(buf + pos, bufsz - pos, "%d\n", |
2130 | priv->missed_beacon_threshold); | 2142 | priv->missed_beacon_threshold); |
2131 | 2143 | ||
2132 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2144 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
2133 | return ret; | ||
2134 | } | 2145 | } |
2135 | 2146 | ||
2136 | static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, | 2147 | static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, |
@@ -2159,27 +2170,6 @@ static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, | |||
2159 | return count; | 2170 | return count; |
2160 | } | 2171 | } |
2161 | 2172 | ||
2162 | static ssize_t iwl_dbgfs_internal_scan_write(struct file *file, | ||
2163 | const char __user *user_buf, | ||
2164 | size_t count, loff_t *ppos) | ||
2165 | { | ||
2166 | struct iwl_priv *priv = file->private_data; | ||
2167 | char buf[8]; | ||
2168 | int buf_size; | ||
2169 | int scan; | ||
2170 | |||
2171 | memset(buf, 0, sizeof(buf)); | ||
2172 | buf_size = min(count, sizeof(buf) - 1); | ||
2173 | if (copy_from_user(buf, user_buf, buf_size)) | ||
2174 | return -EFAULT; | ||
2175 | if (sscanf(buf, "%d", &scan) != 1) | ||
2176 | return -EINVAL; | ||
2177 | |||
2178 | iwl_internal_short_hw_scan(priv); | ||
2179 | |||
2180 | return count; | ||
2181 | } | ||
2182 | |||
2183 | static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, | 2173 | static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, |
2184 | char __user *user_buf, | 2174 | char __user *user_buf, |
2185 | size_t count, loff_t *ppos) { | 2175 | size_t count, loff_t *ppos) { |
@@ -2188,13 +2178,11 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, | |||
2188 | int pos = 0; | 2178 | int pos = 0; |
2189 | char buf[12]; | 2179 | char buf[12]; |
2190 | const size_t bufsz = sizeof(buf); | 2180 | const size_t bufsz = sizeof(buf); |
2191 | ssize_t ret; | ||
2192 | 2181 | ||
2193 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", | 2182 | pos += scnprintf(buf + pos, bufsz - pos, "%u\n", |
2194 | priv->cfg->plcp_delta_threshold); | 2183 | priv->cfg->plcp_delta_threshold); |
2195 | 2184 | ||
2196 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2185 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
2197 | return ret; | ||
2198 | } | 2186 | } |
2199 | 2187 | ||
2200 | static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, | 2188 | static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, |
@@ -2295,9 +2283,10 @@ DEBUGFS_WRITE_FILE_OPS(csr); | |||
2295 | DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); | 2283 | DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); |
2296 | DEBUGFS_READ_FILE_OPS(fh_reg); | 2284 | DEBUGFS_READ_FILE_OPS(fh_reg); |
2297 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); | 2285 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); |
2298 | DEBUGFS_WRITE_FILE_OPS(internal_scan); | ||
2299 | DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); | 2286 | DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); |
2300 | DEBUGFS_READ_WRITE_FILE_OPS(force_reset); | 2287 | DEBUGFS_READ_WRITE_FILE_OPS(force_reset); |
2288 | DEBUGFS_READ_FILE_OPS(rxon_flags); | ||
2289 | DEBUGFS_READ_FILE_OPS(rxon_filter_flags); | ||
2301 | 2290 | ||
2302 | /* | 2291 | /* |
2303 | * Create the debugfs files and directories | 2292 | * Create the debugfs files and directories |
@@ -2349,7 +2338,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2349 | DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); | 2338 | DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); |
2350 | DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); | 2339 | DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); |
2351 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); | 2340 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); |
2352 | DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR); | ||
2353 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); | 2341 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); |
2354 | DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); | 2342 | DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); |
2355 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { | 2343 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { |
@@ -2360,6 +2348,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2360 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); | 2348 | DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); |
2361 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); | 2349 | DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); |
2362 | } | 2350 | } |
2351 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | ||
2352 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | ||
2363 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); | 2353 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); |
2364 | DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, | 2354 | DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, |
2365 | &priv->disable_chain_noise_cal); | 2355 | &priv->disable_chain_noise_cal); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6054c5fba0c1..2e4d47c7139b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -304,13 +304,11 @@ struct iwl_channel_info { | |||
304 | struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; | 304 | struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; |
305 | }; | 305 | }; |
306 | 306 | ||
307 | #define IWL_TX_FIFO_AC0 0 | 307 | #define IWL_TX_FIFO_BK 0 |
308 | #define IWL_TX_FIFO_AC1 1 | 308 | #define IWL_TX_FIFO_BE 1 |
309 | #define IWL_TX_FIFO_AC2 2 | 309 | #define IWL_TX_FIFO_VI 2 |
310 | #define IWL_TX_FIFO_AC3 3 | 310 | #define IWL_TX_FIFO_VO 3 |
311 | #define IWL_TX_FIFO_HCCA_1 5 | 311 | #define IWL_TX_FIFO_UNUSED -1 |
312 | #define IWL_TX_FIFO_HCCA_2 6 | ||
313 | #define IWL_TX_FIFO_NONE 7 | ||
314 | 312 | ||
315 | /* Minimum number of queues. MAX_NUM is defined in hw specific files. | 313 | /* Minimum number of queues. MAX_NUM is defined in hw specific files. |
316 | * Set the minimum to accommodate the 4 standard TX queues, 1 command | 314 | * Set the minimum to accommodate the 4 standard TX queues, 1 command |
@@ -1092,10 +1090,6 @@ struct iwl_priv { | |||
1092 | struct iwl_channel_info *channel_info; /* channel info array */ | 1090 | struct iwl_channel_info *channel_info; /* channel info array */ |
1093 | u8 channel_count; /* # of channels */ | 1091 | u8 channel_count; /* # of channels */ |
1094 | 1092 | ||
1095 | /* each calibration channel group in the EEPROM has a derived | ||
1096 | * clip setting for each rate. 3945 only.*/ | ||
1097 | const struct iwl3945_clip_group clip39_groups[5]; | ||
1098 | |||
1099 | /* thermal calibration */ | 1093 | /* thermal calibration */ |
1100 | s32 temperature; /* degrees Kelvin */ | 1094 | s32 temperature; /* degrees Kelvin */ |
1101 | s32 last_temperature; | 1095 | s32 last_temperature; |
@@ -1168,7 +1162,6 @@ struct iwl_priv { | |||
1168 | u64 led_tpt; | 1162 | u64 led_tpt; |
1169 | 1163 | ||
1170 | u16 active_rate; | 1164 | u16 active_rate; |
1171 | u16 active_rate_basic; | ||
1172 | 1165 | ||
1173 | u8 assoc_station_added; | 1166 | u8 assoc_station_added; |
1174 | u8 start_calib; | 1167 | u8 start_calib; |
@@ -1197,7 +1190,6 @@ struct iwl_priv { | |||
1197 | 1190 | ||
1198 | unsigned long status; | 1191 | unsigned long status; |
1199 | 1192 | ||
1200 | int last_rx_rssi; /* From Rx packet statistics */ | ||
1201 | int last_rx_noise; /* From beacon statistics */ | 1193 | int last_rx_noise; /* From beacon statistics */ |
1202 | 1194 | ||
1203 | /* counts mgmt, ctl, and data packets */ | 1195 | /* counts mgmt, ctl, and data packets */ |
@@ -1218,8 +1210,6 @@ struct iwl_priv { | |||
1218 | #endif | 1210 | #endif |
1219 | 1211 | ||
1220 | /* context information */ | 1212 | /* context information */ |
1221 | u16 rates_mask; | ||
1222 | |||
1223 | u8 bssid[ETH_ALEN]; | 1213 | u8 bssid[ETH_ALEN]; |
1224 | u16 rts_threshold; | 1214 | u16 rts_threshold; |
1225 | u8 mac_addr[ETH_ALEN]; | 1215 | u8 mac_addr[ETH_ALEN]; |
@@ -1228,7 +1218,7 @@ struct iwl_priv { | |||
1228 | spinlock_t sta_lock; | 1218 | spinlock_t sta_lock; |
1229 | int num_stations; | 1219 | int num_stations; |
1230 | struct iwl_station_entry stations[IWL_STATION_COUNT]; | 1220 | struct iwl_station_entry stations[IWL_STATION_COUNT]; |
1231 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; | 1221 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */ |
1232 | u8 default_wep_key; | 1222 | u8 default_wep_key; |
1233 | u8 key_mapping_key; | 1223 | u8 key_mapping_key; |
1234 | unsigned long ucode_key_table; | 1224 | unsigned long ucode_key_table; |
@@ -1244,10 +1234,6 @@ struct iwl_priv { | |||
1244 | 1234 | ||
1245 | u8 mac80211_registered; | 1235 | u8 mac80211_registered; |
1246 | 1236 | ||
1247 | /* Rx'd packet timing information */ | ||
1248 | u32 last_beacon_time; | ||
1249 | u64 last_tsf; | ||
1250 | |||
1251 | /* eeprom -- this is in the card's little endian byte order */ | 1237 | /* eeprom -- this is in the card's little endian byte order */ |
1252 | u8 *eeprom; | 1238 | u8 *eeprom; |
1253 | int nvm_device_type; | 1239 | int nvm_device_type; |
@@ -1262,20 +1248,48 @@ struct iwl_priv { | |||
1262 | u16 beacon_int; | 1248 | u16 beacon_int; |
1263 | struct ieee80211_vif *vif; | 1249 | struct ieee80211_vif *vif; |
1264 | 1250 | ||
1265 | /*Added for 3945 */ | 1251 | union { |
1266 | void *shared_virt; | 1252 | #if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE) |
1267 | dma_addr_t shared_phys; | 1253 | struct { |
1268 | /*End*/ | 1254 | void *shared_virt; |
1269 | struct iwl_hw_params hw_params; | 1255 | dma_addr_t shared_phys; |
1256 | |||
1257 | struct delayed_work thermal_periodic; | ||
1258 | struct delayed_work rfkill_poll; | ||
1259 | |||
1260 | struct iwl3945_notif_statistics statistics; | ||
1261 | |||
1262 | u32 sta_supp_rates; | ||
1263 | int last_rx_rssi; /* From Rx packet statistics */ | ||
1264 | |||
1265 | /* Rx'd packet timing information */ | ||
1266 | u32 last_beacon_time; | ||
1267 | u64 last_tsf; | ||
1270 | 1268 | ||
1271 | /* INT ICT Table */ | 1269 | /* |
1272 | __le32 *ict_tbl; | 1270 | * each calibration channel group in the |
1273 | dma_addr_t ict_tbl_dma; | 1271 | * EEPROM has a derived clip setting for |
1274 | dma_addr_t aligned_ict_tbl_dma; | 1272 | * each rate. |
1275 | int ict_index; | 1273 | */ |
1276 | void *ict_tbl_vir; | 1274 | const struct iwl3945_clip_group clip_groups[5]; |
1277 | u32 inta; | 1275 | |
1278 | bool use_ict; | 1276 | } _3945; |
1277 | #endif | ||
1278 | #if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE) | ||
1279 | struct { | ||
1280 | /* INT ICT Table */ | ||
1281 | __le32 *ict_tbl; | ||
1282 | void *ict_tbl_vir; | ||
1283 | dma_addr_t ict_tbl_dma; | ||
1284 | dma_addr_t aligned_ict_tbl_dma; | ||
1285 | int ict_index; | ||
1286 | u32 inta; | ||
1287 | bool use_ict; | ||
1288 | } _agn; | ||
1289 | #endif | ||
1290 | }; | ||
1291 | |||
1292 | struct iwl_hw_params hw_params; | ||
1279 | 1293 | ||
1280 | u32 inta_mask; | 1294 | u32 inta_mask; |
1281 | /* Current association information needed to configure the | 1295 | /* Current association information needed to configure the |
@@ -1303,10 +1317,6 @@ struct iwl_priv { | |||
1303 | struct delayed_work alive_start; | 1317 | struct delayed_work alive_start; |
1304 | struct delayed_work scan_check; | 1318 | struct delayed_work scan_check; |
1305 | 1319 | ||
1306 | /*For 3945 only*/ | ||
1307 | struct delayed_work thermal_periodic; | ||
1308 | struct delayed_work rfkill_poll; | ||
1309 | |||
1310 | /* TX Power */ | 1320 | /* TX Power */ |
1311 | s8 tx_power_user_lmt; | 1321 | s8 tx_power_user_lmt; |
1312 | s8 tx_power_device_lmt; | 1322 | s8 tx_power_device_lmt; |
@@ -1339,12 +1349,6 @@ struct iwl_priv { | |||
1339 | struct timer_list statistics_periodic; | 1349 | struct timer_list statistics_periodic; |
1340 | struct timer_list ucode_trace; | 1350 | struct timer_list ucode_trace; |
1341 | bool hw_ready; | 1351 | bool hw_ready; |
1342 | /*For 3945*/ | ||
1343 | #define IWL_DEFAULT_TX_POWER 0x0F | ||
1344 | |||
1345 | struct iwl3945_notif_statistics statistics_39; | ||
1346 | |||
1347 | u32 sta_supp_rates; | ||
1348 | 1352 | ||
1349 | struct iwl_event_log event_log; | 1353 | struct iwl_event_log event_log; |
1350 | }; /*iwl_priv */ | 1354 | }; /*iwl_priv */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 51a67fb2e185..3ff6b9d25a10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -31,6 +31,9 @@ | |||
31 | #define __iwl_helpers_h__ | 31 | #define __iwl_helpers_h__ |
32 | 32 | ||
33 | #include <linux/ctype.h> | 33 | #include <linux/ctype.h> |
34 | #include <net/mac80211.h> | ||
35 | |||
36 | #include "iwl-io.h" | ||
34 | 37 | ||
35 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | 38 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |
36 | 39 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index d2d2a9174900..5944de7a98a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -254,7 +254,7 @@ | |||
254 | * device. A queue maps to only one (selectable by driver) Tx DMA channel, | 254 | * device. A queue maps to only one (selectable by driver) Tx DMA channel, |
255 | * but one DMA channel may take input from several queues. | 255 | * but one DMA channel may take input from several queues. |
256 | * | 256 | * |
257 | * Tx DMA channels have dedicated purposes. For 4965, they are used as follows | 257 | * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows |
258 | * (cf. default_queue_to_tx_fifo in iwl-4965.c): | 258 | * (cf. default_queue_to_tx_fifo in iwl-4965.c): |
259 | * | 259 | * |
260 | * 0 -- EDCA BK (background) frames, lowest priority | 260 | * 0 -- EDCA BK (background) frames, lowest priority |
@@ -262,20 +262,20 @@ | |||
262 | * 2 -- EDCA VI (video) frames, higher priority | 262 | * 2 -- EDCA VI (video) frames, higher priority |
263 | * 3 -- EDCA VO (voice) and management frames, highest priority | 263 | * 3 -- EDCA VO (voice) and management frames, highest priority |
264 | * 4 -- Commands (e.g. RXON, etc.) | 264 | * 4 -- Commands (e.g. RXON, etc.) |
265 | * 5 -- HCCA short frames | 265 | * 5 -- unused (HCCA) |
266 | * 6 -- HCCA long frames | 266 | * 6 -- unused (HCCA) |
267 | * 7 -- not used by driver (device-internal only) | 267 | * 7 -- not used by driver (device-internal only) |
268 | * | 268 | * |
269 | * For 5000 series and up, they are used slightly differently | 269 | * For 5000 series and up, they are used differently |
270 | * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): | 270 | * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): |
271 | * | 271 | * |
272 | * 0 -- EDCA BK (background) frames, lowest priority | 272 | * 0 -- EDCA BK (background) frames, lowest priority |
273 | * 1 -- EDCA BE (best effort) frames, normal priority | 273 | * 1 -- EDCA BE (best effort) frames, normal priority |
274 | * 2 -- EDCA VI (video) frames, higher priority | 274 | * 2 -- EDCA VI (video) frames, higher priority |
275 | * 3 -- EDCA VO (voice) and management frames, highest priority | 275 | * 3 -- EDCA VO (voice) and management frames, highest priority |
276 | * 4 -- (TBD) | 276 | * 4 -- unused |
277 | * 5 -- HCCA short frames | 277 | * 5 -- unused |
278 | * 6 -- HCCA long frames | 278 | * 6 -- unused |
279 | * 7 -- Commands | 279 | * 7 -- Commands |
280 | * | 280 | * |
281 | * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. | 281 | * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index df257bc15f49..8116aa0d7678 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -1036,24 +1036,6 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
1036 | rxb->page = NULL; | 1036 | rxb->page = NULL; |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | /* This is necessary only for a number of statistics, see the caller. */ | ||
1040 | static int iwl_is_network_packet(struct iwl_priv *priv, | ||
1041 | struct ieee80211_hdr *header) | ||
1042 | { | ||
1043 | /* Filter incoming packets to determine if they are targeted toward | ||
1044 | * this network, discarding packets coming from ourselves */ | ||
1045 | switch (priv->iw_mode) { | ||
1046 | case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ | ||
1047 | /* packets to our IBSS update information */ | ||
1048 | return !compare_ether_addr(header->addr3, priv->bssid); | ||
1049 | case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ | ||
1050 | /* packets to our IBSS update information */ | ||
1051 | return !compare_ether_addr(header->addr2, priv->bssid); | ||
1052 | default: | ||
1053 | return 1; | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | /* Called for REPLY_RX (legacy ABG frames), or | 1039 | /* Called for REPLY_RX (legacy ABG frames), or |
1058 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | 1040 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ |
1059 | void iwl_rx_reply_rx(struct iwl_priv *priv, | 1041 | void iwl_rx_reply_rx(struct iwl_priv *priv, |
@@ -1190,12 +1172,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
1190 | if (rate_n_flags & RATE_MCS_SGI_MSK) | 1172 | if (rate_n_flags & RATE_MCS_SGI_MSK) |
1191 | rx_status.flag |= RX_FLAG_SHORT_GI; | 1173 | rx_status.flag |= RX_FLAG_SHORT_GI; |
1192 | 1174 | ||
1193 | if (iwl_is_network_packet(priv, header)) { | ||
1194 | priv->last_rx_rssi = rx_status.signal; | ||
1195 | priv->last_beacon_time = priv->ucode_beacon_time; | ||
1196 | priv->last_tsf = le64_to_cpu(phy_res->timestamp); | ||
1197 | } | ||
1198 | |||
1199 | iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, | 1175 | iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, |
1200 | rxb, &rx_status); | 1176 | rxb, &rx_status); |
1201 | } | 1177 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index bd2f7c420563..84b19b12ff03 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -580,7 +580,6 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv) | |||
580 | out: | 580 | out: |
581 | return ret; | 581 | return ret; |
582 | } | 582 | } |
583 | EXPORT_SYMBOL(iwl_internal_short_hw_scan); | ||
584 | 583 | ||
585 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 584 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) |
586 | 585 | ||
@@ -665,7 +664,6 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
665 | }; | 664 | }; |
666 | struct iwl_scan_cmd *scan; | 665 | struct iwl_scan_cmd *scan; |
667 | struct ieee80211_conf *conf = NULL; | 666 | struct ieee80211_conf *conf = NULL; |
668 | int ret = 0; | ||
669 | u32 rate_flags = 0; | 667 | u32 rate_flags = 0; |
670 | u16 cmd_len; | 668 | u16 cmd_len; |
671 | u16 rx_chain = 0; | 669 | u16 rx_chain = 0; |
@@ -698,7 +696,6 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
698 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { | 696 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
699 | IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. " | 697 | IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. " |
700 | "Ignoring second request.\n"); | 698 | "Ignoring second request.\n"); |
701 | ret = -EIO; | ||
702 | goto done; | 699 | goto done; |
703 | } | 700 | } |
704 | 701 | ||
@@ -731,7 +728,8 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
731 | priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) + | 728 | priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) + |
732 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); | 729 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); |
733 | if (!priv->scan) { | 730 | if (!priv->scan) { |
734 | ret = -ENOMEM; | 731 | IWL_DEBUG_SCAN(priv, |
732 | "fail to allocate memory for scan\n"); | ||
735 | goto done; | 733 | goto done; |
736 | } | 734 | } |
737 | } | 735 | } |
@@ -892,8 +890,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
892 | scan->len = cpu_to_le16(cmd.len); | 890 | scan->len = cpu_to_le16(cmd.len); |
893 | 891 | ||
894 | set_bit(STATUS_SCAN_HW, &priv->status); | 892 | set_bit(STATUS_SCAN_HW, &priv->status); |
895 | ret = iwl_send_cmd_sync(priv, &cmd); | 893 | if (iwl_send_cmd_sync(priv, &cmd)) |
896 | if (ret) | ||
897 | goto done; | 894 | goto done; |
898 | 895 | ||
899 | queue_delayed_work(priv->workqueue, &priv->scan_check, | 896 | queue_delayed_work(priv->workqueue, &priv->scan_check, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 4a6686fa6b36..b1aad306efa9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -549,9 +549,11 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) | |||
549 | struct iwl_host_cmd cmd = { | 549 | struct iwl_host_cmd cmd = { |
550 | .id = REPLY_WEPKEY, | 550 | .id = REPLY_WEPKEY, |
551 | .data = wep_cmd, | 551 | .data = wep_cmd, |
552 | .flags = CMD_ASYNC, | 552 | .flags = CMD_SYNC, |
553 | }; | 553 | }; |
554 | 554 | ||
555 | might_sleep(); | ||
556 | |||
555 | memset(wep_cmd, 0, cmd_size + | 557 | memset(wep_cmd, 0, cmd_size + |
556 | (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); | 558 | (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); |
557 | 559 | ||
@@ -587,9 +589,9 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
587 | struct ieee80211_key_conf *keyconf) | 589 | struct ieee80211_key_conf *keyconf) |
588 | { | 590 | { |
589 | int ret; | 591 | int ret; |
590 | unsigned long flags; | ||
591 | 592 | ||
592 | spin_lock_irqsave(&priv->sta_lock, flags); | 593 | WARN_ON(!mutex_is_locked(&priv->mutex)); |
594 | |||
593 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", | 595 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", |
594 | keyconf->keyidx); | 596 | keyconf->keyidx); |
595 | 597 | ||
@@ -601,13 +603,12 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
601 | memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); | 603 | memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); |
602 | if (iwl_is_rfkill(priv)) { | 604 | if (iwl_is_rfkill(priv)) { |
603 | IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); | 605 | IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); |
604 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 606 | /* but keys in device are clear anyway so return success */ |
605 | return 0; | 607 | return 0; |
606 | } | 608 | } |
607 | ret = iwl_send_static_wepkey_cmd(priv, 1); | 609 | ret = iwl_send_static_wepkey_cmd(priv, 1); |
608 | IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", | 610 | IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", |
609 | keyconf->keyidx, ret); | 611 | keyconf->keyidx, ret); |
610 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
611 | 612 | ||
612 | return ret; | 613 | return ret; |
613 | } | 614 | } |
@@ -617,7 +618,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
617 | struct ieee80211_key_conf *keyconf) | 618 | struct ieee80211_key_conf *keyconf) |
618 | { | 619 | { |
619 | int ret; | 620 | int ret; |
620 | unsigned long flags; | 621 | |
622 | WARN_ON(!mutex_is_locked(&priv->mutex)); | ||
621 | 623 | ||
622 | if (keyconf->keylen != WEP_KEY_LEN_128 && | 624 | if (keyconf->keylen != WEP_KEY_LEN_128 && |
623 | keyconf->keylen != WEP_KEY_LEN_64) { | 625 | keyconf->keylen != WEP_KEY_LEN_64) { |
@@ -629,12 +631,11 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
629 | keyconf->hw_key_idx = HW_KEY_DEFAULT; | 631 | keyconf->hw_key_idx = HW_KEY_DEFAULT; |
630 | priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; | 632 | priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; |
631 | 633 | ||
632 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
633 | priv->default_wep_key++; | 634 | priv->default_wep_key++; |
634 | 635 | ||
635 | if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) | 636 | if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) |
636 | IWL_ERR(priv, "index %d already used in uCode key table.\n", | 637 | IWL_ERR(priv, "index %d already used in uCode key table.\n", |
637 | keyconf->keyidx); | 638 | keyconf->keyidx); |
638 | 639 | ||
639 | priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; | 640 | priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; |
640 | memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, | 641 | memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, |
@@ -643,7 +644,6 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
643 | ret = iwl_send_static_wepkey_cmd(priv, 0); | 644 | ret = iwl_send_static_wepkey_cmd(priv, 0); |
644 | IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", | 645 | IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", |
645 | keyconf->keylen, keyconf->keyidx, ret); | 646 | keyconf->keylen, keyconf->keyidx, ret); |
646 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
647 | 647 | ||
648 | return ret; | 648 | return ret; |
649 | } | 649 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 8c12311dbb0a..d6222aabe6ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -37,26 +37,63 @@ | |||
37 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
38 | #include "iwl-helpers.h" | 38 | #include "iwl-helpers.h" |
39 | 39 | ||
40 | static const u16 default_tid_to_tx_fifo[] = { | 40 | /* |
41 | IWL_TX_FIFO_AC1, | 41 | * mac80211 queues, ACs, hardware queues, FIFOs. |
42 | IWL_TX_FIFO_AC0, | 42 | * |
43 | IWL_TX_FIFO_AC0, | 43 | * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues |
44 | IWL_TX_FIFO_AC1, | 44 | * |
45 | IWL_TX_FIFO_AC2, | 45 | * Mac80211 uses the following numbers, which we get as from it |
46 | IWL_TX_FIFO_AC2, | 46 | * by way of skb_get_queue_mapping(skb): |
47 | IWL_TX_FIFO_AC3, | 47 | * |
48 | IWL_TX_FIFO_AC3, | 48 | * VO 0 |
49 | IWL_TX_FIFO_NONE, | 49 | * VI 1 |
50 | IWL_TX_FIFO_NONE, | 50 | * BE 2 |
51 | IWL_TX_FIFO_NONE, | 51 | * BK 3 |
52 | IWL_TX_FIFO_NONE, | 52 | * |
53 | IWL_TX_FIFO_NONE, | 53 | * |
54 | IWL_TX_FIFO_NONE, | 54 | * Regular (not A-MPDU) frames are put into hardware queues corresponding |
55 | IWL_TX_FIFO_NONE, | 55 | * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their |
56 | IWL_TX_FIFO_NONE, | 56 | * own queue per aggregation session (RA/TID combination), such queues are |
57 | IWL_TX_FIFO_AC3 | 57 | * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In |
58 | * order to map frames to the right queue, we also need an AC->hw queue | ||
59 | * mapping. This is implemented here. | ||
60 | * | ||
61 | * Due to the way hw queues are set up (by the hw specific modules like | ||
62 | * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity | ||
63 | * mapping. | ||
64 | */ | ||
65 | |||
66 | static const u8 tid_to_ac[] = { | ||
67 | /* this matches the mac80211 numbers */ | ||
68 | 2, 3, 3, 2, 1, 1, 0, 0 | ||
69 | }; | ||
70 | |||
71 | static const u8 ac_to_fifo[] = { | ||
72 | IWL_TX_FIFO_VO, | ||
73 | IWL_TX_FIFO_VI, | ||
74 | IWL_TX_FIFO_BE, | ||
75 | IWL_TX_FIFO_BK, | ||
58 | }; | 76 | }; |
59 | 77 | ||
78 | static inline int get_fifo_from_ac(u8 ac) | ||
79 | { | ||
80 | return ac_to_fifo[ac]; | ||
81 | } | ||
82 | |||
83 | static inline int get_queue_from_ac(u16 ac) | ||
84 | { | ||
85 | return ac; | ||
86 | } | ||
87 | |||
88 | static inline int get_fifo_from_tid(u16 tid) | ||
89 | { | ||
90 | if (likely(tid < ARRAY_SIZE(tid_to_ac))) | ||
91 | return get_fifo_from_ac(tid_to_ac[tid]); | ||
92 | |||
93 | /* no support for TIDs 8-15 yet */ | ||
94 | return -EINVAL; | ||
95 | } | ||
96 | |||
60 | static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv, | 97 | static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv, |
61 | struct iwl_dma_ptr *ptr, size_t size) | 98 | struct iwl_dma_ptr *ptr, size_t size) |
62 | { | 99 | { |
@@ -591,13 +628,12 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
591 | tx_cmd->next_frame_len = 0; | 628 | tx_cmd->next_frame_len = 0; |
592 | } | 629 | } |
593 | 630 | ||
594 | #define RTS_HCCA_RETRY_LIMIT 3 | ||
595 | #define RTS_DFAULT_RETRY_LIMIT 60 | 631 | #define RTS_DFAULT_RETRY_LIMIT 60 |
596 | 632 | ||
597 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | 633 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, |
598 | struct iwl_tx_cmd *tx_cmd, | 634 | struct iwl_tx_cmd *tx_cmd, |
599 | struct ieee80211_tx_info *info, | 635 | struct ieee80211_tx_info *info, |
600 | __le16 fc, int is_hcca) | 636 | __le16 fc) |
601 | { | 637 | { |
602 | u32 rate_flags; | 638 | u32 rate_flags; |
603 | int rate_idx; | 639 | int rate_idx; |
@@ -613,8 +649,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | |||
613 | tx_cmd->data_retry_limit = data_retry_limit; | 649 | tx_cmd->data_retry_limit = data_retry_limit; |
614 | 650 | ||
615 | /* Set retry limit on RTS packets */ | 651 | /* Set retry limit on RTS packets */ |
616 | rts_retry_limit = (is_hcca) ? RTS_HCCA_RETRY_LIMIT : | 652 | rts_retry_limit = RTS_DFAULT_RETRY_LIMIT; |
617 | RTS_DFAULT_RETRY_LIMIT; | ||
618 | if (data_retry_limit < rts_retry_limit) | 653 | if (data_retry_limit < rts_retry_limit) |
619 | rts_retry_limit = data_retry_limit; | 654 | rts_retry_limit = data_retry_limit; |
620 | tx_cmd->rts_retry_limit = rts_retry_limit; | 655 | tx_cmd->rts_retry_limit = rts_retry_limit; |
@@ -761,16 +796,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
761 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); | 796 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); |
762 | #endif | 797 | #endif |
763 | 798 | ||
764 | /* drop all non-injected data frame if we are not associated */ | ||
765 | if (ieee80211_is_data(fc) && | ||
766 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | ||
767 | (!iwl_is_associated(priv) || | ||
768 | ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) || | ||
769 | !priv->assoc_station_added)) { | ||
770 | IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n"); | ||
771 | goto drop_unlock; | ||
772 | } | ||
773 | |||
774 | hdr_len = ieee80211_hdrlen(fc); | 799 | hdr_len = ieee80211_hdrlen(fc); |
775 | 800 | ||
776 | /* Find (or create) index into station table for destination station */ | 801 | /* Find (or create) index into station table for destination station */ |
@@ -804,7 +829,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
804 | iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); | 829 | iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); |
805 | } | 830 | } |
806 | 831 | ||
807 | txq_id = skb_get_queue_mapping(skb); | 832 | txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); |
808 | if (ieee80211_is_data_qos(fc)) { | 833 | if (ieee80211_is_data_qos(fc)) { |
809 | qc = ieee80211_get_qos_ctl(hdr); | 834 | qc = ieee80211_get_qos_ctl(hdr); |
810 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 835 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
@@ -869,8 +894,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
869 | iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); | 894 | iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); |
870 | iwl_dbg_log_tx_data_frame(priv, len, hdr); | 895 | iwl_dbg_log_tx_data_frame(priv, len, hdr); |
871 | 896 | ||
872 | /* set is_hcca to 0; it probably will never be implemented */ | 897 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc); |
873 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, 0); | ||
874 | 898 | ||
875 | iwl_update_stats(priv, true, fc, len); | 899 | iwl_update_stats(priv, true, fc, len); |
876 | /* | 900 | /* |
@@ -1270,7 +1294,7 @@ EXPORT_SYMBOL(iwl_tx_cmd_complete); | |||
1270 | * Find first available (lowest unused) Tx Queue, mark it "active". | 1294 | * Find first available (lowest unused) Tx Queue, mark it "active". |
1271 | * Called only when finding queue for aggregation. | 1295 | * Called only when finding queue for aggregation. |
1272 | * Should never return anything < 7, because they should already | 1296 | * Should never return anything < 7, because they should already |
1273 | * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6). | 1297 | * be in use as EDCA AC (0-3), Command (4), reserved (5, 6) |
1274 | */ | 1298 | */ |
1275 | static int iwl_txq_ctx_activate_free(struct iwl_priv *priv) | 1299 | static int iwl_txq_ctx_activate_free(struct iwl_priv *priv) |
1276 | { | 1300 | { |
@@ -1291,10 +1315,9 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) | |||
1291 | unsigned long flags; | 1315 | unsigned long flags; |
1292 | struct iwl_tid_data *tid_data; | 1316 | struct iwl_tid_data *tid_data; |
1293 | 1317 | ||
1294 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) | 1318 | tx_fifo = get_fifo_from_tid(tid); |
1295 | tx_fifo = default_tid_to_tx_fifo[tid]; | 1319 | if (unlikely(tx_fifo < 0)) |
1296 | else | 1320 | return tx_fifo; |
1297 | return -EINVAL; | ||
1298 | 1321 | ||
1299 | IWL_WARN(priv, "%s on ra = %pM tid = %d\n", | 1322 | IWL_WARN(priv, "%s on ra = %pM tid = %d\n", |
1300 | __func__, ra, tid); | 1323 | __func__, ra, tid); |
@@ -1355,13 +1378,9 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1355 | return -EINVAL; | 1378 | return -EINVAL; |
1356 | } | 1379 | } |
1357 | 1380 | ||
1358 | if (unlikely(tid >= MAX_TID_COUNT)) | 1381 | tx_fifo_id = get_fifo_from_tid(tid); |
1359 | return -EINVAL; | 1382 | if (unlikely(tx_fifo_id < 0)) |
1360 | 1383 | return tx_fifo_id; | |
1361 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) | ||
1362 | tx_fifo_id = default_tid_to_tx_fifo[tid]; | ||
1363 | else | ||
1364 | return -EINVAL; | ||
1365 | 1384 | ||
1366 | sta_id = iwl_find_station(priv, ra); | 1385 | sta_id = iwl_find_station(priv, ra); |
1367 | 1386 | ||
@@ -1429,7 +1448,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1429 | if ((txq_id == tid_data->agg.txq_id) && | 1448 | if ((txq_id == tid_data->agg.txq_id) && |
1430 | (q->read_ptr == q->write_ptr)) { | 1449 | (q->read_ptr == q->write_ptr)) { |
1431 | u16 ssn = SEQ_TO_SN(tid_data->seq_number); | 1450 | u16 ssn = SEQ_TO_SN(tid_data->seq_number); |
1432 | int tx_fifo = default_tid_to_tx_fifo[tid]; | 1451 | int tx_fifo = get_fifo_from_tid(tid); |
1433 | IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); | 1452 | IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); |
1434 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, | 1453 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, |
1435 | ssn, tx_fifo); | 1454 | ssn, tx_fifo); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 54daa38ecba3..2579bbcaab36 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -351,11 +351,11 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) | |||
351 | 351 | ||
352 | static void iwl3945_unset_hw_params(struct iwl_priv *priv) | 352 | static void iwl3945_unset_hw_params(struct iwl_priv *priv) |
353 | { | 353 | { |
354 | if (priv->shared_virt) | 354 | if (priv->_3945.shared_virt) |
355 | dma_free_coherent(&priv->pci_dev->dev, | 355 | dma_free_coherent(&priv->pci_dev->dev, |
356 | sizeof(struct iwl3945_shared), | 356 | sizeof(struct iwl3945_shared), |
357 | priv->shared_virt, | 357 | priv->_3945.shared_virt, |
358 | priv->shared_phys); | 358 | priv->_3945.shared_phys); |
359 | } | 359 | } |
360 | 360 | ||
361 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | 361 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, |
@@ -504,15 +504,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
504 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); | 504 | IWL_DEBUG_TX(priv, "Sending REASSOC frame\n"); |
505 | #endif | 505 | #endif |
506 | 506 | ||
507 | /* drop all non-injected data frame if we are not associated */ | ||
508 | if (ieee80211_is_data(fc) && | ||
509 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | ||
510 | (!iwl_is_associated(priv) || | ||
511 | ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) { | ||
512 | IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n"); | ||
513 | goto drop_unlock; | ||
514 | } | ||
515 | |||
516 | spin_unlock_irqrestore(&priv->lock, flags); | 507 | spin_unlock_irqrestore(&priv->lock, flags); |
517 | 508 | ||
518 | hdr_len = ieee80211_hdrlen(fc); | 509 | hdr_len = ieee80211_hdrlen(fc); |
@@ -753,7 +744,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
753 | if (iwl_is_associated(priv)) | 744 | if (iwl_is_associated(priv)) |
754 | add_time = | 745 | add_time = |
755 | iwl3945_usecs_to_beacons( | 746 | iwl3945_usecs_to_beacons( |
756 | le64_to_cpu(params->start_time) - priv->last_tsf, | 747 | le64_to_cpu(params->start_time) - priv->_3945.last_tsf, |
757 | le16_to_cpu(priv->rxon_timing.beacon_interval)); | 748 | le16_to_cpu(priv->rxon_timing.beacon_interval)); |
758 | 749 | ||
759 | memset(&spectrum, 0, sizeof(spectrum)); | 750 | memset(&spectrum, 0, sizeof(spectrum)); |
@@ -767,7 +758,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, | |||
767 | 758 | ||
768 | if (iwl_is_associated(priv)) | 759 | if (iwl_is_associated(priv)) |
769 | spectrum.start_time = | 760 | spectrum.start_time = |
770 | iwl3945_add_beacon_time(priv->last_beacon_time, | 761 | iwl3945_add_beacon_time(priv->_3945.last_beacon_time, |
771 | add_time, | 762 | add_time, |
772 | le16_to_cpu(priv->rxon_timing.beacon_interval)); | 763 | le16_to_cpu(priv->rxon_timing.beacon_interval)); |
773 | else | 764 | else |
@@ -2517,8 +2508,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2517 | 2508 | ||
2518 | ieee80211_wake_queues(priv->hw); | 2509 | ieee80211_wake_queues(priv->hw); |
2519 | 2510 | ||
2520 | priv->active_rate = priv->rates_mask; | 2511 | priv->active_rate = IWL_RATES_MASK; |
2521 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | ||
2522 | 2512 | ||
2523 | iwl_power_update_mode(priv, true); | 2513 | iwl_power_update_mode(priv, true); |
2524 | 2514 | ||
@@ -2547,17 +2537,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2547 | set_bit(STATUS_READY, &priv->status); | 2537 | set_bit(STATUS_READY, &priv->status); |
2548 | wake_up_interruptible(&priv->wait_command_queue); | 2538 | wake_up_interruptible(&priv->wait_command_queue); |
2549 | 2539 | ||
2550 | /* reassociate for ADHOC mode */ | ||
2551 | if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { | ||
2552 | struct sk_buff *beacon = ieee80211_beacon_get(priv->hw, | ||
2553 | priv->vif); | ||
2554 | if (beacon) | ||
2555 | iwl_mac_beacon_update(priv->hw, beacon); | ||
2556 | } | ||
2557 | |||
2558 | if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) | ||
2559 | iwl_set_mode(priv, priv->iw_mode); | ||
2560 | |||
2561 | return; | 2540 | return; |
2562 | 2541 | ||
2563 | restart: | 2542 | restart: |
@@ -2718,7 +2697,7 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
2718 | /* load bootstrap state machine, | 2697 | /* load bootstrap state machine, |
2719 | * load bootstrap program into processor's memory, | 2698 | * load bootstrap program into processor's memory, |
2720 | * prepare to load the "initialize" uCode */ | 2699 | * prepare to load the "initialize" uCode */ |
2721 | priv->cfg->ops->lib->load_ucode(priv); | 2700 | rc = priv->cfg->ops->lib->load_ucode(priv); |
2722 | 2701 | ||
2723 | if (rc) { | 2702 | if (rc) { |
2724 | IWL_ERR(priv, | 2703 | IWL_ERR(priv, |
@@ -2786,7 +2765,7 @@ static void iwl3945_bg_alive_start(struct work_struct *data) | |||
2786 | static void iwl3945_rfkill_poll(struct work_struct *data) | 2765 | static void iwl3945_rfkill_poll(struct work_struct *data) |
2787 | { | 2766 | { |
2788 | struct iwl_priv *priv = | 2767 | struct iwl_priv *priv = |
2789 | container_of(data, struct iwl_priv, rfkill_poll.work); | 2768 | container_of(data, struct iwl_priv, _3945.rfkill_poll.work); |
2790 | bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); | 2769 | bool old_rfkill = test_bit(STATUS_RF_KILL_HW, &priv->status); |
2791 | bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) | 2770 | bool new_rfkill = !(iwl_read32(priv, CSR_GP_CNTRL) |
2792 | & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); | 2771 | & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
@@ -2805,7 +2784,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data) | |||
2805 | 2784 | ||
2806 | /* Keep this running, even if radio now enabled. This will be | 2785 | /* Keep this running, even if radio now enabled. This will be |
2807 | * cancelled in mac_start() if system decides to start again */ | 2786 | * cancelled in mac_start() if system decides to start again */ |
2808 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 2787 | queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, |
2809 | round_jiffies_relative(2 * HZ)); | 2788 | round_jiffies_relative(2 * HZ)); |
2810 | 2789 | ||
2811 | } | 2790 | } |
@@ -2820,7 +2799,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
2820 | .len = sizeof(struct iwl3945_scan_cmd), | 2799 | .len = sizeof(struct iwl3945_scan_cmd), |
2821 | .flags = CMD_SIZE_HUGE, | 2800 | .flags = CMD_SIZE_HUGE, |
2822 | }; | 2801 | }; |
2823 | int rc = 0; | ||
2824 | struct iwl3945_scan_cmd *scan; | 2802 | struct iwl3945_scan_cmd *scan; |
2825 | struct ieee80211_conf *conf = NULL; | 2803 | struct ieee80211_conf *conf = NULL; |
2826 | u8 n_probes = 0; | 2804 | u8 n_probes = 0; |
@@ -2848,7 +2826,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
2848 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { | 2826 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { |
2849 | IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests " | 2827 | IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests " |
2850 | "Ignoring second request.\n"); | 2828 | "Ignoring second request.\n"); |
2851 | rc = -EIO; | ||
2852 | goto done; | 2829 | goto done; |
2853 | } | 2830 | } |
2854 | 2831 | ||
@@ -2883,7 +2860,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
2883 | priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) + | 2860 | priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) + |
2884 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); | 2861 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); |
2885 | if (!priv->scan) { | 2862 | if (!priv->scan) { |
2886 | rc = -ENOMEM; | 2863 | IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n"); |
2887 | goto done; | 2864 | goto done; |
2888 | } | 2865 | } |
2889 | } | 2866 | } |
@@ -2926,7 +2903,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
2926 | scan_suspend_time, interval); | 2903 | scan_suspend_time, interval); |
2927 | } | 2904 | } |
2928 | 2905 | ||
2929 | if (priv->scan_request->n_ssids) { | 2906 | if (priv->is_internal_short_scan) { |
2907 | IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); | ||
2908 | } else if (priv->scan_request->n_ssids) { | ||
2930 | int i, p = 0; | 2909 | int i, p = 0; |
2931 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); | 2910 | IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); |
2932 | for (i = 0; i < priv->scan_request->n_ssids; i++) { | 2911 | for (i = 0; i < priv->scan_request->n_ssids; i++) { |
@@ -2973,13 +2952,20 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
2973 | goto done; | 2952 | goto done; |
2974 | } | 2953 | } |
2975 | 2954 | ||
2976 | scan->tx_cmd.len = cpu_to_le16( | 2955 | if (!priv->is_internal_short_scan) { |
2956 | scan->tx_cmd.len = cpu_to_le16( | ||
2977 | iwl_fill_probe_req(priv, | 2957 | iwl_fill_probe_req(priv, |
2978 | (struct ieee80211_mgmt *)scan->data, | 2958 | (struct ieee80211_mgmt *)scan->data, |
2979 | priv->scan_request->ie, | 2959 | priv->scan_request->ie, |
2980 | priv->scan_request->ie_len, | 2960 | priv->scan_request->ie_len, |
2981 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | 2961 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); |
2982 | 2962 | } else { | |
2963 | scan->tx_cmd.len = cpu_to_le16( | ||
2964 | iwl_fill_probe_req(priv, | ||
2965 | (struct ieee80211_mgmt *)scan->data, | ||
2966 | NULL, 0, | ||
2967 | IWL_MAX_SCAN_SIZE - sizeof(*scan))); | ||
2968 | } | ||
2983 | /* select Rx antennas */ | 2969 | /* select Rx antennas */ |
2984 | scan->flags |= iwl3945_get_antenna_flags(priv); | 2970 | scan->flags |= iwl3945_get_antenna_flags(priv); |
2985 | 2971 | ||
@@ -3001,8 +2987,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
3001 | scan->len = cpu_to_le16(cmd.len); | 2987 | scan->len = cpu_to_le16(cmd.len); |
3002 | 2988 | ||
3003 | set_bit(STATUS_SCAN_HW, &priv->status); | 2989 | set_bit(STATUS_SCAN_HW, &priv->status); |
3004 | rc = iwl_send_cmd_sync(priv, &cmd); | 2990 | if (iwl_send_cmd_sync(priv, &cmd)) |
3005 | if (rc) | ||
3006 | goto done; | 2991 | goto done; |
3007 | 2992 | ||
3008 | queue_delayed_work(priv->workqueue, &priv->scan_check, | 2993 | queue_delayed_work(priv->workqueue, &priv->scan_check, |
@@ -3212,7 +3197,7 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3212 | 3197 | ||
3213 | /* ucode is running and will send rfkill notifications, | 3198 | /* ucode is running and will send rfkill notifications, |
3214 | * no need to poll the killswitch state anymore */ | 3199 | * no need to poll the killswitch state anymore */ |
3215 | cancel_delayed_work(&priv->rfkill_poll); | 3200 | cancel_delayed_work(&priv->_3945.rfkill_poll); |
3216 | 3201 | ||
3217 | iwl_led_start(priv); | 3202 | iwl_led_start(priv); |
3218 | 3203 | ||
@@ -3253,7 +3238,7 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) | |||
3253 | flush_workqueue(priv->workqueue); | 3238 | flush_workqueue(priv->workqueue); |
3254 | 3239 | ||
3255 | /* start polling the killswitch state again */ | 3240 | /* start polling the killswitch state again */ |
3256 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 3241 | queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, |
3257 | round_jiffies_relative(2 * HZ)); | 3242 | round_jiffies_relative(2 * HZ)); |
3258 | 3243 | ||
3259 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3244 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
@@ -3365,7 +3350,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3365 | 3350 | ||
3366 | mutex_lock(&priv->mutex); | 3351 | mutex_lock(&priv->mutex); |
3367 | iwl_scan_cancel_timeout(priv, 100); | 3352 | iwl_scan_cancel_timeout(priv, 100); |
3368 | mutex_unlock(&priv->mutex); | ||
3369 | 3353 | ||
3370 | switch (cmd) { | 3354 | switch (cmd) { |
3371 | case SET_KEY: | 3355 | case SET_KEY: |
@@ -3386,6 +3370,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3386 | ret = -EINVAL; | 3370 | ret = -EINVAL; |
3387 | } | 3371 | } |
3388 | 3372 | ||
3373 | mutex_unlock(&priv->mutex); | ||
3389 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3374 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3390 | 3375 | ||
3391 | return ret; | 3376 | return ret; |
@@ -3590,7 +3575,7 @@ static ssize_t store_measurement(struct device *d, | |||
3590 | struct iwl_priv *priv = dev_get_drvdata(d); | 3575 | struct iwl_priv *priv = dev_get_drvdata(d); |
3591 | struct ieee80211_measurement_params params = { | 3576 | struct ieee80211_measurement_params params = { |
3592 | .channel = le16_to_cpu(priv->active_rxon.channel), | 3577 | .channel = le16_to_cpu(priv->active_rxon.channel), |
3593 | .start_time = cpu_to_le64(priv->last_tsf), | 3578 | .start_time = cpu_to_le64(priv->_3945.last_tsf), |
3594 | .duration = cpu_to_le16(1), | 3579 | .duration = cpu_to_le16(1), |
3595 | }; | 3580 | }; |
3596 | u8 type = IWL_MEASURE_BASIC; | 3581 | u8 type = IWL_MEASURE_BASIC; |
@@ -3660,7 +3645,7 @@ static ssize_t show_statistics(struct device *d, | |||
3660 | struct iwl_priv *priv = dev_get_drvdata(d); | 3645 | struct iwl_priv *priv = dev_get_drvdata(d); |
3661 | u32 size = sizeof(struct iwl3945_notif_statistics); | 3646 | u32 size = sizeof(struct iwl3945_notif_statistics); |
3662 | u32 len = 0, ofs = 0; | 3647 | u32 len = 0, ofs = 0; |
3663 | u8 *data = (u8 *)&priv->statistics_39; | 3648 | u8 *data = (u8 *)&priv->_3945.statistics; |
3664 | int rc = 0; | 3649 | int rc = 0; |
3665 | 3650 | ||
3666 | if (!iwl_is_alive(priv)) | 3651 | if (!iwl_is_alive(priv)) |
@@ -3773,7 +3758,7 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) | |||
3773 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 3758 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
3774 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 3759 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
3775 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 3760 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
3776 | INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll); | 3761 | INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); |
3777 | INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); | 3762 | INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); |
3778 | INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan); | 3763 | INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan); |
3779 | INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); | 3764 | INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); |
@@ -3864,7 +3849,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3864 | priv->qos_data.qos_active = 0; | 3849 | priv->qos_data.qos_active = 0; |
3865 | priv->qos_data.qos_cap.val = 0; | 3850 | priv->qos_data.qos_cap.val = 0; |
3866 | 3851 | ||
3867 | priv->rates_mask = IWL_RATES_MASK; | ||
3868 | priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; | 3852 | priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; |
3869 | 3853 | ||
3870 | if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { | 3854 | if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { |
@@ -4129,7 +4113,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4129 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | 4113 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
4130 | 4114 | ||
4131 | /* Start monitoring the killswitch */ | 4115 | /* Start monitoring the killswitch */ |
4132 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 4116 | queue_delayed_work(priv->workqueue, &priv->_3945.rfkill_poll, |
4133 | 2 * HZ); | 4117 | 2 * HZ); |
4134 | 4118 | ||
4135 | return 0; | 4119 | return 0; |
@@ -4203,7 +4187,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4203 | 4187 | ||
4204 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 4188 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
4205 | 4189 | ||
4206 | cancel_delayed_work_sync(&priv->rfkill_poll); | 4190 | cancel_delayed_work_sync(&priv->_3945.rfkill_poll); |
4207 | 4191 | ||
4208 | iwl3945_dealloc_ucode_pci(priv); | 4192 | iwl3945_dealloc_ucode_pci(priv); |
4209 | 4193 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig index b9d34a766964..03f998d098c5 100644 --- a/drivers/net/wireless/iwmc3200wifi/Kconfig +++ b/drivers/net/wireless/iwmc3200wifi/Kconfig | |||
@@ -17,7 +17,7 @@ config IWM | |||
17 | config IWM_DEBUG | 17 | config IWM_DEBUG |
18 | bool "Enable full debugging output in iwmc3200wifi" | 18 | bool "Enable full debugging output in iwmc3200wifi" |
19 | depends on IWM && DEBUG_FS | 19 | depends on IWM && DEBUG_FS |
20 | ---help--- | 20 | help |
21 | This option will enable debug tracing and setting for iwm | 21 | This option will enable debug tracing and setting for iwm |
22 | 22 | ||
23 | You can set the debug level and module through debugfs. By | 23 | You can set the debug level and module through debugfs. By |
@@ -30,3 +30,10 @@ config IWM_DEBUG | |||
30 | Or, if you want the full debug, for all modules: | 30 | Or, if you want the full debug, for all modules: |
31 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level | 31 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level |
32 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules | 32 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules |
33 | |||
34 | config IWM_TRACING | ||
35 | bool "Enable event tracing for iwmc3200wifi" | ||
36 | depends on IWM && EVENT_TRACING | ||
37 | help | ||
38 | Say Y here to trace all the commands and responses between | ||
39 | the driver and firmware (including TX/RX frames) with ftrace. | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile index d34291b652d3..aeed5cd80819 100644 --- a/drivers/net/wireless/iwmc3200wifi/Makefile +++ b/drivers/net/wireless/iwmc3200wifi/Makefile | |||
@@ -3,3 +3,6 @@ iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o | |||
3 | iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o | 3 | iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o |
4 | 4 | ||
5 | iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o | 5 | iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o |
6 | iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o | ||
7 | |||
8 | CFLAGS_trace.o := -I$(src) | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 7c4f44a9c3e6..fc239a32cb6b 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c | |||
@@ -263,7 +263,7 @@ static int iwm_cfg80211_get_station(struct wiphy *wiphy, | |||
263 | int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) | 263 | int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) |
264 | { | 264 | { |
265 | struct wiphy *wiphy = iwm_to_wiphy(iwm); | 265 | struct wiphy *wiphy = iwm_to_wiphy(iwm); |
266 | struct iwm_bss_info *bss, *next; | 266 | struct iwm_bss_info *bss; |
267 | struct iwm_umac_notif_bss_info *umac_bss; | 267 | struct iwm_umac_notif_bss_info *umac_bss; |
268 | struct ieee80211_mgmt *mgmt; | 268 | struct ieee80211_mgmt *mgmt; |
269 | struct ieee80211_channel *channel; | 269 | struct ieee80211_channel *channel; |
@@ -271,7 +271,7 @@ int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) | |||
271 | s32 signal; | 271 | s32 signal; |
272 | int freq; | 272 | int freq; |
273 | 273 | ||
274 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) { | 274 | list_for_each_entry(bss, &iwm->bss_list, node) { |
275 | umac_bss = bss->bss; | 275 | umac_bss = bss->bss; |
276 | mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf); | 276 | mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf); |
277 | 277 | ||
@@ -725,23 +725,26 @@ static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
725 | CFG_POWER_INDEX, iwm->conf.power_index); | 725 | CFG_POWER_INDEX, iwm->conf.power_index); |
726 | } | 726 | } |
727 | 727 | ||
728 | int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, | 728 | static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, |
729 | struct cfg80211_pmksa *pmksa) | 729 | struct net_device *netdev, |
730 | struct cfg80211_pmksa *pmksa) | ||
730 | { | 731 | { |
731 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 732 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
732 | 733 | ||
733 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); | 734 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); |
734 | } | 735 | } |
735 | 736 | ||
736 | int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, | 737 | static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, |
737 | struct cfg80211_pmksa *pmksa) | 738 | struct net_device *netdev, |
739 | struct cfg80211_pmksa *pmksa) | ||
738 | { | 740 | { |
739 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 741 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
740 | 742 | ||
741 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); | 743 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); |
742 | } | 744 | } |
743 | 745 | ||
744 | int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) | 746 | static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, |
747 | struct net_device *netdev) | ||
745 | { | 748 | { |
746 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 749 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
747 | struct cfg80211_pmksa pmksa; | 750 | struct cfg80211_pmksa pmksa; |
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 1e41ad0fcad5..b5cbd2bfd52a 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c | |||
@@ -506,7 +506,7 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address, | |||
506 | return ret; | 506 | return ret; |
507 | } | 507 | } |
508 | 508 | ||
509 | /* When succeding, the send_target routine returns the seq number */ | 509 | /* When succeeding, the send_target routine returns the seq number */ |
510 | seq_num = ret; | 510 | seq_num = ret; |
511 | 511 | ||
512 | ret = wait_event_interruptible_timeout(iwm->nonwifi_queue, | 512 | ret = wait_event_interruptible_timeout(iwm->nonwifi_queue, |
@@ -781,10 +781,9 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm) | |||
781 | return 0; | 781 | return 0; |
782 | } | 782 | } |
783 | 783 | ||
784 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | 784 | int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm) |
785 | { | 785 | { |
786 | struct iwm_umac_invalidate_profile invalid; | 786 | struct iwm_umac_invalidate_profile invalid; |
787 | int ret; | ||
788 | 787 | ||
789 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; | 788 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; |
790 | invalid.hdr.buf_size = | 789 | invalid.hdr.buf_size = |
@@ -793,7 +792,14 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | |||
793 | 792 | ||
794 | invalid.reason = WLAN_REASON_UNSPECIFIED; | 793 | invalid.reason = WLAN_REASON_UNSPECIFIED; |
795 | 794 | ||
796 | ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); | 795 | return iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); |
796 | } | ||
797 | |||
798 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | ||
799 | { | ||
800 | int ret; | ||
801 | |||
802 | ret = __iwm_invalidate_mlme_profile(iwm); | ||
797 | if (ret) | 803 | if (ret) |
798 | return ret; | 804 | return ret; |
799 | 805 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h index 3dfd9f0e9003..7e16bcf59978 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.h +++ b/drivers/net/wireless/iwmc3200wifi/commands.h | |||
@@ -488,6 +488,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key, | |||
488 | void *payload, u16 payload_size); | 488 | void *payload, u16 payload_size); |
489 | int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); | 489 | int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); |
490 | int iwm_send_mlme_profile(struct iwm_priv *iwm); | 490 | int iwm_send_mlme_profile(struct iwm_priv *iwm); |
491 | int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm); | ||
491 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); | 492 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); |
492 | int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); | 493 | int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); |
493 | int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); | 494 | int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); |
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c index c29c994de0e2..5b75a0ddac1c 100644 --- a/drivers/net/wireless/iwmc3200wifi/debugfs.c +++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c | |||
@@ -265,7 +265,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
265 | size_t count, loff_t *ppos) | 265 | size_t count, loff_t *ppos) |
266 | { | 266 | { |
267 | struct iwm_priv *iwm = filp->private_data; | 267 | struct iwm_priv *iwm = filp->private_data; |
268 | struct iwm_rx_ticket_node *ticket, *next; | 268 | struct iwm_rx_ticket_node *ticket; |
269 | char *buf; | 269 | char *buf; |
270 | int buf_len = 4096, i; | 270 | int buf_len = 4096, i; |
271 | size_t len = 0; | 271 | size_t len = 0; |
@@ -280,7 +280,8 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
280 | if (!buf) | 280 | if (!buf) |
281 | return -ENOMEM; | 281 | return -ENOMEM; |
282 | 282 | ||
283 | list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { | 283 | spin_lock(&iwm->ticket_lock); |
284 | list_for_each_entry(ticket, &iwm->rx_tickets, node) { | ||
284 | len += snprintf(buf + len, buf_len - len, "Ticket #%d\n", | 285 | len += snprintf(buf + len, buf_len - len, "Ticket #%d\n", |
285 | ticket->ticket->id); | 286 | ticket->ticket->id); |
286 | len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n", | 287 | len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n", |
@@ -288,14 +289,17 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
288 | len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n", | 289 | len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n", |
289 | ticket->ticket->flags); | 290 | ticket->ticket->flags); |
290 | } | 291 | } |
292 | spin_unlock(&iwm->ticket_lock); | ||
291 | 293 | ||
292 | for (i = 0; i < IWM_RX_ID_HASH; i++) { | 294 | for (i = 0; i < IWM_RX_ID_HASH; i++) { |
293 | struct iwm_rx_packet *packet, *nxt; | 295 | struct iwm_rx_packet *packet; |
294 | struct list_head *pkt_list = &iwm->rx_packets[i]; | 296 | struct list_head *pkt_list = &iwm->rx_packets[i]; |
297 | |||
295 | if (!list_empty(pkt_list)) { | 298 | if (!list_empty(pkt_list)) { |
296 | len += snprintf(buf + len, buf_len - len, | 299 | len += snprintf(buf + len, buf_len - len, |
297 | "Packet hash #%d\n", i); | 300 | "Packet hash #%d\n", i); |
298 | list_for_each_entry_safe(packet, nxt, pkt_list, node) { | 301 | spin_lock(&iwm->packet_lock[i]); |
302 | list_for_each_entry(packet, pkt_list, node) { | ||
299 | len += snprintf(buf + len, buf_len - len, | 303 | len += snprintf(buf + len, buf_len - len, |
300 | "\tPacket id: %d\n", | 304 | "\tPacket id: %d\n", |
301 | packet->id); | 305 | packet->id); |
@@ -303,6 +307,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
303 | "\tPacket length: %lu\n", | 307 | "\tPacket length: %lu\n", |
304 | packet->pkt_size); | 308 | packet->pkt_size); |
305 | } | 309 | } |
310 | spin_unlock(&iwm->packet_lock[i]); | ||
306 | } | 311 | } |
307 | } | 312 | } |
308 | 313 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c index d13c8853ee82..373b5b5001d2 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.c +++ b/drivers/net/wireless/iwmc3200wifi/hal.c | |||
@@ -104,6 +104,7 @@ | |||
104 | #include "hal.h" | 104 | #include "hal.h" |
105 | #include "umac.h" | 105 | #include "umac.h" |
106 | #include "debug.h" | 106 | #include "debug.h" |
107 | #include "trace.h" | ||
107 | 108 | ||
108 | static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm, | 109 | static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm, |
109 | struct iwm_nonwifi_cmd *cmd, | 110 | struct iwm_nonwifi_cmd *cmd, |
@@ -206,9 +207,9 @@ void iwm_cmd_flush(struct iwm_priv *iwm) | |||
206 | 207 | ||
207 | struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) | 208 | struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) |
208 | { | 209 | { |
209 | struct iwm_wifi_cmd *cmd, *next; | 210 | struct iwm_wifi_cmd *cmd; |
210 | 211 | ||
211 | list_for_each_entry_safe(cmd, next, &iwm->wifi_pending_cmd, pending) | 212 | list_for_each_entry(cmd, &iwm->wifi_pending_cmd, pending) |
212 | if (cmd->seq_num == seq_num) { | 213 | if (cmd->seq_num == seq_num) { |
213 | list_del(&cmd->pending); | 214 | list_del(&cmd->pending); |
214 | return cmd; | 215 | return cmd; |
@@ -217,12 +218,12 @@ struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) | |||
217 | return NULL; | 218 | return NULL; |
218 | } | 219 | } |
219 | 220 | ||
220 | struct iwm_nonwifi_cmd * | 221 | struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, |
221 | iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, u8 seq_num, u8 cmd_opcode) | 222 | u8 seq_num, u8 cmd_opcode) |
222 | { | 223 | { |
223 | struct iwm_nonwifi_cmd *cmd, *next; | 224 | struct iwm_nonwifi_cmd *cmd; |
224 | 225 | ||
225 | list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) | 226 | list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending) |
226 | if ((cmd->seq_num == seq_num) && | 227 | if ((cmd->seq_num == seq_num) && |
227 | (cmd->udma_cmd.opcode == cmd_opcode) && | 228 | (cmd->udma_cmd.opcode == cmd_opcode) && |
228 | (cmd->resp_received)) { | 229 | (cmd->resp_received)) { |
@@ -276,6 +277,7 @@ static int iwm_send_udma_nonwifi_cmd(struct iwm_priv *iwm, | |||
276 | udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr, | 277 | udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr, |
277 | udma_cmd->op1_sz, udma_cmd->op2); | 278 | udma_cmd->op1_sz, udma_cmd->op2); |
278 | 279 | ||
280 | trace_iwm_tx_nonwifi_cmd(iwm, udma_hdr); | ||
279 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); | 281 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); |
280 | } | 282 | } |
281 | 283 | ||
@@ -362,6 +364,7 @@ static int iwm_send_udma_wifi_cmd(struct iwm_priv *iwm, | |||
362 | return ret; | 364 | return ret; |
363 | } | 365 | } |
364 | 366 | ||
367 | trace_iwm_tx_wifi_cmd(iwm, umac_hdr); | ||
365 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); | 368 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); |
366 | } | 369 | } |
367 | 370 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.h b/drivers/net/wireless/iwmc3200wifi/hal.h index 0adfdc85765d..c20936d9b6b7 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.h +++ b/drivers/net/wireless/iwmc3200wifi/hal.h | |||
@@ -75,7 +75,8 @@ do { \ | |||
75 | 75 | ||
76 | 76 | ||
77 | /* UDMA IN OP CODE -- cmd bits [3:0] */ | 77 | /* UDMA IN OP CODE -- cmd bits [3:0] */ |
78 | #define UDMA_IN_OPCODE_MASK 0xF | 78 | #define UDMA_HDI_IN_NW_CMD_OPCODE_POS 0 |
79 | #define UDMA_HDI_IN_NW_CMD_OPCODE_SEED 0xF | ||
79 | 80 | ||
80 | #define UDMA_IN_OPCODE_GENERAL_RESP 0x0 | 81 | #define UDMA_IN_OPCODE_GENERAL_RESP 0x0 |
81 | #define UDMA_IN_OPCODE_READ_RESP 0x1 | 82 | #define UDMA_IN_OPCODE_READ_RESP 0x1 |
@@ -130,7 +131,7 @@ do { \ | |||
130 | #define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ | 131 | #define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ |
131 | IWM_MAX_WIFI_HEADERS_SIZE) | 132 | IWM_MAX_WIFI_HEADERS_SIZE) |
132 | 133 | ||
133 | #define IWM_HAL_CONCATENATE_BUF_SIZE 8192 | 134 | #define IWM_HAL_CONCATENATE_BUF_SIZE (32 * 1024) |
134 | 135 | ||
135 | struct iwm_wifi_cmd_buff { | 136 | struct iwm_wifi_cmd_buff { |
136 | u16 len; | 137 | u16 len; |
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 79ffa3b98d73..13266c3842f8 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h | |||
@@ -48,6 +48,7 @@ | |||
48 | #include "umac.h" | 48 | #include "umac.h" |
49 | #include "lmac.h" | 49 | #include "lmac.h" |
50 | #include "eeprom.h" | 50 | #include "eeprom.h" |
51 | #include "trace.h" | ||
51 | 52 | ||
52 | #define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" | 53 | #define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" |
53 | #define IWM_AUTHOR "<ilw@linux.intel.com>" | 54 | #define IWM_AUTHOR "<ilw@linux.intel.com>" |
@@ -268,7 +269,9 @@ struct iwm_priv { | |||
268 | 269 | ||
269 | struct sk_buff_head rx_list; | 270 | struct sk_buff_head rx_list; |
270 | struct list_head rx_tickets; | 271 | struct list_head rx_tickets; |
272 | spinlock_t ticket_lock; | ||
271 | struct list_head rx_packets[IWM_RX_ID_HASH]; | 273 | struct list_head rx_packets[IWM_RX_ID_HASH]; |
274 | spinlock_t packet_lock[IWM_RX_ID_HASH]; | ||
272 | struct workqueue_struct *rx_wq; | 275 | struct workqueue_struct *rx_wq; |
273 | struct work_struct rx_worker; | 276 | struct work_struct rx_worker; |
274 | 277 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c index 7f34d6dd3c41..3a3510a6223a 100644 --- a/drivers/net/wireless/iwmc3200wifi/main.c +++ b/drivers/net/wireless/iwmc3200wifi/main.c | |||
@@ -276,8 +276,11 @@ int iwm_priv_init(struct iwm_priv *iwm) | |||
276 | 276 | ||
277 | skb_queue_head_init(&iwm->rx_list); | 277 | skb_queue_head_init(&iwm->rx_list); |
278 | INIT_LIST_HEAD(&iwm->rx_tickets); | 278 | INIT_LIST_HEAD(&iwm->rx_tickets); |
279 | for (i = 0; i < IWM_RX_ID_HASH; i++) | 279 | spin_lock_init(&iwm->ticket_lock); |
280 | for (i = 0; i < IWM_RX_ID_HASH; i++) { | ||
280 | INIT_LIST_HEAD(&iwm->rx_packets[i]); | 281 | INIT_LIST_HEAD(&iwm->rx_packets[i]); |
282 | spin_lock_init(&iwm->packet_lock[i]); | ||
283 | } | ||
281 | 284 | ||
282 | INIT_WORK(&iwm->rx_worker, iwm_rx_worker); | 285 | INIT_WORK(&iwm->rx_worker, iwm_rx_worker); |
283 | 286 | ||
@@ -423,9 +426,9 @@ int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd, | |||
423 | static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd, | 426 | static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd, |
424 | u8 source) | 427 | u8 source) |
425 | { | 428 | { |
426 | struct iwm_notif *notif, *next; | 429 | struct iwm_notif *notif; |
427 | 430 | ||
428 | list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) { | 431 | list_for_each_entry(notif, &iwm->pending_notif, pending) { |
429 | if ((notif->cmd_id == cmd) && (notif->src == source)) { | 432 | if ((notif->cmd_id == cmd) && (notif->src == source)) { |
430 | list_del(¬if->pending); | 433 | list_del(¬if->pending); |
431 | return notif; | 434 | return notif; |
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 8456b4dbd146..ce36baf34039 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c | |||
@@ -342,15 +342,17 @@ static void iwm_rx_ticket_node_free(struct iwm_rx_ticket_node *ticket_node) | |||
342 | static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id) | 342 | static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id) |
343 | { | 343 | { |
344 | u8 id_hash = IWM_RX_ID_GET_HASH(id); | 344 | u8 id_hash = IWM_RX_ID_GET_HASH(id); |
345 | struct list_head *packet_list; | 345 | struct iwm_rx_packet *packet; |
346 | struct iwm_rx_packet *packet, *next; | ||
347 | |||
348 | packet_list = &iwm->rx_packets[id_hash]; | ||
349 | 346 | ||
350 | list_for_each_entry_safe(packet, next, packet_list, node) | 347 | spin_lock(&iwm->packet_lock[id_hash]); |
351 | if (packet->id == id) | 348 | list_for_each_entry(packet, &iwm->rx_packets[id_hash], node) |
349 | if (packet->id == id) { | ||
350 | list_del(&packet->node); | ||
351 | spin_unlock(&iwm->packet_lock[id_hash]); | ||
352 | return packet; | 352 | return packet; |
353 | } | ||
353 | 354 | ||
355 | spin_unlock(&iwm->packet_lock[id_hash]); | ||
354 | return NULL; | 356 | return NULL; |
355 | } | 357 | } |
356 | 358 | ||
@@ -388,18 +390,22 @@ void iwm_rx_free(struct iwm_priv *iwm) | |||
388 | struct iwm_rx_packet *packet, *np; | 390 | struct iwm_rx_packet *packet, *np; |
389 | int i; | 391 | int i; |
390 | 392 | ||
393 | spin_lock(&iwm->ticket_lock); | ||
391 | list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) { | 394 | list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) { |
392 | list_del(&ticket->node); | 395 | list_del(&ticket->node); |
393 | iwm_rx_ticket_node_free(ticket); | 396 | iwm_rx_ticket_node_free(ticket); |
394 | } | 397 | } |
398 | spin_unlock(&iwm->ticket_lock); | ||
395 | 399 | ||
396 | for (i = 0; i < IWM_RX_ID_HASH; i++) { | 400 | for (i = 0; i < IWM_RX_ID_HASH; i++) { |
401 | spin_lock(&iwm->packet_lock[i]); | ||
397 | list_for_each_entry_safe(packet, np, &iwm->rx_packets[i], | 402 | list_for_each_entry_safe(packet, np, &iwm->rx_packets[i], |
398 | node) { | 403 | node) { |
399 | list_del(&packet->node); | 404 | list_del(&packet->node); |
400 | kfree_skb(packet->skb); | 405 | kfree_skb(packet->skb); |
401 | kfree(packet); | 406 | kfree(packet); |
402 | } | 407 | } |
408 | spin_unlock(&iwm->packet_lock[i]); | ||
403 | } | 409 | } |
404 | } | 410 | } |
405 | 411 | ||
@@ -427,7 +433,9 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf, | |||
427 | ticket->action == IWM_RX_TICKET_RELEASE ? | 433 | ticket->action == IWM_RX_TICKET_RELEASE ? |
428 | "RELEASE" : "DROP", | 434 | "RELEASE" : "DROP", |
429 | ticket->id); | 435 | ticket->id); |
436 | spin_lock(&iwm->ticket_lock); | ||
430 | list_add_tail(&ticket_node->node, &iwm->rx_tickets); | 437 | list_add_tail(&ticket_node->node, &iwm->rx_tickets); |
438 | spin_unlock(&iwm->ticket_lock); | ||
431 | 439 | ||
432 | /* | 440 | /* |
433 | * We received an Rx ticket, most likely there's | 441 | * We received an Rx ticket, most likely there's |
@@ -460,6 +468,7 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf, | |||
460 | struct iwm_rx_packet *packet; | 468 | struct iwm_rx_packet *packet; |
461 | u16 id, buf_offset; | 469 | u16 id, buf_offset; |
462 | u32 packet_size; | 470 | u32 packet_size; |
471 | u8 id_hash; | ||
463 | 472 | ||
464 | IWM_DBG_RX(iwm, DBG, "\n"); | 473 | IWM_DBG_RX(iwm, DBG, "\n"); |
465 | 474 | ||
@@ -477,7 +486,10 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf, | |||
477 | if (IS_ERR(packet)) | 486 | if (IS_ERR(packet)) |
478 | return PTR_ERR(packet); | 487 | return PTR_ERR(packet); |
479 | 488 | ||
480 | list_add_tail(&packet->node, &iwm->rx_packets[IWM_RX_ID_GET_HASH(id)]); | 489 | id_hash = IWM_RX_ID_GET_HASH(id); |
490 | spin_lock(&iwm->packet_lock[id_hash]); | ||
491 | list_add_tail(&packet->node, &iwm->rx_packets[id_hash]); | ||
492 | spin_unlock(&iwm->packet_lock[id_hash]); | ||
481 | 493 | ||
482 | /* We might (unlikely) have received the packet _after_ the ticket */ | 494 | /* We might (unlikely) have received the packet _after_ the ticket */ |
483 | queue_work(iwm->rx_wq, &iwm->rx_worker); | 495 | queue_work(iwm->rx_wq, &iwm->rx_worker); |
@@ -518,6 +530,8 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
518 | unsigned long buf_size, | 530 | unsigned long buf_size, |
519 | struct iwm_wifi_cmd *cmd) | 531 | struct iwm_wifi_cmd *cmd) |
520 | { | 532 | { |
533 | struct wiphy *wiphy = iwm_to_wiphy(iwm); | ||
534 | struct ieee80211_channel *chan; | ||
521 | struct iwm_umac_notif_assoc_complete *complete = | 535 | struct iwm_umac_notif_assoc_complete *complete = |
522 | (struct iwm_umac_notif_assoc_complete *)buf; | 536 | (struct iwm_umac_notif_assoc_complete *)buf; |
523 | 537 | ||
@@ -526,6 +540,18 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
526 | 540 | ||
527 | switch (le32_to_cpu(complete->status)) { | 541 | switch (le32_to_cpu(complete->status)) { |
528 | case UMAC_ASSOC_COMPLETE_SUCCESS: | 542 | case UMAC_ASSOC_COMPLETE_SUCCESS: |
543 | chan = ieee80211_get_channel(wiphy, | ||
544 | ieee80211_channel_to_frequency(complete->channel)); | ||
545 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { | ||
546 | /* Associated to a unallowed channel, disassociate. */ | ||
547 | __iwm_invalidate_mlme_profile(iwm); | ||
548 | IWM_WARN(iwm, "Couldn't associate with %pM due to " | ||
549 | "channel %d is disabled. Check your local " | ||
550 | "regulatory setting.\n", | ||
551 | complete->bssid, complete->channel); | ||
552 | goto failure; | ||
553 | } | ||
554 | |||
529 | set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); | 555 | set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); |
530 | memcpy(iwm->bssid, complete->bssid, ETH_ALEN); | 556 | memcpy(iwm->bssid, complete->bssid, ETH_ALEN); |
531 | iwm->channel = complete->channel; | 557 | iwm->channel = complete->channel; |
@@ -562,6 +588,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
562 | GFP_KERNEL); | 588 | GFP_KERNEL); |
563 | break; | 589 | break; |
564 | case UMAC_ASSOC_COMPLETE_FAILURE: | 590 | case UMAC_ASSOC_COMPLETE_FAILURE: |
591 | failure: | ||
565 | clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); | 592 | clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); |
566 | memset(iwm->bssid, 0, ETH_ALEN); | 593 | memset(iwm->bssid, 0, ETH_ALEN); |
567 | iwm->channel = 0; | 594 | iwm->channel = 0; |
@@ -756,7 +783,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf, | |||
756 | (struct iwm_umac_notif_bss_info *)buf; | 783 | (struct iwm_umac_notif_bss_info *)buf; |
757 | struct ieee80211_channel *channel; | 784 | struct ieee80211_channel *channel; |
758 | struct ieee80211_supported_band *band; | 785 | struct ieee80211_supported_band *band; |
759 | struct iwm_bss_info *bss, *next; | 786 | struct iwm_bss_info *bss; |
760 | s32 signal; | 787 | s32 signal; |
761 | int freq; | 788 | int freq; |
762 | u16 frame_len = le16_to_cpu(umac_bss->frame_len); | 789 | u16 frame_len = le16_to_cpu(umac_bss->frame_len); |
@@ -775,7 +802,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf, | |||
775 | IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi); | 802 | IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi); |
776 | IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len); | 803 | IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len); |
777 | 804 | ||
778 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) | 805 | list_for_each_entry(bss, &iwm->bss_list, node) |
779 | if (bss->bss->table_idx == umac_bss->table_idx) | 806 | if (bss->bss->table_idx == umac_bss->table_idx) |
780 | break; | 807 | break; |
781 | 808 | ||
@@ -842,16 +869,15 @@ static int iwm_mlme_remove_bss(struct iwm_priv *iwm, u8 *buf, | |||
842 | int i; | 869 | int i; |
843 | 870 | ||
844 | for (i = 0; i < le32_to_cpu(bss_rm->count); i++) { | 871 | for (i = 0; i < le32_to_cpu(bss_rm->count); i++) { |
845 | table_idx = (le16_to_cpu(bss_rm->entries[i]) | 872 | table_idx = le16_to_cpu(bss_rm->entries[i]) & |
846 | & IWM_BSS_REMOVE_INDEX_MSK); | 873 | IWM_BSS_REMOVE_INDEX_MSK; |
847 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) | 874 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) |
848 | if (bss->bss->table_idx == cpu_to_le16(table_idx)) { | 875 | if (bss->bss->table_idx == cpu_to_le16(table_idx)) { |
849 | struct ieee80211_mgmt *mgmt; | 876 | struct ieee80211_mgmt *mgmt; |
850 | 877 | ||
851 | mgmt = (struct ieee80211_mgmt *) | 878 | mgmt = (struct ieee80211_mgmt *) |
852 | (bss->bss->frame_buf); | 879 | (bss->bss->frame_buf); |
853 | IWM_DBG_MLME(iwm, ERR, | 880 | IWM_DBG_MLME(iwm, ERR, "BSS removed: %pM\n", |
854 | "BSS removed: %pM\n", | ||
855 | mgmt->bssid); | 881 | mgmt->bssid); |
856 | list_del(&bss->node); | 882 | list_del(&bss->node); |
857 | kfree(bss->bss); | 883 | kfree(bss->bss); |
@@ -1223,18 +1249,24 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf, | |||
1223 | u8 source, cmd_id; | 1249 | u8 source, cmd_id; |
1224 | u16 seq_num; | 1250 | u16 seq_num; |
1225 | u32 count; | 1251 | u32 count; |
1226 | u8 resp; | ||
1227 | 1252 | ||
1228 | wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf; | 1253 | wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf; |
1229 | cmd_id = wifi_hdr->sw_hdr.cmd.cmd; | 1254 | cmd_id = wifi_hdr->sw_hdr.cmd.cmd; |
1230 | |||
1231 | source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); | 1255 | source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); |
1232 | if (source >= IWM_SRC_NUM) { | 1256 | if (source >= IWM_SRC_NUM) { |
1233 | IWM_CRIT(iwm, "invalid source %d\n", source); | 1257 | IWM_CRIT(iwm, "invalid source %d\n", source); |
1234 | return -EINVAL; | 1258 | return -EINVAL; |
1235 | } | 1259 | } |
1236 | 1260 | ||
1237 | count = (GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT)); | 1261 | if (cmd_id == REPLY_RX_MPDU_CMD) |
1262 | trace_iwm_rx_packet(iwm, buf, buf_size); | ||
1263 | else if ((cmd_id == UMAC_NOTIFY_OPCODE_RX_TICKET) && | ||
1264 | (source == UMAC_HDI_IN_SOURCE_FW)) | ||
1265 | trace_iwm_rx_ticket(iwm, buf, buf_size); | ||
1266 | else | ||
1267 | trace_iwm_rx_wifi_cmd(iwm, wifi_hdr); | ||
1268 | |||
1269 | count = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT); | ||
1238 | count += sizeof(struct iwm_umac_wifi_in_hdr) - | 1270 | count += sizeof(struct iwm_umac_wifi_in_hdr) - |
1239 | sizeof(struct iwm_dev_cmd_hdr); | 1271 | sizeof(struct iwm_dev_cmd_hdr); |
1240 | if (count > buf_size) { | 1272 | if (count > buf_size) { |
@@ -1242,8 +1274,6 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf, | |||
1242 | return -EINVAL; | 1274 | return -EINVAL; |
1243 | } | 1275 | } |
1244 | 1276 | ||
1245 | resp = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_STATUS); | ||
1246 | |||
1247 | seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num); | 1277 | seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num); |
1248 | 1278 | ||
1249 | IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n", | 1279 | IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n", |
@@ -1316,8 +1346,9 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf, | |||
1316 | { | 1346 | { |
1317 | u8 seq_num; | 1347 | u8 seq_num; |
1318 | struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf; | 1348 | struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf; |
1319 | struct iwm_nonwifi_cmd *cmd, *next; | 1349 | struct iwm_nonwifi_cmd *cmd; |
1320 | 1350 | ||
1351 | trace_iwm_rx_nonwifi_cmd(iwm, buf, buf_size); | ||
1321 | seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); | 1352 | seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); |
1322 | 1353 | ||
1323 | /* | 1354 | /* |
@@ -1328,7 +1359,7 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf, | |||
1328 | * That means we only support synchronised non wifi command response | 1359 | * That means we only support synchronised non wifi command response |
1329 | * schemes. | 1360 | * schemes. |
1330 | */ | 1361 | */ |
1331 | list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) | 1362 | list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending) |
1332 | if (cmd->seq_num == seq_num) { | 1363 | if (cmd->seq_num == seq_num) { |
1333 | cmd->resp_received = 1; | 1364 | cmd->resp_received = 1; |
1334 | cmd->buf.len = buf_size; | 1365 | cmd->buf.len = buf_size; |
@@ -1647,6 +1678,7 @@ void iwm_rx_worker(struct work_struct *work) | |||
1647 | * We stop whenever a ticket is missing its packet, as we're | 1678 | * We stop whenever a ticket is missing its packet, as we're |
1648 | * supposed to send the packets in order. | 1679 | * supposed to send the packets in order. |
1649 | */ | 1680 | */ |
1681 | spin_lock(&iwm->ticket_lock); | ||
1650 | list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { | 1682 | list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { |
1651 | struct iwm_rx_packet *packet = | 1683 | struct iwm_rx_packet *packet = |
1652 | iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id)); | 1684 | iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id)); |
@@ -1655,12 +1687,12 @@ void iwm_rx_worker(struct work_struct *work) | |||
1655 | IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d " | 1687 | IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d " |
1656 | "to be handled first\n", | 1688 | "to be handled first\n", |
1657 | le16_to_cpu(ticket->ticket->id)); | 1689 | le16_to_cpu(ticket->ticket->id)); |
1658 | return; | 1690 | break; |
1659 | } | 1691 | } |
1660 | 1692 | ||
1661 | list_del(&ticket->node); | 1693 | list_del(&ticket->node); |
1662 | list_del(&packet->node); | ||
1663 | iwm_rx_process_packet(iwm, packet, ticket); | 1694 | iwm_rx_process_packet(iwm, packet, ticket); |
1664 | } | 1695 | } |
1696 | spin_unlock(&iwm->ticket_lock); | ||
1665 | } | 1697 | } |
1666 | 1698 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.c b/drivers/net/wireless/iwmc3200wifi/trace.c new file mode 100644 index 000000000000..904d36f22311 --- /dev/null +++ b/drivers/net/wireless/iwmc3200wifi/trace.c | |||
@@ -0,0 +1,3 @@ | |||
1 | #include "iwm.h" | ||
2 | #define CREATE_TRACE_POINTS | ||
3 | #include "trace.h" | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h new file mode 100644 index 000000000000..320e54fbb38c --- /dev/null +++ b/drivers/net/wireless/iwmc3200wifi/trace.h | |||
@@ -0,0 +1,283 @@ | |||
1 | #if !defined(__IWM_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) | ||
2 | #define __IWM_TRACE_H__ | ||
3 | |||
4 | #include <linux/tracepoint.h> | ||
5 | |||
6 | #if !defined(CONFIG_IWM_TRACING) | ||
7 | #undef TRACE_EVENT | ||
8 | #define TRACE_EVENT(name, proto, ...) \ | ||
9 | static inline void trace_ ## name(proto) {} | ||
10 | #endif | ||
11 | |||
12 | #undef TRACE_SYSTEM | ||
13 | #define TRACE_SYSTEM iwm | ||
14 | |||
15 | #define IWM_ENTRY __array(char, ndev_name, 16) | ||
16 | #define IWM_ASSIGN strlcpy(__entry->ndev_name, iwm_to_ndev(iwm)->name, 16) | ||
17 | #define IWM_PR_FMT "%s" | ||
18 | #define IWM_PR_ARG __entry->ndev_name | ||
19 | |||
20 | TRACE_EVENT(iwm_tx_nonwifi_cmd, | ||
21 | TP_PROTO(struct iwm_priv *iwm, struct iwm_udma_out_nonwifi_hdr *hdr), | ||
22 | |||
23 | TP_ARGS(iwm, hdr), | ||
24 | |||
25 | TP_STRUCT__entry( | ||
26 | IWM_ENTRY | ||
27 | __field(u8, opcode) | ||
28 | __field(u8, resp) | ||
29 | __field(u8, eot) | ||
30 | __field(u8, hw) | ||
31 | __field(u16, seq) | ||
32 | __field(u32, addr) | ||
33 | __field(u32, op1) | ||
34 | __field(u32, op2) | ||
35 | ), | ||
36 | |||
37 | TP_fast_assign( | ||
38 | IWM_ASSIGN; | ||
39 | __entry->opcode = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE); | ||
40 | __entry->resp = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_RESP); | ||
41 | __entry->eot = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT); | ||
42 | __entry->hw = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW); | ||
43 | __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM); | ||
44 | __entry->addr = le32_to_cpu(hdr->addr); | ||
45 | __entry->op1 = le32_to_cpu(hdr->op1_sz); | ||
46 | __entry->op2 = le32_to_cpu(hdr->op2); | ||
47 | ), | ||
48 | |||
49 | TP_printk( | ||
50 | IWM_PR_FMT " Tx TARGET CMD: opcode 0x%x, resp %d, eot %d, " | ||
51 | "hw %d, seq 0x%x, addr 0x%x, op1 0x%x, op2 0x%x", | ||
52 | IWM_PR_ARG, __entry->opcode, __entry->resp, __entry->eot, | ||
53 | __entry->hw, __entry->seq, __entry->addr, __entry->op1, | ||
54 | __entry->op2 | ||
55 | ) | ||
56 | ); | ||
57 | |||
58 | TRACE_EVENT(iwm_tx_wifi_cmd, | ||
59 | TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_out_hdr *hdr), | ||
60 | |||
61 | TP_ARGS(iwm, hdr), | ||
62 | |||
63 | TP_STRUCT__entry( | ||
64 | IWM_ENTRY | ||
65 | __field(u8, opcode) | ||
66 | __field(u8, lmac) | ||
67 | __field(u8, resp) | ||
68 | __field(u8, eot) | ||
69 | __field(u8, ra_tid) | ||
70 | __field(u8, credit_group) | ||
71 | __field(u8, color) | ||
72 | __field(u16, seq) | ||
73 | ), | ||
74 | |||
75 | TP_fast_assign( | ||
76 | IWM_ASSIGN; | ||
77 | __entry->opcode = hdr->sw_hdr.cmd.cmd; | ||
78 | __entry->lmac = 0; | ||
79 | __entry->seq = hdr->sw_hdr.cmd.seq_num; | ||
80 | __entry->resp = GET_VAL8(hdr->sw_hdr.cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ); | ||
81 | __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR); | ||
82 | __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT); | ||
83 | __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID); | ||
84 | __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP); | ||
85 | if (__entry->opcode == UMAC_CMD_OPCODE_WIFI_PASS_THROUGH || | ||
86 | __entry->opcode == UMAC_CMD_OPCODE_WIFI_IF_WRAPPER) { | ||
87 | __entry->lmac = 1; | ||
88 | __entry->opcode = ((struct iwm_lmac_hdr *)(hdr + 1))->id; | ||
89 | } | ||
90 | ), | ||
91 | |||
92 | TP_printk( | ||
93 | IWM_PR_FMT " Tx %cMAC CMD: opcode 0x%x, resp %d, eot %d, " | ||
94 | "seq 0x%x, sta_color 0x%x, ra_tid 0x%x, credit_group 0x%x", | ||
95 | IWM_PR_ARG, __entry->lmac ? 'L' : 'U', __entry->opcode, | ||
96 | __entry->resp, __entry->eot, __entry->seq, __entry->color, | ||
97 | __entry->ra_tid, __entry->credit_group | ||
98 | ) | ||
99 | ); | ||
100 | |||
101 | TRACE_EVENT(iwm_tx_packets, | ||
102 | TP_PROTO(struct iwm_priv *iwm, u8 *buf, int len), | ||
103 | |||
104 | TP_ARGS(iwm, buf, len), | ||
105 | |||
106 | TP_STRUCT__entry( | ||
107 | IWM_ENTRY | ||
108 | __field(u8, eot) | ||
109 | __field(u8, ra_tid) | ||
110 | __field(u8, credit_group) | ||
111 | __field(u8, color) | ||
112 | __field(u16, seq) | ||
113 | __field(u8, npkt) | ||
114 | __field(u32, bytes) | ||
115 | ), | ||
116 | |||
117 | TP_fast_assign( | ||
118 | struct iwm_umac_wifi_out_hdr *hdr = | ||
119 | (struct iwm_umac_wifi_out_hdr *)buf; | ||
120 | |||
121 | IWM_ASSIGN; | ||
122 | __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT); | ||
123 | __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID); | ||
124 | __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP); | ||
125 | __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR); | ||
126 | __entry->seq = hdr->sw_hdr.cmd.seq_num; | ||
127 | __entry->npkt = 1; | ||
128 | __entry->bytes = len; | ||
129 | |||
130 | if (!__entry->eot) { | ||
131 | int count; | ||
132 | u8 *ptr = buf; | ||
133 | |||
134 | __entry->npkt = 0; | ||
135 | while (ptr < buf + len) { | ||
136 | count = GET_VAL32(hdr->sw_hdr.meta_data, | ||
137 | UMAC_FW_CMD_BYTE_COUNT); | ||
138 | ptr += ALIGN(sizeof(*hdr) + count, 16); | ||
139 | hdr = (struct iwm_umac_wifi_out_hdr *)ptr; | ||
140 | __entry->npkt++; | ||
141 | } | ||
142 | } | ||
143 | ), | ||
144 | |||
145 | TP_printk( | ||
146 | IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, " | ||
147 | "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes", | ||
148 | IWM_PR_ARG, !__entry->eot ? "concatenated " : "", | ||
149 | __entry->eot, __entry->seq, __entry->color, __entry->ra_tid, | ||
150 | __entry->credit_group, __entry->npkt, __entry->bytes | ||
151 | ) | ||
152 | ); | ||
153 | |||
154 | TRACE_EVENT(iwm_rx_nonwifi_cmd, | ||
155 | TP_PROTO(struct iwm_priv *iwm, void *buf, int len), | ||
156 | |||
157 | TP_ARGS(iwm, buf, len), | ||
158 | |||
159 | TP_STRUCT__entry( | ||
160 | IWM_ENTRY | ||
161 | __field(u8, opcode) | ||
162 | __field(u16, seq) | ||
163 | __field(u32, len) | ||
164 | ), | ||
165 | |||
166 | TP_fast_assign( | ||
167 | struct iwm_udma_in_hdr *hdr = buf; | ||
168 | |||
169 | IWM_ASSIGN; | ||
170 | __entry->opcode = GET_VAL32(hdr->cmd, UDMA_HDI_IN_NW_CMD_OPCODE); | ||
171 | __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); | ||
172 | __entry->len = len; | ||
173 | ), | ||
174 | |||
175 | TP_printk( | ||
176 | IWM_PR_FMT " Rx TARGET RESP: opcode 0x%x, seq 0x%x, len 0x%x", | ||
177 | IWM_PR_ARG, __entry->opcode, __entry->seq, __entry->len | ||
178 | ) | ||
179 | ); | ||
180 | |||
181 | TRACE_EVENT(iwm_rx_wifi_cmd, | ||
182 | TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_in_hdr *hdr), | ||
183 | |||
184 | TP_ARGS(iwm, hdr), | ||
185 | |||
186 | TP_STRUCT__entry( | ||
187 | IWM_ENTRY | ||
188 | __field(u8, cmd) | ||
189 | __field(u8, source) | ||
190 | __field(u16, seq) | ||
191 | __field(u32, count) | ||
192 | ), | ||
193 | |||
194 | TP_fast_assign( | ||
195 | IWM_ASSIGN; | ||
196 | __entry->cmd = hdr->sw_hdr.cmd.cmd; | ||
197 | __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); | ||
198 | __entry->count = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT); | ||
199 | __entry->seq = le16_to_cpu(hdr->sw_hdr.cmd.seq_num); | ||
200 | ), | ||
201 | |||
202 | TP_printk( | ||
203 | IWM_PR_FMT " Rx %s RESP: cmd 0x%x, seq 0x%x, count 0x%x", | ||
204 | IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ? "LMAC" : | ||
205 | __entry->source == UMAC_HDI_IN_SOURCE_FW ? "UMAC" : "UDMA", | ||
206 | __entry->cmd, __entry->seq, __entry->count | ||
207 | ) | ||
208 | ); | ||
209 | |||
210 | #define iwm_ticket_action_symbol \ | ||
211 | { IWM_RX_TICKET_DROP, "DROP" }, \ | ||
212 | { IWM_RX_TICKET_RELEASE, "RELEASE" }, \ | ||
213 | { IWM_RX_TICKET_SNIFFER, "SNIFFER" }, \ | ||
214 | { IWM_RX_TICKET_ENQUEUE, "ENQUEUE" } | ||
215 | |||
216 | TRACE_EVENT(iwm_rx_ticket, | ||
217 | TP_PROTO(struct iwm_priv *iwm, void *buf, int len), | ||
218 | |||
219 | TP_ARGS(iwm, buf, len), | ||
220 | |||
221 | TP_STRUCT__entry( | ||
222 | IWM_ENTRY | ||
223 | __field(u8, action) | ||
224 | __field(u8, reason) | ||
225 | __field(u16, id) | ||
226 | __field(u16, flags) | ||
227 | ), | ||
228 | |||
229 | TP_fast_assign( | ||
230 | struct iwm_rx_ticket *ticket = | ||
231 | ((struct iwm_umac_notif_rx_ticket *)buf)->tickets; | ||
232 | |||
233 | IWM_ASSIGN; | ||
234 | __entry->id = le16_to_cpu(ticket->id); | ||
235 | __entry->action = le16_to_cpu(ticket->action); | ||
236 | __entry->flags = le16_to_cpu(ticket->flags); | ||
237 | __entry->reason = (__entry->flags & IWM_RX_TICKET_DROP_REASON_MSK) >> IWM_RX_TICKET_DROP_REASON_POS; | ||
238 | ), | ||
239 | |||
240 | TP_printk( | ||
241 | IWM_PR_FMT " Rx ticket: id 0x%x, action %s, %s 0x%x%s", | ||
242 | IWM_PR_ARG, __entry->id, | ||
243 | __print_symbolic(__entry->action, iwm_ticket_action_symbol), | ||
244 | __entry->reason ? "reason" : "flags", | ||
245 | __entry->reason ? __entry->reason : __entry->flags, | ||
246 | __entry->flags & IWM_RX_TICKET_AMSDU_MSK ? ", AMSDU frame" : "" | ||
247 | ) | ||
248 | ); | ||
249 | |||
250 | TRACE_EVENT(iwm_rx_packet, | ||
251 | TP_PROTO(struct iwm_priv *iwm, void *buf, int len), | ||
252 | |||
253 | TP_ARGS(iwm, buf, len), | ||
254 | |||
255 | TP_STRUCT__entry( | ||
256 | IWM_ENTRY | ||
257 | __field(u8, source) | ||
258 | __field(u16, id) | ||
259 | __field(u32, len) | ||
260 | ), | ||
261 | |||
262 | TP_fast_assign( | ||
263 | struct iwm_umac_wifi_in_hdr *hdr = buf; | ||
264 | |||
265 | IWM_ASSIGN; | ||
266 | __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); | ||
267 | __entry->id = le16_to_cpu(hdr->sw_hdr.cmd.seq_num); | ||
268 | __entry->len = len - sizeof(*hdr); | ||
269 | ), | ||
270 | |||
271 | TP_printk( | ||
272 | IWM_PR_FMT " Rx %s packet: id 0x%x, %d bytes", | ||
273 | IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ? | ||
274 | "LMAC" : "UMAC", __entry->id, __entry->len | ||
275 | ) | ||
276 | ); | ||
277 | #endif | ||
278 | |||
279 | #undef TRACE_INCLUDE_PATH | ||
280 | #define TRACE_INCLUDE_PATH . | ||
281 | #undef TRACE_INCLUDE_FILE | ||
282 | #define TRACE_INCLUDE_FILE trace | ||
283 | #include <trace/define_trace.h> | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c index 55905f02309c..a20b936ae21f 100644 --- a/drivers/net/wireless/iwmc3200wifi/tx.c +++ b/drivers/net/wireless/iwmc3200wifi/tx.c | |||
@@ -346,6 +346,7 @@ static int iwm_tx_send_concat_packets(struct iwm_priv *iwm, | |||
346 | /* mark EOP for the last packet */ | 346 | /* mark EOP for the last packet */ |
347 | iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1); | 347 | iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1); |
348 | 348 | ||
349 | trace_iwm_tx_packets(iwm, txq->concat_buf, txq->concat_count); | ||
349 | ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count); | 350 | ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count); |
350 | 351 | ||
351 | txq->concat_count = 0; | 352 | txq->concat_count = 0; |
@@ -450,7 +451,6 @@ void iwm_tx_worker(struct work_struct *work) | |||
450 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 451 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
451 | { | 452 | { |
452 | struct iwm_priv *iwm = ndev_to_iwm(netdev); | 453 | struct iwm_priv *iwm = ndev_to_iwm(netdev); |
453 | struct net_device *ndev = iwm_to_ndev(iwm); | ||
454 | struct wireless_dev *wdev = iwm_to_wdev(iwm); | 454 | struct wireless_dev *wdev = iwm_to_wdev(iwm); |
455 | struct iwm_tx_info *tx_info; | 455 | struct iwm_tx_info *tx_info; |
456 | struct iwm_tx_queue *txq; | 456 | struct iwm_tx_queue *txq; |
@@ -517,12 +517,12 @@ int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
517 | 517 | ||
518 | queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker); | 518 | queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker); |
519 | 519 | ||
520 | ndev->stats.tx_packets++; | 520 | netdev->stats.tx_packets++; |
521 | ndev->stats.tx_bytes += skb->len; | 521 | netdev->stats.tx_bytes += skb->len; |
522 | return NETDEV_TX_OK; | 522 | return NETDEV_TX_OK; |
523 | 523 | ||
524 | drop: | 524 | drop: |
525 | ndev->stats.tx_dropped++; | 525 | netdev->stats.tx_dropped++; |
526 | dev_kfree_skb_any(skb); | 526 | dev_kfree_skb_any(skb); |
527 | return NETDEV_TX_OK; | 527 | return NETDEV_TX_OK; |
528 | } | 528 | } |
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h index 7f54a145ca65..0cbba3ecc813 100644 --- a/drivers/net/wireless/iwmc3200wifi/umac.h +++ b/drivers/net/wireless/iwmc3200wifi/umac.h | |||
@@ -362,7 +362,7 @@ struct iwm_udma_out_wifi_hdr { | |||
362 | #define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4 | 362 | #define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4 |
363 | #define IWM_RX_TICKET_AMSDU_MSK 0x8 | 363 | #define IWM_RX_TICKET_AMSDU_MSK 0x8 |
364 | #define IWM_RX_TICKET_DROP_REASON_POS 4 | 364 | #define IWM_RX_TICKET_DROP_REASON_POS 4 |
365 | #define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << RX_TICKET_FLAGS_DROP_REASON_POS) | 365 | #define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << IWM_RX_TICKET_DROP_REASON_POS) |
366 | 366 | ||
367 | #define IWM_RX_DROP_NO_DROP 0x0 | 367 | #define IWM_RX_DROP_NO_DROP 0x0 |
368 | #define IWM_RX_DROP_BAD_CRC 0x1 | 368 | #define IWM_RX_DROP_BAD_CRC 0x1 |
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 2daf8ffdb7e1..7a867e31ca5a 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c | |||
@@ -38,10 +38,10 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, | |||
38 | struct sk_buff *skb); | 38 | struct sk_buff *skb); |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * @brief This function computes the avgSNR . | 41 | * @brief This function computes the avgSNR . |
42 | * | 42 | * |
43 | * @param priv A pointer to struct lbs_private structure | 43 | * @param priv A pointer to struct lbs_private structure |
44 | * @return avgSNR | 44 | * @return avgSNR |
45 | */ | 45 | */ |
46 | static u8 lbs_getavgsnr(struct lbs_private *priv) | 46 | static u8 lbs_getavgsnr(struct lbs_private *priv) |
47 | { | 47 | { |
@@ -56,10 +56,10 @@ static u8 lbs_getavgsnr(struct lbs_private *priv) | |||
56 | } | 56 | } |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * @brief This function computes the AvgNF | 59 | * @brief This function computes the AvgNF |
60 | * | 60 | * |
61 | * @param priv A pointer to struct lbs_private structure | 61 | * @param priv A pointer to struct lbs_private structure |
62 | * @return AvgNF | 62 | * @return AvgNF |
63 | */ | 63 | */ |
64 | static u8 lbs_getavgnf(struct lbs_private *priv) | 64 | static u8 lbs_getavgnf(struct lbs_private *priv) |
65 | { | 65 | { |
@@ -74,11 +74,11 @@ static u8 lbs_getavgnf(struct lbs_private *priv) | |||
74 | } | 74 | } |
75 | 75 | ||
76 | /** | 76 | /** |
77 | * @brief This function save the raw SNR/NF to our internel buffer | 77 | * @brief This function save the raw SNR/NF to our internel buffer |
78 | * | 78 | * |
79 | * @param priv A pointer to struct lbs_private structure | 79 | * @param priv A pointer to struct lbs_private structure |
80 | * @param prxpd A pointer to rxpd structure of received packet | 80 | * @param prxpd A pointer to rxpd structure of received packet |
81 | * @return n/a | 81 | * @return n/a |
82 | */ | 82 | */ |
83 | static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) | 83 | static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) |
84 | { | 84 | { |
@@ -93,11 +93,11 @@ static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * @brief This function computes the RSSI in received packet. | 96 | * @brief This function computes the RSSI in received packet. |
97 | * | 97 | * |
98 | * @param priv A pointer to struct lbs_private structure | 98 | * @param priv A pointer to struct lbs_private structure |
99 | * @param prxpd A pointer to rxpd structure of received packet | 99 | * @param prxpd A pointer to rxpd structure of received packet |
100 | * @return n/a | 100 | * @return n/a |
101 | */ | 101 | */ |
102 | static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) | 102 | static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) |
103 | { | 103 | { |
@@ -134,9 +134,9 @@ static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) | |||
134 | * @brief This function processes received packet and forwards it | 134 | * @brief This function processes received packet and forwards it |
135 | * to kernel/upper layer | 135 | * to kernel/upper layer |
136 | * | 136 | * |
137 | * @param priv A pointer to struct lbs_private | 137 | * @param priv A pointer to struct lbs_private |
138 | * @param skb A pointer to skb which includes the received packet | 138 | * @param skb A pointer to skb which includes the received packet |
139 | * @return 0 or -1 | 139 | * @return 0 or -1 |
140 | */ | 140 | */ |
141 | int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | 141 | int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) |
142 | { | 142 | { |
@@ -196,7 +196,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | |||
196 | * before the snap_type. | 196 | * before the snap_type. |
197 | */ | 197 | */ |
198 | p_ethhdr = (struct ethhdr *) | 198 | p_ethhdr = (struct ethhdr *) |
199 | ((u8 *) & p_rx_pkt->eth803_hdr | 199 | ((u8 *) &p_rx_pkt->eth803_hdr |
200 | + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr) | 200 | + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr) |
201 | - sizeof(p_rx_pkt->eth803_hdr.dest_addr) | 201 | - sizeof(p_rx_pkt->eth803_hdr.dest_addr) |
202 | - sizeof(p_rx_pkt->eth803_hdr.src_addr) | 202 | - sizeof(p_rx_pkt->eth803_hdr.src_addr) |
@@ -213,7 +213,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | |||
213 | hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd; | 213 | hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd; |
214 | } else { | 214 | } else { |
215 | lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", | 215 | lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", |
216 | (u8 *) & p_rx_pkt->rfc1042_hdr, | 216 | (u8 *) &p_rx_pkt->rfc1042_hdr, |
217 | sizeof(p_rx_pkt->rfc1042_hdr)); | 217 | sizeof(p_rx_pkt->rfc1042_hdr)); |
218 | 218 | ||
219 | /* Chop off the rxpd */ | 219 | /* Chop off the rxpd */ |
@@ -254,8 +254,8 @@ EXPORT_SYMBOL_GPL(lbs_process_rxed_packet); | |||
254 | * @brief This function converts Tx/Rx rates from the Marvell WLAN format | 254 | * @brief This function converts Tx/Rx rates from the Marvell WLAN format |
255 | * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) | 255 | * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) |
256 | * | 256 | * |
257 | * @param rate Input rate | 257 | * @param rate Input rate |
258 | * @return Output Rate (0 if invalid) | 258 | * @return Output Rate (0 if invalid) |
259 | */ | 259 | */ |
260 | static u8 convert_mv_rate_to_radiotap(u8 rate) | 260 | static u8 convert_mv_rate_to_radiotap(u8 rate) |
261 | { | 261 | { |
@@ -294,9 +294,9 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) | |||
294 | * @brief This function processes a received 802.11 packet and forwards it | 294 | * @brief This function processes a received 802.11 packet and forwards it |
295 | * to kernel/upper layer | 295 | * to kernel/upper layer |
296 | * | 296 | * |
297 | * @param priv A pointer to struct lbs_private | 297 | * @param priv A pointer to struct lbs_private |
298 | * @param skb A pointer to skb which includes the received packet | 298 | * @param skb A pointer to skb which includes the received packet |
299 | * @return 0 or -1 | 299 | * @return 0 or -1 |
300 | */ | 300 | */ |
301 | static int process_rxed_802_11_packet(struct lbs_private *priv, | 301 | static int process_rxed_802_11_packet(struct lbs_private *priv, |
302 | struct sk_buff *skb) | 302 | struct sk_buff *skb) |
@@ -313,7 +313,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, | |||
313 | p_rx_pkt = (struct rx80211packethdr *) skb->data; | 313 | p_rx_pkt = (struct rx80211packethdr *) skb->data; |
314 | prxpd = &p_rx_pkt->rx_pd; | 314 | prxpd = &p_rx_pkt->rx_pd; |
315 | 315 | ||
316 | // lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); | 316 | /* lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); */ |
317 | 317 | ||
318 | if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { | 318 | if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { |
319 | lbs_deb_rx("rx err: frame received with bad length\n"); | 319 | lbs_deb_rx("rx err: frame received with bad length\n"); |
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig index e2a2c18920aa..6116b546861d 100644 --- a/drivers/net/wireless/orinoco/Kconfig +++ b/drivers/net/wireless/orinoco/Kconfig | |||
@@ -27,6 +27,17 @@ config HERMES | |||
27 | configure your card and that /etc/pcmcia/wireless.opts works : | 27 | configure your card and that /etc/pcmcia/wireless.opts works : |
28 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> | 28 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> |
29 | 29 | ||
30 | config HERMES_PRISM | ||
31 | bool "Support Prism 2/2.5 chipset" | ||
32 | depends on HERMES | ||
33 | ---help--- | ||
34 | |||
35 | Say Y to enable support for Prism 2 and 2.5 chipsets. These | ||
36 | chipsets are better handled by the hostap driver. This driver | ||
37 | would not support WPA or firmware download for Prism chipset. | ||
38 | |||
39 | If you are not sure, say N. | ||
40 | |||
30 | config HERMES_CACHE_FW_ON_INIT | 41 | config HERMES_CACHE_FW_ON_INIT |
31 | bool "Cache Hermes firmware on driver initialisation" | 42 | bool "Cache Hermes firmware on driver initialisation" |
32 | depends on HERMES | 43 | depends on HERMES |
@@ -86,7 +97,7 @@ config NORTEL_HERMES | |||
86 | 97 | ||
87 | config PCI_HERMES | 98 | config PCI_HERMES |
88 | tristate "Prism 2.5 PCI 802.11b adaptor support" | 99 | tristate "Prism 2.5 PCI 802.11b adaptor support" |
89 | depends on PCI && HERMES | 100 | depends on PCI && HERMES && HERMES_PRISM |
90 | help | 101 | help |
91 | Enable support for PCI and mini-PCI 802.11b wireless NICs based on | 102 | Enable support for PCI and mini-PCI 802.11b wireless NICs based on |
92 | the Prism 2.5 chipset. These are true PCI cards, not the 802.11b | 103 | the Prism 2.5 chipset. These are true PCI cards, not the 802.11b |
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index e6369242e49c..883b8f868626 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -262,6 +262,13 @@ int determine_fw_capabilities(struct orinoco_private *priv, | |||
262 | if (fw_name) | 262 | if (fw_name) |
263 | dev_info(dev, "Firmware determined as %s\n", fw_name); | 263 | dev_info(dev, "Firmware determined as %s\n", fw_name); |
264 | 264 | ||
265 | #ifndef CONFIG_HERMES_PRISM | ||
266 | if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL) { | ||
267 | dev_err(dev, "Support for Prism chipset is not enabled\n"); | ||
268 | return -ENODEV; | ||
269 | } | ||
270 | #endif | ||
271 | |||
265 | return 0; | 272 | return 0; |
266 | } | 273 | } |
267 | 274 | ||
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 1d4ada188eda..fdc961379170 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -374,87 +374,90 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION | |||
374 | "Pavel Roskin <proski@gnu.org>, et al)"; | 374 | "Pavel Roskin <proski@gnu.org>, et al)"; |
375 | 375 | ||
376 | static struct pcmcia_device_id orinoco_cs_ids[] = { | 376 | static struct pcmcia_device_id orinoco_cs_ids[] = { |
377 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */ | ||
378 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */ | ||
379 | PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ | ||
380 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ | 377 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ |
381 | PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */ | ||
382 | PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */ | ||
383 | PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ | 378 | PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ |
384 | PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ | 379 | PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ |
385 | PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ | 380 | PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ |
386 | PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */ | ||
387 | PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ | ||
388 | PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ | 381 | PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ |
389 | PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ | 382 | PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ |
390 | PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */ | 383 | PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */ |
391 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ | 384 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ |
392 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ | ||
393 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ | ||
394 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ | ||
395 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ | ||
396 | PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ | 385 | PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ |
397 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ | 386 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ |
398 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ | 387 | PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ |
399 | PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ | 388 | PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ |
389 | PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), | ||
390 | PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), | ||
391 | PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), | ||
392 | PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), | ||
393 | PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169), | ||
394 | PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb), | ||
395 | PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), | ||
396 | PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), | ||
397 | PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3), | ||
398 | PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c), | ||
399 | PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077), | ||
400 | PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92), | ||
401 | PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a), | ||
402 | PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410), | ||
403 | PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3), | ||
404 | PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a), | ||
405 | PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767), | ||
406 | PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed), | ||
407 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), | ||
408 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), | ||
409 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), | ||
410 | PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), | ||
411 | #ifdef CONFIG_HERMES_PRISM | ||
412 | /* Only entries that certainly identify Prism chipset */ | ||
413 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */ | ||
414 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */ | ||
415 | PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ | ||
416 | PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */ | ||
417 | PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */ | ||
418 | PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */ | ||
419 | PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ | ||
420 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ | ||
421 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ | ||
422 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ | ||
423 | PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ | ||
400 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ | 424 | PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ |
401 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ | 425 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ |
402 | PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ | 426 | PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ |
403 | PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ | 427 | PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ |
404 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ | 428 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ |
405 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ | 429 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ |
406 | PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), | 430 | PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), |
407 | PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), | ||
408 | PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), | 431 | PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), |
409 | PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), | 432 | PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), |
410 | PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), | ||
411 | PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), | ||
412 | PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), | ||
413 | PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169), | ||
414 | PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb), | ||
415 | PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), | ||
416 | PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), | 433 | PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), |
417 | PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), | 434 | PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), |
418 | PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), | 435 | PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), |
419 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), | 436 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), |
420 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), | 437 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), |
421 | PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), | 438 | PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), |
439 | PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), | ||
422 | PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), | 440 | PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), |
423 | PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), | 441 | PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), |
424 | PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), | 442 | PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), |
425 | PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), | ||
426 | PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3), | ||
427 | PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c), | ||
428 | PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), | ||
429 | PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077), | ||
430 | PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), | 443 | PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), |
431 | PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), | 444 | PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), |
432 | PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), | 445 | PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), |
433 | PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92), | ||
434 | PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), | 446 | PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), |
435 | PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a), | ||
436 | PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410), | ||
437 | PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3), | ||
438 | PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01), | 447 | PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01), |
439 | PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a), | ||
440 | PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1), | ||
441 | PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1), | 448 | PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1), |
442 | PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767), | 449 | PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1), |
443 | PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6), | 450 | PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6), |
444 | PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed), | ||
445 | PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264), | 451 | PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264), |
446 | PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), | 452 | PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), |
447 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), | ||
448 | PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), | ||
449 | PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), | ||
450 | PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), | 453 | PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), |
451 | PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), | 454 | PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), |
452 | PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), | ||
453 | PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), | 455 | PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), |
454 | PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092), | 456 | PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092), |
455 | PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2), | 457 | PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2), |
456 | PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b), | 458 | PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b), |
457 | PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39), | 459 | PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39), |
460 | #endif | ||
458 | PCMCIA_DEVICE_NULL, | 461 | PCMCIA_DEVICE_NULL, |
459 | }; | 462 | }; |
460 | MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); | 463 | MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 4f752a21495f..36f4c820ad01 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -545,6 +545,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
545 | IEEE80211_HW_SUPPORTS_PS | | 545 | IEEE80211_HW_SUPPORTS_PS | |
546 | IEEE80211_HW_PS_NULLFUNC_STACK | | 546 | IEEE80211_HW_PS_NULLFUNC_STACK | |
547 | IEEE80211_HW_BEACON_FILTER | | 547 | IEEE80211_HW_BEACON_FILTER | |
548 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | ||
548 | IEEE80211_HW_NOISE_DBM; | 549 | IEEE80211_HW_NOISE_DBM; |
549 | 550 | ||
550 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 551 | dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 2887047069f2..aceb95ef7274 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -117,6 +117,7 @@ MODULE_PARM_DESC(workaround_interval, | |||
117 | #define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d) | 117 | #define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d) |
118 | #define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e) | 118 | #define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e) |
119 | #define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f) | 119 | #define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f) |
120 | #define OID_802_11_CAPABILITY cpu_to_le32(0x0d010122) | ||
120 | #define OID_802_11_PMKID cpu_to_le32(0x0d010123) | 121 | #define OID_802_11_PMKID cpu_to_le32(0x0d010123) |
121 | #define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203) | 122 | #define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203) |
122 | #define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204) | 123 | #define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204) |
@@ -358,6 +359,30 @@ struct ndis_80211_assoc_info { | |||
358 | __le32 offset_resp_ies; | 359 | __le32 offset_resp_ies; |
359 | } __attribute__((packed)); | 360 | } __attribute__((packed)); |
360 | 361 | ||
362 | struct ndis_80211_auth_encr_pair { | ||
363 | __le32 auth_mode; | ||
364 | __le32 encr_mode; | ||
365 | } __attribute__((packed)); | ||
366 | |||
367 | struct ndis_80211_capability { | ||
368 | __le32 length; | ||
369 | __le32 version; | ||
370 | __le32 num_pmkids; | ||
371 | __le32 num_auth_encr_pair; | ||
372 | struct ndis_80211_auth_encr_pair auth_encr_pair[0]; | ||
373 | } __attribute__((packed)); | ||
374 | |||
375 | struct ndis_80211_bssid_info { | ||
376 | u8 bssid[6]; | ||
377 | u8 pmkid[16]; | ||
378 | }; | ||
379 | |||
380 | struct ndis_80211_pmkid { | ||
381 | __le32 length; | ||
382 | __le32 bssid_info_count; | ||
383 | struct ndis_80211_bssid_info bssid_info[0]; | ||
384 | }; | ||
385 | |||
361 | /* | 386 | /* |
362 | * private data | 387 | * private data |
363 | */ | 388 | */ |
@@ -476,13 +501,7 @@ struct rndis_wlan_private { | |||
476 | /* encryption stuff */ | 501 | /* encryption stuff */ |
477 | int encr_tx_key_index; | 502 | int encr_tx_key_index; |
478 | struct rndis_wlan_encr_key encr_keys[4]; | 503 | struct rndis_wlan_encr_key encr_keys[4]; |
479 | enum nl80211_auth_type wpa_auth_type; | ||
480 | int wpa_version; | 504 | int wpa_version; |
481 | int wpa_keymgmt; | ||
482 | int wpa_ie_len; | ||
483 | u8 *wpa_ie; | ||
484 | int wpa_cipher_pair; | ||
485 | int wpa_cipher_group; | ||
486 | 505 | ||
487 | u8 command_buffer[COMMAND_BUFFER_SIZE]; | 506 | u8 command_buffer[COMMAND_BUFFER_SIZE]; |
488 | }; | 507 | }; |
@@ -534,6 +553,14 @@ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
534 | static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev, | 553 | static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev, |
535 | int idx, u8 *mac, struct station_info *sinfo); | 554 | int idx, u8 *mac, struct station_info *sinfo); |
536 | 555 | ||
556 | static int rndis_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
557 | struct cfg80211_pmksa *pmksa); | ||
558 | |||
559 | static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
560 | struct cfg80211_pmksa *pmksa); | ||
561 | |||
562 | static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev); | ||
563 | |||
537 | static struct cfg80211_ops rndis_config_ops = { | 564 | static struct cfg80211_ops rndis_config_ops = { |
538 | .change_virtual_intf = rndis_change_virtual_intf, | 565 | .change_virtual_intf = rndis_change_virtual_intf, |
539 | .scan = rndis_scan, | 566 | .scan = rndis_scan, |
@@ -550,6 +577,9 @@ static struct cfg80211_ops rndis_config_ops = { | |||
550 | .set_default_key = rndis_set_default_key, | 577 | .set_default_key = rndis_set_default_key, |
551 | .get_station = rndis_get_station, | 578 | .get_station = rndis_get_station, |
552 | .dump_station = rndis_dump_station, | 579 | .dump_station = rndis_dump_station, |
580 | .set_pmksa = rndis_set_pmksa, | ||
581 | .del_pmksa = rndis_del_pmksa, | ||
582 | .flush_pmksa = rndis_flush_pmksa, | ||
553 | }; | 583 | }; |
554 | 584 | ||
555 | static void *rndis_wiphy_privid = &rndis_wiphy_privid; | 585 | static void *rndis_wiphy_privid = &rndis_wiphy_privid; |
@@ -704,6 +734,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
704 | struct rndis_query_c *get_c; | 734 | struct rndis_query_c *get_c; |
705 | } u; | 735 | } u; |
706 | int ret, buflen; | 736 | int ret, buflen; |
737 | int resplen, respoffs, copylen; | ||
707 | 738 | ||
708 | buflen = *len + sizeof(*u.get); | 739 | buflen = *len + sizeof(*u.get); |
709 | if (buflen < CONTROL_BUFFER_SIZE) | 740 | if (buflen < CONTROL_BUFFER_SIZE) |
@@ -733,11 +764,34 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
733 | le32_to_cpu(u.get_c->status)); | 764 | le32_to_cpu(u.get_c->status)); |
734 | 765 | ||
735 | if (ret == 0) { | 766 | if (ret == 0) { |
736 | memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); | 767 | resplen = le32_to_cpu(u.get_c->len); |
768 | respoffs = le32_to_cpu(u.get_c->offset) + 8; | ||
737 | 769 | ||
738 | ret = le32_to_cpu(u.get_c->len); | 770 | if (respoffs > buflen) { |
739 | if (ret > *len) | 771 | /* Device returned data offset outside buffer, error. */ |
740 | *len = ret; | 772 | netdev_dbg(dev->net, "%s(%s): received invalid " |
773 | "data offset: %d > %d\n", __func__, | ||
774 | oid_to_string(oid), respoffs, buflen); | ||
775 | |||
776 | ret = -EINVAL; | ||
777 | goto exit_unlock; | ||
778 | } | ||
779 | |||
780 | if ((resplen + respoffs) > buflen) { | ||
781 | /* Device would have returned more data if buffer would | ||
782 | * have been big enough. Copy just the bits that we got. | ||
783 | */ | ||
784 | copylen = buflen - respoffs; | ||
785 | } else { | ||
786 | copylen = resplen; | ||
787 | } | ||
788 | |||
789 | if (copylen > *len) | ||
790 | copylen = *len; | ||
791 | |||
792 | memcpy(data, u.buf + respoffs, copylen); | ||
793 | |||
794 | *len = resplen; | ||
741 | 795 | ||
742 | ret = rndis_error_status(u.get_c->status); | 796 | ret = rndis_error_status(u.get_c->status); |
743 | if (ret < 0) | 797 | if (ret < 0) |
@@ -746,6 +800,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
746 | le32_to_cpu(u.get_c->status), ret); | 800 | le32_to_cpu(u.get_c->status), ret); |
747 | } | 801 | } |
748 | 802 | ||
803 | exit_unlock: | ||
749 | mutex_unlock(&priv->command_lock); | 804 | mutex_unlock(&priv->command_lock); |
750 | 805 | ||
751 | if (u.buf != priv->command_buffer) | 806 | if (u.buf != priv->command_buffer) |
@@ -1091,8 +1146,6 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version, | |||
1091 | } | 1146 | } |
1092 | 1147 | ||
1093 | priv->wpa_version = wpa_version; | 1148 | priv->wpa_version = wpa_version; |
1094 | priv->wpa_auth_type = auth_type; | ||
1095 | priv->wpa_keymgmt = keymgmt; | ||
1096 | 1149 | ||
1097 | return 0; | 1150 | return 0; |
1098 | } | 1151 | } |
@@ -1117,7 +1170,6 @@ static int set_priv_filter(struct usbnet *usbdev) | |||
1117 | 1170 | ||
1118 | static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | 1171 | static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) |
1119 | { | 1172 | { |
1120 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | ||
1121 | __le32 tmp; | 1173 | __le32 tmp; |
1122 | int encr_mode, ret; | 1174 | int encr_mode, ret; |
1123 | 1175 | ||
@@ -1146,8 +1198,6 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | |||
1146 | return ret; | 1198 | return ret; |
1147 | } | 1199 | } |
1148 | 1200 | ||
1149 | priv->wpa_cipher_pair = pairwise; | ||
1150 | priv->wpa_cipher_group = groupwise; | ||
1151 | return 0; | 1201 | return 0; |
1152 | } | 1202 | } |
1153 | 1203 | ||
@@ -1568,6 +1618,194 @@ set_filter: | |||
1568 | le32_to_cpu(filter), ret); | 1618 | le32_to_cpu(filter), ret); |
1569 | } | 1619 | } |
1570 | 1620 | ||
1621 | #ifdef DEBUG | ||
1622 | static void debug_print_pmkids(struct usbnet *usbdev, | ||
1623 | struct ndis_80211_pmkid *pmkids, | ||
1624 | const char *func_str) | ||
1625 | { | ||
1626 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | ||
1627 | int i, len, count, max_pmkids, entry_len; | ||
1628 | |||
1629 | max_pmkids = priv->wdev.wiphy->max_num_pmkids; | ||
1630 | len = le32_to_cpu(pmkids->length); | ||
1631 | count = le32_to_cpu(pmkids->bssid_info_count); | ||
1632 | |||
1633 | entry_len = (count > 0) ? (len - sizeof(*pmkids)) / count : -1; | ||
1634 | |||
1635 | netdev_dbg(usbdev->net, "%s(): %d PMKIDs (data len: %d, entry len: " | ||
1636 | "%d)\n", func_str, count, len, entry_len); | ||
1637 | |||
1638 | if (count > max_pmkids) | ||
1639 | count = max_pmkids; | ||
1640 | |||
1641 | for (i = 0; i < count; i++) { | ||
1642 | u32 *tmp = (u32 *)pmkids->bssid_info[i].pmkid; | ||
1643 | |||
1644 | netdev_dbg(usbdev->net, "%s(): bssid: %pM, " | ||
1645 | "pmkid: %08X:%08X:%08X:%08X\n", | ||
1646 | func_str, pmkids->bssid_info[i].bssid, | ||
1647 | cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]), | ||
1648 | cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3])); | ||
1649 | } | ||
1650 | } | ||
1651 | #else | ||
1652 | static void debug_print_pmkids(struct usbnet *usbdev, | ||
1653 | struct ndis_80211_pmkid *pmkids, | ||
1654 | const char *func_str) | ||
1655 | { | ||
1656 | return; | ||
1657 | } | ||
1658 | #endif | ||
1659 | |||
1660 | static struct ndis_80211_pmkid *get_device_pmkids(struct usbnet *usbdev) | ||
1661 | { | ||
1662 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | ||
1663 | struct ndis_80211_pmkid *pmkids; | ||
1664 | int len, ret, max_pmkids; | ||
1665 | |||
1666 | max_pmkids = priv->wdev.wiphy->max_num_pmkids; | ||
1667 | len = sizeof(*pmkids) + max_pmkids * sizeof(pmkids->bssid_info[0]); | ||
1668 | |||
1669 | pmkids = kzalloc(len, GFP_KERNEL); | ||
1670 | if (!pmkids) | ||
1671 | return ERR_PTR(-ENOMEM); | ||
1672 | |||
1673 | pmkids->length = cpu_to_le32(len); | ||
1674 | pmkids->bssid_info_count = cpu_to_le32(max_pmkids); | ||
1675 | |||
1676 | ret = rndis_query_oid(usbdev, OID_802_11_PMKID, pmkids, &len); | ||
1677 | if (ret < 0) { | ||
1678 | netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d)" | ||
1679 | " -> %d\n", __func__, len, max_pmkids, ret); | ||
1680 | |||
1681 | kfree(pmkids); | ||
1682 | return ERR_PTR(ret); | ||
1683 | } | ||
1684 | |||
1685 | if (le32_to_cpu(pmkids->bssid_info_count) > max_pmkids) | ||
1686 | pmkids->bssid_info_count = cpu_to_le32(max_pmkids); | ||
1687 | |||
1688 | debug_print_pmkids(usbdev, pmkids, __func__); | ||
1689 | |||
1690 | return pmkids; | ||
1691 | } | ||
1692 | |||
1693 | static int set_device_pmkids(struct usbnet *usbdev, | ||
1694 | struct ndis_80211_pmkid *pmkids) | ||
1695 | { | ||
1696 | int ret, len, num_pmkids; | ||
1697 | |||
1698 | num_pmkids = le32_to_cpu(pmkids->bssid_info_count); | ||
1699 | len = sizeof(*pmkids) + num_pmkids * sizeof(pmkids->bssid_info[0]); | ||
1700 | pmkids->length = cpu_to_le32(len); | ||
1701 | |||
1702 | debug_print_pmkids(usbdev, pmkids, __func__); | ||
1703 | |||
1704 | ret = rndis_set_oid(usbdev, OID_802_11_PMKID, pmkids, | ||
1705 | le32_to_cpu(pmkids->length)); | ||
1706 | if (ret < 0) { | ||
1707 | netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d) -> %d" | ||
1708 | "\n", __func__, len, num_pmkids, ret); | ||
1709 | } | ||
1710 | |||
1711 | kfree(pmkids); | ||
1712 | return ret; | ||
1713 | } | ||
1714 | |||
1715 | static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev, | ||
1716 | struct ndis_80211_pmkid *pmkids, | ||
1717 | struct cfg80211_pmksa *pmksa, | ||
1718 | int max_pmkids) | ||
1719 | { | ||
1720 | int i, len, count, newlen, err; | ||
1721 | |||
1722 | len = le32_to_cpu(pmkids->length); | ||
1723 | count = le32_to_cpu(pmkids->bssid_info_count); | ||
1724 | |||
1725 | if (count > max_pmkids) | ||
1726 | count = max_pmkids; | ||
1727 | |||
1728 | for (i = 0; i < count; i++) | ||
1729 | if (!compare_ether_addr(pmkids->bssid_info[i].bssid, | ||
1730 | pmksa->bssid)) | ||
1731 | break; | ||
1732 | |||
1733 | /* pmkid not found */ | ||
1734 | if (i == count) { | ||
1735 | netdev_dbg(usbdev->net, "%s(): bssid not found (%pM)\n", | ||
1736 | __func__, pmksa->bssid); | ||
1737 | err = -ENOENT; | ||
1738 | goto error; | ||
1739 | } | ||
1740 | |||
1741 | for (; i + 1 < count; i++) | ||
1742 | pmkids->bssid_info[i] = pmkids->bssid_info[i + 1]; | ||
1743 | |||
1744 | count--; | ||
1745 | newlen = sizeof(*pmkids) + count * sizeof(pmkids->bssid_info[0]); | ||
1746 | |||
1747 | pmkids->length = cpu_to_le32(newlen); | ||
1748 | pmkids->bssid_info_count = cpu_to_le32(count); | ||
1749 | |||
1750 | return pmkids; | ||
1751 | error: | ||
1752 | kfree(pmkids); | ||
1753 | return ERR_PTR(err); | ||
1754 | } | ||
1755 | |||
1756 | static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, | ||
1757 | struct ndis_80211_pmkid *pmkids, | ||
1758 | struct cfg80211_pmksa *pmksa, | ||
1759 | int max_pmkids) | ||
1760 | { | ||
1761 | int i, err, len, count, newlen; | ||
1762 | |||
1763 | len = le32_to_cpu(pmkids->length); | ||
1764 | count = le32_to_cpu(pmkids->bssid_info_count); | ||
1765 | |||
1766 | if (count > max_pmkids) | ||
1767 | count = max_pmkids; | ||
1768 | |||
1769 | /* update with new pmkid */ | ||
1770 | for (i = 0; i < count; i++) { | ||
1771 | if (compare_ether_addr(pmkids->bssid_info[i].bssid, | ||
1772 | pmksa->bssid)) | ||
1773 | continue; | ||
1774 | |||
1775 | memcpy(pmkids->bssid_info[i].pmkid, pmksa->pmkid, | ||
1776 | WLAN_PMKID_LEN); | ||
1777 | |||
1778 | return pmkids; | ||
1779 | } | ||
1780 | |||
1781 | /* out of space, return error */ | ||
1782 | if (i == max_pmkids) { | ||
1783 | netdev_dbg(usbdev->net, "%s(): out of space\n", __func__); | ||
1784 | err = -ENOSPC; | ||
1785 | goto error; | ||
1786 | } | ||
1787 | |||
1788 | /* add new pmkid */ | ||
1789 | newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]); | ||
1790 | |||
1791 | pmkids = krealloc(pmkids, newlen, GFP_KERNEL); | ||
1792 | if (!pmkids) { | ||
1793 | err = -ENOMEM; | ||
1794 | goto error; | ||
1795 | } | ||
1796 | |||
1797 | pmkids->length = cpu_to_le32(newlen); | ||
1798 | pmkids->bssid_info_count = cpu_to_le32(count + 1); | ||
1799 | |||
1800 | memcpy(pmkids->bssid_info[count].bssid, pmksa->bssid, ETH_ALEN); | ||
1801 | memcpy(pmkids->bssid_info[count].pmkid, pmksa->pmkid, WLAN_PMKID_LEN); | ||
1802 | |||
1803 | return pmkids; | ||
1804 | error: | ||
1805 | kfree(pmkids); | ||
1806 | return ERR_PTR(err); | ||
1807 | } | ||
1808 | |||
1571 | /* | 1809 | /* |
1572 | * cfg80211 ops | 1810 | * cfg80211 ops |
1573 | */ | 1811 | */ |
@@ -2178,6 +2416,78 @@ static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev, | |||
2178 | return 0; | 2416 | return 0; |
2179 | } | 2417 | } |
2180 | 2418 | ||
2419 | static int rndis_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
2420 | struct cfg80211_pmksa *pmksa) | ||
2421 | { | ||
2422 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); | ||
2423 | struct usbnet *usbdev = priv->usbdev; | ||
2424 | struct ndis_80211_pmkid *pmkids; | ||
2425 | u32 *tmp = (u32 *)pmksa->pmkid; | ||
2426 | |||
2427 | netdev_dbg(usbdev->net, "%s(%pM, %08X:%08X:%08X:%08X)\n", __func__, | ||
2428 | pmksa->bssid, | ||
2429 | cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]), | ||
2430 | cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3])); | ||
2431 | |||
2432 | pmkids = get_device_pmkids(usbdev); | ||
2433 | if (IS_ERR(pmkids)) { | ||
2434 | /* couldn't read PMKID cache from device */ | ||
2435 | return PTR_ERR(pmkids); | ||
2436 | } | ||
2437 | |||
2438 | pmkids = update_pmkid(usbdev, pmkids, pmksa, wiphy->max_num_pmkids); | ||
2439 | if (IS_ERR(pmkids)) { | ||
2440 | /* not found, list full, etc */ | ||
2441 | return PTR_ERR(pmkids); | ||
2442 | } | ||
2443 | |||
2444 | return set_device_pmkids(usbdev, pmkids); | ||
2445 | } | ||
2446 | |||
2447 | static int rndis_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, | ||
2448 | struct cfg80211_pmksa *pmksa) | ||
2449 | { | ||
2450 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); | ||
2451 | struct usbnet *usbdev = priv->usbdev; | ||
2452 | struct ndis_80211_pmkid *pmkids; | ||
2453 | u32 *tmp = (u32 *)pmksa->pmkid; | ||
2454 | |||
2455 | netdev_dbg(usbdev->net, "%s(%pM, %08X:%08X:%08X:%08X)\n", __func__, | ||
2456 | pmksa->bssid, | ||
2457 | cpu_to_be32(tmp[0]), cpu_to_be32(tmp[1]), | ||
2458 | cpu_to_be32(tmp[2]), cpu_to_be32(tmp[3])); | ||
2459 | |||
2460 | pmkids = get_device_pmkids(usbdev); | ||
2461 | if (IS_ERR(pmkids)) { | ||
2462 | /* Couldn't read PMKID cache from device */ | ||
2463 | return PTR_ERR(pmkids); | ||
2464 | } | ||
2465 | |||
2466 | pmkids = remove_pmkid(usbdev, pmkids, pmksa, wiphy->max_num_pmkids); | ||
2467 | if (IS_ERR(pmkids)) { | ||
2468 | /* not found, etc */ | ||
2469 | return PTR_ERR(pmkids); | ||
2470 | } | ||
2471 | |||
2472 | return set_device_pmkids(usbdev, pmkids); | ||
2473 | } | ||
2474 | |||
2475 | static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) | ||
2476 | { | ||
2477 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); | ||
2478 | struct usbnet *usbdev = priv->usbdev; | ||
2479 | struct ndis_80211_pmkid pmkid; | ||
2480 | |||
2481 | netdev_dbg(usbdev->net, "%s()\n", __func__); | ||
2482 | |||
2483 | memset(&pmkid, 0, sizeof(pmkid)); | ||
2484 | |||
2485 | pmkid.length = cpu_to_le32(sizeof(pmkid)); | ||
2486 | pmkid.bssid_info_count = cpu_to_le32(0); | ||
2487 | |||
2488 | return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid)); | ||
2489 | } | ||
2490 | |||
2181 | /* | 2491 | /* |
2182 | * workers, indication handlers, device poller | 2492 | * workers, indication handlers, device poller |
2183 | */ | 2493 | */ |
@@ -2522,12 +2832,14 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen) | |||
2522 | } | 2832 | } |
2523 | } | 2833 | } |
2524 | 2834 | ||
2525 | static int rndis_wlan_get_caps(struct usbnet *usbdev) | 2835 | static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy) |
2526 | { | 2836 | { |
2527 | struct { | 2837 | struct { |
2528 | __le32 num_items; | 2838 | __le32 num_items; |
2529 | __le32 items[8]; | 2839 | __le32 items[8]; |
2530 | } networks_supported; | 2840 | } networks_supported; |
2841 | struct ndis_80211_capability *caps; | ||
2842 | u8 caps_buf[sizeof(*caps) + sizeof(caps->auth_encr_pair) * 16]; | ||
2531 | int len, retval, i, n; | 2843 | int len, retval, i, n; |
2532 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 2844 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2533 | 2845 | ||
@@ -2555,6 +2867,21 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev) | |||
2555 | } | 2867 | } |
2556 | } | 2868 | } |
2557 | 2869 | ||
2870 | /* get device 802.11 capabilities, number of PMKIDs */ | ||
2871 | caps = (struct ndis_80211_capability *)caps_buf; | ||
2872 | len = sizeof(caps_buf); | ||
2873 | retval = rndis_query_oid(usbdev, OID_802_11_CAPABILITY, caps, &len); | ||
2874 | if (retval >= 0) { | ||
2875 | netdev_dbg(usbdev->net, "OID_802_11_CAPABILITY -> len %d, " | ||
2876 | "ver %d, pmkids %d, auth-encr-pairs %d\n", | ||
2877 | le32_to_cpu(caps->length), | ||
2878 | le32_to_cpu(caps->version), | ||
2879 | le32_to_cpu(caps->num_pmkids), | ||
2880 | le32_to_cpu(caps->num_auth_encr_pair)); | ||
2881 | wiphy->max_num_pmkids = le32_to_cpu(caps->num_pmkids); | ||
2882 | } else | ||
2883 | wiphy->max_num_pmkids = 0; | ||
2884 | |||
2558 | return retval; | 2885 | return retval; |
2559 | } | 2886 | } |
2560 | 2887 | ||
@@ -2802,7 +3129,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2802 | wiphy->max_scan_ssids = 1; | 3129 | wiphy->max_scan_ssids = 1; |
2803 | 3130 | ||
2804 | /* TODO: fill-out band/encr information based on priv->caps */ | 3131 | /* TODO: fill-out band/encr information based on priv->caps */ |
2805 | rndis_wlan_get_caps(usbdev); | 3132 | rndis_wlan_get_caps(usbdev, wiphy); |
2806 | 3133 | ||
2807 | memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); | 3134 | memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); |
2808 | memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); | 3135 | memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); |
@@ -2862,9 +3189,6 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2862 | flush_workqueue(priv->workqueue); | 3189 | flush_workqueue(priv->workqueue); |
2863 | destroy_workqueue(priv->workqueue); | 3190 | destroy_workqueue(priv->workqueue); |
2864 | 3191 | ||
2865 | if (priv && priv->wpa_ie_len) | ||
2866 | kfree(priv->wpa_ie); | ||
2867 | |||
2868 | rndis_unbind(usbdev, intf); | 3192 | rndis_unbind(usbdev, intf); |
2869 | 3193 | ||
2870 | wiphy_unregister(priv->wdev.wiphy); | 3194 | wiphy_unregister(priv->wdev.wiphy); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 91cce2d0f6db..b1f5643f83fc 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -907,14 +907,12 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
907 | { | 907 | { |
908 | struct data_queue *queue; | 908 | struct data_queue *queue; |
909 | struct queue_entry *entry; | 909 | struct queue_entry *entry; |
910 | struct queue_entry *entry_done; | 910 | __le32 *txwi; |
911 | struct queue_entry_priv_pci *entry_priv; | ||
912 | struct txdone_entry_desc txdesc; | 911 | struct txdone_entry_desc txdesc; |
913 | u32 word; | 912 | u32 word; |
914 | u32 reg; | 913 | u32 reg; |
915 | u32 old_reg; | 914 | u32 old_reg; |
916 | unsigned int type; | 915 | int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; |
917 | unsigned int index; | ||
918 | u16 mcs, real_mcs; | 916 | u16 mcs, real_mcs; |
919 | 917 | ||
920 | /* | 918 | /* |
@@ -936,71 +934,76 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
936 | break; | 934 | break; |
937 | old_reg = reg; | 935 | old_reg = reg; |
938 | 936 | ||
937 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
938 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
939 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
940 | |||
939 | /* | 941 | /* |
940 | * Skip this entry when it contains an invalid | 942 | * Skip this entry when it contains an invalid |
941 | * queue identication number. | 943 | * queue identication number. |
942 | */ | 944 | */ |
943 | type = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE) - 1; | 945 | if (pid <= 0 || pid > QID_RX) |
944 | if (type >= QID_RX) | ||
945 | continue; | 946 | continue; |
946 | 947 | ||
947 | queue = rt2x00queue_get_queue(rt2x00dev, type); | 948 | queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); |
948 | if (unlikely(!queue)) | 949 | if (unlikely(!queue)) |
949 | continue; | 950 | continue; |
950 | 951 | ||
951 | /* | 952 | /* |
952 | * Skip this entry when it contains an invalid | 953 | * Inside each queue, we process each entry in a chronological |
953 | * index number. | 954 | * order. We first check that the queue is not empty. |
954 | */ | 955 | */ |
955 | index = rt2x00_get_field32(reg, TX_STA_FIFO_WCID) - 1; | 956 | if (rt2x00queue_empty(queue)) |
956 | if (unlikely(index >= queue->limit)) | ||
957 | continue; | 957 | continue; |
958 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
958 | 959 | ||
959 | entry = &queue->entries[index]; | 960 | /* Check if we got a match by looking at WCID/ACK/PID |
960 | entry_priv = entry->priv_data; | 961 | * fields */ |
961 | rt2x00_desc_read((__le32 *)entry->skb->data, 0, &word); | 962 | txwi = (__le32 *)(entry->skb->data - |
962 | 963 | rt2x00dev->ops->extra_tx_headroom); | |
963 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
964 | while (entry != entry_done) { | ||
965 | /* | ||
966 | * Catch up. | ||
967 | * Just report any entries we missed as failed. | ||
968 | */ | ||
969 | WARNING(rt2x00dev, | ||
970 | "TX status report missed for entry %d\n", | ||
971 | entry_done->entry_idx); | ||
972 | 964 | ||
973 | txdesc.flags = 0; | 965 | rt2x00_desc_read(txwi, 1, &word); |
974 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); | 966 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); |
975 | txdesc.retry = 0; | 967 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); |
968 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
976 | 969 | ||
977 | rt2x00lib_txdone(entry_done, &txdesc); | 970 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) |
978 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 971 | WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n"); |
979 | } | ||
980 | 972 | ||
981 | /* | 973 | /* |
982 | * Obtain the status about this packet. | 974 | * Obtain the status about this packet. |
983 | */ | 975 | */ |
984 | txdesc.flags = 0; | 976 | txdesc.flags = 0; |
985 | if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) | 977 | rt2x00_desc_read(txwi, 0, &word); |
986 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | 978 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); |
987 | else | 979 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); |
988 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
989 | 980 | ||
990 | /* | 981 | /* |
991 | * Ralink has a retry mechanism using a global fallback | 982 | * Ralink has a retry mechanism using a global fallback |
992 | * table. We setup this fallback table to try immediate | 983 | * table. We setup this fallback table to try the immediate |
993 | * lower rate for all rates. In the TX_STA_FIFO, | 984 | * lower rate for all rates. In the TX_STA_FIFO, the MCS field |
994 | * the MCS field contains the MCS used for the successfull | 985 | * always contains the MCS used for the last transmission, be |
995 | * transmission. If the first transmission succeed, | 986 | * it successful or not. |
996 | * we have mcs == tx_mcs. On the second transmission, | ||
997 | * we have mcs = tx_mcs - 1. So the number of | ||
998 | * retry is (tx_mcs - mcs). | ||
999 | */ | 987 | */ |
1000 | mcs = rt2x00_get_field32(word, TXWI_W0_MCS); | 988 | if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { |
1001 | real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); | 989 | /* |
990 | * Transmission succeeded. The number of retries is | ||
991 | * mcs - real_mcs | ||
992 | */ | ||
993 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
994 | txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); | ||
995 | } else { | ||
996 | /* | ||
997 | * Transmission failed. The number of retries is | ||
998 | * always 7 in this case (for a total number of 8 | ||
999 | * frames sent). | ||
1000 | */ | ||
1001 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
1002 | txdesc.retry = 7; | ||
1003 | } | ||
1004 | |||
1002 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | 1005 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); |
1003 | txdesc.retry = mcs - min(mcs, real_mcs); | 1006 | |
1004 | 1007 | ||
1005 | rt2x00lib_txdone(entry, &txdesc); | 1008 | rt2x00lib_txdone(entry, &txdesc); |
1006 | } | 1009 | } |
@@ -1184,6 +1187,7 @@ static const struct rt2x00_ops rt2800pci_ops = { | |||
1184 | /* | 1187 | /* |
1185 | * RT2800pci module information. | 1188 | * RT2800pci module information. |
1186 | */ | 1189 | */ |
1190 | #ifdef CONFIG_RT2800PCI_PCI | ||
1187 | static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | 1191 | static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { |
1188 | { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1192 | { PCI_DEVICE(0x1814, 0x0601), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1189 | { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1193 | { PCI_DEVICE(0x1814, 0x0681), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
@@ -1211,6 +1215,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | |||
1211 | #endif | 1215 | #endif |
1212 | { 0, } | 1216 | { 0, } |
1213 | }; | 1217 | }; |
1218 | #endif /* CONFIG_RT2800PCI_PCI */ | ||
1214 | 1219 | ||
1215 | MODULE_AUTHOR(DRV_PROJECT); | 1220 | MODULE_AUTHOR(DRV_PROJECT); |
1216 | MODULE_VERSION(DRV_VERSION); | 1221 | MODULE_VERSION(DRV_VERSION); |
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 785e0244e305..337fc7bec5a5 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig | |||
@@ -51,3 +51,27 @@ config WL1271 | |||
51 | 51 | ||
52 | If you choose to build a module, it'll be called wl1271. Say N if | 52 | If you choose to build a module, it'll be called wl1271. Say N if |
53 | unsure. | 53 | unsure. |
54 | |||
55 | config WL1271_SPI | ||
56 | tristate "TI wl1271 SPI support" | ||
57 | depends on WL1271 && SPI_MASTER | ||
58 | ---help--- | ||
59 | This module adds support for the SPI interface of adapters using | ||
60 | TI wl1271 chipset. Select this if your platform is using | ||
61 | the SPI bus. | ||
62 | |||
63 | If you choose to build a module, it'll be called wl1251_spi. | ||
64 | Say N if unsure. | ||
65 | |||
66 | config WL1271_SDIO | ||
67 | tristate "TI wl1271 SDIO support" | ||
68 | depends on WL1271 && MMC && ARM | ||
69 | ---help--- | ||
70 | This module adds support for the SDIO interface of adapters using | ||
71 | TI wl1271 chipset. Select this if your platform is using | ||
72 | the SDIO bus. | ||
73 | |||
74 | If you choose to build a module, it'll be called | ||
75 | wl1271_sdio. Say N if unsure. | ||
76 | |||
77 | |||
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index f47ec94c16dc..27ddd2be0a91 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile | |||
@@ -7,10 +7,12 @@ obj-$(CONFIG_WL1251) += wl1251.o | |||
7 | obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o | 7 | obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o |
8 | obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o | 8 | obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o |
9 | 9 | ||
10 | wl1271-objs = wl1271_main.o wl1271_spi.o wl1271_cmd.o \ | 10 | wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \ |
11 | wl1271_event.o wl1271_tx.o wl1271_rx.o \ | 11 | wl1271_event.o wl1271_tx.o wl1271_rx.o \ |
12 | wl1271_ps.o wl1271_acx.o wl1271_boot.o \ | 12 | wl1271_ps.o wl1271_acx.o wl1271_boot.o \ |
13 | wl1271_init.o wl1271_debugfs.o wl1271_io.o | 13 | wl1271_init.o wl1271_debugfs.o |
14 | 14 | ||
15 | wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o | 15 | wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o |
16 | obj-$(CONFIG_WL1271) += wl1271.o | 16 | obj-$(CONFIG_WL1271) += wl1271.o |
17 | obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o | ||
18 | obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 37c61c19cae5..4f5f02a26e62 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h | |||
@@ -256,6 +256,8 @@ struct wl1251_debugfs { | |||
256 | struct wl1251_if_operations { | 256 | struct wl1251_if_operations { |
257 | void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len); | 257 | void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len); |
258 | void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); | 258 | void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len); |
259 | void (*read_elp)(struct wl1251 *wl, int addr, u32 *val); | ||
260 | void (*write_elp)(struct wl1251 *wl, int addr, u32 val); | ||
259 | void (*reset)(struct wl1251 *wl); | 261 | void (*reset)(struct wl1251 *wl); |
260 | void (*enable_irq)(struct wl1251 *wl); | 262 | void (*enable_irq)(struct wl1251 *wl); |
261 | void (*disable_irq)(struct wl1251 *wl); | 263 | void (*disable_irq)(struct wl1251 *wl); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c index 28a808674080..acb334184d70 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl12xx/wl1251_boot.c | |||
@@ -496,7 +496,8 @@ int wl1251_boot(struct wl1251 *wl) | |||
496 | /* 2. start processing NVS file */ | 496 | /* 2. start processing NVS file */ |
497 | if (wl->use_eeprom) { | 497 | if (wl->use_eeprom) { |
498 | wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); | 498 | wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR); |
499 | msleep(4000); | 499 | /* Wait for EEPROM NVS burst read to complete */ |
500 | msleep(40); | ||
500 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); | 501 | wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM); |
501 | } else { | 502 | } else { |
502 | ret = wl1251_boot_upload_nvs(wl); | 503 | ret = wl1251_boot_upload_nvs(wl); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h index b89d2ac62efb..c545e9d5f512 100644 --- a/drivers/net/wireless/wl12xx/wl1251_io.h +++ b/drivers/net/wireless/wl12xx/wl1251_io.h | |||
@@ -48,6 +48,26 @@ static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val) | |||
48 | wl->if_ops->write(wl, addr, &val, sizeof(u32)); | 48 | wl->if_ops->write(wl, addr, &val, sizeof(u32)); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr) | ||
52 | { | ||
53 | u32 response; | ||
54 | |||
55 | if (wl->if_ops->read_elp) | ||
56 | wl->if_ops->read_elp(wl, addr, &response); | ||
57 | else | ||
58 | wl->if_ops->read(wl, addr, &response, sizeof(u32)); | ||
59 | |||
60 | return response; | ||
61 | } | ||
62 | |||
63 | static inline void wl1251_write_elp(struct wl1251 *wl, int addr, u32 val) | ||
64 | { | ||
65 | if (wl->if_ops->write_elp) | ||
66 | wl->if_ops->write_elp(wl, addr, val); | ||
67 | else | ||
68 | wl->if_ops->write(wl, addr, &val, sizeof(u32)); | ||
69 | } | ||
70 | |||
51 | /* Memory target IO, address is translated to partition 0 */ | 71 | /* Memory target IO, address is translated to partition 0 */ |
52 | void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len); | 72 | void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len); |
53 | void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len); | 73 | void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 24ae6a360ac8..0155653b7105 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c | |||
@@ -146,8 +146,8 @@ static void wl1251_fw_wakeup(struct wl1251 *wl) | |||
146 | u32 elp_reg; | 146 | u32 elp_reg; |
147 | 147 | ||
148 | elp_reg = ELPCTRL_WAKE_UP; | 148 | elp_reg = ELPCTRL_WAKE_UP; |
149 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); | 149 | wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg); |
150 | elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); | 150 | elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); |
151 | 151 | ||
152 | if (!(elp_reg & ELPCTRL_WLAN_READY)) | 152 | if (!(elp_reg & ELPCTRL_WLAN_READY)) |
153 | wl1251_warning("WLAN not ready"); | 153 | wl1251_warning("WLAN not ready"); |
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c index 851dfb65e474..b55cb2bd459a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ b/drivers/net/wireless/wl12xx/wl1251_ps.c | |||
@@ -45,7 +45,7 @@ void wl1251_elp_work(struct work_struct *work) | |||
45 | goto out; | 45 | goto out; |
46 | 46 | ||
47 | wl1251_debug(DEBUG_PSM, "chip to elp"); | 47 | wl1251_debug(DEBUG_PSM, "chip to elp"); |
48 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); | 48 | wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); |
49 | wl->elp = true; | 49 | wl->elp = true; |
50 | 50 | ||
51 | out: | 51 | out: |
@@ -79,9 +79,9 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl) | |||
79 | start = jiffies; | 79 | start = jiffies; |
80 | timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); | 80 | timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); |
81 | 81 | ||
82 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); | 82 | wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); |
83 | 83 | ||
84 | elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); | 84 | elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * FIXME: we should wait for irq from chip but, as a temporary | 87 | * FIXME: we should wait for irq from chip but, as a temporary |
@@ -93,7 +93,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl) | |||
93 | return -ETIMEDOUT; | 93 | return -ETIMEDOUT; |
94 | } | 94 | } |
95 | msleep(1); | 95 | msleep(1); |
96 | elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); | 96 | elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR); |
97 | } | 97 | } |
98 | 98 | ||
99 | wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", | 99 | wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", |
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c index 9423f22bdced..2051ef06e9ec 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c | |||
@@ -20,20 +20,11 @@ | |||
20 | * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com) | 20 | * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com) |
21 | */ | 21 | */ |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/crc7.h> | ||
24 | #include <linux/mod_devicetable.h> | 23 | #include <linux/mod_devicetable.h> |
25 | #include <linux/irq.h> | ||
26 | #include <linux/mmc/sdio_func.h> | 24 | #include <linux/mmc/sdio_func.h> |
27 | #include <linux/mmc/sdio_ids.h> | 25 | #include <linux/mmc/sdio_ids.h> |
28 | #include <linux/platform_device.h> | ||
29 | 26 | ||
30 | #include "wl1251.h" | 27 | #include "wl1251.h" |
31 | #include "wl12xx_80211.h" | ||
32 | #include "wl1251_reg.h" | ||
33 | #include "wl1251_ps.h" | ||
34 | #include "wl1251_io.h" | ||
35 | #include "wl1251_tx.h" | ||
36 | #include "wl1251_debugfs.h" | ||
37 | 28 | ||
38 | #ifndef SDIO_VENDOR_ID_TI | 29 | #ifndef SDIO_VENDOR_ID_TI |
39 | #define SDIO_VENDOR_ID_TI 0x104c | 30 | #define SDIO_VENDOR_ID_TI 0x104c |
@@ -65,7 +56,8 @@ static const struct sdio_device_id wl1251_devices[] = { | |||
65 | MODULE_DEVICE_TABLE(sdio, wl1251_devices); | 56 | MODULE_DEVICE_TABLE(sdio, wl1251_devices); |
66 | 57 | ||
67 | 58 | ||
68 | void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len) | 59 | static void wl1251_sdio_read(struct wl1251 *wl, int addr, |
60 | void *buf, size_t len) | ||
69 | { | 61 | { |
70 | int ret; | 62 | int ret; |
71 | struct sdio_func *func = wl_to_func(wl); | 63 | struct sdio_func *func = wl_to_func(wl); |
@@ -77,7 +69,8 @@ void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len) | |||
77 | sdio_release_host(func); | 69 | sdio_release_host(func); |
78 | } | 70 | } |
79 | 71 | ||
80 | void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len) | 72 | static void wl1251_sdio_write(struct wl1251 *wl, int addr, |
73 | void *buf, size_t len) | ||
81 | { | 74 | { |
82 | int ret; | 75 | int ret; |
83 | struct sdio_func *func = wl_to_func(wl); | 76 | struct sdio_func *func = wl_to_func(wl); |
@@ -89,7 +82,33 @@ void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len) | |||
89 | sdio_release_host(func); | 82 | sdio_release_host(func); |
90 | } | 83 | } |
91 | 84 | ||
92 | void wl1251_sdio_reset(struct wl1251 *wl) | 85 | static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val) |
86 | { | ||
87 | int ret = 0; | ||
88 | struct sdio_func *func = wl_to_func(wl); | ||
89 | |||
90 | sdio_claim_host(func); | ||
91 | *val = sdio_readb(func, addr, &ret); | ||
92 | sdio_release_host(func); | ||
93 | |||
94 | if (ret) | ||
95 | wl1251_error("sdio_readb failed (%d)", ret); | ||
96 | } | ||
97 | |||
98 | static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val) | ||
99 | { | ||
100 | int ret = 0; | ||
101 | struct sdio_func *func = wl_to_func(wl); | ||
102 | |||
103 | sdio_claim_host(func); | ||
104 | sdio_writeb(func, val, addr, &ret); | ||
105 | sdio_release_host(func); | ||
106 | |||
107 | if (ret) | ||
108 | wl1251_error("sdio_writeb failed (%d)", ret); | ||
109 | } | ||
110 | |||
111 | static void wl1251_sdio_reset(struct wl1251 *wl) | ||
93 | { | 112 | { |
94 | } | 113 | } |
95 | 114 | ||
@@ -111,19 +130,22 @@ static void wl1251_sdio_disable_irq(struct wl1251 *wl) | |||
111 | sdio_release_host(func); | 130 | sdio_release_host(func); |
112 | } | 131 | } |
113 | 132 | ||
114 | void wl1251_sdio_set_power(bool enable) | 133 | static void wl1251_sdio_set_power(bool enable) |
115 | { | 134 | { |
116 | } | 135 | } |
117 | 136 | ||
118 | struct wl1251_if_operations wl1251_sdio_ops = { | 137 | static const struct wl1251_if_operations wl1251_sdio_ops = { |
119 | .read = wl1251_sdio_read, | 138 | .read = wl1251_sdio_read, |
120 | .write = wl1251_sdio_write, | 139 | .write = wl1251_sdio_write, |
140 | .write_elp = wl1251_sdio_write_elp, | ||
141 | .read_elp = wl1251_sdio_read_elp, | ||
121 | .reset = wl1251_sdio_reset, | 142 | .reset = wl1251_sdio_reset, |
122 | .enable_irq = wl1251_sdio_enable_irq, | 143 | .enable_irq = wl1251_sdio_enable_irq, |
123 | .disable_irq = wl1251_sdio_disable_irq, | 144 | .disable_irq = wl1251_sdio_disable_irq, |
124 | }; | 145 | }; |
125 | 146 | ||
126 | int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) | 147 | static int wl1251_sdio_probe(struct sdio_func *func, |
148 | const struct sdio_device_id *id) | ||
127 | { | 149 | { |
128 | int ret; | 150 | int ret; |
129 | struct wl1251 *wl; | 151 | struct wl1251 *wl; |
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 97ea5096bc8c..0deb4fdf916b 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h | |||
@@ -110,6 +110,9 @@ enum { | |||
110 | #define WL1271_FW_NAME "wl1271-fw.bin" | 110 | #define WL1271_FW_NAME "wl1271-fw.bin" |
111 | #define WL1271_NVS_NAME "wl1271-nvs.bin" | 111 | #define WL1271_NVS_NAME "wl1271-nvs.bin" |
112 | 112 | ||
113 | #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) | ||
114 | #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) | ||
115 | |||
113 | /* NVS data structure */ | 116 | /* NVS data structure */ |
114 | #define WL1271_NVS_SECTION_SIZE 468 | 117 | #define WL1271_NVS_SECTION_SIZE 468 |
115 | 118 | ||
@@ -334,11 +337,25 @@ struct wl1271_scan { | |||
334 | u8 probe_requests; | 337 | u8 probe_requests; |
335 | }; | 338 | }; |
336 | 339 | ||
340 | struct wl1271_if_operations { | ||
341 | void (*read)(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
342 | bool fixed); | ||
343 | void (*write)(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
344 | bool fixed); | ||
345 | void (*reset)(struct wl1271 *wl); | ||
346 | void (*init)(struct wl1271 *wl); | ||
347 | struct device* (*dev)(struct wl1271 *wl); | ||
348 | void (*enable_irq)(struct wl1271 *wl); | ||
349 | void (*disable_irq)(struct wl1271 *wl); | ||
350 | }; | ||
351 | |||
337 | struct wl1271 { | 352 | struct wl1271 { |
338 | struct ieee80211_hw *hw; | 353 | struct ieee80211_hw *hw; |
339 | bool mac80211_registered; | 354 | bool mac80211_registered; |
340 | 355 | ||
341 | struct spi_device *spi; | 356 | void *if_priv; |
357 | |||
358 | struct wl1271_if_operations *if_ops; | ||
342 | 359 | ||
343 | void (*set_power)(bool enable); | 360 | void (*set_power)(bool enable); |
344 | int irq; | 361 | int irq; |
@@ -357,6 +374,8 @@ struct wl1271 { | |||
357 | #define WL1271_FLAG_IN_ELP (6) | 374 | #define WL1271_FLAG_IN_ELP (6) |
358 | #define WL1271_FLAG_PSM (7) | 375 | #define WL1271_FLAG_PSM (7) |
359 | #define WL1271_FLAG_PSM_REQUESTED (8) | 376 | #define WL1271_FLAG_PSM_REQUESTED (8) |
377 | #define WL1271_FLAG_IRQ_PENDING (9) | ||
378 | #define WL1271_FLAG_IRQ_RUNNING (10) | ||
360 | unsigned long flags; | 379 | unsigned long flags; |
361 | 380 | ||
362 | struct wl1271_partition_set part; | 381 | struct wl1271_partition_set part; |
@@ -382,13 +401,13 @@ struct wl1271 { | |||
382 | /* Accounting for allocated / available TX blocks on HW */ | 401 | /* Accounting for allocated / available TX blocks on HW */ |
383 | u32 tx_blocks_freed[NUM_TX_QUEUES]; | 402 | u32 tx_blocks_freed[NUM_TX_QUEUES]; |
384 | u32 tx_blocks_available; | 403 | u32 tx_blocks_available; |
385 | u8 tx_results_count; | 404 | u32 tx_results_count; |
386 | 405 | ||
387 | /* Transmitted TX packets counter for chipset interface */ | 406 | /* Transmitted TX packets counter for chipset interface */ |
388 | int tx_packets_count; | 407 | u32 tx_packets_count; |
389 | 408 | ||
390 | /* Time-offset between host and chipset clocks */ | 409 | /* Time-offset between host and chipset clocks */ |
391 | int time_offset; | 410 | s64 time_offset; |
392 | 411 | ||
393 | /* Session counter for the chipset */ | 412 | /* Session counter for the chipset */ |
394 | int session_counter; | 413 | int session_counter; |
@@ -403,8 +422,7 @@ struct wl1271 { | |||
403 | 422 | ||
404 | /* Security sequence number counters */ | 423 | /* Security sequence number counters */ |
405 | u8 tx_security_last_seq; | 424 | u8 tx_security_last_seq; |
406 | u16 tx_security_seq_16; | 425 | s64 tx_security_seq; |
407 | u32 tx_security_seq_32; | ||
408 | 426 | ||
409 | /* FW Rx counter */ | 427 | /* FW Rx counter */ |
410 | u32 rx_counter; | 428 | u32 rx_counter; |
@@ -477,7 +495,8 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
477 | 495 | ||
478 | #define WL1271_DEFAULT_POWER_LEVEL 0 | 496 | #define WL1271_DEFAULT_POWER_LEVEL 0 |
479 | 497 | ||
480 | #define WL1271_TX_QUEUE_MAX_LENGTH 20 | 498 | #define WL1271_TX_QUEUE_LOW_WATERMARK 10 |
499 | #define WL1271_TX_QUEUE_HIGH_WATERMARK 25 | ||
481 | 500 | ||
482 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power | 501 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power |
483 | on in case is has been shut down shortly before */ | 502 | on in case is has been shut down shortly before */ |
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index 60f10dce4800..60e20876e6d8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include "wl1271.h" | 31 | #include "wl1271.h" |
32 | #include "wl12xx_80211.h" | 32 | #include "wl12xx_80211.h" |
33 | #include "wl1271_reg.h" | 33 | #include "wl1271_reg.h" |
34 | #include "wl1271_spi.h" | ||
35 | #include "wl1271_ps.h" | 34 | #include "wl1271_ps.h" |
36 | 35 | ||
37 | int wl1271_acx_wake_up_conditions(struct wl1271 *wl) | 36 | int wl1271_acx_wake_up_conditions(struct wl1271 *wl) |
@@ -136,12 +135,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power) | |||
136 | goto out; | 135 | goto out; |
137 | } | 136 | } |
138 | 137 | ||
139 | /* | 138 | acx->current_tx_power = power * 10; |
140 | * FIXME: This is a workaround needed while we don't the correct | ||
141 | * calibration, to avoid distortions | ||
142 | */ | ||
143 | /* acx->current_tx_power = power * 10; */ | ||
144 | acx->current_tx_power = 120; | ||
145 | 139 | ||
146 | ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); | 140 | ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx)); |
147 | if (ret < 0) { | 141 | if (ret < 0) { |
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index 2be76ee42bb9..f88d52e87e82 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "wl1271_acx.h" | 26 | #include "wl1271_acx.h" |
27 | #include "wl1271_reg.h" | 27 | #include "wl1271_reg.h" |
28 | #include "wl1271_boot.h" | 28 | #include "wl1271_boot.h" |
29 | #include "wl1271_spi.h" | ||
30 | #include "wl1271_io.h" | 29 | #include "wl1271_io.h" |
31 | #include "wl1271_event.h" | 30 | #include "wl1271_event.h" |
32 | 31 | ||
@@ -299,7 +298,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) | |||
299 | 298 | ||
300 | static void wl1271_boot_enable_interrupts(struct wl1271 *wl) | 299 | static void wl1271_boot_enable_interrupts(struct wl1271 *wl) |
301 | { | 300 | { |
302 | enable_irq(wl->irq); | 301 | wl1271_enable_interrupts(wl); |
303 | wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, | 302 | wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, |
304 | WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); | 303 | WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); |
305 | wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL); | 304 | wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL); |
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index 36a64e06f290..d59b3830a6a5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include "wl1271.h" | 30 | #include "wl1271.h" |
31 | #include "wl1271_reg.h" | 31 | #include "wl1271_reg.h" |
32 | #include "wl1271_spi.h" | ||
33 | #include "wl1271_io.h" | 32 | #include "wl1271_io.h" |
34 | #include "wl1271_acx.h" | 33 | #include "wl1271_acx.h" |
35 | #include "wl12xx_80211.h" | 34 | #include "wl12xx_80211.h" |
@@ -248,7 +247,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) | |||
248 | return ret; | 247 | return ret; |
249 | } | 248 | } |
250 | 249 | ||
251 | int wl1271_cmd_join(struct wl1271 *wl) | 250 | int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) |
252 | { | 251 | { |
253 | static bool do_cal = true; | 252 | static bool do_cal = true; |
254 | struct wl1271_cmd_join *join; | 253 | struct wl1271_cmd_join *join; |
@@ -279,7 +278,7 @@ int wl1271_cmd_join(struct wl1271 *wl) | |||
279 | 278 | ||
280 | join->rx_config_options = cpu_to_le32(wl->rx_config); | 279 | join->rx_config_options = cpu_to_le32(wl->rx_config); |
281 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); | 280 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); |
282 | join->bss_type = wl->bss_type; | 281 | join->bss_type = bss_type; |
283 | 282 | ||
284 | /* | 283 | /* |
285 | * FIXME: disable temporarily all filters because after commit | 284 | * FIXME: disable temporarily all filters because after commit |
@@ -319,8 +318,7 @@ int wl1271_cmd_join(struct wl1271 *wl) | |||
319 | 318 | ||
320 | /* reset TX security counters */ | 319 | /* reset TX security counters */ |
321 | wl->tx_security_last_seq = 0; | 320 | wl->tx_security_last_seq = 0; |
322 | wl->tx_security_seq_16 = 0; | 321 | wl->tx_security_seq = 0; |
323 | wl->tx_security_seq_32 = 0; | ||
324 | 322 | ||
325 | ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); | 323 | ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); |
326 | if (ret < 0) { | 324 | if (ret < 0) { |
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index 2dc06c73532b..4297205b8d6d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h | |||
@@ -33,7 +33,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, | |||
33 | size_t res_len); | 33 | size_t res_len); |
34 | int wl1271_cmd_general_parms(struct wl1271 *wl); | 34 | int wl1271_cmd_general_parms(struct wl1271 *wl); |
35 | int wl1271_cmd_radio_parms(struct wl1271 *wl); | 35 | int wl1271_cmd_radio_parms(struct wl1271 *wl); |
36 | int wl1271_cmd_join(struct wl1271 *wl); | 36 | int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); |
37 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); | 37 | int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); |
38 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); | 38 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); |
39 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); | 39 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); |
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index 7468ef10194b..5533519a1418 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include "wl1271.h" | 24 | #include "wl1271.h" |
25 | #include "wl1271_reg.h" | 25 | #include "wl1271_reg.h" |
26 | #include "wl1271_spi.h" | ||
27 | #include "wl1271_io.h" | 26 | #include "wl1271_io.h" |
28 | #include "wl1271_event.h" | 27 | #include "wl1271_event.h" |
29 | #include "wl1271_ps.h" | 28 | #include "wl1271_ps.h" |
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.c b/drivers/net/wireless/wl12xx/wl1271_io.c index 5cd94d5666c2..c8759acef131 100644 --- a/drivers/net/wireless/wl12xx/wl1271_io.c +++ b/drivers/net/wireless/wl12xx/wl1271_io.c | |||
@@ -28,30 +28,29 @@ | |||
28 | 28 | ||
29 | #include "wl1271.h" | 29 | #include "wl1271.h" |
30 | #include "wl12xx_80211.h" | 30 | #include "wl12xx_80211.h" |
31 | #include "wl1271_spi.h" | ||
32 | #include "wl1271_io.h" | 31 | #include "wl1271_io.h" |
33 | 32 | ||
34 | static int wl1271_translate_addr(struct wl1271 *wl, int addr) | 33 | #define OCP_CMD_LOOP 32 |
34 | |||
35 | #define OCP_CMD_WRITE 0x1 | ||
36 | #define OCP_CMD_READ 0x2 | ||
37 | |||
38 | #define OCP_READY_MASK BIT(18) | ||
39 | #define OCP_STATUS_MASK (BIT(16) | BIT(17)) | ||
40 | |||
41 | #define OCP_STATUS_NO_RESP 0x00000 | ||
42 | #define OCP_STATUS_OK 0x10000 | ||
43 | #define OCP_STATUS_REQ_FAILED 0x20000 | ||
44 | #define OCP_STATUS_RESP_ERROR 0x30000 | ||
45 | |||
46 | void wl1271_disable_interrupts(struct wl1271 *wl) | ||
35 | { | 47 | { |
36 | /* | 48 | wl->if_ops->disable_irq(wl); |
37 | * To translate, first check to which window of addresses the | 49 | } |
38 | * particular address belongs. Then subtract the starting address | 50 | |
39 | * of that window from the address. Then, add offset of the | 51 | void wl1271_enable_interrupts(struct wl1271 *wl) |
40 | * translated region. | 52 | { |
41 | * | 53 | wl->if_ops->enable_irq(wl); |
42 | * The translated regions occur next to each other in physical device | ||
43 | * memory, so just add the sizes of the preceeding address regions to | ||
44 | * get the offset to the new region. | ||
45 | * | ||
46 | * Currently, only the two first regions are addressed, and the | ||
47 | * assumption is that all addresses will fall into either of those | ||
48 | * two. | ||
49 | */ | ||
50 | if ((addr >= wl->part.reg.start) && | ||
51 | (addr < wl->part.reg.start + wl->part.reg.size)) | ||
52 | return addr - wl->part.reg.start + wl->part.mem.size; | ||
53 | else | ||
54 | return addr - wl->part.mem.start; | ||
55 | } | 54 | } |
56 | 55 | ||
57 | /* Set the SPI partitions to access the chip addresses | 56 | /* Set the SPI partitions to access the chip addresses |
@@ -117,54 +116,12 @@ int wl1271_set_partition(struct wl1271 *wl, | |||
117 | 116 | ||
118 | void wl1271_io_reset(struct wl1271 *wl) | 117 | void wl1271_io_reset(struct wl1271 *wl) |
119 | { | 118 | { |
120 | wl1271_spi_reset(wl); | 119 | wl->if_ops->reset(wl); |
121 | } | 120 | } |
122 | 121 | ||
123 | void wl1271_io_init(struct wl1271 *wl) | 122 | void wl1271_io_init(struct wl1271 *wl) |
124 | { | 123 | { |
125 | wl1271_spi_init(wl); | 124 | wl->if_ops->init(wl); |
126 | } | ||
127 | |||
128 | void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, | ||
129 | size_t len, bool fixed) | ||
130 | { | ||
131 | wl1271_spi_raw_write(wl, addr, buf, len, fixed); | ||
132 | } | ||
133 | |||
134 | void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, | ||
135 | size_t len, bool fixed) | ||
136 | { | ||
137 | wl1271_spi_raw_read(wl, addr, buf, len, fixed); | ||
138 | } | ||
139 | |||
140 | void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
141 | bool fixed) | ||
142 | { | ||
143 | int physical; | ||
144 | |||
145 | physical = wl1271_translate_addr(wl, addr); | ||
146 | |||
147 | wl1271_spi_raw_read(wl, physical, buf, len, fixed); | ||
148 | } | ||
149 | |||
150 | void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
151 | bool fixed) | ||
152 | { | ||
153 | int physical; | ||
154 | |||
155 | physical = wl1271_translate_addr(wl, addr); | ||
156 | |||
157 | wl1271_spi_raw_write(wl, physical, buf, len, fixed); | ||
158 | } | ||
159 | |||
160 | u32 wl1271_read32(struct wl1271 *wl, int addr) | ||
161 | { | ||
162 | return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); | ||
163 | } | ||
164 | |||
165 | void wl1271_write32(struct wl1271 *wl, int addr, u32 val) | ||
166 | { | ||
167 | wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); | ||
168 | } | 125 | } |
169 | 126 | ||
170 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) | 127 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val) |
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h index fa9a0b35788f..95d2168f8af4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_io.h +++ b/drivers/net/wireless/wl12xx/wl1271_io.h | |||
@@ -25,31 +25,49 @@ | |||
25 | #ifndef __WL1271_IO_H__ | 25 | #ifndef __WL1271_IO_H__ |
26 | #define __WL1271_IO_H__ | 26 | #define __WL1271_IO_H__ |
27 | 27 | ||
28 | #include "wl1271_reg.h" | ||
29 | |||
30 | #define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 | ||
31 | |||
32 | #define HW_PARTITION_REGISTERS_ADDR 0x1FFC0 | ||
33 | #define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR) | ||
34 | #define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4) | ||
35 | #define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8) | ||
36 | #define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12) | ||
37 | #define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16) | ||
38 | #define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20) | ||
39 | #define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24) | ||
40 | |||
41 | #define HW_ACCESS_REGISTER_SIZE 4 | ||
42 | |||
43 | #define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 | ||
44 | |||
28 | struct wl1271; | 45 | struct wl1271; |
29 | 46 | ||
47 | void wl1271_disable_interrupts(struct wl1271 *wl); | ||
48 | void wl1271_enable_interrupts(struct wl1271 *wl); | ||
49 | |||
30 | void wl1271_io_reset(struct wl1271 *wl); | 50 | void wl1271_io_reset(struct wl1271 *wl); |
31 | void wl1271_io_init(struct wl1271 *wl); | 51 | void wl1271_io_init(struct wl1271 *wl); |
32 | 52 | ||
33 | /* Raw target IO, address is not translated */ | 53 | static inline struct device *wl1271_wl_to_dev(struct wl1271 *wl) |
34 | void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, | 54 | { |
35 | size_t len, bool fixed); | 55 | return wl->if_ops->dev(wl); |
36 | void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, | 56 | } |
37 | size_t len, bool fixed); | ||
38 | 57 | ||
39 | /* Translated target IO */ | ||
40 | void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
41 | bool fixed); | ||
42 | void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len, | ||
43 | bool fixed); | ||
44 | u32 wl1271_read32(struct wl1271 *wl, int addr); | ||
45 | void wl1271_write32(struct wl1271 *wl, int addr, u32 val); | ||
46 | 58 | ||
47 | /* Top Register IO */ | 59 | /* Raw target IO, address is not translated */ |
48 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); | 60 | static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, |
49 | u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); | 61 | size_t len, bool fixed) |
62 | { | ||
63 | wl->if_ops->write(wl, addr, buf, len, fixed); | ||
64 | } | ||
50 | 65 | ||
51 | int wl1271_set_partition(struct wl1271 *wl, | 66 | static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, |
52 | struct wl1271_partition_set *p); | 67 | size_t len, bool fixed) |
68 | { | ||
69 | wl->if_ops->read(wl, addr, buf, len, fixed); | ||
70 | } | ||
53 | 71 | ||
54 | static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) | 72 | static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) |
55 | { | 73 | { |
@@ -65,4 +83,74 @@ static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) | |||
65 | wl1271_raw_write(wl, addr, &wl->buffer_32, | 83 | wl1271_raw_write(wl, addr, &wl->buffer_32, |
66 | sizeof(wl->buffer_32), false); | 84 | sizeof(wl->buffer_32), false); |
67 | } | 85 | } |
86 | |||
87 | /* Translated target IO */ | ||
88 | static inline int wl1271_translate_addr(struct wl1271 *wl, int addr) | ||
89 | { | ||
90 | /* | ||
91 | * To translate, first check to which window of addresses the | ||
92 | * particular address belongs. Then subtract the starting address | ||
93 | * of that window from the address. Then, add offset of the | ||
94 | * translated region. | ||
95 | * | ||
96 | * The translated regions occur next to each other in physical device | ||
97 | * memory, so just add the sizes of the preceeding address regions to | ||
98 | * get the offset to the new region. | ||
99 | * | ||
100 | * Currently, only the two first regions are addressed, and the | ||
101 | * assumption is that all addresses will fall into either of those | ||
102 | * two. | ||
103 | */ | ||
104 | if ((addr >= wl->part.reg.start) && | ||
105 | (addr < wl->part.reg.start + wl->part.reg.size)) | ||
106 | return addr - wl->part.reg.start + wl->part.mem.size; | ||
107 | else | ||
108 | return addr - wl->part.mem.start; | ||
109 | } | ||
110 | |||
111 | static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, | ||
112 | size_t len, bool fixed) | ||
113 | { | ||
114 | int physical; | ||
115 | |||
116 | physical = wl1271_translate_addr(wl, addr); | ||
117 | |||
118 | wl1271_raw_read(wl, physical, buf, len, fixed); | ||
119 | } | ||
120 | |||
121 | static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, | ||
122 | size_t len, bool fixed) | ||
123 | { | ||
124 | int physical; | ||
125 | |||
126 | physical = wl1271_translate_addr(wl, addr); | ||
127 | |||
128 | wl1271_raw_write(wl, physical, buf, len, fixed); | ||
129 | } | ||
130 | |||
131 | static inline u32 wl1271_read32(struct wl1271 *wl, int addr) | ||
132 | { | ||
133 | return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); | ||
134 | } | ||
135 | |||
136 | static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) | ||
137 | { | ||
138 | wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); | ||
139 | } | ||
140 | |||
141 | |||
142 | /* Top Register IO */ | ||
143 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); | ||
144 | u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); | ||
145 | |||
146 | int wl1271_set_partition(struct wl1271 *wl, | ||
147 | struct wl1271_partition_set *p); | ||
148 | |||
149 | /* Functions from wl1271_main.c */ | ||
150 | |||
151 | int wl1271_register_hw(struct wl1271 *wl); | ||
152 | int wl1271_init_ieee80211(struct wl1271 *wl); | ||
153 | struct ieee80211_hw *wl1271_alloc_hw(void); | ||
154 | int wl1271_free_hw(struct wl1271 *wl); | ||
155 | |||
68 | #endif | 156 | #endif |
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 2a864b24291d..0a4ff7b02f59 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -22,22 +22,17 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
28 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
29 | #include <linux/irq.h> | ||
30 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
31 | #include <linux/crc32.h> | 28 | #include <linux/crc32.h> |
32 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
33 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
34 | #include <linux/spi/wl12xx.h> | ||
35 | #include <linux/inetdevice.h> | 31 | #include <linux/inetdevice.h> |
36 | 32 | ||
37 | #include "wl1271.h" | 33 | #include "wl1271.h" |
38 | #include "wl12xx_80211.h" | 34 | #include "wl12xx_80211.h" |
39 | #include "wl1271_reg.h" | 35 | #include "wl1271_reg.h" |
40 | #include "wl1271_spi.h" | ||
41 | #include "wl1271_io.h" | 36 | #include "wl1271_io.h" |
42 | #include "wl1271_event.h" | 37 | #include "wl1271_event.h" |
43 | #include "wl1271_tx.h" | 38 | #include "wl1271_tx.h" |
@@ -364,11 +359,6 @@ static int wl1271_plt_init(struct wl1271 *wl) | |||
364 | return ret; | 359 | return ret; |
365 | } | 360 | } |
366 | 361 | ||
367 | static void wl1271_disable_interrupts(struct wl1271 *wl) | ||
368 | { | ||
369 | disable_irq(wl->irq); | ||
370 | } | ||
371 | |||
372 | static void wl1271_power_off(struct wl1271 *wl) | 362 | static void wl1271_power_off(struct wl1271 *wl) |
373 | { | 363 | { |
374 | wl->set_power(false); | 364 | wl->set_power(false); |
@@ -384,10 +374,11 @@ static void wl1271_power_on(struct wl1271 *wl) | |||
384 | static void wl1271_fw_status(struct wl1271 *wl, | 374 | static void wl1271_fw_status(struct wl1271 *wl, |
385 | struct wl1271_fw_status *status) | 375 | struct wl1271_fw_status *status) |
386 | { | 376 | { |
377 | struct timespec ts; | ||
387 | u32 total = 0; | 378 | u32 total = 0; |
388 | int i; | 379 | int i; |
389 | 380 | ||
390 | wl1271_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); | 381 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); |
391 | 382 | ||
392 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " | 383 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " |
393 | "drv_rx_counter = %d, tx_results_counter = %d)", | 384 | "drv_rx_counter = %d, tx_results_counter = %d)", |
@@ -412,14 +403,19 @@ static void wl1271_fw_status(struct wl1271 *wl, | |||
412 | ieee80211_queue_work(wl->hw, &wl->tx_work); | 403 | ieee80211_queue_work(wl->hw, &wl->tx_work); |
413 | 404 | ||
414 | /* update the host-chipset time offset */ | 405 | /* update the host-chipset time offset */ |
415 | wl->time_offset = jiffies_to_usecs(jiffies) - | 406 | getnstimeofday(&ts); |
416 | le32_to_cpu(status->fw_localtime); | 407 | wl->time_offset = (timespec_to_ns(&ts) >> 10) - |
408 | (s64)le32_to_cpu(status->fw_localtime); | ||
417 | } | 409 | } |
418 | 410 | ||
411 | #define WL1271_IRQ_MAX_LOOPS 10 | ||
412 | |||
419 | static void wl1271_irq_work(struct work_struct *work) | 413 | static void wl1271_irq_work(struct work_struct *work) |
420 | { | 414 | { |
421 | int ret; | 415 | int ret; |
422 | u32 intr; | 416 | u32 intr; |
417 | int loopcount = WL1271_IRQ_MAX_LOOPS; | ||
418 | unsigned long flags; | ||
423 | struct wl1271 *wl = | 419 | struct wl1271 *wl = |
424 | container_of(work, struct wl1271, irq_work); | 420 | container_of(work, struct wl1271, irq_work); |
425 | 421 | ||
@@ -427,91 +423,77 @@ static void wl1271_irq_work(struct work_struct *work) | |||
427 | 423 | ||
428 | wl1271_debug(DEBUG_IRQ, "IRQ work"); | 424 | wl1271_debug(DEBUG_IRQ, "IRQ work"); |
429 | 425 | ||
430 | if (wl->state == WL1271_STATE_OFF) | 426 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
431 | goto out; | 427 | goto out; |
432 | 428 | ||
433 | ret = wl1271_ps_elp_wakeup(wl, true); | 429 | ret = wl1271_ps_elp_wakeup(wl, true); |
434 | if (ret < 0) | 430 | if (ret < 0) |
435 | goto out; | 431 | goto out; |
436 | 432 | ||
437 | wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); | 433 | spin_lock_irqsave(&wl->wl_lock, flags); |
438 | 434 | while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) { | |
439 | wl1271_fw_status(wl, wl->fw_status); | 435 | clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); |
440 | intr = le32_to_cpu(wl->fw_status->intr); | 436 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
441 | if (!intr) { | 437 | loopcount--; |
442 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); | 438 | |
443 | goto out_sleep; | 439 | wl1271_fw_status(wl, wl->fw_status); |
444 | } | 440 | intr = le32_to_cpu(wl->fw_status->intr); |
441 | if (!intr) { | ||
442 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); | ||
443 | continue; | ||
444 | } | ||
445 | 445 | ||
446 | intr &= WL1271_INTR_MASK; | 446 | intr &= WL1271_INTR_MASK; |
447 | 447 | ||
448 | if (intr & WL1271_ACX_INTR_EVENT_A) { | 448 | if (intr & WL1271_ACX_INTR_DATA) { |
449 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); | 449 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); |
450 | wl1271_event_handle(wl, 0); | ||
451 | } | ||
452 | 450 | ||
453 | if (intr & WL1271_ACX_INTR_EVENT_B) { | 451 | /* check for tx results */ |
454 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); | 452 | if (wl->fw_status->tx_results_counter != |
455 | wl1271_event_handle(wl, 1); | 453 | (wl->tx_results_count & 0xff)) |
456 | } | 454 | wl1271_tx_complete(wl); |
457 | 455 | ||
458 | if (intr & WL1271_ACX_INTR_INIT_COMPLETE) | 456 | wl1271_rx(wl, wl->fw_status); |
459 | wl1271_debug(DEBUG_IRQ, | 457 | } |
460 | "WL1271_ACX_INTR_INIT_COMPLETE"); | ||
461 | 458 | ||
462 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) | 459 | if (intr & WL1271_ACX_INTR_EVENT_A) { |
463 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); | 460 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); |
461 | wl1271_event_handle(wl, 0); | ||
462 | } | ||
464 | 463 | ||
465 | if (intr & WL1271_ACX_INTR_DATA) { | 464 | if (intr & WL1271_ACX_INTR_EVENT_B) { |
466 | u8 tx_res_cnt = wl->fw_status->tx_results_counter - | 465 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); |
467 | wl->tx_results_count; | 466 | wl1271_event_handle(wl, 1); |
467 | } | ||
468 | 468 | ||
469 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); | 469 | if (intr & WL1271_ACX_INTR_INIT_COMPLETE) |
470 | wl1271_debug(DEBUG_IRQ, | ||
471 | "WL1271_ACX_INTR_INIT_COMPLETE"); | ||
470 | 472 | ||
471 | /* check for tx results */ | 473 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) |
472 | if (tx_res_cnt) | 474 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); |
473 | wl1271_tx_complete(wl, tx_res_cnt); | ||
474 | 475 | ||
475 | wl1271_rx(wl, wl->fw_status); | 476 | spin_lock_irqsave(&wl->wl_lock, flags); |
476 | } | 477 | } |
477 | 478 | ||
478 | out_sleep: | 479 | if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags)) |
479 | wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, | 480 | ieee80211_queue_work(wl->hw, &wl->irq_work); |
480 | WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); | 481 | else |
482 | clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
483 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
484 | |||
481 | wl1271_ps_elp_sleep(wl); | 485 | wl1271_ps_elp_sleep(wl); |
482 | 486 | ||
483 | out: | 487 | out: |
484 | mutex_unlock(&wl->mutex); | 488 | mutex_unlock(&wl->mutex); |
485 | } | 489 | } |
486 | 490 | ||
487 | static irqreturn_t wl1271_irq(int irq, void *cookie) | ||
488 | { | ||
489 | struct wl1271 *wl; | ||
490 | unsigned long flags; | ||
491 | |||
492 | wl1271_debug(DEBUG_IRQ, "IRQ"); | ||
493 | |||
494 | wl = cookie; | ||
495 | |||
496 | /* complete the ELP completion */ | ||
497 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
498 | if (wl->elp_compl) { | ||
499 | complete(wl->elp_compl); | ||
500 | wl->elp_compl = NULL; | ||
501 | } | ||
502 | |||
503 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
504 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
505 | |||
506 | return IRQ_HANDLED; | ||
507 | } | ||
508 | |||
509 | static int wl1271_fetch_firmware(struct wl1271 *wl) | 491 | static int wl1271_fetch_firmware(struct wl1271 *wl) |
510 | { | 492 | { |
511 | const struct firmware *fw; | 493 | const struct firmware *fw; |
512 | int ret; | 494 | int ret; |
513 | 495 | ||
514 | ret = request_firmware(&fw, WL1271_FW_NAME, &wl->spi->dev); | 496 | ret = request_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl)); |
515 | 497 | ||
516 | if (ret < 0) { | 498 | if (ret < 0) { |
517 | wl1271_error("could not get firmware: %d", ret); | 499 | wl1271_error("could not get firmware: %d", ret); |
@@ -583,7 +565,7 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) | |||
583 | const struct firmware *fw; | 565 | const struct firmware *fw; |
584 | int ret; | 566 | int ret; |
585 | 567 | ||
586 | ret = request_firmware(&fw, WL1271_NVS_NAME, &wl->spi->dev); | 568 | ret = request_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl)); |
587 | 569 | ||
588 | if (ret < 0) { | 570 | if (ret < 0) { |
589 | wl1271_error("could not get nvs file: %d", ret); | 571 | wl1271_error("could not get nvs file: %d", ret); |
@@ -825,15 +807,13 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
825 | * The workqueue is slow to process the tx_queue and we need stop | 807 | * The workqueue is slow to process the tx_queue and we need stop |
826 | * the queue here, otherwise the queue will get too long. | 808 | * the queue here, otherwise the queue will get too long. |
827 | */ | 809 | */ |
828 | if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) { | 810 | if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_HIGH_WATERMARK) { |
829 | ieee80211_stop_queues(wl->hw); | 811 | wl1271_debug(DEBUG_TX, "op_tx: stopping queues"); |
830 | 812 | ||
831 | /* | 813 | spin_lock_irqsave(&wl->wl_lock, flags); |
832 | * FIXME: this is racy, the variable is not properly | 814 | ieee80211_stop_queues(wl->hw); |
833 | * protected. Maybe fix this by removing the stupid | ||
834 | * variable altogether and checking the real queue state? | ||
835 | */ | ||
836 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | 815 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); |
816 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
837 | } | 817 | } |
838 | 818 | ||
839 | return NETDEV_TX_OK; | 819 | return NETDEV_TX_OK; |
@@ -1040,8 +1020,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1040 | wl->tx_results_count = 0; | 1020 | wl->tx_results_count = 0; |
1041 | wl->tx_packets_count = 0; | 1021 | wl->tx_packets_count = 0; |
1042 | wl->tx_security_last_seq = 0; | 1022 | wl->tx_security_last_seq = 0; |
1043 | wl->tx_security_seq_16 = 0; | 1023 | wl->tx_security_seq = 0; |
1044 | wl->tx_security_seq_32 = 0; | ||
1045 | wl->time_offset = 0; | 1024 | wl->time_offset = 0; |
1046 | wl->session_counter = 0; | 1025 | wl->session_counter = 0; |
1047 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 1026 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
@@ -1127,7 +1106,7 @@ static int wl1271_op_config_interface(struct ieee80211_hw *hw, | |||
1127 | 1106 | ||
1128 | memcpy(wl->bssid, conf->bssid, ETH_ALEN); | 1107 | memcpy(wl->bssid, conf->bssid, ETH_ALEN); |
1129 | 1108 | ||
1130 | ret = wl1271_cmd_join(wl); | 1109 | ret = wl1271_cmd_join(wl, wl->bss_type); |
1131 | if (ret < 0) | 1110 | if (ret < 0) |
1132 | goto out_sleep; | 1111 | goto out_sleep; |
1133 | 1112 | ||
@@ -1176,17 +1155,16 @@ static int wl1271_join_channel(struct wl1271 *wl, int channel) | |||
1176 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, | 1155 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, |
1177 | 0xad, 0xbe, 0xef }; | 1156 | 0xad, 0xbe, 0xef }; |
1178 | 1157 | ||
1179 | /* the dummy join is not required for ad-hoc */ | ||
1180 | if (wl->bss_type == BSS_TYPE_IBSS) | ||
1181 | goto out; | ||
1182 | |||
1183 | /* disable mac filter, so we hear everything */ | 1158 | /* disable mac filter, so we hear everything */ |
1184 | wl->rx_config &= ~CFG_BSSID_FILTER_EN; | 1159 | wl->rx_config &= ~CFG_BSSID_FILTER_EN; |
1185 | 1160 | ||
1186 | wl->channel = channel; | 1161 | wl->channel = channel; |
1187 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); | 1162 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); |
1188 | 1163 | ||
1189 | ret = wl1271_cmd_join(wl); | 1164 | /* the dummy join is performed always with STATION BSS type to allow |
1165 | also ad-hoc mode to listen to the surroundings without sending any | ||
1166 | beacons yet. */ | ||
1167 | ret = wl1271_cmd_join(wl, BSS_TYPE_STA_BSS); | ||
1190 | if (ret < 0) | 1168 | if (ret < 0) |
1191 | goto out; | 1169 | goto out; |
1192 | 1170 | ||
@@ -1255,7 +1233,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1255 | test_bit(WL1271_FLAG_JOINED, &wl->flags)) { | 1233 | test_bit(WL1271_FLAG_JOINED, &wl->flags)) { |
1256 | wl->channel = channel; | 1234 | wl->channel = channel; |
1257 | /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */ | 1235 | /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */ |
1258 | ret = wl1271_cmd_join(wl); | 1236 | ret = wl1271_cmd_join(wl, wl->bss_type); |
1259 | if (ret < 0) | 1237 | if (ret < 0) |
1260 | wl1271_warning("cmd join to update channel failed %d", | 1238 | wl1271_warning("cmd join to update channel failed %d", |
1261 | ret); | 1239 | ret); |
@@ -1272,13 +1250,13 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1272 | * through the bss_info_changed() hook. | 1250 | * through the bss_info_changed() hook. |
1273 | */ | 1251 | */ |
1274 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { | 1252 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { |
1275 | wl1271_info("psm enabled"); | 1253 | wl1271_debug(DEBUG_PSM, "psm enabled"); |
1276 | ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, | 1254 | ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, |
1277 | true); | 1255 | true); |
1278 | } | 1256 | } |
1279 | } else if (!(conf->flags & IEEE80211_CONF_PS) && | 1257 | } else if (!(conf->flags & IEEE80211_CONF_PS) && |
1280 | test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { | 1258 | test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { |
1281 | wl1271_info("psm disabled"); | 1259 | wl1271_debug(DEBUG_PSM, "psm disabled"); |
1282 | 1260 | ||
1283 | clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); | 1261 | clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags); |
1284 | 1262 | ||
@@ -1449,15 +1427,15 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1449 | key_type = KEY_TKIP; | 1427 | key_type = KEY_TKIP; |
1450 | 1428 | ||
1451 | key_conf->hw_key_idx = key_conf->keyidx; | 1429 | key_conf->hw_key_idx = key_conf->keyidx; |
1452 | tx_seq_32 = wl->tx_security_seq_32; | 1430 | tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); |
1453 | tx_seq_16 = wl->tx_security_seq_16; | 1431 | tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); |
1454 | break; | 1432 | break; |
1455 | case ALG_CCMP: | 1433 | case ALG_CCMP: |
1456 | key_type = KEY_AES; | 1434 | key_type = KEY_AES; |
1457 | 1435 | ||
1458 | key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | 1436 | key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
1459 | tx_seq_32 = wl->tx_security_seq_32; | 1437 | tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); |
1460 | tx_seq_16 = wl->tx_security_seq_16; | 1438 | tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); |
1461 | break; | 1439 | break; |
1462 | default: | 1440 | default: |
1463 | wl1271_error("Unknown key algo 0x%x", key_conf->alg); | 1441 | wl1271_error("Unknown key algo 0x%x", key_conf->alg); |
@@ -1738,7 +1716,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1738 | } | 1716 | } |
1739 | 1717 | ||
1740 | if (do_join) { | 1718 | if (do_join) { |
1741 | ret = wl1271_cmd_join(wl); | 1719 | ret = wl1271_cmd_join(wl, wl->bss_type); |
1742 | if (ret < 0) { | 1720 | if (ret < 0) { |
1743 | wl1271_warning("cmd join failed %d", ret); | 1721 | wl1271_warning("cmd join failed %d", ret); |
1744 | goto out_sleep; | 1722 | goto out_sleep; |
@@ -1959,7 +1937,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
1959 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) | 1937 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) |
1960 | }; | 1938 | }; |
1961 | 1939 | ||
1962 | static int wl1271_register_hw(struct wl1271 *wl) | 1940 | int wl1271_register_hw(struct wl1271 *wl) |
1963 | { | 1941 | { |
1964 | int ret; | 1942 | int ret; |
1965 | 1943 | ||
@@ -1980,8 +1958,9 @@ static int wl1271_register_hw(struct wl1271 *wl) | |||
1980 | 1958 | ||
1981 | return 0; | 1959 | return 0; |
1982 | } | 1960 | } |
1961 | EXPORT_SYMBOL_GPL(wl1271_register_hw); | ||
1983 | 1962 | ||
1984 | static int wl1271_init_ieee80211(struct wl1271 *wl) | 1963 | int wl1271_init_ieee80211(struct wl1271 *wl) |
1985 | { | 1964 | { |
1986 | /* The tx descriptor buffer and the TKIP space. */ | 1965 | /* The tx descriptor buffer and the TKIP space. */ |
1987 | wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + | 1966 | wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + |
@@ -1994,7 +1973,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
1994 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | | 1973 | wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | |
1995 | IEEE80211_HW_NOISE_DBM | | 1974 | IEEE80211_HW_NOISE_DBM | |
1996 | IEEE80211_HW_BEACON_FILTER | | 1975 | IEEE80211_HW_BEACON_FILTER | |
1997 | IEEE80211_HW_SUPPORTS_PS; | 1976 | IEEE80211_HW_SUPPORTS_PS | |
1977 | IEEE80211_HW_HAS_RATE_CONTROL; | ||
1998 | 1978 | ||
1999 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 1979 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
2000 | BIT(NL80211_IFTYPE_ADHOC); | 1980 | BIT(NL80211_IFTYPE_ADHOC); |
@@ -2004,29 +1984,15 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
2004 | if (wl1271_11a_enabled()) | 1984 | if (wl1271_11a_enabled()) |
2005 | wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; | 1985 | wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; |
2006 | 1986 | ||
2007 | SET_IEEE80211_DEV(wl->hw, &wl->spi->dev); | 1987 | SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); |
2008 | 1988 | ||
2009 | return 0; | 1989 | return 0; |
2010 | } | 1990 | } |
2011 | 1991 | EXPORT_SYMBOL_GPL(wl1271_init_ieee80211); | |
2012 | static void wl1271_device_release(struct device *dev) | ||
2013 | { | ||
2014 | |||
2015 | } | ||
2016 | |||
2017 | static struct platform_device wl1271_device = { | ||
2018 | .name = "wl1271", | ||
2019 | .id = -1, | ||
2020 | |||
2021 | /* device model insists to have a release function */ | ||
2022 | .dev = { | ||
2023 | .release = wl1271_device_release, | ||
2024 | }, | ||
2025 | }; | ||
2026 | 1992 | ||
2027 | #define WL1271_DEFAULT_CHANNEL 0 | 1993 | #define WL1271_DEFAULT_CHANNEL 0 |
2028 | 1994 | ||
2029 | static struct ieee80211_hw *wl1271_alloc_hw(void) | 1995 | struct ieee80211_hw *wl1271_alloc_hw(void) |
2030 | { | 1996 | { |
2031 | struct ieee80211_hw *hw; | 1997 | struct ieee80211_hw *hw; |
2032 | struct wl1271 *wl; | 1998 | struct wl1271 *wl; |
@@ -2073,8 +2039,11 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) | |||
2073 | /* Apply default driver configuration. */ | 2039 | /* Apply default driver configuration. */ |
2074 | wl1271_conf_init(wl); | 2040 | wl1271_conf_init(wl); |
2075 | 2041 | ||
2042 | wl1271_debugfs_init(wl); | ||
2043 | |||
2076 | return hw; | 2044 | return hw; |
2077 | } | 2045 | } |
2046 | EXPORT_SYMBOL_GPL(wl1271_alloc_hw); | ||
2078 | 2047 | ||
2079 | int wl1271_free_hw(struct wl1271 *wl) | 2048 | int wl1271_free_hw(struct wl1271 *wl) |
2080 | { | 2049 | { |
@@ -2095,145 +2064,8 @@ int wl1271_free_hw(struct wl1271 *wl) | |||
2095 | 2064 | ||
2096 | return 0; | 2065 | return 0; |
2097 | } | 2066 | } |
2098 | 2067 | EXPORT_SYMBOL_GPL(wl1271_free_hw); | |
2099 | static int __devinit wl1271_probe(struct spi_device *spi) | ||
2100 | { | ||
2101 | struct wl12xx_platform_data *pdata; | ||
2102 | struct ieee80211_hw *hw; | ||
2103 | struct wl1271 *wl; | ||
2104 | int ret; | ||
2105 | |||
2106 | pdata = spi->dev.platform_data; | ||
2107 | if (!pdata) { | ||
2108 | wl1271_error("no platform data"); | ||
2109 | return -ENODEV; | ||
2110 | } | ||
2111 | |||
2112 | hw = wl1271_alloc_hw(); | ||
2113 | if (IS_ERR(hw)) | ||
2114 | return PTR_ERR(hw); | ||
2115 | |||
2116 | wl = hw->priv; | ||
2117 | |||
2118 | dev_set_drvdata(&spi->dev, wl); | ||
2119 | wl->spi = spi; | ||
2120 | |||
2121 | /* This is the only SPI value that we need to set here, the rest | ||
2122 | * comes from the board-peripherals file */ | ||
2123 | spi->bits_per_word = 32; | ||
2124 | |||
2125 | ret = spi_setup(spi); | ||
2126 | if (ret < 0) { | ||
2127 | wl1271_error("spi_setup failed"); | ||
2128 | goto out_free; | ||
2129 | } | ||
2130 | |||
2131 | wl->set_power = pdata->set_power; | ||
2132 | if (!wl->set_power) { | ||
2133 | wl1271_error("set power function missing in platform data"); | ||
2134 | ret = -ENODEV; | ||
2135 | goto out_free; | ||
2136 | } | ||
2137 | |||
2138 | wl->irq = spi->irq; | ||
2139 | if (wl->irq < 0) { | ||
2140 | wl1271_error("irq missing in platform data"); | ||
2141 | ret = -ENODEV; | ||
2142 | goto out_free; | ||
2143 | } | ||
2144 | |||
2145 | ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); | ||
2146 | if (ret < 0) { | ||
2147 | wl1271_error("request_irq() failed: %d", ret); | ||
2148 | goto out_free; | ||
2149 | } | ||
2150 | |||
2151 | set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); | ||
2152 | |||
2153 | disable_irq(wl->irq); | ||
2154 | |||
2155 | ret = platform_device_register(&wl1271_device); | ||
2156 | if (ret) { | ||
2157 | wl1271_error("couldn't register platform device"); | ||
2158 | goto out_irq; | ||
2159 | } | ||
2160 | dev_set_drvdata(&wl1271_device.dev, wl); | ||
2161 | |||
2162 | ret = wl1271_init_ieee80211(wl); | ||
2163 | if (ret) | ||
2164 | goto out_platform; | ||
2165 | |||
2166 | ret = wl1271_register_hw(wl); | ||
2167 | if (ret) | ||
2168 | goto out_platform; | ||
2169 | |||
2170 | wl1271_debugfs_init(wl); | ||
2171 | |||
2172 | wl1271_notice("initialized"); | ||
2173 | |||
2174 | return 0; | ||
2175 | |||
2176 | out_platform: | ||
2177 | platform_device_unregister(&wl1271_device); | ||
2178 | |||
2179 | out_irq: | ||
2180 | free_irq(wl->irq, wl); | ||
2181 | |||
2182 | out_free: | ||
2183 | ieee80211_free_hw(hw); | ||
2184 | |||
2185 | return ret; | ||
2186 | } | ||
2187 | |||
2188 | static int __devexit wl1271_remove(struct spi_device *spi) | ||
2189 | { | ||
2190 | struct wl1271 *wl = dev_get_drvdata(&spi->dev); | ||
2191 | |||
2192 | platform_device_unregister(&wl1271_device); | ||
2193 | free_irq(wl->irq, wl); | ||
2194 | |||
2195 | wl1271_free_hw(wl); | ||
2196 | |||
2197 | return 0; | ||
2198 | } | ||
2199 | |||
2200 | |||
2201 | static struct spi_driver wl1271_spi_driver = { | ||
2202 | .driver = { | ||
2203 | .name = "wl1271", | ||
2204 | .bus = &spi_bus_type, | ||
2205 | .owner = THIS_MODULE, | ||
2206 | }, | ||
2207 | |||
2208 | .probe = wl1271_probe, | ||
2209 | .remove = __devexit_p(wl1271_remove), | ||
2210 | }; | ||
2211 | |||
2212 | static int __init wl1271_init(void) | ||
2213 | { | ||
2214 | int ret; | ||
2215 | |||
2216 | ret = spi_register_driver(&wl1271_spi_driver); | ||
2217 | if (ret < 0) { | ||
2218 | wl1271_error("failed to register spi driver: %d", ret); | ||
2219 | goto out; | ||
2220 | } | ||
2221 | |||
2222 | out: | ||
2223 | return ret; | ||
2224 | } | ||
2225 | |||
2226 | static void __exit wl1271_exit(void) | ||
2227 | { | ||
2228 | spi_unregister_driver(&wl1271_spi_driver); | ||
2229 | |||
2230 | wl1271_notice("unloaded"); | ||
2231 | } | ||
2232 | |||
2233 | module_init(wl1271_init); | ||
2234 | module_exit(wl1271_exit); | ||
2235 | 2068 | ||
2236 | MODULE_LICENSE("GPL"); | 2069 | MODULE_LICENSE("GPL"); |
2237 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); | 2070 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); |
2238 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 2071 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
2239 | MODULE_FIRMWARE(WL1271_FW_NAME); | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c index e2b1ebf096e8..5a04482b9353 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ b/drivers/net/wireless/wl12xx/wl1271_ps.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include "wl1271_reg.h" | 24 | #include "wl1271_reg.h" |
25 | #include "wl1271_ps.h" | 25 | #include "wl1271_ps.h" |
26 | #include "wl1271_spi.h" | ||
27 | #include "wl1271_io.h" | 26 | #include "wl1271_io.h" |
28 | 27 | ||
29 | #define WL1271_WAKEUP_TIMEOUT 500 | 28 | #define WL1271_WAKEUP_TIMEOUT 500 |
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index 6730f5b96e76..b824c6cc2cc5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "wl1271_acx.h" | 25 | #include "wl1271_acx.h" |
26 | #include "wl1271_reg.h" | 26 | #include "wl1271_reg.h" |
27 | #include "wl1271_rx.h" | 27 | #include "wl1271_rx.h" |
28 | #include "wl1271_spi.h" | ||
29 | #include "wl1271_io.h" | 28 | #include "wl1271_io.h" |
30 | 29 | ||
31 | static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, | 30 | static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, |
@@ -160,6 +159,13 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) | |||
160 | u8 *buf; | 159 | u8 *buf; |
161 | u8 beacon = 0; | 160 | u8 beacon = 0; |
162 | 161 | ||
162 | /* | ||
163 | * In PLT mode we seem to get frames and mac80211 warns about them, | ||
164 | * workaround this by not retrieving them at all. | ||
165 | */ | ||
166 | if (unlikely(wl->state == WL1271_STATE_PLT)) | ||
167 | return; | ||
168 | |||
163 | skb = __dev_alloc_skb(length, GFP_KERNEL); | 169 | skb = __dev_alloc_skb(length, GFP_KERNEL); |
164 | if (!skb) { | 170 | if (!skb) { |
165 | wl1271_error("Couldn't allocate RX frame"); | 171 | wl1271_error("Couldn't allocate RX frame"); |
@@ -218,6 +224,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) | |||
218 | 224 | ||
219 | wl->rx_counter++; | 225 | wl->rx_counter++; |
220 | drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; | 226 | drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; |
221 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); | ||
222 | } | 227 | } |
228 | |||
229 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); | ||
223 | } | 230 | } |
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c new file mode 100644 index 000000000000..1f204db30c27 --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c | |||
@@ -0,0 +1,307 @@ | |||
1 | /* | ||
2 | * This file is part of wl1271 | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Nokia Corporation | ||
5 | * | ||
6 | * Contact: Luciano Coelho <luciano.coelho@nokia.com> | ||
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 | |||
24 | #include <linux/irq.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/crc7.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | #include <linux/mmc/sdio_func.h> | ||
29 | #include <linux/mmc/sdio_ids.h> | ||
30 | #include <linux/mmc/card.h> | ||
31 | #include <plat/gpio.h> | ||
32 | |||
33 | #include "wl1271.h" | ||
34 | #include "wl12xx_80211.h" | ||
35 | #include "wl1271_io.h" | ||
36 | |||
37 | |||
38 | #define RX71_WL1271_IRQ_GPIO 42 | ||
39 | |||
40 | #ifndef SDIO_VENDOR_ID_TI | ||
41 | #define SDIO_VENDOR_ID_TI 0x0097 | ||
42 | #endif | ||
43 | |||
44 | #ifndef SDIO_DEVICE_ID_TI_WL1271 | ||
45 | #define SDIO_DEVICE_ID_TI_WL1271 0x4076 | ||
46 | #endif | ||
47 | |||
48 | static const struct sdio_device_id wl1271_devices[] = { | ||
49 | { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, | ||
50 | {} | ||
51 | }; | ||
52 | MODULE_DEVICE_TABLE(sdio, wl1271_devices); | ||
53 | |||
54 | static inline struct sdio_func *wl_to_func(struct wl1271 *wl) | ||
55 | { | ||
56 | return wl->if_priv; | ||
57 | } | ||
58 | |||
59 | static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) | ||
60 | { | ||
61 | return &(wl_to_func(wl)->dev); | ||
62 | } | ||
63 | |||
64 | static irqreturn_t wl1271_irq(int irq, void *cookie) | ||
65 | { | ||
66 | struct wl1271 *wl = cookie; | ||
67 | unsigned long flags; | ||
68 | |||
69 | wl1271_debug(DEBUG_IRQ, "IRQ"); | ||
70 | |||
71 | /* complete the ELP completion */ | ||
72 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
73 | if (wl->elp_compl) { | ||
74 | complete(wl->elp_compl); | ||
75 | wl->elp_compl = NULL; | ||
76 | } | ||
77 | |||
78 | if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) | ||
79 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
80 | set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | ||
81 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
82 | |||
83 | return IRQ_HANDLED; | ||
84 | } | ||
85 | |||
86 | static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) | ||
87 | { | ||
88 | disable_irq(wl->irq); | ||
89 | } | ||
90 | |||
91 | static void wl1271_sdio_enable_interrupts(struct wl1271 *wl) | ||
92 | { | ||
93 | enable_irq(wl->irq); | ||
94 | } | ||
95 | |||
96 | static void wl1271_sdio_reset(struct wl1271 *wl) | ||
97 | { | ||
98 | } | ||
99 | |||
100 | static void wl1271_sdio_init(struct wl1271 *wl) | ||
101 | { | ||
102 | } | ||
103 | |||
104 | static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, | ||
105 | size_t len, bool fixed) | ||
106 | { | ||
107 | int ret; | ||
108 | struct sdio_func *func = wl_to_func(wl); | ||
109 | |||
110 | sdio_claim_host(func); | ||
111 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | ||
112 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); | ||
113 | wl1271_debug(DEBUG_SPI, "sdio read 52 addr 0x%x, byte 0x%02x", | ||
114 | addr, ((u8 *)buf)[0]); | ||
115 | } else { | ||
116 | if (fixed) | ||
117 | ret = sdio_readsb(func, buf, addr, len); | ||
118 | else | ||
119 | ret = sdio_memcpy_fromio(func, buf, addr, len); | ||
120 | |||
121 | wl1271_debug(DEBUG_SPI, "sdio read 53 addr 0x%x, %d bytes", | ||
122 | addr, len); | ||
123 | wl1271_dump_ascii(DEBUG_SPI, "data: ", buf, len); | ||
124 | } | ||
125 | |||
126 | if (ret) | ||
127 | wl1271_error("sdio read failed (%d)", ret); | ||
128 | |||
129 | sdio_release_host(func); | ||
130 | } | ||
131 | |||
132 | static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | ||
133 | size_t len, bool fixed) | ||
134 | { | ||
135 | int ret; | ||
136 | struct sdio_func *func = wl_to_func(wl); | ||
137 | |||
138 | sdio_claim_host(func); | ||
139 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | ||
140 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); | ||
141 | wl1271_debug(DEBUG_SPI, "sdio write 52 addr 0x%x, byte 0x%02x", | ||
142 | addr, ((u8 *)buf)[0]); | ||
143 | } else { | ||
144 | wl1271_debug(DEBUG_SPI, "sdio write 53 addr 0x%x, %d bytes", | ||
145 | addr, len); | ||
146 | wl1271_dump_ascii(DEBUG_SPI, "data: ", buf, len); | ||
147 | |||
148 | if (fixed) | ||
149 | ret = sdio_writesb(func, addr, buf, len); | ||
150 | else | ||
151 | ret = sdio_memcpy_toio(func, addr, buf, len); | ||
152 | } | ||
153 | if (ret) | ||
154 | wl1271_error("sdio write failed (%d)", ret); | ||
155 | |||
156 | sdio_release_host(func); | ||
157 | } | ||
158 | |||
159 | static struct wl1271_if_operations sdio_ops = { | ||
160 | .read = wl1271_sdio_raw_read, | ||
161 | .write = wl1271_sdio_raw_write, | ||
162 | .reset = wl1271_sdio_reset, | ||
163 | .init = wl1271_sdio_init, | ||
164 | .dev = wl1271_sdio_wl_to_dev, | ||
165 | .enable_irq = wl1271_sdio_enable_interrupts, | ||
166 | .disable_irq = wl1271_sdio_disable_interrupts | ||
167 | }; | ||
168 | |||
169 | static void wl1271_sdio_set_power(bool enable) | ||
170 | { | ||
171 | } | ||
172 | |||
173 | static int __devinit wl1271_probe(struct sdio_func *func, | ||
174 | const struct sdio_device_id *id) | ||
175 | { | ||
176 | struct ieee80211_hw *hw; | ||
177 | struct wl1271 *wl; | ||
178 | int ret; | ||
179 | |||
180 | /* We are only able to handle the wlan function */ | ||
181 | if (func->num != 0x02) | ||
182 | return -ENODEV; | ||
183 | |||
184 | hw = wl1271_alloc_hw(); | ||
185 | if (IS_ERR(hw)) | ||
186 | return PTR_ERR(hw); | ||
187 | |||
188 | wl = hw->priv; | ||
189 | |||
190 | wl->if_priv = func; | ||
191 | wl->if_ops = &sdio_ops; | ||
192 | |||
193 | wl->set_power = wl1271_sdio_set_power; | ||
194 | |||
195 | /* Grab access to FN0 for ELP reg. */ | ||
196 | func->card->quirks |= MMC_QUIRK_LENIENT_FN0; | ||
197 | |||
198 | wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO); | ||
199 | if (wl->irq < 0) { | ||
200 | ret = wl->irq; | ||
201 | wl1271_error("could not get irq!"); | ||
202 | goto out_free; | ||
203 | } | ||
204 | |||
205 | ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); | ||
206 | if (ret < 0) { | ||
207 | wl1271_error("request_irq() failed: %d", ret); | ||
208 | goto out_free; | ||
209 | } | ||
210 | |||
211 | set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); | ||
212 | |||
213 | disable_irq(wl->irq); | ||
214 | |||
215 | ret = wl1271_init_ieee80211(wl); | ||
216 | if (ret) | ||
217 | goto out_irq; | ||
218 | |||
219 | ret = wl1271_register_hw(wl); | ||
220 | if (ret) | ||
221 | goto out_irq; | ||
222 | |||
223 | sdio_claim_host(func); | ||
224 | sdio_set_drvdata(func, wl); | ||
225 | |||
226 | ret = sdio_enable_func(func); | ||
227 | if (ret) | ||
228 | goto out_release; | ||
229 | |||
230 | sdio_release_host(func); | ||
231 | |||
232 | wl1271_notice("initialized"); | ||
233 | |||
234 | return 0; | ||
235 | |||
236 | out_release: | ||
237 | sdio_release_host(func); | ||
238 | |||
239 | out_irq: | ||
240 | free_irq(wl->irq, wl); | ||
241 | |||
242 | |||
243 | out_free: | ||
244 | ieee80211_free_hw(hw); | ||
245 | |||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | static void __devexit wl1271_remove(struct sdio_func *func) | ||
250 | { | ||
251 | struct wl1271 *wl = sdio_get_drvdata(func); | ||
252 | |||
253 | ieee80211_unregister_hw(wl->hw); | ||
254 | |||
255 | sdio_claim_host(func); | ||
256 | sdio_disable_func(func); | ||
257 | sdio_release_host(func); | ||
258 | |||
259 | free_irq(wl->irq, wl); | ||
260 | |||
261 | kfree(wl->target_mem_map); | ||
262 | vfree(wl->fw); | ||
263 | wl->fw = NULL; | ||
264 | kfree(wl->nvs); | ||
265 | wl->nvs = NULL; | ||
266 | |||
267 | kfree(wl->fw_status); | ||
268 | kfree(wl->tx_res_if); | ||
269 | |||
270 | ieee80211_free_hw(wl->hw); | ||
271 | } | ||
272 | |||
273 | static struct sdio_driver wl1271_sdio_driver = { | ||
274 | .name = "wl1271", | ||
275 | .id_table = wl1271_devices, | ||
276 | .probe = wl1271_probe, | ||
277 | .remove = __devexit_p(wl1271_remove), | ||
278 | }; | ||
279 | |||
280 | static int __init wl1271_init(void) | ||
281 | { | ||
282 | int ret; | ||
283 | |||
284 | ret = sdio_register_driver(&wl1271_sdio_driver); | ||
285 | if (ret < 0) { | ||
286 | wl1271_error("failed to register sdio driver: %d", ret); | ||
287 | goto out; | ||
288 | } | ||
289 | |||
290 | out: | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | static void __exit wl1271_exit(void) | ||
295 | { | ||
296 | sdio_unregister_driver(&wl1271_sdio_driver); | ||
297 | |||
298 | wl1271_notice("unloaded"); | ||
299 | } | ||
300 | |||
301 | module_init(wl1271_init); | ||
302 | module_exit(wl1271_exit); | ||
303 | |||
304 | MODULE_LICENSE("GPL"); | ||
305 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); | ||
306 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | ||
307 | MODULE_FIRMWARE(WL1271_FW_NAME); | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 67a82934f36e..ed285fec2a08 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c | |||
@@ -21,17 +21,69 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/irq.h> | ||
24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
26 | #include <linux/crc7.h> | 27 | #include <linux/crc7.h> |
27 | #include <linux/spi/spi.h> | 28 | #include <linux/spi/spi.h> |
29 | #include <linux/spi/wl12xx.h> | ||
28 | 30 | ||
29 | #include "wl1271.h" | 31 | #include "wl1271.h" |
30 | #include "wl12xx_80211.h" | 32 | #include "wl12xx_80211.h" |
31 | #include "wl1271_spi.h" | 33 | #include "wl1271_io.h" |
34 | |||
35 | #include "wl1271_reg.h" | ||
36 | |||
37 | #define WSPI_CMD_READ 0x40000000 | ||
38 | #define WSPI_CMD_WRITE 0x00000000 | ||
39 | #define WSPI_CMD_FIXED 0x20000000 | ||
40 | #define WSPI_CMD_BYTE_LENGTH 0x1FFE0000 | ||
41 | #define WSPI_CMD_BYTE_LENGTH_OFFSET 17 | ||
42 | #define WSPI_CMD_BYTE_ADDR 0x0001FFFF | ||
43 | |||
44 | #define WSPI_INIT_CMD_CRC_LEN 5 | ||
45 | |||
46 | #define WSPI_INIT_CMD_START 0x00 | ||
47 | #define WSPI_INIT_CMD_TX 0x40 | ||
48 | /* the extra bypass bit is sampled by the TNET as '1' */ | ||
49 | #define WSPI_INIT_CMD_BYPASS_BIT 0x80 | ||
50 | #define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07 | ||
51 | #define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80 | ||
52 | #define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00 | ||
53 | #define WSPI_INIT_CMD_IOD 0x40 | ||
54 | #define WSPI_INIT_CMD_IP 0x20 | ||
55 | #define WSPI_INIT_CMD_CS 0x10 | ||
56 | #define WSPI_INIT_CMD_WS 0x08 | ||
57 | #define WSPI_INIT_CMD_WSPI 0x01 | ||
58 | #define WSPI_INIT_CMD_END 0x01 | ||
59 | |||
60 | #define WSPI_INIT_CMD_LEN 8 | ||
61 | |||
62 | #define HW_ACCESS_WSPI_FIXED_BUSY_LEN \ | ||
63 | ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) | ||
64 | #define HW_ACCESS_WSPI_INIT_CMD_MASK 0 | ||
65 | |||
66 | static inline struct spi_device *wl_to_spi(struct wl1271 *wl) | ||
67 | { | ||
68 | return wl->if_priv; | ||
69 | } | ||
70 | |||
71 | static struct device *wl1271_spi_wl_to_dev(struct wl1271 *wl) | ||
72 | { | ||
73 | return &(wl_to_spi(wl)->dev); | ||
74 | } | ||
32 | 75 | ||
76 | static void wl1271_spi_disable_interrupts(struct wl1271 *wl) | ||
77 | { | ||
78 | disable_irq(wl->irq); | ||
79 | } | ||
80 | |||
81 | static void wl1271_spi_enable_interrupts(struct wl1271 *wl) | ||
82 | { | ||
83 | enable_irq(wl->irq); | ||
84 | } | ||
33 | 85 | ||
34 | void wl1271_spi_reset(struct wl1271 *wl) | 86 | static void wl1271_spi_reset(struct wl1271 *wl) |
35 | { | 87 | { |
36 | u8 *cmd; | 88 | u8 *cmd; |
37 | struct spi_transfer t; | 89 | struct spi_transfer t; |
@@ -52,12 +104,12 @@ void wl1271_spi_reset(struct wl1271 *wl) | |||
52 | t.len = WSPI_INIT_CMD_LEN; | 104 | t.len = WSPI_INIT_CMD_LEN; |
53 | spi_message_add_tail(&t, &m); | 105 | spi_message_add_tail(&t, &m); |
54 | 106 | ||
55 | spi_sync(wl->spi, &m); | 107 | spi_sync(wl_to_spi(wl), &m); |
56 | 108 | ||
57 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); | 109 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); |
58 | } | 110 | } |
59 | 111 | ||
60 | void wl1271_spi_init(struct wl1271 *wl) | 112 | static void wl1271_spi_init(struct wl1271 *wl) |
61 | { | 113 | { |
62 | u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; | 114 | u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd; |
63 | struct spi_transfer t; | 115 | struct spi_transfer t; |
@@ -106,7 +158,7 @@ void wl1271_spi_init(struct wl1271 *wl) | |||
106 | t.len = WSPI_INIT_CMD_LEN; | 158 | t.len = WSPI_INIT_CMD_LEN; |
107 | spi_message_add_tail(&t, &m); | 159 | spi_message_add_tail(&t, &m); |
108 | 160 | ||
109 | spi_sync(wl->spi, &m); | 161 | spi_sync(wl_to_spi(wl), &m); |
110 | 162 | ||
111 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); | 163 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); |
112 | } | 164 | } |
@@ -138,7 +190,7 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len) | |||
138 | t[0].rx_buf = buf + (len - num_busy_bytes); | 190 | t[0].rx_buf = buf + (len - num_busy_bytes); |
139 | t[0].len = num_busy_bytes; | 191 | t[0].len = num_busy_bytes; |
140 | spi_message_add_tail(&t[0], &m); | 192 | spi_message_add_tail(&t[0], &m); |
141 | spi_sync(wl->spi, &m); | 193 | spi_sync(wl_to_spi(wl), &m); |
142 | return; | 194 | return; |
143 | } | 195 | } |
144 | } | 196 | } |
@@ -158,7 +210,7 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len) | |||
158 | t[0].rx_buf = busy_buf; | 210 | t[0].rx_buf = busy_buf; |
159 | t[0].len = sizeof(u32); | 211 | t[0].len = sizeof(u32); |
160 | spi_message_add_tail(&t[0], &m); | 212 | spi_message_add_tail(&t[0], &m); |
161 | spi_sync(wl->spi, &m); | 213 | spi_sync(wl_to_spi(wl), &m); |
162 | 214 | ||
163 | if (*busy_buf & 0x1) { | 215 | if (*busy_buf & 0x1) { |
164 | spi_message_init(&m); | 216 | spi_message_init(&m); |
@@ -166,7 +218,7 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len) | |||
166 | t[0].rx_buf = buf; | 218 | t[0].rx_buf = buf; |
167 | t[0].len = len; | 219 | t[0].len = len; |
168 | spi_message_add_tail(&t[0], &m); | 220 | spi_message_add_tail(&t[0], &m); |
169 | spi_sync(wl->spi, &m); | 221 | spi_sync(wl_to_spi(wl), &m); |
170 | return; | 222 | return; |
171 | } | 223 | } |
172 | } | 224 | } |
@@ -177,7 +229,7 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len) | |||
177 | } | 229 | } |
178 | #endif | 230 | #endif |
179 | 231 | ||
180 | void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | 232 | static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, |
181 | size_t len, bool fixed) | 233 | size_t len, bool fixed) |
182 | { | 234 | { |
183 | struct spi_transfer t[3]; | 235 | struct spi_transfer t[3]; |
@@ -212,7 +264,7 @@ void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
212 | t[2].len = len; | 264 | t[2].len = len; |
213 | spi_message_add_tail(&t[2], &m); | 265 | spi_message_add_tail(&t[2], &m); |
214 | 266 | ||
215 | spi_sync(wl->spi, &m); | 267 | spi_sync(wl_to_spi(wl), &m); |
216 | 268 | ||
217 | /* FIXME: Check busy words, removed due to SPI bug */ | 269 | /* FIXME: Check busy words, removed due to SPI bug */ |
218 | /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1)) | 270 | /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1)) |
@@ -222,7 +274,7 @@ void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
222 | wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); | 274 | wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); |
223 | } | 275 | } |
224 | 276 | ||
225 | void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | 277 | static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, |
226 | size_t len, bool fixed) | 278 | size_t len, bool fixed) |
227 | { | 279 | { |
228 | struct spi_transfer t[2]; | 280 | struct spi_transfer t[2]; |
@@ -250,8 +302,199 @@ void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
250 | t[1].len = len; | 302 | t[1].len = len; |
251 | spi_message_add_tail(&t[1], &m); | 303 | spi_message_add_tail(&t[1], &m); |
252 | 304 | ||
253 | spi_sync(wl->spi, &m); | 305 | spi_sync(wl_to_spi(wl), &m); |
254 | 306 | ||
255 | wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); | 307 | wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); |
256 | wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); | 308 | wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); |
257 | } | 309 | } |
310 | |||
311 | static irqreturn_t wl1271_irq(int irq, void *cookie) | ||
312 | { | ||
313 | struct wl1271 *wl; | ||
314 | unsigned long flags; | ||
315 | |||
316 | wl1271_debug(DEBUG_IRQ, "IRQ"); | ||
317 | |||
318 | wl = cookie; | ||
319 | |||
320 | /* complete the ELP completion */ | ||
321 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
322 | if (wl->elp_compl) { | ||
323 | complete(wl->elp_compl); | ||
324 | wl->elp_compl = NULL; | ||
325 | } | ||
326 | |||
327 | if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) | ||
328 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
329 | set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | ||
330 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
331 | |||
332 | return IRQ_HANDLED; | ||
333 | } | ||
334 | |||
335 | static void wl1271_device_release(struct device *dev) | ||
336 | { | ||
337 | |||
338 | } | ||
339 | |||
340 | static struct platform_device wl1271_device = { | ||
341 | .name = "wl1271", | ||
342 | .id = -1, | ||
343 | |||
344 | /* device model insists to have a release function */ | ||
345 | .dev = { | ||
346 | .release = wl1271_device_release, | ||
347 | }, | ||
348 | }; | ||
349 | |||
350 | static struct wl1271_if_operations spi_ops = { | ||
351 | .read = wl1271_spi_raw_read, | ||
352 | .write = wl1271_spi_raw_write, | ||
353 | .reset = wl1271_spi_reset, | ||
354 | .init = wl1271_spi_init, | ||
355 | .dev = wl1271_spi_wl_to_dev, | ||
356 | .enable_irq = wl1271_spi_enable_interrupts, | ||
357 | .disable_irq = wl1271_spi_disable_interrupts | ||
358 | }; | ||
359 | |||
360 | static int __devinit wl1271_probe(struct spi_device *spi) | ||
361 | { | ||
362 | struct wl12xx_platform_data *pdata; | ||
363 | struct ieee80211_hw *hw; | ||
364 | struct wl1271 *wl; | ||
365 | int ret; | ||
366 | |||
367 | pdata = spi->dev.platform_data; | ||
368 | if (!pdata) { | ||
369 | wl1271_error("no platform data"); | ||
370 | return -ENODEV; | ||
371 | } | ||
372 | |||
373 | hw = wl1271_alloc_hw(); | ||
374 | if (IS_ERR(hw)) | ||
375 | return PTR_ERR(hw); | ||
376 | |||
377 | wl = hw->priv; | ||
378 | |||
379 | dev_set_drvdata(&spi->dev, wl); | ||
380 | wl->if_priv = spi; | ||
381 | |||
382 | wl->if_ops = &spi_ops; | ||
383 | |||
384 | /* This is the only SPI value that we need to set here, the rest | ||
385 | * comes from the board-peripherals file */ | ||
386 | spi->bits_per_word = 32; | ||
387 | |||
388 | ret = spi_setup(spi); | ||
389 | if (ret < 0) { | ||
390 | wl1271_error("spi_setup failed"); | ||
391 | goto out_free; | ||
392 | } | ||
393 | |||
394 | wl->set_power = pdata->set_power; | ||
395 | if (!wl->set_power) { | ||
396 | wl1271_error("set power function missing in platform data"); | ||
397 | ret = -ENODEV; | ||
398 | goto out_free; | ||
399 | } | ||
400 | |||
401 | wl->irq = spi->irq; | ||
402 | if (wl->irq < 0) { | ||
403 | wl1271_error("irq missing in platform data"); | ||
404 | ret = -ENODEV; | ||
405 | goto out_free; | ||
406 | } | ||
407 | |||
408 | ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); | ||
409 | if (ret < 0) { | ||
410 | wl1271_error("request_irq() failed: %d", ret); | ||
411 | goto out_free; | ||
412 | } | ||
413 | |||
414 | set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); | ||
415 | |||
416 | disable_irq(wl->irq); | ||
417 | |||
418 | ret = platform_device_register(&wl1271_device); | ||
419 | if (ret) { | ||
420 | wl1271_error("couldn't register platform device"); | ||
421 | goto out_irq; | ||
422 | } | ||
423 | dev_set_drvdata(&wl1271_device.dev, wl); | ||
424 | |||
425 | ret = wl1271_init_ieee80211(wl); | ||
426 | if (ret) | ||
427 | goto out_platform; | ||
428 | |||
429 | ret = wl1271_register_hw(wl); | ||
430 | if (ret) | ||
431 | goto out_platform; | ||
432 | |||
433 | wl1271_notice("initialized"); | ||
434 | |||
435 | return 0; | ||
436 | |||
437 | out_platform: | ||
438 | platform_device_unregister(&wl1271_device); | ||
439 | |||
440 | out_irq: | ||
441 | free_irq(wl->irq, wl); | ||
442 | |||
443 | out_free: | ||
444 | ieee80211_free_hw(hw); | ||
445 | |||
446 | return ret; | ||
447 | } | ||
448 | |||
449 | static int __devexit wl1271_remove(struct spi_device *spi) | ||
450 | { | ||
451 | struct wl1271 *wl = dev_get_drvdata(&spi->dev); | ||
452 | |||
453 | platform_device_unregister(&wl1271_device); | ||
454 | free_irq(wl->irq, wl); | ||
455 | |||
456 | wl1271_free_hw(wl); | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | |||
462 | static struct spi_driver wl1271_spi_driver = { | ||
463 | .driver = { | ||
464 | .name = "wl1271", | ||
465 | .bus = &spi_bus_type, | ||
466 | .owner = THIS_MODULE, | ||
467 | }, | ||
468 | |||
469 | .probe = wl1271_probe, | ||
470 | .remove = __devexit_p(wl1271_remove), | ||
471 | }; | ||
472 | |||
473 | static int __init wl1271_init(void) | ||
474 | { | ||
475 | int ret; | ||
476 | |||
477 | ret = spi_register_driver(&wl1271_spi_driver); | ||
478 | if (ret < 0) { | ||
479 | wl1271_error("failed to register spi driver: %d", ret); | ||
480 | goto out; | ||
481 | } | ||
482 | |||
483 | out: | ||
484 | return ret; | ||
485 | } | ||
486 | |||
487 | static void __exit wl1271_exit(void) | ||
488 | { | ||
489 | spi_unregister_driver(&wl1271_spi_driver); | ||
490 | |||
491 | wl1271_notice("unloaded"); | ||
492 | } | ||
493 | |||
494 | module_init(wl1271_init); | ||
495 | module_exit(wl1271_exit); | ||
496 | |||
497 | MODULE_LICENSE("GPL"); | ||
498 | MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>"); | ||
499 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | ||
500 | MODULE_FIRMWARE(WL1271_FW_NAME); | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h deleted file mode 100644 index a803596dad4a..000000000000 --- a/drivers/net/wireless/wl12xx/wl1271_spi.h +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | /* | ||
2 | * This file is part of wl1271 | ||
3 | * | ||
4 | * Copyright (C) 1998-2009 Texas Instruments. All rights reserved. | ||
5 | * Copyright (C) 2008-2009 Nokia Corporation | ||
6 | * | ||
7 | * Contact: Luciano Coelho <luciano.coelho@nokia.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * version 2 as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
21 | * 02110-1301 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef __WL1271_SPI_H__ | ||
26 | #define __WL1271_SPI_H__ | ||
27 | |||
28 | #include "wl1271_reg.h" | ||
29 | |||
30 | #define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 | ||
31 | |||
32 | #define HW_PARTITION_REGISTERS_ADDR 0x1ffc0 | ||
33 | #define HW_PART0_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR) | ||
34 | #define HW_PART0_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 4) | ||
35 | #define HW_PART1_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 8) | ||
36 | #define HW_PART1_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 12) | ||
37 | #define HW_PART2_SIZE_ADDR (HW_PARTITION_REGISTERS_ADDR + 16) | ||
38 | #define HW_PART2_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 20) | ||
39 | #define HW_PART3_START_ADDR (HW_PARTITION_REGISTERS_ADDR + 24) | ||
40 | |||
41 | #define HW_ACCESS_REGISTER_SIZE 4 | ||
42 | |||
43 | #define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 | ||
44 | |||
45 | #define WSPI_CMD_READ 0x40000000 | ||
46 | #define WSPI_CMD_WRITE 0x00000000 | ||
47 | #define WSPI_CMD_FIXED 0x20000000 | ||
48 | #define WSPI_CMD_BYTE_LENGTH 0x1FFE0000 | ||
49 | #define WSPI_CMD_BYTE_LENGTH_OFFSET 17 | ||
50 | #define WSPI_CMD_BYTE_ADDR 0x0001FFFF | ||
51 | |||
52 | #define WSPI_INIT_CMD_CRC_LEN 5 | ||
53 | |||
54 | #define WSPI_INIT_CMD_START 0x00 | ||
55 | #define WSPI_INIT_CMD_TX 0x40 | ||
56 | /* the extra bypass bit is sampled by the TNET as '1' */ | ||
57 | #define WSPI_INIT_CMD_BYPASS_BIT 0x80 | ||
58 | #define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07 | ||
59 | #define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80 | ||
60 | #define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00 | ||
61 | #define WSPI_INIT_CMD_IOD 0x40 | ||
62 | #define WSPI_INIT_CMD_IP 0x20 | ||
63 | #define WSPI_INIT_CMD_CS 0x10 | ||
64 | #define WSPI_INIT_CMD_WS 0x08 | ||
65 | #define WSPI_INIT_CMD_WSPI 0x01 | ||
66 | #define WSPI_INIT_CMD_END 0x01 | ||
67 | |||
68 | #define WSPI_INIT_CMD_LEN 8 | ||
69 | |||
70 | #define HW_ACCESS_WSPI_FIXED_BUSY_LEN \ | ||
71 | ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) | ||
72 | #define HW_ACCESS_WSPI_INIT_CMD_MASK 0 | ||
73 | |||
74 | #define OCP_CMD_LOOP 32 | ||
75 | |||
76 | #define OCP_CMD_WRITE 0x1 | ||
77 | #define OCP_CMD_READ 0x2 | ||
78 | |||
79 | #define OCP_READY_MASK BIT(18) | ||
80 | #define OCP_STATUS_MASK (BIT(16) | BIT(17)) | ||
81 | |||
82 | #define OCP_STATUS_NO_RESP 0x00000 | ||
83 | #define OCP_STATUS_OK 0x10000 | ||
84 | #define OCP_STATUS_REQ_FAILED 0x20000 | ||
85 | #define OCP_STATUS_RESP_ERROR 0x30000 | ||
86 | |||
87 | /* Raw target IO, address is not translated */ | ||
88 | void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | ||
89 | size_t len, bool fixed); | ||
90 | void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, | ||
91 | size_t len, bool fixed); | ||
92 | |||
93 | /* INIT and RESET words */ | ||
94 | void wl1271_spi_reset(struct wl1271 *wl); | ||
95 | void wl1271_spi_init(struct wl1271 *wl); | ||
96 | #endif /* __WL1271_SPI_H__ */ | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c index 3919102e942e..2401e6035d51 100644 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <net/genetlink.h> | 25 | #include <net/genetlink.h> |
26 | 26 | ||
27 | #include "wl1271.h" | 27 | #include "wl1271.h" |
28 | #include "wl1271_spi.h" | ||
29 | #include "wl1271_acx.h" | 28 | #include "wl1271_acx.h" |
30 | 29 | ||
31 | #define WL1271_TM_MAX_DATA_LENGTH 1024 | 30 | #define WL1271_TM_MAX_DATA_LENGTH 1024 |
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index 811e739d05bf..6d109df9a0a0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | 26 | ||
27 | #include "wl1271.h" | 27 | #include "wl1271.h" |
28 | #include "wl1271_spi.h" | ||
29 | #include "wl1271_io.h" | 28 | #include "wl1271_io.h" |
30 | #include "wl1271_reg.h" | 29 | #include "wl1271_reg.h" |
31 | #include "wl1271_ps.h" | 30 | #include "wl1271_ps.h" |
@@ -47,7 +46,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) | |||
47 | { | 46 | { |
48 | struct wl1271_tx_hw_descr *desc; | 47 | struct wl1271_tx_hw_descr *desc; |
49 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; | 48 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; |
50 | u32 total_blocks, excluded; | 49 | u32 total_blocks; |
51 | int id, ret = -EBUSY; | 50 | int id, ret = -EBUSY; |
52 | 51 | ||
53 | /* allocate free identifier for the packet */ | 52 | /* allocate free identifier for the packet */ |
@@ -57,12 +56,8 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) | |||
57 | 56 | ||
58 | /* approximate the number of blocks required for this packet | 57 | /* approximate the number of blocks required for this packet |
59 | in the firmware */ | 58 | in the firmware */ |
60 | /* FIXME: try to figure out what is done here and make it cleaner */ | 59 | total_blocks = total_len + TX_HW_BLOCK_SIZE - 1; |
61 | total_blocks = (total_len + 20) >> TX_HW_BLOCK_SHIFT_DIV; | 60 | total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE; |
62 | excluded = (total_blocks << 2) + ((total_len + 20) & 0xff) + 34; | ||
63 | total_blocks += (excluded > 252) ? 2 : 1; | ||
64 | total_blocks += TX_HW_BLOCK_SPARE; | ||
65 | |||
66 | if (total_blocks <= wl->tx_blocks_available) { | 61 | if (total_blocks <= wl->tx_blocks_available) { |
67 | desc = (struct wl1271_tx_hw_descr *)skb_push( | 62 | desc = (struct wl1271_tx_hw_descr *)skb_push( |
68 | skb, total_len - skb->len); | 63 | skb, total_len - skb->len); |
@@ -87,8 +82,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) | |||
87 | static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, | 82 | static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, |
88 | u32 extra, struct ieee80211_tx_info *control) | 83 | u32 extra, struct ieee80211_tx_info *control) |
89 | { | 84 | { |
85 | struct timespec ts; | ||
90 | struct wl1271_tx_hw_descr *desc; | 86 | struct wl1271_tx_hw_descr *desc; |
91 | int pad, ac; | 87 | int pad, ac; |
88 | s64 hosttime; | ||
92 | u16 tx_attr; | 89 | u16 tx_attr; |
93 | 90 | ||
94 | desc = (struct wl1271_tx_hw_descr *) skb->data; | 91 | desc = (struct wl1271_tx_hw_descr *) skb->data; |
@@ -102,8 +99,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, | |||
102 | } | 99 | } |
103 | 100 | ||
104 | /* configure packet life time */ | 101 | /* configure packet life time */ |
105 | desc->start_time = cpu_to_le32(jiffies_to_usecs(jiffies) - | 102 | getnstimeofday(&ts); |
106 | wl->time_offset); | 103 | hosttime = (timespec_to_ns(&ts) >> 10); |
104 | desc->start_time = cpu_to_le32(hosttime - wl->time_offset); | ||
107 | desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); | 105 | desc->life_time = cpu_to_le16(TX_HW_MGMT_PKT_LIFETIME_TU); |
108 | 106 | ||
109 | /* configure the tx attributes */ | 107 | /* configure the tx attributes */ |
@@ -170,7 +168,6 @@ static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb, | |||
170 | 168 | ||
171 | /* write packet new counter into the write access register */ | 169 | /* write packet new counter into the write access register */ |
172 | wl->tx_packets_count++; | 170 | wl->tx_packets_count++; |
173 | wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); | ||
174 | 171 | ||
175 | desc = (struct wl1271_tx_hw_descr *) skb->data; | 172 | desc = (struct wl1271_tx_hw_descr *) skb->data; |
176 | wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)", | 173 | wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)", |
@@ -245,6 +242,7 @@ void wl1271_tx_work(struct work_struct *work) | |||
245 | struct sk_buff *skb; | 242 | struct sk_buff *skb; |
246 | bool woken_up = false; | 243 | bool woken_up = false; |
247 | u32 sta_rates = 0; | 244 | u32 sta_rates = 0; |
245 | u32 prev_tx_packets_count; | ||
248 | int ret; | 246 | int ret; |
249 | 247 | ||
250 | /* check if the rates supported by the AP have changed */ | 248 | /* check if the rates supported by the AP have changed */ |
@@ -261,6 +259,8 @@ void wl1271_tx_work(struct work_struct *work) | |||
261 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 259 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
262 | goto out; | 260 | goto out; |
263 | 261 | ||
262 | prev_tx_packets_count = wl->tx_packets_count; | ||
263 | |||
264 | /* if rates have changed, re-configure the rate policy */ | 264 | /* if rates have changed, re-configure the rate policy */ |
265 | if (unlikely(sta_rates)) { | 265 | if (unlikely(sta_rates)) { |
266 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); | 266 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); |
@@ -271,31 +271,26 @@ void wl1271_tx_work(struct work_struct *work) | |||
271 | if (!woken_up) { | 271 | if (!woken_up) { |
272 | ret = wl1271_ps_elp_wakeup(wl, false); | 272 | ret = wl1271_ps_elp_wakeup(wl, false); |
273 | if (ret < 0) | 273 | if (ret < 0) |
274 | goto out; | 274 | goto out_ack; |
275 | woken_up = true; | 275 | woken_up = true; |
276 | } | 276 | } |
277 | 277 | ||
278 | ret = wl1271_tx_frame(wl, skb); | 278 | ret = wl1271_tx_frame(wl, skb); |
279 | if (ret == -EBUSY) { | 279 | if (ret == -EBUSY) { |
280 | /* firmware buffer is full, stop queues */ | 280 | /* firmware buffer is full, lets stop transmitting. */ |
281 | wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, " | ||
282 | "stop queues"); | ||
283 | ieee80211_stop_queues(wl->hw); | ||
284 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | ||
285 | skb_queue_head(&wl->tx_queue, skb); | 281 | skb_queue_head(&wl->tx_queue, skb); |
286 | goto out; | 282 | goto out_ack; |
287 | } else if (ret < 0) { | 283 | } else if (ret < 0) { |
288 | dev_kfree_skb(skb); | 284 | dev_kfree_skb(skb); |
289 | goto out; | 285 | goto out_ack; |
290 | } else if (test_and_clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, | ||
291 | &wl->flags)) { | ||
292 | /* firmware buffer has space, restart queues */ | ||
293 | wl1271_debug(DEBUG_TX, | ||
294 | "complete_packet: waking queues"); | ||
295 | ieee80211_wake_queues(wl->hw); | ||
296 | } | 286 | } |
297 | } | 287 | } |
298 | 288 | ||
289 | out_ack: | ||
290 | /* interrupt the firmware with the new packets */ | ||
291 | if (prev_tx_packets_count != wl->tx_packets_count) | ||
292 | wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); | ||
293 | |||
299 | out: | 294 | out: |
300 | if (woken_up) | 295 | if (woken_up) |
301 | wl1271_ps_elp_sleep(wl); | 296 | wl1271_ps_elp_sleep(wl); |
@@ -308,11 +303,10 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
308 | { | 303 | { |
309 | struct ieee80211_tx_info *info; | 304 | struct ieee80211_tx_info *info; |
310 | struct sk_buff *skb; | 305 | struct sk_buff *skb; |
311 | u16 seq; | ||
312 | int id = result->id; | 306 | int id = result->id; |
313 | 307 | ||
314 | /* check for id legality */ | 308 | /* check for id legality */ |
315 | if (id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL) { | 309 | if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) { |
316 | wl1271_warning("TX result illegal id: %d", id); | 310 | wl1271_warning("TX result illegal id: %d", id); |
317 | return; | 311 | return; |
318 | } | 312 | } |
@@ -336,15 +330,10 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
336 | wl->stats.retry_count += result->ack_failures; | 330 | wl->stats.retry_count += result->ack_failures; |
337 | 331 | ||
338 | /* update security sequence number */ | 332 | /* update security sequence number */ |
339 | seq = wl->tx_security_seq_16 + | 333 | wl->tx_security_seq += (result->lsb_security_sequence_number - |
340 | (result->lsb_security_sequence_number - | 334 | wl->tx_security_last_seq); |
341 | wl->tx_security_last_seq); | ||
342 | wl->tx_security_last_seq = result->lsb_security_sequence_number; | 335 | wl->tx_security_last_seq = result->lsb_security_sequence_number; |
343 | 336 | ||
344 | if (seq < wl->tx_security_seq_16) | ||
345 | wl->tx_security_seq_32++; | ||
346 | wl->tx_security_seq_16 = seq; | ||
347 | |||
348 | /* remove private header from packet */ | 337 | /* remove private header from packet */ |
349 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | 338 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); |
350 | 339 | ||
@@ -361,29 +350,37 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
361 | result->id, skb, result->ack_failures, | 350 | result->id, skb, result->ack_failures, |
362 | result->rate_class_index, result->status); | 351 | result->rate_class_index, result->status); |
363 | 352 | ||
353 | /* FIXME: do we need to tell the stack about the used rate? */ | ||
354 | |||
364 | /* return the packet to the stack */ | 355 | /* return the packet to the stack */ |
365 | ieee80211_tx_status(wl->hw, skb); | 356 | ieee80211_tx_status(wl->hw, skb); |
366 | wl->tx_frames[result->id] = NULL; | 357 | wl->tx_frames[result->id] = NULL; |
367 | } | 358 | } |
368 | 359 | ||
369 | /* Called upon reception of a TX complete interrupt */ | 360 | /* Called upon reception of a TX complete interrupt */ |
370 | void wl1271_tx_complete(struct wl1271 *wl, u32 count) | 361 | void wl1271_tx_complete(struct wl1271 *wl) |
371 | { | 362 | { |
372 | struct wl1271_acx_mem_map *memmap = | 363 | struct wl1271_acx_mem_map *memmap = |
373 | (struct wl1271_acx_mem_map *)wl->target_mem_map; | 364 | (struct wl1271_acx_mem_map *)wl->target_mem_map; |
365 | u32 count, fw_counter; | ||
374 | u32 i; | 366 | u32 i; |
375 | 367 | ||
376 | wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); | ||
377 | |||
378 | /* read the tx results from the chipset */ | 368 | /* read the tx results from the chipset */ |
379 | wl1271_read(wl, le32_to_cpu(memmap->tx_result), | 369 | wl1271_read(wl, le32_to_cpu(memmap->tx_result), |
380 | wl->tx_res_if, sizeof(*wl->tx_res_if), false); | 370 | wl->tx_res_if, sizeof(*wl->tx_res_if), false); |
371 | fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); | ||
372 | |||
373 | /* write host counter to chipset (to ack) */ | ||
374 | wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + | ||
375 | offsetof(struct wl1271_tx_hw_res_if, | ||
376 | tx_result_host_counter), fw_counter); | ||
377 | |||
378 | count = fw_counter - wl->tx_results_count; | ||
379 | wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); | ||
381 | 380 | ||
382 | /* verify that the result buffer is not getting overrun */ | 381 | /* verify that the result buffer is not getting overrun */ |
383 | if (count > TX_HW_RESULT_QUEUE_LEN) { | 382 | if (unlikely(count > TX_HW_RESULT_QUEUE_LEN)) |
384 | wl1271_warning("TX result overflow from chipset: %d", count); | 383 | wl1271_warning("TX result overflow from chipset: %d", count); |
385 | count = TX_HW_RESULT_QUEUE_LEN; | ||
386 | } | ||
387 | 384 | ||
388 | /* process the results */ | 385 | /* process the results */ |
389 | for (i = 0; i < count; i++) { | 386 | for (i = 0; i < count; i++) { |
@@ -397,11 +394,18 @@ void wl1271_tx_complete(struct wl1271 *wl, u32 count) | |||
397 | wl->tx_results_count++; | 394 | wl->tx_results_count++; |
398 | } | 395 | } |
399 | 396 | ||
400 | /* write host counter to chipset (to ack) */ | 397 | if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && |
401 | wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + | 398 | skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { |
402 | offsetof(struct wl1271_tx_hw_res_if, | 399 | unsigned long flags; |
403 | tx_result_host_counter), | 400 | |
404 | le32_to_cpu(wl->tx_res_if->tx_result_fw_counter)); | 401 | /* firmware buffer has space, restart queues */ |
402 | wl1271_debug(DEBUG_TX, "tx_complete: waking queues"); | ||
403 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
404 | ieee80211_wake_queues(wl->hw); | ||
405 | clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | ||
406 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
407 | ieee80211_queue_work(wl->hw, &wl->tx_work); | ||
408 | } | ||
405 | } | 409 | } |
406 | 410 | ||
407 | /* caller must hold wl->mutex */ | 411 | /* caller must hold wl->mutex */ |
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index 17e405a09caa..8b9f6b4f5652 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #define __WL1271_TX_H__ | 26 | #define __WL1271_TX_H__ |
27 | 27 | ||
28 | #define TX_HW_BLOCK_SPARE 2 | 28 | #define TX_HW_BLOCK_SPARE 2 |
29 | #define TX_HW_BLOCK_SHIFT_DIV 8 | 29 | #define TX_HW_BLOCK_SIZE 252 |
30 | 30 | ||
31 | #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 | 31 | #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 |
32 | /* The chipset reference driver states, that the "aid" value 1 | 32 | /* The chipset reference driver states, that the "aid" value 1 |
@@ -160,7 +160,7 @@ static inline int wl1271_tx_ac_to_tid(int ac) | |||
160 | } | 160 | } |
161 | 161 | ||
162 | void wl1271_tx_work(struct work_struct *work); | 162 | void wl1271_tx_work(struct work_struct *work); |
163 | void wl1271_tx_complete(struct wl1271 *wl, u32 count); | 163 | void wl1271_tx_complete(struct wl1271 *wl); |
164 | void wl1271_tx_flush(struct wl1271 *wl); | 164 | void wl1271_tx_flush(struct wl1271 *wl); |
165 | 165 | ||
166 | #endif | 166 | #endif |